管理Pod(rc,rs,deployment)

1.概述

  能夠把容器想像成豆莢裏的豆子,把一個或多個關係緊密的豆子包在一塊兒就是豆莢(一個Pod)。在k8s中咱們不會直接操做容器,而是把容器包裝成Pod再進行管理.node

2.管理Pod

a. 使用Replication Controller 來部署、升級Pod
b. Replica Set – 下一代Replication Controller
c. Deployment – 更加方便的管理Pod和Replica Set

  例子1: 提出疑惑python

先舉個例子,假設咱們有一個Pod在提供線上服務,如今有以下幾個場景,你們想一想如何應對:

1.節日活動,網站訪問量突增
2.遭到攻擊,網站訪問量突增
3.運行Pod的節點發生故障


第1種狀況,活動前預先多啓動幾個Pod,活動結束後再結束掉多餘的,雖然要啓動和結束的Pod有點多,但也能有條不紊按計劃進行
第2種狀況,正在睡覺忽然手機響了說網站反應特慢卡得要死,趕忙爬起來邊擴容邊查找攻擊模式、封IP等等……
第3種狀況,正在休假忽然手機又響了說網站上不去,趕忙打開電腦查看緣由,啓動新的Pod

  解決辦法:引入rcnginx

Pod須要手動管理,好累……可否在Pod發生問題時自動恢復呢,咱們先來看下Replication Controller(如下簡稱RC)

先說RC是什麼。RC保證在同一時間可以運行指定數量的Pod副本,保證Pod老是可用。若是實際Pod數量比指定的多就結束掉多餘的,若是實際數量比指定的少就啓動缺乏的。
當Pod失敗、被刪除或被終結時RC會自動建立新的Pod來保證副本數量。因此即便只有一個Pod也應該使用RC來進行管理。

  

這個文件定義了RC的屬性,咱們先關注以下字段:
spec.replicas:副本數量3
spec.selector:RC經過spec.selector來篩選要控制的Pod
spec.template:這裏寫Pod的定義(但不須要apiVersion和kind)
spec.template.metadata.labels:Pod的label,能夠看到這個label與spec.selector相同

這個文件的意思是定義了一個RC對象,它的名字是hello-rc(metadata.name:hello-rc),保證有3個Pod運行(spec.replicas:3),
Pod的鏡像是index.tenxcloud.com/tailnode/hello:v1.0(spec.template.spec.containers.image: index.tenxcloud.com/tailnode/hello:v1.0)
關鍵在於spec.selector與spec.template.metadata.labels,這兩個字段必須相同,不然下一步建立RC會失敗。
(也能夠不寫spec.selector,這樣默認與spec.template.metadata.labels相同)

  如今經過kubectl來建立RC:docker


 

  解決辦法:引入rs,官方推薦使用RS代替RC數據庫

1.RC只支持基於等式的selector(env=dev或environment!=qa)但Replica Set還支持新的基於集合的selector(version in (v1.0, v2.0)或env notin (dev, qa)),
這對複雜的運維管理帶來很大方便 2.使用Deployment升級Pod只須要定義Pod的最終狀態,k8s會爲你執行必要的操做,雖然可以使用命令kubectl rolling-update完成升級,
但它是在客戶端與服務端屢次交互控制RC完成的,因此REST API中並無rolling-update的接口,這爲定製本身的管理系統帶來了一些麻煩。 3.Deployment擁有更加靈活強大的升級、回滾功能

  Replica Set目前與RC的區別只是支持的selector不一樣,後續確定會加入更多功能。Deployment使用了Replica Set,是更高一層的概念。除非須要自定義升級功能或根本不須要升級Pod,因此推薦使用Deployment而不直接使用Replica Set。api

3.Pod建立流程

step.1
  kubectl 向 k8s api server 發起一個create pod 請求(即咱們使用Kubectl敲一個create pod命令) 。

step.2
  k8s api server接收到pod建立請求後,不會去直接建立pod;而是生成一個包含建立信息的yaml。
        
step.3
  apiserver 將剛纔的yaml信息寫入etcd數據庫。到此爲止僅僅是在etcd中添加了一條記錄, 尚未任何的實質性進展。
     
step.4
  scheduler 查看 k8s api ,相似於通知機制。
  首先判斷:pod.spec.Node == null?
  若爲null,表示這個Pod請求是新來的,須要建立;所以先進行調度計算,找到最「閒」的node。
  而後將信息在etcd數據庫中更新分配結果:pod.spec.Node = nodeA (設置一個具體的節點)
  ps:一樣上述操做的各類信息也要寫到etcd數據庫中中。
 
step.5
  kubelet 經過監測etcd數據庫(即不停地看etcd中的記錄),發現 k8s api server 中有了個新的Node;
  若是這條記錄中的Node與本身的編號相同(即這個Pod由scheduler分配給本身了);
  則調用node中的docker api,建立container。

  

 4.ReplicaSet建立流程網絡

step.1
  kubectl 發起 create replicaSet 請求
    
step.2
  k8s api server 接受 replicaSet 建立請求,建立yaml。
    
step.3
  k8s api server將yaml的信息寫入etcd數據庫。
    
step.4
  Controller-Manager中的ReplicaSetController,在etcd數據庫中讀到了新的replicaSet 信息後,
  向k8s api server發起請求,建立3個Pod(個數能夠本身指定)。

step.5
  scheduler 在etcd中讀到相應信息
  若 3pod.spec.Node == null
  則執行調度計算,找到最「閒」的若干個Node(若是有一個Node真的太閒,可能3個Pod都會被起在這個Node上面)
  pod1.spec.Node = nodeA (更新記錄)
  pod2.spec.Node = nodeB
  pod3.spec.Node = nodeA (Node都是隨機分配的)
  將這些信息寫回etcd數據庫中。
    
step.6
  nodeA 的 kubelet 讀etcd時讀到apiserver的信息,調用docker api;建立屬於本身的pod1/pod3的container

step.7
  nodeB kubelet 讀到 k8s api server的信息,調用docker api,建立pod2的container。

4.生命週期,重啓策略,鏡像拉取

pod聲明週期(狀態):pending , running, succeeded, failed, unknown

掛起(Pending):Pod 已被 Kubernetes 系統接受,但有一個或者多個容器鏡像還沒有建立。等待時間包括調度 Pod 的時間和經過網絡下載鏡像的時間,這可能須要花點時間。
運行中(Running):該 Pod 已經綁定到了一個節點上,Pod 中全部的容器都已被建立。至少有一個容器正在運行,或者正處於啓動或重啓狀態。
成功(Succeeded):Pod 中的全部容器都被成功終止,而且不會再重啓。
失敗(Failed):Pod 中的全部容器都已終止了,而且至少有一個容器是由於失敗終止。也就是說,容器以非0狀態退出或者被系統終止。
未知(Unknown):由於某些緣由沒法取得 Pod 的狀態,一般是由於與 Pod 所在主機通訊失敗。

  

pod重啓策略: 當某個容器異常退出或者健康檢查失敗, kubelet將根據RestartPolicy的設置來進行相應的操做, 重啓策略有Always , OnFailure, Never

Always: 當容器失效時, 由kubelet自動重啓該容器
OnFailure: 當容器終止運行且退出碼不爲0時, 由kubelet自動重啓該容器
Never: 不論容器運行狀態如何, kubelet都不會重啓該容器

  

kubelet重啓失效容器的時間間隔以sync-frequency乘以2n來計算, 例如1丶2丶4丶8倍等, 最長延時5min, 而且在重啓後的10min後重置該時間
pod的重啓策略與控制方式息息相關app

RC和DeamonSet必須設置爲Always,須要保證該容器持續運行
Job: OnFailure或Never, 確保容器執行完成後再也不重啓

 

鏡像拉取策略

Always: 表示每次都嘗試從新拉取鏡像
IfNotPresent: 表示若是本地有鏡像, 則使用本地的鏡像, 本地不存在時拉取鏡像
Never: 表示僅使用本地鏡像

示例

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: default 
  labels:
    app: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx

    spec:
      restartPolicy: Always
      containers:
      - name: nginx
        image: nginx:1.12
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
相關文章
相關標籤/搜索