Kubernetes進階 -- 五種控制器的使用方法

控制器

  • Pod 的分類:
    • 自主式 Pod:Pod 退出後不會被創建
    • 控制器管理的 Pod:在控制器的生命週期裏,始終要維持 Pod 的副本數目
  • 控制器類型:
    • Replication Controller和ReplicaSet
    • Deployment
    • DaemonSet
    • StatefulSet
    • Job //定時任務
    • CronJob //重複任務
    • HPA全稱Horizontal Pod Autoscaler

Replication Controller和ReplicaSet

  • ReplicaSet 是下一代的 Replication Controller,官方推薦使用ReplicaSet。
  • ReplicaSet 和 Replication Controller 的唯一區別是選擇器的支持,ReplicaSet支持新的基於集合的選擇器需求。
  • ReplicaSet 確保任何時間都有指定數量的 Pod 副本在運行。
  • 雖然 ReplicaSets 可以獨立使用,但今天它主要被Deployments 用作協調 Pod 創
    建、刪除和更新的機制。

Deployment

  • Deployment 爲 Pod 和 ReplicaSet 提供了一個申明式的定義方法。

典型的應用場景:

  • 用來創建Pod和ReplicaSet
  • 滾動更新和回滾
  • 擴容和縮容
  • 暫停與恢復

DaemonSet

  • DaemonSet 確保全部(或者某些)節點上運行一個 Pod 的副本。當有節點加入集羣時, 也會爲他們新增一個 Pod 。當有節點從集羣移除時,這些Pod 也會被回收。刪除 DaemonSet 將會刪除它創建的所有 Pod。

DaemonSet 的典型用法:

  • 在每個節點上運行集羣存儲 DaemonSet,例如 glusterd、ceph。
  • 在每個節點上運行日誌收集 DaemonSet,例如 fluentd、logstash。
  • 在每個節點上運行監控 DaemonSet,例如 Prometheus Nodexporter、zabbix agent等
  • 一個簡單的用法是在所有的節點上都啓動一個 DaemonSet,將被作爲每種
    類型的 daemon 使用。
  • 一個稍微複雜的用法是單獨對每種 daemon 類型使用多個 DaemonSet,
    但具有不同的標誌, 並且對不同硬件類型具有不同的內存、CPU 要求。

StatefulSet

  • StatefulSet 是用來管理有狀態應用的工作負載 API 對象。實例之間有不對
    等關係,以及實例對外部數據有依賴關係的應用,稱爲“有狀態應用”
  • StatefulSet 用來管理 Deployment 和擴展一組 Pod,並且能爲這些 Pod
    提供序號和唯一性保證
  • StatefulSets 對於需要滿足以下一個或多個需求的應用程序很有價值:
    • 穩定的、唯一的網絡標識符。
    • 穩定的、持久的存儲。
    • 有序的、優雅的部署和縮放。
    • 有序的、自動的滾動更新。

Job

  • 執行批處理任務,僅執行一次任務,保證任務的一個或多個Pod成功結束。

CronJob

  • Cron Job 創建基於時間調度的 Jobs。
  • 一個 CronJob 對象就像 crontab (cron table) 文件中的一行,它用 Cron
    格式進行編寫,並週期性地在給定的調度時間執行 Job。

HPA

  • 根據資源利用率自動調整service中Pod數量,實現Pod水平自動縮放。

Replicaset控制器示例

[root@server2 manifest]# vim rs.yml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: replicaset-example
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:v1

[root@server2 manifest]# kubectl apply -f rs.yml 
replicaset.apps/replicaset-example created
[root@server2 manifest]# kubectl get pod -o wide
NAME                       READY   STATUS    RESTARTS   AGE   IP            NODE      NOMINATED NODE   READINESS GATES
replicaset-example-dcrwh   1/1     Running   0          16s   10.244.2.38   server4   <none>           <none>
replicaset-example-l8gw8   1/1     Running   0          16s   10.244.1.63   server3   <none>           <none>
replicaset-example-mlx8p   1/1     Running   0          16s   10.244.2.39   server4   <none>           <none>
[root@server2 manifest]# vim rs.yml
spec:
  replicas: 2		
[root@server2 manifest]# kubectl apply -f rs.yml 	直接應用,不用刪除之前的副本
replicaset.apps/replicaset-example configured
[root@server2 manifest]# kubectl get pod -o wide
NAME                       READY   STATUS        RESTARTS   AGE     IP            NODE      NOMINATED NODE   READINESS GATES
replicaset-example-dcrwh   1/1     Running       0          2m19s   10.244.2.38   server4   <none>           <none>
replicaset-example-l8gw8   1/1     Running       0          2m19s   10.244.1.63   server3   <none>           <none>
replicaset-example-mlx8p   0/1     Terminating   0          2m19s   10.244.2.39   server4   <none>           <none>
	//這個正在回收,默認會回收最新的pod
[root@server2 manifest]# kubectl  get all
NAME                           READY   STATUS    RESTARTS   AGE
pod/replicaset-example-dcrwh   1/1     Running   0          9m11s
pod/replicaset-example-l8gw8   1/1     Running   0          9m11s

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   8d

NAME                                 DESIRED   CURRENT   READY   AGE
replicaset.apps/replicaset-example   2         2         2       9m11s
// 多了一個控制器在前面

那我們讓副本數不變,更換鏡像哪?

spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:v2		// 改成v2

[root@server2 manifest]# kubectl  apply -f rs.yml 
replicaset.apps/replicaset-example configured
[root@server2 manifest]# kubectl get pod
NAME                       READY   STATUS    RESTARTS   AGE
replicaset-example-dcrwh   1/1     Running   0          11m
replicaset-example-l8gw8   1/1     Running   0          11m
// 還是這兩個pod,沒有變。

[root@server2 manifest]# vim  rs.yml
  replicas: 4		//再將副本改稱4個
...
        image: myapp:v2	
[root@server2 manifest]# kubectl  apply -f rs.yml 
replicaset.apps/replicaset-example configured
[root@server2 manifest]# kubectl get pod -o wide
NAME                       READY   STATUS    RESTARTS   AGE   IP            NODE      NOMINATED NODE   READINESS GATES
replicaset-example-bsckv   1/1     Running   0          2m    10.244.1.64   server3   <none>           <none>
replicaset-example-dcrwh   1/1     Running   0          15m   10.244.2.38   server4   <none>           <none>
replicaset-example-jkvfb   1/1     Running   0          2m    10.244.2.40   server4   <none>           <none>
replicaset-example-l8gw8   1/1     Running   0          15m   10.244.1.63   server3   <none>           <none>
// 新開起了兩個容器,我們進行訪問:

[root@server2 manifest]# curl 10.244.2.40
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
[root@server2 manifest]# curl 10.244.1.64
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
[root@server2 manifest]# curl 10.244.1.63
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@server2 manifest]# curl 10.244.2.38
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>

//通過訪問我們發現,副本數不變更改鏡像,不會發生改變,增加副本數改變鏡像,新增的副本使用改變後的鏡像。

若要想直接全部更新,就需要使用deployment控制器了。

Deployment控制器

[root@server2 manifest]# vim deployment.yml
apiVersion: apps/v1
kind: Deployment	//和rs控制器寫法一致,只有這裏改變,因爲deployment調用的底層就是rs控制器
metadata:
  name: deployment-example
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:v1

[root@server2 manifest]# kubectl apply -f deployment.yml 
deployment.apps/deployment-example created
[root@server2 manifest]# kubectl get all
NAME                                      READY   STATUS    RESTARTS   AGE
pod/deployment-example-7449b5b68f-cnxsw   1/1     Running   0          18s
pod/deployment-example-7449b5b68f-kv7zb   1/1     Running   0          18s
pod/deployment-example-7449b5b68f-rfbtf   1/1     Running   0          18s

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   8d

NAME                                 READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/deployment-example   3/3     3            3           18s

NAME                                            DESIRED   CURRENT   READY   AGE
replicaset.apps/deployment-example-7449b5b68f   3         3         3       18s                      

我們可以看到不止有deployment控制器,還有rs控制器

pod/deployment-example-7449b5b68f-cnxsw
這個pod的名稱是由 pod 名 + rs名 + pod唯一標示 組成的.

[root@server2 manifest]# vim deployment.yml 
...
    spec:
      containers:
      - name: myapp
        image: myapp:v2		//將鏡像換爲v2
[root@server2 manifest]# kubectl apply -f deployment.yml 
kubec	deployment.apps/deployment-example configured

[root@server2 manifest]# kubectl get pod
NAME                                  READY   STATUS              RESTARTS   AGE
deployment-example-67764dd8bd-bqxt4   1/1     Running             0          7s
deployment-example-67764dd8bd-z8mf4   1/1     Running             0          5s
deployment-example-67764dd8bd-zwdgr   0/1     ContainerCreating   0          2s
deployment-example-7449b5b68f-cnxsw   0/1     Terminating         0          7m32s
deployment-example-7449b5b68f-kv7zb   1/1     Running             0          7m32s
deployment-example-7449b5b68f-rfbtf   1/1     Terminating         0          7m32s
[root@server2 manifest]# kubectl get pod
NAME                                  READY   STATUS        RESTARTS   AGE
deployment-example-67764dd8bd-bqxt4   1/1     Running       0          16s
deployment-example-67764dd8bd-z8mf4   1/1     Running       0          14s
deployment-example-67764dd8bd-zwdgr   1/1     Running       0          11s

現在我們在更換鏡像的時候會直接刪除原來的三個容器,重新打開三個pod。
而且:

[root@server2 manifest]# kubectl get all
...
NAME                                 READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/deployment-example   3/3     3            3           10m

NAME                                            DESIRED   CURRENT   READY   AGE
replicaset.apps/deployment-example-67764dd8bd   3         3         3       3m4s
replicaset.apps/deployment-example-7449b5b68f   0         0         0       10m

生成了一個新的rs控制器,但是原來的rs還保留着,這是用於回滾的。
新生成的三個pod都使用的是新的rs控制器生成的。

  • 回滾
[root@server2 manifest]# vim deployment.yml 
...
    spec:
      containers:
      - name: myapp
        image: myapp:v1		//改回v1
[root@server2 manifest]# kubectl get pod
NAME                                  READY   STATUS    RESTARTS   AGE
deployment-example-7449b5b68f-c94st   1/1     Running   0          23s
deployment-example-7449b5b68f-f59mw   1/1     Running   0          20s
deployment-example-7449b5b68f-lwq2k   1/1     Running   0          17s
它就會使用原來的那個rs。
  • pod更新
    當我們發現一個pod的狀態不正常時,我們可以直接刪除這個pod,控制器回自動的拉取一個新的pod:
[root@server2 manifest]# kubectl delete pod deployment-example-7449b5b68f-c94st 
pod "deployment-example-7449b5b68f-c94st" deleted
[root@server2 manifest]# kubectl get pod
NAME                                  READY   STATUS    RESTARTS   AGE
deployment-example-7449b5b68f-f59mw   1/1     Running   0          4m14s	//新pod
deployment-example-7449b5b68f-lwq2k   1/1     Running   0          4m11s
deployment-example-7449b5b68f-wwpgp   1/1     Running   0          17s
  • pod刪除
[root@server2 manifest]# kubectl delete  -f  deployment.yml 
deployment.apps "deployment-example" deleted
[root@server2 manifest]# kubectl get all
NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   8d
// 連同控制器,rs,pod一塊刪除了

多個控制器

多個控制器和多個資源的放時一樣,用—分割開就行了

[root@server2 manifest]# vim deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-v1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:v1

---		//分割線

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-v2
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:v2
[root@server2 manifest]# kubectl apply -f deployment.yml 
deployment.apps/deployment-v1 created
deployment.apps/deployment-v2 created
[root@server2 manifest]# kubectl get deployments.apps 
NAME            READY   UP-TO-DATE   AVAILABLE   AGE
deployment-v1   3/3     3            3           10s
deployment-v2   3/3     3            3           10s
[root@server2 manifest]# kubectl get rs
NAME                       DESIRED   CURRENT   READY   AGE
deployment-v1-7449b5b68f   3         3         3       105s
deployment-v2-67764dd8bd   3         3         3       105s
[root@server2 manifest]# kubectl get pod -o wide
NAME                             READY   STATUS    RESTARTS   AGE    IP            NODE      NOMINATED NODE   READINESS GATES
deployment-v1-7449b5b68f-csldb   1/1     Running   0          119s   10.244.1.73   server3   <none>           <none>
deployment-v1-7449b5b68f-srkxx   1/1     Running   0          119s   10.244.2.49   server4   <none>           <none>
deployment-v1-7449b5b68f-x5c59   1/1     Running   0          119s   10.244.2.50   server4   <none>           <none>
deployment-v2-67764dd8bd-bmmrc   1/1     Running   0          119s   10.244.2.51   server4   <none>           <none>
deployment-v2-67764dd8bd-m5c2g   1/1     Running   0          119s   10.244.1.75   server3   <none>           <none>
deployment-v2-67764dd8bd-zf8wx   1/1     Running   0          119s   10.244.1.74   server3   <none>           <none>
  • 刪除
[root@server2 manifest]# kubectl delete deployments.apps deployment-v1
deployment.apps "deployment-v1" deleted
[root@server2 manifest]# kubectl get all
NAME                                 READY   STATUS        RESTARTS   AGE
pod/deployment-v1-7449b5b68f-g2s28   1/1     Terminating   0          87s
pod/deployment-v1-7449b5b68f-l4z8q   0/1     Terminating   0          87s
pod/deployment-v1-7449b5b68f-mqkqc   1/1     Terminating   0          87s
pod/deployment-v2-67764dd8bd-89t2z   1/1     Running       0          87s
pod/deployment-v2-67764dd8bd-rqsjn   1/1     Running       0          87s
pod/deployment-v2-67764dd8bd-sqrzg   1/1     Running       0          87s

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   8d

NAME                            READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/deployment-v2   3/3     3            3           87s

NAME                                       DESIRED   CURRENT   READY   AGE
replicaset.apps/deployment-v2-67764dd8bd   3         3         3       87s

刪除v1,v2還在。

Daemonset控制器

Daemonset控制器適用於每個節點運行一個的pod。
我們之前使用的控制器不是在每個結點運行一個的,而是有可能都再一個結點運行:

[root@server2 manifest]# kubectl get pod -o wide
NAME                             READY   STATUS              RESTARTS   AGE   IP       NODE      NOMINATED NODE   READINESS GATES
deployment-v1-7449b5b68f-jz5h9   0/1     ContainerCreating   0          3s    <none>   server4   <none>           <none>
deployment-v1-7449b5b68f-lmksm   0/1     ContainerCreating   0          3s    <none>   server4   <none>           <none>
deployment-v1-7449b5b68f-v9d64   0/1     ContainerCreating   0          3s    <none>   server4   <none>           <none>
[root@server2 manifest]# vim daemonset.yml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: daemonset-example
  labels:
    k8s-app: zabbix-agent
spec:
  selector:
    matchLabels:
      name: zabbix-agent
  template:
    metadata:
      labels:
        name: zabbix-agent
    spec:
      containers:
      - name: zabbix-agent
        image:  zabbix-agent

[root@server2 manifest]# kubectl apply -f daemonset.yml 
daemonset.apps/daemonset-example created
[root@server2 manifest]# kubectl get pod -o wide
NAME                      READY   STATUS    RESTARTS   AGE   IP            NODE      NOMINATED NODE   READINESS GATES
daemonset-example-67tmd   1/1     Running   0          6s    10.244.1.78   server3   <none>           <none>
daemonset-example-qjtks   1/1     Running   0          6s    10.244.2.56   server4   <none>           <none>
//一個結點一個,新加入的結點頁回自動拉起一個這個pod

job控制器

[root@server2 manifest]# vim job.yml
apiVersion: batch/v1
kind: Job
metadata:
  name: example-job
spec:
  template:
    metadata:
      name: example-job
    spec:
      containers:
      - name: pi
        image: perl
        command: ["perl"]
        args: ["-Mbignum=bpi", "-wle", "print bpi(2000)"]	//計算pi的值.2000位
      restartPolicy: Never

[root@server2 manifest]# kubectl apply -f job.yml 
job.batch/example-job created
[root@server2 manifest]# kubectl get pod -w
NAME                READY   STATUS              RESTARTS   AGE
example-job-9vzb9   0/1     ContainerCreating   0          42s	//正在拉取鏡像,比較大
example-job-9vzb9   1/1     Running             0          50s	//正在計算
example-job-9vzb9   0/1     Completed           0          54s	//計算完畢
[root@server2 manifest]# kubectl logs example-job-9vzb9 
3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384
[root@server2 manifest]# kubectl get job
NAME          COMPLETIONS   DURATION   AGE
example-job   1/1           54s        3m16s
[root@server2 manifest]# kubectl delete -f job.yml 
job.batch "example-job" deleted
[root@server2 manifest]# kubectl get job
No resources found in default namespace.

cronjob控制器

執行週期性任務。

[root@server2 manifest]# vim cronjob.yml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: cronjob-example
spec:
  schedule: "* * * * *"		//每分鐘
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: cronjob
            image: busybox
            args:
            - /bin/sh
            - -c
            - date; echo Hello from k8s cluster
          restartPolicy: OnFailure
[root@server2 manifest]# kubectl apply -f cronjob.yml 
cronjob.batch/cronjob-example created
No resources found in default namespace.
[root@server2 manifest]# kubectl get pod 	//每分鐘執行一次,所以等待一分鐘
No resources found in default namespace.
[root@server2 manifest]# kubectl get pod 
NAME                               READY   STATUS      RESTARTS   AGE
cronjob-example-1593239100-hd4mk   0/1     Completed   0          3s
[root@server2 manifest]# kubectl logs cronjob-example-1593239100-hd4mk 
Sat Jun 27 06:25:03 UTC 2020
Hello from k8s cluster
//再等待一分鐘
[root@server2 manifest]# kubectl get pod 
NAME                               READY   STATUS      RESTARTS   AGE
cronjob-example-1593239100-hd4mk   0/1     Completed   0          60s
[root@server2 manifest]# kubectl get pod 
NAME                               READY   STATUS      RESTARTS   AGE
cronjob-example-1593239100-hd4mk   0/1     Completed   0          66s
cronjob-example-1593239160-mzwrz   0/1     Completed   0          5s	//又拉起一個
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章