pod控制器介紹


deployment控制器(pod副本控制器)

    實現pod的水平擴展和收縮功能 遵循滾動更新的方式來升級現有的容器   

    deployment操作的不是pod對象    而是控制replicaSet對象通過它來間接控制Pod滾動更新

    Deployment 同樣通過"控制器模式",來操作 ReplicaSet 的個數和屬性,進而實現“水平擴展 / 收縮”和“滾動更新”這兩個編排動作

    將一個集群中正在運行的多個Pod版本,交替地逐一升級的過程,就是"滾動更新"創建成功一個新的Pod后 再刪除一個舊版本的Pod

    如果創建新的pod沒有正常運行起來   那么deployment控制器就不會刪除舊的pod 中止滾動更新

    Deployment實際上是一個兩層控制器.首先,它通過ReplicaSet的個數來描述應用的版本.然后,它再通過ReplicaSet 的屬性(比如replicas 的值)來保證Pod的副本數量

    Deployment只允許容器的restartPolicy=Always 

    一個應用的所有Pod是完全一樣的.所以,它們互相之間沒有順序也無所謂運行在哪台宿主機上 

    需要的時候Deployment就可以通過Pod模板創建新的Pod,不需要的時候Deployment就可以“殺掉”任意一個Pod

    Deployment無法適用的場景

          分布式應用,它的多個實例之間,往往有依賴關系,比如:主從關系/主備關系

          數據存儲類應用,它的多個實例,往往都會在本地磁盤上保存一份自己獨立的數據  而這些實例一旦被殺掉,即便重建出來,實例與數據之間的對應關系也已經丟失

   Deployment和ReplicaSet的關系

      

 

     1. 一個定義了replicas=3的Deployment與它的ReplicaSet以及Pod的關系,實際上是一種“層層控制”的關系

     2.ReplicaSet負責通過“控制器模式”保證系統中Pod的個數永遠等於指定的個數(比如3個)

     3.Deployment同樣通過“控制器模式”來操作ReplicaSet的個數和屬性,進而實現“水平擴展 / 收縮”和“滾動更新”這兩個編排動作

DaemonSet控制器

      在Kubernetes集群里的每一個節點(Node)上運行一個指定的Pod實例

      跟其他編排對象不一樣,DaemonSet開始運行的時機,很多時候比整個Kubernetes集群出現的時機都要早.

      在集群中指定的節點(不是所有節點)創建Daemon Pod 通過spec.nodeAffinity字段來設置  nodeAffinity相當於是過濾不相關的節點

      DaemonSet Controller會在創建Pod的時候,自動在Pod 的API對象里加上一個nodeAffinity定義.其中,需要綁定的節點名字正是當前正在遍歷的這個節點

      DaemonSet還會給這個Pod自動加上另外一個與調度相關的字段,叫作 tolerations.這個字段意味着這個Pod會“容忍”(Toleration)某些Node的“污點”(Taint) 

      在DaemonSet上,我們一般都應該加上resources字段,來限制它的 CPU 和內存使用,防止它占用過多的宿主機資源

      相比於 Deployment,DaemonSet只管理Pod對象,然后通過 nodeAffinity 和Toleration 這兩個調度器的小功能,保證了每個節點上有且只有一個 Pod

      DaemonSet 使用 ControllerRevision,來保存和管理自己對應的“版本”.這種“面向API對象”的設計思路簡化了控制器本身邏輯正是K8s“聲明式 API”的優勢

      StatefulSet也是直接控制Pod對象的,那么它也在使用ControllerRevision 進行版本管理

      在Kubernetes項目里ControllerRevision 其實是一個通用的版本管理對象

     

statefuset(有狀態應用)控制器

    把所有的有狀態應用分為兩種情況:

    拓撲狀態

       應用的多個實例之間不是完全對等的關系.這些應用實例必須按照某些順序啟動,比如應用的主節點A要先於從節點B啟動.而如果你把A和B兩個Pod 刪除掉,它們再次被創建出來時也必須嚴格按照這個順序才行.並且新創建出來的 Pod,必須和原來Pod 的網絡標識一樣.這樣原先的訪問者才能使用同樣的方法訪問到這個新Pod

       Pod 的創建,也是嚴格按照編號順序進行的.比如,在 web-0 進入到 Running 狀態、並且細分狀態(Conditions)成為 Ready 之前web-1 會一直處於 Pending 狀態

      Kubernetes 就成功地將 Pod 的拓撲狀態(比如:哪個節點先啟動,哪個節點后啟動),按照 Pod 的“名字 + 編號”的方式固定了下來.此外,Kubernetes 還為每一個 Pod 提供了一個固定並且唯一的訪問入口,即:這個 Pod 對應的 DNS 記錄。這些狀態,在 StatefulSet 的整個生命周期里都會保持不變

      

   存儲狀態

       應用的多個實例分別綁定了不同的存儲數據.對於這些應用實例來說,Pod A第一次讀取到的數據和隔了十分鍾之后再次讀取到的數據應該是同一份

       哪怕在此期間 Pod A 被重新創建過。這種情況最典型的例子,就是一個數據庫應用的多個存儲實例

       PVC/PV 的設計  也使得 StatefulSet 對存儲狀態的管理成為了可能

       PVC都以"<PVC 名字 >-<StatefulSet 名字 >-< 編號 >"的方式命名並且處於 Bound 狀態

      StatefulSet管理的 Pod,都會聲明一個對應的PVC;而這個PVC的定義,就來自於volumeClaimTemplates 這個模板字段。

      更重要的是這個 PVC 的名字會被分配一個與這個 Pod 完全一致的編號

      

    StatefulSet的滾動更新

        StatefulSet Controller就會按照與Pod編號相反的順序從最后一個 Pod 開始,逐一更新這個 StatefulSet 管理的每個 Pod.而如果更新發生了錯誤,這次“滾動更新”就會停止.此外,StatefulSet的“滾動更新”還允許我們進行更精細的控制,比如金絲雀發布(Canary Deploy)或者灰度發布,這意味着應用的多個實例中被指定的一部分不會被更新到最新的版本

 

service介紹

         用來將一組Pod暴露給外部訪問的一種機制

         normal service

               通過虛擬IP(vip)的方式把請求轉發到所代理的某一個Pod上
               通過service的DNS方式解析到vip(my-svc.my-namespace.svc.cluster.local)

         headless service  

               clusterIP=None的service           Headless Service 不需要分配一個VIP,而是可以直接以DNS記錄的方式解析出被代理Pod的IP地址

               創建了一個Headless Service之后,它所代理的所有Pod的IP 地址都會被綁定一個這樣格式的DNS記錄(podname.svcname.namespace.svc.cluster.local)

               這個DNS記錄 正是Kubernetes項目為Pod 分配的唯一的“可解析身份”(Resolvable Identity).有了這個“可解析身份”

               只要你知道了一個Pod的名字以及它對應的 Service 的名字,你就可以非常確定地通過這條DNS記錄訪問到Pod的IP地址

statefuset的實現原理

     StatefulSet 這個控制器的主要作用之一,就是使用 Pod 模板創建 Pod 的時候,對它們進行編號,並且按照編號順序逐一完成創建工作

     StatefulSet 的“控制循環”發現 Pod 的“實際狀態”與“期望狀態”不一致,需要新建或者刪除 Pod 進行“調諧”的時候,它會嚴格按照這些 Pod 編號的順序,逐一完成這些操作

     與此同時,通過 Headless Service 的方式,StatefulSet 為每個 Pod 創建了一個固定並且穩定的 DNS 記錄,來作為它的訪問入口

      在部署“有狀態應用”的時候,應用的每個實例擁有唯一並且穩定的“網絡標識”,是一個非常重要的假設

      StatefulSet的控制器直接管理的是Pod

      Kubernetes 通過 Headless Service,為這些有編號的 Pod,在 DNS 服務器中生成帶有同樣編號的DNS記錄

      StatefulSet 還為每一個 Pod 分配並創建一個同樣編號的 PVC

      StatefulSet 其實就是一種特殊的 Deployment,而其獨特之處在於,它的每個 Pod 都被編號了.而且,這個編號會體現在Pod的名字和hostname等標識信息上,這不僅代表了 Pod 的創建順序也是Pod的重要網絡標識(即:在整個集群里唯一的、可被的訪問身份).

     有了這個編號后,StatefulSet 就使用 Kubernetes 里的兩個標准功能:Headless Service 和 PV/PVC,實現了對 Pod 的拓撲狀態和存儲狀態的維護  

statefuset實現mysql集群

  1.搭建好k8s集群

  2.下載好鏡像

      docker pull  gcr.io/google-samples/xtrabackup:1.0

      docker pull mysql:5.7

  3.創建好pv

      使用nfs服務實現遠程存儲

vi /etc/exports

/data/volumes/pv1 192.168.164.0/24(insecure,rw,async,no_root_squash)
/data/volumes/pv2 192.168.164.0/24(insecure,rw,async,no_root_squash)
/data/volumes/pv3 192.168.164.0/24(insecure,rw,async,no_root_squash)
View Code

    kubectl apply -f pvs.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv001
  labels:
    name: pv001
spec:
  nfs:
   path: /data/volumes/pv1
   server: 192.168.164.141
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 20Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv002
  labels:
    name: pv002
spec:
  nfs:
   path: /data/volumes/pv2
   server: 192.168.164.141
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 10Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv003
  labels:
    name: pv003
spec:
  nfs:
   path: /data/volumes/pv3
   server: 192.168.164.141
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 10Gi
pvs.yaml

 

  4.創建configmap

apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql
  labels:
    app: mysql
data:
  master.cnf: |
    [mysqld]
    log-bin
  slave.cnf: |
    [mysqld]
    super-read-only
configmap.yaml

  5.創建service

apiVersion: v1
kind: Service
metadata:
  name: mysql
  labels:
    app: mysql
spec:
  ports:
  - name: mysql
    port: 3306
  clusterIP: None
  selector:
    app: mysql
---
apiVersion: v1
kind: Service
metadata:
  name: mysql-read
  labels:
    app: mysql
spec:
  ports:
  - name: mysql
    port: 3306
  selector:
   app: mysql
service.yaml

  7.檢測結果

 

 總結:

       StatefulSet其實就是對現有典型運維業務的容器化抽象.你一定有方法在不使用Kubernetes甚至不使用容器的情況下,自己DIY一個類似的方案出來.
       但是一旦涉及到升級、版本管理等更工程化的能力,Kubernetes的好處就會體現出來 如何對StatefulSet進行"滾動更新" (rolling update)
      StatefulSet Controller 就會按照與Pod編號相反的順序,從最后一個Pod開始,逐一更新這個StatefulSet管理的每個Pod.而如果更新發生了錯誤,這次"滾動更新"就會停止.此外StatefulSet 的"滾動更新"還允許我們進行更精細的控制,比如金絲雀發布(Canary Deploy)或者灰度發布,這意味着應用的多個實例中被指定的一部分不會被更新到 
      


免責聲明!

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



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