k8s 管理Pod(rc,rs,deployment)


管理Pod(rc,rs,deployment)

 

1.概述

  可以把容器想像成豆莢里的豆子,把一個或多個關系緊密的豆子包在一起就是豆莢(一個Pod)。在k8s中我們不會直接操作容器,而是把容器包裝成Pod再進行管理.

2.管理Pod

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

  例子1: 提出疑惑

?
1
2
3
4
5
6
7
8
9
10
先舉個例子,假設我們有一個Pod在提供線上服務,現在有如下幾個場景,大家想想如何應對:
 
1. 節日活動,網站訪問量突增
2. 遭到攻擊,網站訪問量突增
3. 運行Pod的節點發生故障
 
 
1 種情況,活動前預先多啟動幾個Pod,活動結束后再結束掉多余的,雖然要啟動和結束的Pod有點多,但也能有條不紊按計划進行
2 種情況,正在睡覺突然手機響了說網站反應特慢卡得要死,趕緊爬起來邊擴容邊查找攻擊模式、封IP等等……
3 種情況,正在休假突然手機又響了說網站上不去,趕緊打開電腦查看原因,啟動新的Pod

  解決辦法:引入rc

?
1
2
3
Pod需要手動管理,好累……能否在Pod發生問題時自動恢復呢,我們先來看下Replication Controller(以下簡稱RC)
 
先說RC是什么。RC保證在同一時間能夠運行指定數量的Pod副本,保證Pod總是可用。如果實際Pod數量比指定的多就結束掉多余的,如果實際數量比指定的少就啟動缺少的。<br>當Pod失敗、被刪除或被終結時RC會自動創建新的Pod來保證副本數量。所以即使只有一個Pod也應該使用RC來進行管理。

  

?
1
2
3
4
5
6
7
這個文件定義了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 ),<br>Pod的鏡像是index.tenxcloud.com / tailnode / hello:v1. 0 (spec.template.spec.containers.image: index.tenxcloud.com / tailnode / hello:v1. 0 )<br>關鍵在於spec.selector與spec.template.metadata.labels,這兩個字段必須相同,否則下一步創建RC會失敗。<br>(也可以不寫spec.selector,這樣默認與spec.template.metadata.labels相同)

  現在通過kubectl來創建RC:


 

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

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

  Replica Set目前與RC的區別只是支持的selector不同,后續肯定會加入更多功能。Deployment使用了Replica Set,是更高一層的概念。除非需要自定義升級功能或根本不需要升級Pod,所以推薦使用Deployment而不直接使用Replica Set。

3.Pod創建流程

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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創建流程

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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

?
1
2
3
4
5
掛起(Pending):Pod 已被 Kubernetes 系統接受,但有一個或者多個容器鏡像尚未創建。等待時間包括調度 Pod 的時間和通過網絡下載鏡像的時間,這可能需要花點時間。
運行中(Running):該 Pod 已經綁定到了一個節點上,Pod 中所有的容器都已被創建。至少有一個容器正在運行,或者正處於啟動或重啟狀態。
成功(Succeeded):Pod 中的所有容器都被成功終止,並且不會再重啟。
失敗(Failed):Pod 中的所有容器都已終止了,並且至少有一個容器是因為失敗終止。也就是說,容器以非 0 狀態退出或者被系統終止。
未知(Unknown):因為某些原因無法取得 Pod 的狀態,通常是因為與 Pod 所在主機通信失敗。

  

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

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

  

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

RC和DeamonSet必須設置為Always,需要保證該容器持續運行
Job: OnFailure或Never, 確保容器執行完成后不再重啟

 

鏡像拉取策略

?
1
2
3
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
復制代碼

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM