pod在以前說過,pod是kubernetes集羣中是最小的調度單元,pod中能夠運行多個容器,而node又能夠包含多個pod,關係以下圖:node
在對pod的用法進行說明以前,有必要先對docker容器進行說明mysql
在使用docker時,可使用docker run命令建立一個容器,而在kubernetes集羣中對長時間運行容器的要求是:nginx
若是咱們建立的docker鏡像的啓動命令是後臺執行程序,例如Linux腳本:web
nohup ./start.sh &
那麼kubelet在建立這個Pod執行完這個命令後,會認爲這個Pod執行完畢,從而進行銷燬pod,若是pod定義了ReplicationController,那麼銷燬了還會在建立,繼續執行上述的命令而後又銷燬,而後又重建,這樣就會陷入惡性循環,這也是爲何執行的命令要運行在前臺的緣由,這一點必定要注意redis
Pod的重啓策略(RestartPolicy):sql
Pod的重啓策略和控制器息息相關,每種控制器對Pod的重啓策略以下:docker
咱們簡單介紹完kubernetes的邏輯結構以後咱們來看一下k8s控制器資源,k8s控制器資源分不少種,有replication controller,deployment,Horizontal pod autoscaler,statefulSet,daemonSet,job等...,接下來咱們來詳細分析一下下面資源的使用場景和區別vim
replication controller簡稱RC,是kubernetes系統中的核心概念之一,簡單來講,它其實定義了一個指望的場景,即聲明某種pod的副本數量在任意時刻都複合某個預期值,因此RC的定義包含如下部分:api
下面是一個完整的RC定義的例子,即確保擁有app=mynginx標籤的這個pod在整個kubernetes集羣中始終只有一個副本,紅色字體必定要一直,由於咱們的控制器就是根據標籤篩選出來的(由於pod的ip和pod名字都會變化):安全
[root@master ~]# vim nginx.yaml apiVersion: v1 kind: ReplicationController metadata: name: myweb namespace: default spec: replicas: 1 selector: app: mynginx template: metadata: labels: app: mynginx spec: containers: - name: mycontainer image: lizhaoqwe/nginx:v1 imagePullPolicy: IfNotPresent ports: - containerPort: 80
在咱們定義了一個RC並將其提交到kubernetes集羣中後,master上的controller Manager組件就獲得了通知,按期巡檢系統中當前存貨的目標pod,並確保目標pod實力數量恰好等於此RC的指望值,若是多餘指望值,則停掉一些,若是少於指望值會再建立一些。
如下面3個Node節點的集羣爲例,說明kubernetes是如何經過RC來實現pod副本數量自動控制的機制,咱們建立2個pod運行redis-slave,系統可能會再兩個節點上建立pod,以下圖
假設Node2上的pod意外終止,則根據RC定義的replicas數量1,kubernetes將會自動建立並啓動兩個新的pod,以保證在整個集羣中始終有兩個redis-slave Pod運行,以下圖所示,系統可能選擇Node3或者Node1來建立新的pod
此外,咱們還能夠經過修改RC的副本數量,來實現Pod的動態擴容和縮容
[root@master ~]# kubectl scale --replicas=3 rc myweb replicationcontroller/myweb scaled
結果以下
這裏須要注意的是,刪除RC並不會影響經過該RC已建立好的pod,爲了刪除全部pod,能夠設置replicas的值爲0,而後更新該RC,另外,kubectl提供了stop和delete命令來一次性刪除RC和RC控制的所有Pod
上一階段講過了ReplicationController控制器以後,相信你們對其已經瞭解了,ReplicaSet控制器其實就是ReplicationController的升級版,官網解釋爲下一代的「RC」,ReplicationController和ReplicaSet的惟一區別是ReplicaSet支持基於集合的Label selector,而RC只支持基於等式的Label Selector,這使得ReplicaSet的功能更強,下面等價於以前的RC例子的ReokucaSet的定義
[root@master ~]# vim replicaSet.yaml apiVersion: extensions/v1beta1 kind: ReplicaSet metadata: name: myweb namespace: default spec: replicas: 1 selector: matchLabels: app: mynginx matchExpressions: - {key: app, operator: In, values: [mynginx]} template: metadata: labels: app: mynginx spec: containers: - name: mycontainer image: lizhaoqwe/nginx:v1 imagePullPolicy: IfNotPresent ports: - containerPort: 80
kubectl命令行工具適用於RC的絕大部分命令一樣適用於ReplicaSet,此外,咱們當前不多單獨適用ReplicaSet,它主要被Deployment這個更高層的資源對象所使用,從而造成一整套Pod建立,刪除,更新的編排機制,咱們在使用Deployment時無需關心它是如何維護和建立ReplicaSet的,這一切都是自動發生的
最後,總結一下RC(ReplicaSet)的一些特性和做用:
Deployment是kubernetes在1.2版本中引入的新概念,用於更好的解決Pod的編排問題,爲此,Deployment在內部使用了ReplicaSet來實現目的,咱們能夠把Deployment理解爲ReplicaSet的一次升級,二者的類似度超過90%
Deployment的使用場景有如下幾個:
除了API生命與Kind類型有區別,Deployment的定義與Replica Set的定義很相似,咱們這裏仍是以上面爲例子
apiVersion: extensions/v1beta1 apiVersion: apps/v1
kind: ReplicaSet kind: Deployment
執行文件
[root@master ~]# kubectl apply -f deploy.yaml
deployment.apps/myweb created
查看結果
[root@master ~]# kubectl get deployments NAME READY UP-TO-DATE AVAILABLE AGE myweb 1/1 1 1 5m5s
解釋一下上面的顯示
NAME:你的deployment控制器的名字
READY:已經準備好的Pod個數/所指望的Pod個數
UP-TO-DATE:最新版本的Pod數量,用於在執行滾動升級時,有多少個Pod副本已經成功升級
AVAILABLE:當前集羣中可用的Pod數量,也就是集羣中存活的Pod數量
在kubernetes系統中,Pod的管理對象RC,Deployment,DaemonSet和Job都面向無狀態的服務,但現實中有不少服務時有狀態的,好比一些集羣服務,例如mysql集羣,集羣通常都會有這四個特色:
若是你經過RC或Deployment控制Pod副本數量來實現上述有狀態的集羣,就會發現第一點是沒法知足的,由於Pod名稱和ip是隨機產生的,而且各Pod中的共享存儲中的數據不能都動,所以StatefulSet在這種狀況下就派上用場了,那麼StatefulSet具備如下特性:
StatefulSet除了要與PV卷捆綁使用以存儲Pod的狀態數據,還要與Headless,Service配合使用,每一個StatefulSet定義中都要生命它屬於哪一個Handless Service,Handless Service與普通Service的關鍵區別在於,它沒有Cluster IP
在每個node節點上只調度一個Pod,所以無需指定replicas的個數,好比:
[root@localhost ~]# cat daemon.yaml apiVersion: apps/v1 kind: DaemonSet metadata: name: fluentd-cloud-logging namespace: kube-system labels: k8s-app: fluentd-cloud-logging spec: selector: matchLabels: k8s-app: fluentd-cloud-logging template: metadata: namespace: kube-system labels: k8s-app: fluentd-cloud-logging spec: containers: - name: fluentd-cloud-logging image: kayrus/fluentd-elasticsearch:1.20 resources: limits: cpu: 100m memory: 200Mi env: - name: FLUENTD_ARGS value: -q volumeMounts: - name: varlog mountPath: /var/log readOnly: false - name: containers mountPath: /var/lib/docker/containers readOnly: false volumes: - name: containers hostPath: path: /usr - name: varlog hostPath: path: /usr/sbin
查看pod所在的節點
[root@localhost ~]# kubectl get pods -n kube-system -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES coredns-bccdc95cf-8sqzn 1/1 Running 2 2d7h 10.244.0.6 master <none> <none> coredns-bccdc95cf-vt8nz 1/1 Running 2 2d7h 10.244.0.7 master <none> <none> etcd-master 1/1 Running 1 2d7h 192.168.254.13 master <none> <none> fluentd-cloud-logging-6xx4l 1/1 Running 0 4h24m 10.244.2.7 node2 <none> <none> fluentd-cloud-logging-qrgg6 1/1 Rruning 0 4h24m 10.244.1.7 node1 <none> <none> kube-apiserver-master 1/1 Running 1 2d7h 192.168.254.13 master <none> <none> kube-controller-manager-master 1/1 Running 1 2d7h 192.168.254.13 master <none> <none> kube-flannel-ds-amd64-c97wh 1/1 Running 0 2d7h 192.168.254.12 node1 <none> <none> kube-flannel-ds-amd64-gl6wg 1/1 Running 1 2d7h 192.168.254.13 master <none> <none> kube-flannel-ds-amd64-npsqf 1/1 Running 0 2d7h 192.168.254.10 node2 <none> <none> kube-proxy-gwmx8 1/1 Running 1 2d7h 192.168.254.13 master <none> <none> kube-proxy-phqk2 1/1 Running 0 2d7h 192.168.254.12 node1 <none> <none> kube-proxy-qtt4b 1/1 Running 0 2d7h 192.168.254.10 node2 <none> <none> kube-scheduler-master 1/1 Running 2 2d7h 192.168.254.13 master <none> <none>