1. 程式人生 > 其它 >Docker叢集編排工具之Kubernetes(K8s)介紹、安裝及使用

Docker叢集編排工具之Kubernetes(K8s)介紹、安裝及使用

Docker叢集編排工具之Kubernetes(K8s)介紹、安裝及使用

目錄


回到頂部

K8s基礎原理

k8s中文社群:https://www.kubernetes.org.cn/

簡介

Kubernetes與較早的叢集管理系統Mesos和YARN相比,對容器尤其是 Docker的支援更加原生,同時提供了更強大的機制實現資源排程,自動 管理容器生命週期,負載均衡,高可用等底層功能,使開發者可以專注於開發應用。

Kubernetes是一個開源的,用於管理雲平臺中多個主機上的容器化的應用,Kubernetes的目標是讓部署容器化的應用簡單並且高效(powerful),Kubernetes提供了應用部署,規劃,更新,維護的一種機制。

K8s特性

Kubernetes是為生產環境而設計的容器排程管理系統,對於負載均衡、 服務發現、高可用、滾動升級、自動伸縮等容器雲平臺的功能要求有原生支援

一個K8s叢集是由分散式儲存(etcd)、服務節點(Minion, etcd現在稱為Node)和控制節點(Master)構成的。所有的叢集狀態都儲存在etcd中,Master節點上則執行叢集的管理控制模組。Node節點是真正執行應用容器的主機節點,在每個Minion節點上都會執行一個Kubelet代理,控制該節點上的容器、映象和儲存卷等。

K8s架構圖,介紹

Master(管理節點)

  • API Server:供Kubernetes API介面,主要處理 Rest操作以及更新Etcd中的物件。 所有資源增刪改查的唯一入口。
  • Scheduler:繫結Pod到Node上,資源排程。
  • Controller Manager: 所有其他群集級別的功能,目前由控制器Manager執行。資源物件的 自動化控制中心。
  • Etcd:所有持久化的狀態資訊儲存在Etcd中。

Node(計算節點)

  • Kubelet:管理Pods以及容器、映象、Volume等,實現對叢集 對節點的管理
  • Kube-proxy:提供網路代理以及負載均衡,實現與Service通訊。
  • Docker Engine:負責節點的容器的管理工作。

API SERVER(授權)

  • 只有API Server與儲存通訊,其他模組通過 API Server訪問叢集狀態。
  • 一個工作節點的問題不影響叢集體。
  • 在K8s叢集中,所有的配置管理操作都宣告 式而非命令式的。
  • 各個模組在記憶體中快取自己的相關狀態以 提高系統性能。

Scheduler(資源排程)

  • 負責叢集的資源排程,根據特定的排程演算法將pod排程到指定的minion上。
  • 這部分工作分出來變成一個元件,意味著可以很方便地替換成其他的排程器。
  • Scheduler排程器輸入是待排程pod和可用的工作節點列表,輸出則是應用排程 演算法從列表中選擇一個最優的用於繫結待排程的pod節點。

Controller Manager(控制管理中心)

  • Controller Manager作為叢集內部的管理控制中心,負責叢集內的Node、Pod副本、服務端點、名稱空間、服務賬號、資源定額等的管理並執行自動化修復流程,確保叢集處於預期的工作狀態
  • 在Kubernetes叢集中,每個Controller就是一個作業系統,它通過API Server監控系統的共享狀態,並嘗試著將系統狀態從“現有狀態”修正到“期望狀態”

POD(資源池)

  • Pod是K8s叢集中所有業務型別的基礎
  • Pod是在K8s叢集中執行部署應用或服務的最小單元,它是可以支援多容器的。
  • Pod的設計理念是支援多個容器在一個Pod中共享網路地址和檔案系統。
  • POD控制器Deployment、Job、DaemonSet和 PetSet

LABEL(標籤)

  • Label是一個 key=value的鍵值對,由使用者指定,可以附加到 K8S資源之上。
  • 給某個資源定義一個標籤,隨後可以通過label進行查詢和篩選 ,類似SQL的where語句。
  • Label可以給物件建立多組標籤

Replication Controller,RC

  • RC是K8s叢集中最早的保證Pod高可用的API物件。通過監控執行中的Pod來保證叢集中執行指定數目的Pod副本。
  • 指定的數目可以是多個也可以是1個;少於指定數目,RC就會啟動執行新的Pod副本;多於指定數目,RC就會殺死多餘的Pod副本。
  • 即使在指定數目為1的情況下,通過RC執行Pod也比直接執行Pod更明智,因為RC也可以發揮它高可用的能力,保證永遠有1個Pod在執行。
PC總結
  • RC裡包括完整的POD定義模板
  • RC通過Label Selector(標籤選擇器)機制實現對POD副本的自動控制。
  • 通過改變RC裡的POD副本以實現POD的擴容和縮容
  • 通過改變RC裡POD模組中的映象版本,可以實現POD的滾動升級。

K8s元件

回到頂部

K8s安裝配置

K8s安裝方法

yum安裝 1.5.2

二進位制安裝

kubeadm安裝(官方) 需要梯子,全部容器化

minkube安裝

編譯安裝

自動化安裝

K8s資源

官網    kubernetes.io

中文社群  https://www.kubernetes.org.cn/

Github   https://github.com/kubernetes/kubernetes

命令列參考https://kubernetes.io/docs/reference/generated/kub ectl/kubectl-commands#

K8s的安裝環境要求

1、linux 核心3.10以上

2、64位系統

3、記憶體4G

4、安裝epel

5、安裝docker

6、開啟yum cache儲存安裝RPM包

K8s中有三種類型的ip

物理ip(宿主機ip)

叢集ip(cluster ip):10.254.0.0/16

pod(容器的ip):172.16.0.0/16

回到頂部

K8s安裝與使用

安裝

環境:三臺機器,兩個node(計算節點),一個主節點(master)

yum源需要:repo:CentOS-Base.repo docker1.12

主節點(master)

主機名:K8s-master ip:10.0.0.11 系統:centos7.2

yuminstalletcd -yyuminstalldocker -yyuminstallkubernetes -yyuminstallflannel -y

計算節點(node)

K8s-node-1 10.0.0.12 centos7.2

K8s-node-2 10.0.0.13 centos7.2

yuminstalldocker -yyuminstallkubernetes -yyuminstallflannel -y

在master節點上

修改配置

修改etcd配置檔案
[root@k8s-master ~]# vim /etc/etcd/etcd.confETCD_NAME="default"ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"ETCD_ADVERTISE_CLIENT_URLS="http://10.0.0.11:2379"

啟動

systemctl enable etcd.servicesystemctl start etcd.service

檢查

[root@k8s-master ~]# etcdctl -C http://10.0.0.11:2379 cluster-healthmember 8e9e05c52164694d is healthy: got healthy result from http://10.0.0.11:2379cluster is healthy
修改/etc/kubernetes/apiserver
vim /etc/kubernetes/apiserver8KUBE_API_ADDRESS="--insecure-bind-address=0.0.0.0"11KUBE_API_PORT="--port=8080"17KUBE_ETCD_SERVERS="--etcd-servers=http://10.0.0.11:2379"23KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ResourceQuota"
修改/etc/kubernetes/config
vim /etc/kubernetes/config22KUBE_MASTER="--master=http://10.0.0.11:8080"

啟動

systemctl enable kube-apiserver.servicesystemctl start kube-apiserver.servicesystemctl enable kube-controller-manager.servicesystemctl start kube-controller-manager.servicesystemctl enable kube-scheduler.servicesystemctl start kube-scheduler.service

檢視是否啟動成功

systemctl status kube-apiserver.service kube-controller-manager.service kube-scheduler.service

在node節點

vim /etc/kubernetes/configKUBE_MASTER="--master=http://10.0.0.11:8080"

node-1

vim /etc/kubernetes/kubeletKUBELET_ADDRESS="--address=0.0.0.0"KUBELET_HOSTNAME="--hostname-override=10.0.0.12"KUBELET_API_SERVER="--api-servers=http://10.0.0.11:8080"

node-2

vim /etc/kubernetes/kubeletKUBELET_ADDRESS="--address=0.0.0.0"KUBELET_HOSTNAME="--hostname-override=10.0.0.13"KUBELET_API_SERVER="--api-servers=http://10.0.0.11:8080"

啟動檢查

systemctl enable kubelet.servicesystemctl start kubelet.servicesystemctl enable kube-proxy.servicesystemctl start kube-proxy.service

檢查:

[root@k8s-master ~]# kubectl get nodesNAME STATUS AGE10.0.0.12Ready 3m10.0.0.13Ready 3m

配置flannel網路

修改配置檔案

master、node上均編輯/etc/sysconfig/flanneld

vim /etc/sysconfig/flanneldFLANNEL_ETCD_ENDPOINTS="http://10.0.0.11:2379"

配置flannel的網路範圍

etcdctl mk /atomic.io/network/config '{ "Network": "172.16.0.0/16" }'

實操:

[root@k8s-master ~]# etcdctl mk /atomic.io/network/config'{ "Network": "172.16.0.0/16" }'{"Network":"172.16.0.0/16"}

啟動

在master執行:

systemctl enable flanneld.service systemctl start flanneld.service service docker restartsystemctl restart kube-apiserver.servicesystemctl restart kube-controller-manager.servicesystemctl restart kube-scheduler.service

在node上執行:

systemctl enable flanneld.service systemctl start flanneld.service service docker restartsystemctl restart kubelet.servicesystemctl restart kube-proxy.service

K8s常見命令操作

命令:kubectl create -f hello.yaml

檔案內容:

[root@k8s-master ~]# vim hello.yaml apiVersion: v1kind: Podmetadata: name: hello-worldspec: restartPolicy: Never containers:-name: hello image:"docker.io/busybox:latest"command: ["/bin/echo","hello”,”world"]

實操:

[root@k8s-master ~]# kubectl create -f hello.yamlpod"hello-world"createdkubectl get pods 檢視預設name資訊kubectl describe pods hello-world 檢視hello-world的詳細資訊kubectl delete pods hello-world 刪除名叫hello-worldkubectl replace-f nginx-rc.yaml 對已有資源進行更新、替換kubectl edit rc nginx 對現有資源直接進行修改,立即生效kubectl logs nginx-gt1jd    檢視訪問日誌

存在的坑

因為沒有證書,拉取影象失敗。

[root@k8s-master ~]# kubectl describe pods hello-worldName: hello-worldNamespace: defaultNode:10.0.0.13/10.0.0.13Start Time: Fri,02Feb201819:28:31+0800Labels:<none>Status: PendingIP: Controllers:<none>Containers: hello: Container ID: Image: docker.io/busybox:latest Image ID: Port: Command:/bin/echohello”,”world State: Waiting Reason: ContainerCreating Ready: False Restart Count:0Volume Mounts:<none>Environment Variables:<none>Conditions: Type Status Initialized True Ready False PodScheduled True No volumes.QoS Class: BestEffortTolerations:<none>Events: FirstSeen LastSeen Count From SubObjectPath Type Reason Message--------- -------- ----- ---- ------------- -------- ------ -------4m 4m1{default-scheduler } Normal Scheduled Successfully assigned hello-world to10.0.0.134m 1m5{kubelet10.0.0.13} Warning FailedSync Error syncing pod, skipping: failed to"StartContainer"for"POD"with ErrImagePull:"image pull failed for registry.access.redhat.com/rhel7/pod-infrastructure:latest, this may be because there are no credentials on this request. details: (open /etc/docker/certs.d/registry.access.redhat.com/redhat-ca.crt: no such file or directory)"3m 5s16{kubelet10.0.0.13} Warning FailedSync Error syncing pod, skipping: failed to"StartContainer"for"POD"with ImagePullBackOff:"Back-off pulling image \"registry.access.redhat.com/rhel7/pod-infrastructure:latest\""

解決:yum install python-rhsm* -y

建立:

[root@k8s-master ~]# kubectl create -f nginx.yaml pod"hello-nginx"created

檢查是否成功

[root@k8s-master ~]# kubectl get pods -o wideNAME READY STATUS RESTARTS AGE IP NODEhello-nginx1/1Running02h172.16.42.210.0.0.13

RC:保證高可用

  • RC是K8s叢集中最早的保證Pod高可用的API物件。通過監控執行中的Pod來保證叢集中執行指定數目的Pod副本。
  • 指定的數目可以是多個也可以是1個;少於指定數目,RC就會啟動執行新的Pod副本;多於指定數目,RC就會殺死多餘的Pod副本。
  • 即使在指定數目為1的情況下,通過RC執行Pod也比直接執行Pod更明智,因為RC也可以發揮它高可用的能力,保證永遠有1個Pod在執行。

始終保持一個在活著

rc版yaml編寫:

[root@k8s-master ~]#catnginx-rc.yaml apiVersion: v1kind: ReplicationControllermetadata: name: nginxspec: replicas:1selector: app: nginx template: metadata: labels: app: nginx spec: containers:-name: nginx image: nginx:latest ports:- containerPort:80

啟動rc版容器

[root@k8s-master ~]# kubectl create -f nginx-rc.yaml replicationcontroller"nginx"created

檢查:

[root@k8s-master ~]# kubectl get pods -o wideNAME READY STATUS RESTARTS AGE IP NODEnginx-gt1jd1/1Running02m172.16.79.210.0.0.12

這樣的話就算刪除了這個容器RC也會立馬在起一個

版本升級

[root@k8s-master ~]#catweb-rc2.yaml apiVersion: v1kind: ReplicationControllermetadata: name: myweb-2spec: replicas:2selector: app: myweb-2template: metadata: labels: app: myweb-2spec: containers:- name: myweb-2image: kubeguide/tomcat-app:v2 ports:- containerPort:8080env:-name: MYSQL_SERVICE_HOST value:'mysql'-name: MYSQL_SERVICE_PORT value:'3306'

升級操作:

[root@k8s-master ~]# kubectl rolling-update myweb -f web-rc2.yaml Created myweb-2Scaling up myweb-2from0to2, scaling down myweb from2to0(keep2pods available, don't exceed 3 pods)Scaling myweb-2up to1Scaling myweb down to1Scaling myweb-2up to2Scaling myweb down to0Update succeeded. Deleting mywebreplicationcontroller"myweb"rolling updated to"myweb-2"

升級過程

[root@k8s-master ~]# kubectl get pods -o wideNAME READY STATUS RESTARTS AGE IP NODEmyweb-2-mmlcm1/1Running032s172.16.42.310.0.0.13myweb-714381/1Running02m172.16.42.210.0.0.13myweb-cx9j21/1Running02m172.16.79.310.0.0.12nginx-gt1jd1/1Running01h172.16.79.210.0.0.12[root@k8s-master ~]# kubectl get pods -o wideNAME READY STATUS RESTARTS AGE IP NODEmyweb-2-0kmzf1/1Running07s172.16.79.410.0.0.12myweb-2-mmlcm1/1Running01m172.16.42.310.0.0.13myweb-cx9j21/1Running02m172.16.79.310.0.0.12nginx-gt1jd1/1Running01h172.16.79.210.0.0.12

回滾

[root@k8s-master ~]#catweb-rc.yaml apiVersion: v1kind: ReplicationControllermetadata: name: mywebspec: replicas:2selector: app: myweb template: metadata: labels: app: myweb spec: containers:-name: myweb image: kubeguide/tomcat-app:v1 ports:- containerPort:8080env:-name: MYSQL_SERVICE_HOST value:'mysql'-name: MYSQL_SERVICE_PORT value:'3306'

操作:

[root@k8s-master ~]# kubectl rolling-update myweb-2-f web-rc.yaml Created mywebScaling up myweb from0to2, scaling down myweb-2from2to0(keep2pods available, don't exceed 3 pods)Scaling myweb up to1Scaling myweb-2down to1Scaling myweb up to2Scaling myweb-2down to0Update succeeded. Deleting myweb-2replicationcontroller"myweb-2"rolling updated to"myweb"

檢查

[root@k8s-master ~]# kubectl get pods -o wideNAME READY STATUS RESTARTS AGE IP NODEmyweb-mbndc1/1Running01m172.16.79.310.0.0.12myweb-qh38r1/1Running02m172.16.42.210.0.0.13nginx-gt1jd1/1Running01h172.16.79.210.0.0.12

svc設定

[root@k8s-master ~]#catweb-svc.yaml apiVersion: v1kind: Servicemetadata: name: mywebspec: type: NodePort ports:- port:8080nodePort:30001selector: app: myweb [root@k8s-master ~]# kubectl create -f web-svc.yaml [root@k8s-master ~]# kubectl get svcNAME CLUSTER-IP EXTERNAL-IP PORT(S) AGEkubernetes10.254.0.1<none>443/TCP 6hmyweb10.254.91.34<nodes>8080:30001/TCP 1m

然後取node節點檢查30001埠是否啟動

然後瀏覽器web訪問node節點的ip:30001進行測試

web介面管理

[root@k8s-master ~]#catdashboard.yaml apiVersion: extensions/v1beta1kind: Deploymentmetadata:# Keep the nameinsyncwith image version and# gce/coreos/kube-manifests/addons/dashboard counterparts name: kubernetes-dashboard-latest namespace: kube-systemspec: replicas:1template: metadata: labels: k8s-app: kubernetes-dashboard version: latest kubernetes.io/cluster-service:"true"spec: containers:- name: kubernetes-dashboard image: index.tenxcloud.com/google_containers/kubernetes-dashboard-amd64:v1.4.1resources: # keep request= limit to keep this containeringuaranteed class limits: cpu: 100m memory: 50Mi requests: cpu: 100m memory: 50Mi ports:- containerPort:9090args:- --apiserver-host=http://10.0.0.11:8080livenessProbe: httpGet: path:/port:9090initialDelaySeconds:30timeoutSeconds:30

操作:

[root@k8s-master ~]#catdashboard-svc.yaml apiVersion: v1kind: Servicemetadata: name: kubernetes-dashboard namespace: kube-system labels: k8s-app: kubernetes-dashboard kubernetes.io/cluster-service:"true"spec: selector: k8s-app: kubernetes-dashboard ports:- port:80targetPort:9090

啟動:

kubectl create -f dashboard.yamlkubectl create-f dashboard-svc.yaml

然後訪問:http://10.0.0.11:8080/ui/