Kubernetes Pod 控制器

在機器人技術和自動化中,控制環是一個控制系統狀態的不終止的循環node

這是一個控制環的例子:"房間裏的溫度自動調節器"
當你設置了溫度,告訴了溫度自動調節器你的"指望狀態",房間的實際溫度是"當前狀態"。經過對設備的開關控制,溫度自動調節器讓其當前狀態無限接近於指望狀態。
控制器經過 k8s的apiserver 去監控集羣的公共狀態,並致力於將當前狀態轉變爲所指望的狀態。nginx

kubernetes 之Pod控制器(Controller)git

Controller是kubernetes中用於對Pod進行管理的控制器,經過該控制器可讓Pod始終維持在一個用戶本來設定或指望的狀態下。如節點宕機或Pod因其餘緣由死亡,則在其餘節點起一個相同的Pod來替代該Pod。github

  • 經常使用的內置控制器類型,它一般與集羣API服務器進行交互:
    ReplicaSet:是Replication Controller 升級版本,區別是對選擇器的支持;
    Deployments:管理RS並提供對Pod的更新等功能,建議使用它管理RS,除非自定義更新編排;
    DaemonSet:用於確保集羣中的每個節點只運行一個Pod副本,一般用來實現系統級的後臺任務;
    StatefulSets:一般用來管理有狀態應用;
    Job:一次性任務執行;
    Crontab:定時任務執行;
    任意控制器學習方法可參考中文官方站點:Kubernetes 內置控制器
  • 舉個例子:
    運行Pod以前,儘可能把鏡像給先下載到本地,依據Pod調度結果使用docker save load導入導出
[root@node1 controllers]# cat replicaset-demo.yaml 
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: myapp
  namespace: default
spec:
  replicas: 1
  selector: 
    matchLabels:
      app: myapp
      release: canary
  template:
    metadata:
      name: myapp-httpd
      labels:
        app: myapp
        release: canary
        environment: qa
    spec:
      containers:
      - name: myapp-container
        image: httpd
                imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 80
[root@node1 controllers]#

Kubernetes 最小運行單元 Pod,瞭解Pod是什麼你須要瞭解容器web

容器本質其實是一個進程,是一個視圖被隔離,資源受限的進程。
容器的設計自己是"單進程"模型,不是容器裏只能起一個進程,由於容器的應用等於進程,只能管理PID=1的進程。(Linux 容器的"單進程"模型,指的是容器的生命週期等同於 PID=1 的進程的生命週期,而不是說容器裏不能建立多進程),也能夠啓動多個進程,可是隻有PID=1的進程被容器所管理,這時其它進程則處於tuoguan狀態。若是這個時候PID=1的這個進程出問題了被kill掉了或者是fail了沒人知道,而後其它的進程資源怎麼辦呢?就沒人管,沒人回收......
因此每每在容器當中運行一個複雜程序是比較苦難的,但kubernetes的控制器的脫引而出,爲它奠基了其在容器當中運行多個應用的歷史地位,至少現階段是的。docker

Pod 是什麼apache

讓Kubernetes集羣能跑起來的基礎組件就叫 Pod。 api

  • Pod 是 Kubernetes 應用程序的基本執行單元,即它是 Kubernetes 對象模型中建立或部署的最小和最簡單的單元。Pod 表示在 集羣 上運行的一個進程。
  • Pod 能夠是封裝了單個應用程序的容器(或多個)、存儲資源、惟一網絡 IP 以及控制容器應該如何運行的選項。 Pod 表示部署單元:"Kubernetes 中應用程序的單個實例",它可能由單個 容器 或少許緊密耦合並共享資源的容器組成。
  • Docker 是 Kubernetes Pod 中最經常使用的容器運行時,但 Pod 也能支持其餘的容器運行。

Pod = "進程組"tomcat

在 Kubernetes 裏面,Pod 實際上正是 Kubernetes 項目爲你抽象出來的一個能夠類比爲進程組的概念。
簡單點就是在kubernets當中會把多個應用定義爲多個容器,而後把多個容器運行在一個Pod資源裏面,你也能夠說是多個容器的組合就叫作 Pod。當Kubernetes把定義在一個Pod組合裏的容器運行起來後,你會看到多個容器在運行。它們會同時去共享系統底層的某些資源(共享同一個底層的net、uts、ipc、等...),而這些資源都屬於 Pod。
Pod 在 Kubernetes 裏面只有一個邏輯單位,Pod 是 Kubernetes 分配資源的一個單位。由於裏面的容器要共享某些資源,因此Pod 它也是 Kubernetes 的原子調度單位。服務器

Pod 的工做特色

  • 自主式Pod,自主式管理;
  • 將多個容器鏈接起來,給容器作成抽象封裝;
  • 一個Pod包含多個容器,共享同一個底層的 UTS、IPC、Network、等......;
  • Pod模擬傳統虛擬機,一個Pod建議只運行一個容器;
  • 共享存儲卷,再也不屬於容器而屬於Pod;
  • Pod在各node上運行,取決其節點容忍度;
  • Pod控制器:Replication Controller、ReplicaSet、DeployMent、StatefulSet、DaemonSet、Job;

Kubernetes 中Pod 的運行方式

  • 運行單個容器的 Pod
    "每一個 Pod 一個容器"的模型是最多見的 Kubernetes 用例,即one-container-per-Pod模式。在這種狀況下能夠將 Pod 看做單個容器的包裝器,而且 Kubernetes 直接管理 Pod,而不是容器。
  • 運行多個協同工做的容器的 Pod
    Pod 可能封裝由多個緊密耦合且須要共享資源的共處容器組成的應用程序。即sidecar模式,Pod 封裝了一組緊耦合、共享資源、協同尋址的容器,將這組容器做爲一個管理單元做爲一個可管理的實體。
    舉個例子:
    自包含式容器設計Sidecar示例,鏡像可私有倉庫建立打包並上傳至github
[root@node1 controllers]# cat pod-tomcat-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: web-2
  namespace: default
spec:
  initContainers:
  - image: ik8s.io/sample:v2
    imagePullPolicy: IfNotPresent
    name: war
    command: [ "cp", "/sample.war", "/app" ]
    volumeMounts:
    - mountPath: /app
      name: app-volume
  containers:
  - image: ik8s.io/tomcat:8.0
    imagePullPolicy: IfNotPresent
    name: tomcat8
    command: [ "sh", "-c", "/root/apache-tomcat-8.0.5/bin/start.sh" ]
    volumeMounts:
    - mountPath: /root/apache-tomcat-8.0.5/webapps
      name: app-volume
    ports:
    - containerPort: 8080
      hostPort: 8008
  volumes:
  - name: app-volume
    emptyDir: {}
[root@node1 controllers]#

利用DeployMents控制器實現滾動更新及灰度應用發佈

  • 任意應用程序建立必須知足三個核心組件:
    用戶指望的Pod副本、標籤選擇器、Pod模版(現有Pods數量不夠副本中所定義的指望Pod)
    命令幫助:
[root@node1 controllers]# kubectl explain deploy
[root@node1 controllers]# kubectl explain deploy.spec
[root@node1 controllers]# kubectl explain deploy.spec.strategy

此示例中會告訴您怎麼實現一組應用的滾動更新,版本回退,Pod數量更新等。

[root@node1 controllers]# cat deployment-myapp-demo.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
  namespace: default
spec:
  replicas: 2
  selector: 
    matchLabels:
      app: myapp
      release: canary
  template:
    metadata:
      labels:
        app: myapp
        release: canary
    spec:
      containers:
      - name: myapp
        image: nginx
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 80
[root@node1 controllers]#
[root@node1 controllers]# kubectl apply -f deployment-myapp-demo.yaml 
deployment.apps/myapp-deployment created
[root@node1 controllers]# 
[root@node1 controllers]# kubectl delete -f deployment-myapp-demo.yaml 
deployment.apps "myapp-deployment" deleted
[root@node1 controllers]# 
[root@node1 controllers]# kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
myapp-deployment-5b776d9cf7-29s7b   1/1     Running   0          9m26s
myapp-deployment-5b776d9cf7-8hb8c   1/1     Running   0          9m26s
[root@node1 controllers]# 
[root@node1 controllers]# kubectl logs myapp-deployment-5b776d9cf7-8hb8c
[root@node1 controllers]# 
[root@node1 controllers]# kubectl describe pods myapp-deployment-5b776d9cf7-8hb8c
.............
Events:
Type    Reason     Age        From               Message
    ----    ------     ----       ----               -------
    Normal  Scheduled  <unknown>  default-scheduler  Successfully assigned default/myapp-deployment-5b776d9cf7-8hb8c to node2
    Normal  Pulled     10h        kubelet, node2     Container image "nginx" already present on machine
    Normal  Created    10h        kubelet, node2     Created container myapp
    Normal  Started    10h        kubelet, node2     Started container myapp
[root@node1 controllers]#
  • 更新Pod數量,滾動更新
    經過打補丁的方式進行更新,也可直接編輯文件進行更新,其值默認爲1
# 更新當前副本集爲5個
[root@node1 controllers]# kubectl patch deployment myapp-deploy -p '{"spec":{"relicas":5}}' 
# 實時查看更新狀態
[root@node1 controllers]# kubectl get pods -w
  • 更新image版本號,滾動更新
    所運用到的命令:kubectl set、kubectl edit、kubectl apply、kubectl rollout
# 更新容器鏡像版本至最新
[root@node1 controllers]# kubectl set image deployment/myapp-deployment nginx=nginx:latest 
# 查看滾動更新歷史
[root@node1 controllers]# kubectl rollout history deployment myapp-deployment 
# 查看ReplicaSet空間image版本號狀態
[root@node1 controllers]# kubectl get rs -l app=myapp -o wide
# 查看image字段
[root@node1 controllers]# kubectl describe pods myapp-deployment-5b776d9cf7-8hb8c | grep 'Image' 
# 查看其更新的過程是怎麼更新的,作了什麼
[root@node1 controllers]# kubectl describe deployment/myapp-deployment
  • 模擬金絲雀發佈
    更改maxSurge和maxUnavailable更新策略
# 命令幫助
[root@node1 controllers]# kubectl explain deploy.spec.strategy.rollingUpdate
# 先打補丁,更改當前更新策略,以模擬金絲雀發佈
[root@node1 controllers]# kubectl patch deployment myapp-deployment -p '{"spec":{"strategy":{"rollingUpdate":{"maxSurge":1,"maxUnavailable":0}}}}'
# 查看
[root@node1 controllers]# kubectl describe deploy myapp-deployment
# 再更新(金絲雀發佈)
[root@node1 controllers]# kubectl set image deployment myapp-deployment myapp=nginx:v1  && kubectl rollout pause deployment myapp-
Waiting for deployment "myapp-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
# 查看歷史版本,使用 "--record" 參數可看到每一個版本所使用的命令
[root@node1 controllers]# kubectl rollout history deployment myapp-deployment 
# 回滾不加版本號,默認回退到上一個版本
[root@node1 controllers]# kubectl rollout undo deployment myapp-deployment
# 使用 "--to-reversion=[N]" 回滾到指定版本
[root@node1 controllers]# kubectl rollout undo deploy myapp-deployment --to-reversion=1
# 如以上沒問題,再次執行更新操做
[root@node1 controllers]# kubectl rollout resume deploy myapp-deployment

更多DeployMents控制器的Pod和ReplicaSet使用可參考 ---> 中文官方 DeployMnet 控制器使用

利用DaemonSet 運行指定一個Pod副本,把系統某個目錄做爲存儲卷

更多 "DaemonSet" 控制器的使用可參考官網 ---> 中文官方 DaemonSet 控制器使用

再補充......

相關文章
相關標籤/搜索