Kubernetes食用指南

Kubernetes食用簡介

Kubernetes是Google在2014年6月開源的一個容器集羣管理系統,使用Go語言開發,Kubernetes也叫K8S。K8S是Google內部一個叫Borg的容器集羣管理系統衍生出來的,Borg已經在Google大規模生產運行十年之久。
K8S主要用於自動化部署、擴展和管理容器應用,提供了資源調度、部署管理、服務發現、擴容縮容、監控等一整套功能;2015年7月,Kubernetes v1.0正式發佈,截止到2018年8月2日最新穩定版本是v1.15.1,最新穩定版本是v1.16.0-alpha.2,Kubernetes目標是讓部署容器化應用簡單高效。

官方網站:https://kubernetes.io

Kubernetes主要功效

數據卷
Pod中容器之間共享數據,可以使用數據卷;
應用程序健康檢
查容器內服務可能進程堵塞無法處理請求,可以設置監控檢查策略保證應用健壯性;
複製應用程序實例
控制器維護着Pod副本數量,保證一個Pod或一組同類的Pod數量始終可用;
彈性伸縮
根據設定的指標(CPU利用率)自動縮放Pod副本數;
服務發現
使用環境變量或DNS服務插件保證容器中程序發現Pod入口訪問地址;
負載均衡
一組Pod副本分配一個私有的集羣IP地址,負載均衡轉發請求到後端容器,在集羣內部其他Pod可通過這個ClusterIP訪問應用;
滾動更新
更新服務不中斷,一次更新一個Pod,而不是同時刪除整個服務;
服務編排
通過文件描述部署服務,使得應用程序部署變得更高效;
資源監控
Node節點組件集成cAdvisor資源收集工具,可通過Heapster彙總整個集羣節點資源數據,然後存儲到InfluxDB時序數據庫,再由Grafana展示;
提供認證和授權
支持屬性訪問控制(ABAC)、角色訪問控制(RBAC)認證授權策略;

Kubernetes基本對象概念

PodPod
是最小部署單元,一個Pod有一個或多個容器組成,Pod中容器共享存儲和網絡,在同一臺Docker主機上運行;
Service
Service一個應用服務抽象,定義了Pod邏輯集合和訪問這個Pod集合的策略,Service代理Pod集合對外表現是爲一個訪問入口,分配一個集羣IP地址,來自這個IP的請求將負載均衡轉發後端Pod中的容器,Service通過Lable Selector選擇一組Pod提供服務;
Volume
數據卷,共享Pod中容器使用的數據;
Namespace
命名空間將對象邏輯上分配到不同Namespace,可以是不同的項目、用戶等區分管理,並設定控制策略,從而實現多租戶;命名空間也稱爲虛擬集羣;
Lable
標籤用於區分對象(比如Pod、Service),鍵/值對存在,每個對象可以有多個標籤,通過標籤關聯對象;
ReplicaSet
下一代Replication Controller;確保任何給定時間指定的Pod副本數量,並提供聲明式更新等功能;RC與RS唯一區別就是lable selector支持不同,RS支持新的基於集合的標籤,RC僅支持基於等式的標籤;
Deployment
Deployment是一個更高層次的API對象,它管理ReplicaSets和Pod,並提供聲明式更新等功能,官方建議使用Deployment管理ReplicaSets,而不是直接使用ReplicaSets,這就意味着可能永遠不需要直接操作ReplicaSet對象;
Stateful
SetStatefulSet適合持久性的應用程序,有唯一的網絡標識符(IP),持久存儲,有序的部署、擴展、刪除和滾動更新;
DaemonSet
DaemonSet確保所有(或一些)節點運行同一個Pod;當節點加入Kubernetes集羣中,Pod會被調度到該節點上運行,當節點從集羣中移除時,DaemonSet的Pod會被刪除;刪除DaemonSet會清理它所有創建的Pod;
Job
一次性任務,運行完成後Pod銷燬,不再重新啓動新容器,還可以任務定時運行;

系統架構及組件功能

Kubernetes成分

Master組件:

kube-apiserver
Kubernetes API,集羣的統一入口,各組件協調者,以HTTP API提供接口服務,所有對象資源的增刪改查和監聽操作都交給APIServer處理後再提交給Etcd存儲;

kube-controller-manager
處理集羣中常規後臺任務,一個資源對應一個控制器,而ControllerManager就是負責管理這些控制器的;

kube-scheduler
根據調度算法爲新創建的Pod選擇一個Node節點;

Node組件:

kubelet
kubelet是Master在Node節點上的Agent,管理本機運行容器的生命週期,比如創建容器、Pod掛載數據卷、下載secret、獲取容器和節點狀態等工作,kubelet將每個Pod轉換成一組容器;

kube-proxy
在Node節點上實現Pod網絡代理,維護網絡規則和四層負載均衡工作;

docker或rocket/rkt
運行容器;

第三方服務:

etcd
分佈式鍵值存儲系統;用於保持集羣狀態,比如Pod、Service等對象信息;

非必要組件:

kube-dns
負責爲整個集羣提供DNS服務

Ingress Controller
爲服務提供外網入口

Heapster
提供資源監控

Dashboard
提供GUI

Federation
提供跨可用區的集羣

Fluentd-elasticsearch
提供集羣日誌採集、存儲與查詢

系統架構及組件功能

Kubernetes食用配方

角色IP組件
master192.168.0.201etcd
kube-apiserver
kube-controller-manager
kube-scheduler
node01192.168.0.202kubelet
kube-proxy
docker
node02192.168.0.203kubelet
kube-proxy
docker
Pod 網絡10.244.0.0/16
Service 網絡10.96.0.0/12
  1. 獲取 yum 源

  2. 安裝 Docker、Kubelet、Kubeadm、Kubectl 到所有節點上

  3. Master節點初始化

  4. Flannel安裝

  5. 節點加入

獲取 yum 源

#進入 yum 的 repo 目錄cd /etc/yum.repos.d/#獲取 Docker 的 yum 源wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo#編寫 Kubernetes 的 yum 源vim /etc/yum.repos.d/kubernetes.repo
[Kubernetes]
name=Kubernetes Repo
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
gpgcheck=0gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
enabled=1#檢測 yum 源的可用性yum repolist

安裝 Docker、Kubelet、Kubeadm、Kubectl 到所有節點上

#yum 安裝所需部件yum -y install docker-ce kubelet kubeadm kubectl#啓動 Docker 服務systemctl start docker#設置開機自啓systemctl enable docker
systemctl enable kubelet


在啓動 Docker 前,由於某種不可抗力和不可描述的原因,建議國內的程序猿修改HttpsProxy的參數,具體如下:


vim /usr/lib/systemd/system/docker.service 
Environment="HTTPS_PROXY=http://www.ik8s.io:10080"Environment="NO_PROXY=127.0.0.0/8,192.168.0.0/24"systemctl daemon-reload
systemctl restart docker
docker info

docker.service

#檢查bridge-nfcat /proc/sys/net/bridge/bridge-nf-call-ip6tables1cat /proc/sys/net/bridge/bridge-nf-call-iptables1

Master節點初始化

#配置kubelet文件,使其忽略 Swap 的報錯vim /etc/sysconfig/kubelet
KUBELET_EXTRA_ARGS="--fail-swap-on=false"kubeadm init --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/12 --ignore-preflight-errors=Swap

Master節點初始化結果

#根據初始化完成後所給的提示進行設置(建議創建普通用戶進行操作)mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config#查看集羣健康狀態kubectl get cs
NAME                 STATUS    MESSAGE             ERROR
scheduler            Healthy   ok                  
controller-manager   Healthy   ok                  
etcd-0               Healthy   {"health":"true"}#查看集羣節點信息kubectl get node
NAME                  STATUS     ROLES    AGE     VERSION
centos701.0x50j.com   NotReady   master   9m52s   v1.15.2
#查看 docker 容器docker ps

Docker容器

#查看 docker 鏡像docker images

Docker鏡像


節點狀態之所以顯示 NoReady 是應爲還沒有安裝flannel


Flannel安裝

#自動拉取鏡像啓動kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml#查看 Pods 網絡信息kubectl get pods -n kube-system -o wide#查看節點狀態是否爲 Ready 狀態kubectl get node
NAME                  STATUS   ROLES    AGE   VERSION
centos701.0x50j.com   Ready    master   27m   v1.15.2

節點加入集羣

#加入集羣kubeadm join [MastertIP地址]:6443 --token [token值] --discovery-token-ca-cert-hash [證書哈希值] --ignore-preflight-errors=Swap#主節點上獲取節點信息kubectl get node
NAME                  STATUS   ROLES    AGE   VERSION
centos701.0x50j.com   Ready    master   15h   v1.15.2centos702.0x50j.com   Ready    <none>   15h   v1.15.2centos703.0x50j.com   Ready    <none>   15h   v1.15.2


token值和證書哈希值在初始化集羣的時候有提供


Dashboard可視化插件

#下載yaml文件到本地wget https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/recommended/kubernetes-dashboard.yaml#修改yaml文件,使其外網能訪問vim kubernetes-dashboard.yaml
......
---# ------------------- Dashboard Service ------------------- #kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kube-system
spec:
  type: NodePort       #增加type: NodePort
  ports:
    - port: 443
      targetPort: 8443
      nodePort: 31620  #增加nodePort: 31620
  selector:
    k8s-app: kubernetes-dashboard#修改配置從阿里雲倉庫拉取鏡像vim kubernetes-dashboard.yaml
......
 containers:
  - name: kubernetes-dashboard
    #image: k8s.gcr.io/kubernetes-dashboard-amd64:v1.10.1
    image: registry.cn-hangzhou.aliyuncs.com/google_containers/kubernetes-dashboard-amd64:v1.10.1
    ports:
......#執行部署dashboard服務kubectl create -f kubernetes-dashboard.yaml


查看Pod的狀態爲running說明dashboard已經部署成功
kubectl get pod --namespace=kube-system -o wide | grep dashboard



Dashboard 會在 kube-system namespace 中創建自己的 Deployment 和 Service
kubectl get deployment kubernetes-dashboard --namespace=kube-system
kubectl get service kubernetes-dashboard --namespace=kube-system


Pod的狀態

訪問 https://[host_ip]:31620/#!/login
dashboard web

#創建dashboard-adminuser.yaml,獲取 Tokenvim dashboard-adminuser.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kube-system---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kube-system#執行yaml文件kubectl create -f dashboard-adminuser.yaml#查看admin-user賬戶的tokenkubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk '{print $1}')

查看 Token

使用獲取到的 Token 值登陸 Dashboard 面板
登陸Dashboard面板

Dashboard面板

Kubernetes食用方式

#查詢節點信息kubectl describe node [節點名稱]#查看集羣信息kubectl cluster-info#查看創建了的 Podskubectl get pods -o wide#查看創建了的 Serviceskubectl get services -o wide#查看 Pod 的網絡信息kubectl describe pods [Pod名稱]#查看 Pod 的網絡信息kubectl describe service [Pod名稱]
#運行Podkubectl run NAME --image=image [--env="key=value"] [--port=port] [--replicas=replicas] [--dry-run=bool] [--overrides=inline-json] [--command] -- [COMMAND] [args...] [options]#栗子:運行 Nginx
kubectl run nginx --image=nginx:1.14 --port=80 --replicas=1運行 Busybox
kubectl run client --image=busybox --replicas=1 -it --restart=Never

--image 指定所需食用的鏡像
--port 指定暴露的端口
--replicas 指定創建的個數

#刪除 Podkubectl delete ([-f FILENAME] | [-k DIRECTORY] | TYPE [(NAME | -l label | --all)])#栗子:kubectl delete pods nginx-7c45b84548-7bnr6

TYPE 指定刪除的是什麼類型,如 services,pods
NAME 指定名稱
-l 指定標籤

#創建 servicekubectl expose (-f FILENAME | TYPE NAME) [--port=port] [--protocol=TCP|UDP|SCTP] [--target-port=number-or-name] [--name=name] [--external-ip=external-ip-of-service] [--type=type] [options]#栗子:kubectl expose deployment nginx --name=nginx-service --port=8081 --target-port=80 --protocol=TCP

deployment 指定 deployment pod 的名稱
--name services的名稱
--port 對外的端口
--target-port 對內的端口(pod 暴露的端口)
--protocol 指定協議

#擴展/縮減 pod的數量kubectl scale [--resource-version=version] [--current-replicas=count] --replicas=COUNT (-f FILENAME | TYPE NAME)#栗子:kubectl scale --replicas=0 deployment myapp

--replicas 指定數量

#滾動升級kubectl set image (-f FILENAME | TYPE NAME) CONTAINER_NAME_1=CONTAINER_IMAGE_1#栗子:kubectl set image deployment nginx-web nginx-web=nginx:1.10#回滾到上一版本kubectl rollout undo deployment [Pod名稱]#查看狀態kubectl rollout status deployment nginx-web

CONTAINER_NAME_1 pod的名稱
CONTAINER_IMAGE_1 升級到那個鏡像

#添加標籤kubectl label [--overwrite] (-f FILENAME | TYPE NAME) KEY_1=VAL_1 ... KEY_N=VAL_N [--resource-version=version]#栗子:kubectl label pods test-pod release=canary

TYPE 指定類型,如:svc,pods
NAME 指定名稱
KEY 指定鍵值
VAL 指定標籤值


get信息時可以添加--show-labels查看標籤


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章