k8s控制器類型及演示

一、Pod控制器

Pod 的分類

1.自主式 Pod

Pod 退出後不會被創建

2.控制器管理的 Pod

在控制器的生命週期裏,始終要維持 Pod 的副本數目

3.控制器類型

Replication Controller和ReplicaSet Deployment DaemonSet StatefulSet Job CronJob HPA全稱Horizontal Pod Autoscaler Replication Controller和ReplicaSet ReplicaSet (RS)是下一代的 Replication Controller(RC),官方推薦使用ReplicaSet。

ReplicaSet 和 Replication Controller 的唯一區別是選擇器的支持,ReplicaSet 支持新的基於集合的選擇器需求。

ReplicaSet 確保任何時間都有指定數量的 Pod 副本在運行。

雖然 ReplicaSets 可以獨立使用,但今天它主要被Deployments 用作協調 Pod 創建、刪除和更新的機制。

1>Deployment

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

.典型的應用場景:

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

2>DaemonSet

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

DaemonSet 的典型用法:

在每個節點上運行集羣存儲 DaemonSet,例如 glusterd、ceph。 在每個節點上運行日誌收集 DaemonSet,例如 fluentd、logstash。 在每個節點上運行監控 DaemonSet,例如 Prometheus Node Exporter、zabbix agent等 一個簡單的用法是在所有的節點上都啓動一個 DaemonSet,將被作爲每種類型的 daemon 使用。

一個稍微複雜的用法是單獨對每種 daemon 類型使用多個 DaemonSet,但具有不同的標誌, 並且對不同硬件類型具有不同的內存、CPU 要求。

3>StatefulSet

StatefulSet 是用來管理有狀態應用的工作負載 API 對象。實例之間有不對等關係,以及實例對外部數據有依賴關係的應用,稱爲“有狀態應用”

StatefulSet 用來管理 Deployment 和擴展一組 Pod,並且能爲這些 Pod 提供序號和唯一性保證。

StatefulSets 對於需要滿足以下一個或多個需求的應用程序很有價值:

穩定的、唯一的網絡標識符。 穩定的、持久的存儲。 有序的、優雅的部署和縮放。 有序的、自動的滾動更新。 Job 執行批處理任務,僅執行一次任務,保證任務的一個或多個Pod成功結束。

4>CronJob

Cron Job 創建基於時間調度的 Jobs。

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

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

二、Pod控制器使用示例

ReplicaSet舉例

1.編輯以下yaml文件:

[root@server1 ~]# vim rs.yaml 
[root@server1 ~]# cat rs.yaml 
apiVersion: apps/v1
kind: ReplicaSet
metadata:
    name: replicaset-example
spec:
  replicas: 2           #啓動pod的副本數
  selector:             #定義選擇器爲標籤選擇器。
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx              #定義容器的標籤
    spec:                       #定義容器
      containers:
      - name: nginx
        image: nginx

2.運行

以上使用的控制器的RS,RS控制器通過pod的標籤(matchLabels)來控制pod的數量,使用apply命令可以實現創建,更新pod,而create命令創建後若需要更新只能刪除之後再創建,因此建議使用apply:

[root@server1 ~]# kubectl apply -f rs.yaml 
replicaset.apps/replicaset-example created
[root@server1 ~]# kubectl apply -f rs.yaml 
replicaset.apps/replicaset-example unchanged

3.查看狀態:

查看狀態:

[root@server1 ~]# kubectl get pod
NAME                       READY   STATUS    RESTARTS   AGE
replicaset-example-p6sv6   1/1     Running   0          34s
replicaset-example-s5jps   1/1     Running   0          34s
[root@server1 ~]# kubectl get rs            #獲取rs的信息
NAME                 DESIRED   CURRENT   READY   AGE
replicaset-example   2         2         2       36s
[root@server1 ~]# kubectl get pod -o wide
NAME                       READY   STATUS    RESTARTS   AGE   IP            NODE      NOMINATED NODE   READINESS GATES
replicaset-example-p6sv6   1/1     Running   0          38s   10.244.1.14   server2   <none>           <none>
replicaset-example-s5jps   1/1     Running   0          38s   10.244.2.21   server3   <none>           <none>

可以看出一且正常,接下來進行pod的拉伸與壓縮:

4.拉伸副本數:

[root@server1 ~]# vim rs.yaml 
[root@server1 ~]# cat rs.yaml 
apiVersion: apps/v1
kind: ReplicaSet
metadata:
    name: replicaset-example
spec:
  replicas: 4       #拉伸爲4個
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx

[root@server1 ~]# kubectl apply -f rs.yaml 
replicaset.apps/replicaset-example configured

5.查看pod數:

[root@server1 ~]# kubectl get pod
NAME                       READY   STATUS    RESTARTS   AGE
replicaset-example-p6sv6   1/1     Running   0          97s
replicaset-example-s5jps   1/1     Running   0          97s
replicaset-example-wzclz   1/1     Running   0          21s
replicaset-example-zk4mb   1/1     Running   0          21s

已經被拉伸成了4個。

6.縮減:

[root@server1 ~]# vim rs.yaml 
[root@server1 ~]# cat rs.yaml 
apiVersion: apps/v1
kind: ReplicaSet
metadata:
    name: replicaset-example
spec:
  replicas: 2           #縮減爲2個
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx

[root@server1 ~]# kubectl apply -f rs.yaml 
replicaset.apps/replicaset-example configured
[root@server1 ~]# kubectl get pod
NAME                       READY   STATUS        RESTARTS   AGE
replicaset-example-p6sv6   1/1     Running       0          2m6s
replicaset-example-s5jps   1/1     Running       0          2m6s

可以看出刪除的是剛剛創建的那兩個pod。

7.更改一個pod 的標籤:

[root@server1 ~]# kubectl label pod replicaset-example-s5jps app=myapp --overwrite      #將標籤強制更改爲myapp
pod/replicaset-example-s5jps labeled
[root@server1 ~]# kubectl get pod --show-labels
NAME                       READY   STATUS    RESTARTS   AGE     LABELS
replicaset-example-p6sv6   1/1     Running   0          3m56s   app=nginx
replicaset-example-s5jps   1/1     Running   0          3m56s   app=myapp
replicaset-example-w98nk   1/1     Running   0          26s     app=nginx

可以看出現在有3個pod,兩個標籤爲nginx一個爲myapp,RS控制器的工作原理就是維持標籤爲nginx的pod個數有2個,因此當我們更改一個pod的標籤後,RS又會給我們創建一個標籤爲nginx的pod,而當我們將標籤爲myapp的pod刪除後RS控制器不會有操作:

[root@server1 ~]# kubectl delete pod replicaset-example-s5jps
pod "replicaset-example-s5jps" deleted
[root@server1 ~]# kubectl get pod --show-labels
NAME                       READY   STATUS    RESTARTS   AGE    LABELS
replicaset-example-p6sv6   1/1     Running   0          5m8s   app=nginx
replicaset-example-w98nk   1/1     Running   0          98s    app=nginx

8.再更改驗證:

[root@server1 ~]# kubectl label pod replicaset-example-p6sv6 app=myapp --overwrite      #首先保證3個pod
pod/replicaset-example-p6sv6 labeled
[root@server1 ~]# kubectl get pod --show-labels
NAME                       READY   STATUS    RESTARTS   AGE     LABELS
replicaset-example-p6sv6   1/1     Running   0          6m4s    app=myapp
replicaset-example-w98nk   1/1     Running   0          2m34s   app=nginx
replicaset-example-x2lq9   1/1     Running   0          26s     app=nginx

[root@server1 ~]# kubectl label pod replicaset-example-p6sv6 app=nginx --overwrite
pod/replicaset-example-p6sv6 labeled
[root@server1 ~]# kubectl get pod --show-labels
NAME                       READY   STATUS        RESTARTS   AGE     LABELS
replicaset-example-p6sv6   1/1     Running       0          6m23s   app=nginx
replicaset-example-w98nk   1/1     Running       0          2m53s   app=nginx
replicaset-example-x2lq9   0/1     Terminating   0          45s     app=nginx
[root@server1 ~]# kubectl get pod --show-labels
NAME                       READY   STATUS    RESTARTS   AGE     LABELS
replicaset-example-p6sv6   1/1     Running   0          6m25s   app=nginx
replicaset-example-w98nk   1/1     Running   0          2m55s   app=nginx

以上實驗可以看出,當集羣裏有3個標籤是nginx的pod的時候,RS控制器又會幫我們將最後創建的pod刪除。

實驗後刪除:

[root@server1 ~]# kubectl delete -f rs.yaml 
replicaset.apps "replicaset-example" deleted

Deployment控制器示例

1.編輯yaml文件:

Deployment控制器示例 編輯yaml文件:

[root@server1 ~]# vim deployment.yaml 
[root@server1 ~]# cat deployment.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-nginx
  labels:
    app: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: ikubernetes/myapp:v1
        ports:
        - containerPort: 80

2.創建pod:

[root@server1 ~]# kubectl apply -f deployment.yaml 
deployment.apps/deployment-nginx created
[root@server1 ~]# kubectl get pod
NAME                                READY   STATUS    RESTARTS   AGE
deployment-nginx-56d786cd98-kx5pw   1/1     Running   0          23s
deployment-nginx-56d786cd98-qgcjl   1/1     Running   0          23s

[root@server1 ~]# kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
deployment-nginx-56d786cd98   2         2         2       28s
[root@server1 ~]# kubectl get deployments.apps      #查看deployments
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
deployment-nginx   2/2     2            2           32s

以上運行結果可以看出deployments底層也是由RS實現的,接下來

3.進行拉伸:

[root@server1 ~]# vim deployment.yaml 
[root@server1 ~]# cat deployment.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-nginx
  labels:
    app: nginx
spec:
  replicas: 4           #拉伸爲4個
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: ikubernetes/myapp:v1
        ports:
        - containerPort: 80
[root@server1 ~]# kubectl apply -f deployment.yaml 
deployment.apps/deployment-nginx configured
[root@server1 ~]# kubectl get pod
NAME                                READY   STATUS    RESTARTS   AGE
deployment-nginx-56d786cd98-942dh   1/1     Running   0          26s
deployment-nginx-56d786cd98-kx5pw   1/1     Running   0          108s
deployment-nginx-56d786cd98-qgcjl   1/1     Running   0          108s
deployment-nginx-56d786cd98-zb8s8   1/1     Running   0          26s

可以看出已經拉伸爲4個。接下來進行

4.滾動更新:

[root@server1 ~]# vim deployment.yaml 
[root@server1 ~]# cat deployment.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-nginx
  labels:
    app: nginx
spec:
  replicas: 4
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: ikubernetes/myapp:v2     #更新到v2
        ports:
        - containerPort: 80
[root@server1 ~]# kubectl apply -f deployment.yaml 
deployment.apps/deployment-nginx configured
[root@server1 ~]# kubectl get pod -o wide
NAME                                READY   STATUS    RESTARTS   AGE     IP            NODE      NOMINATED NODE   READINESS GATES
deployment-nginx-868855d887-2zh45   1/1     Running   0          2m39s   10.244.2.26   server3   <none>           <none>
deployment-nginx-868855d887-87m22   1/1     Running   0          2m34s   10.244.1.20   server2   <none>           <none>
deployment-nginx-868855d887-hb6mv   1/1     Running   0          2m39s   10.244.1.19   server2   <none>           <none>
deployment-nginx-868855d887-v8ndt   1/1     Running   0          2m33s   10.244.2.27   server3   <none>           <none>
[root@server1 ~]# curl 10.244.2.26
Hello MyApp | Version: v2 | Pod Name

可以看出更新時控制器新建一個rs,然後再新建4個pod,原來的rs依然存在,爲了方便我們

5.進行回滾:

[root@server1 ~]# vim deployment.yaml 
[root@server1 ~]# cat deployment.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-nginx
  labels:
    app: nginx
spec:
  replicas: 4
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: ikubernetes/myapp:v1
        ports:
        - containerPort: 80
[root@server1 ~]# kubectl apply -f deployment.yaml 
deployment.apps/deployment-nginx configured
[root@server1 ~]# kubectl get pod
NAME                                READY   STATUS              RESTARTS   AGE
deployment-nginx-56d786cd98-78m7z   0/1     ContainerCreating   0          4s
deployment-nginx-56d786cd98-8hnns   1/1     Running             0          9s
deployment-nginx-56d786cd98-lcvzw   1/1     Running             0          9s
deployment-nginx-56d786cd98-xkjhq   0/1     ContainerCreating   0          3s
deployment-nginx-868855d887-2zh45   1/1     Running             0          3m22s
deployment-nginx-868855d887-hb6mv   1/1     Terminating         0          3m22s
deployment-nginx-868855d887-v8ndt   1/1     Terminating         0          3m16s

[root@server1 ~]# kubectl get pod
NAME                                READY   STATUS    RESTARTS   AGE
deployment-nginx-56d786cd98-78m7z   1/1     Running   0          26s
deployment-nginx-56d786cd98-8hnns   1/1     Running   0          31s
deployment-nginx-56d786cd98-lcvzw   1/1     Running   0          31s
deployment-nginx-56d786cd98-xkjhq   1/1     Running   0          25s

可以看出原來v1版本的rs被重新啓用,再原來的rs下面新建4個pod。當然我門也可以使用kubectl delete rs --all命令刪除不用的rs(注意:正在使用的rs不會刪除):

[root@server1 ~]# kubectl delete rs --all
replicaset.apps "deployment-nginx-56d786cd98" deleted
replicaset.apps "deployment-nginx-868855d887" deleted
[root@server1 ~]# kubectl get pod
NAME                                READY   STATUS    RESTARTS   AGE
deployment-nginx-56d786cd98-6r589   1/1     Running   0          21s
deployment-nginx-56d786cd98-hvz24   1/1     Running   0          21s
deployment-nginx-56d786cd98-k62lj   1/1     Running   0          21s
deployment-nginx-56d786cd98-ss97z   1/1     Running   0          21s
[root@server1 ~]# kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
deployment-nginx-56d786cd98   4         4         4       24s       #正在使用的RS不會刪除

實驗後刪除:

[root@server1 ~]# kubectl delete -f deployment.yaml 
deployment.apps "deployment-nginx" deleted

DaemonSet舉例

1.編輯yaml

DaemonSet控制器保證每個節點上都運行一個pod:

[root@server1 ~]# vim daemonset.yaml 
[root@server1 ~]# cat daemonset.yaml 
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: daemonset-example
  labels:
    app: zabbix-agent
spec:
  selector:
    matchLabels:
      name: zabbix-agent
  template:
    metadata:
      labels:
        name: zabbix-agent
    spec:
      containers:
      - name: zabbix-agent
        image: zabbix/zabbix-agent

2.創建pod:

[root@server1 ~]# kubectl apply -f daemonset.yaml 
daemonset.apps/daemonset-example created
[root@server1 ~]# kubectl get pod
NAME                      READY   STATUS    RESTARTS   AGE
daemonset-example-ctbgh   1/1     Running   0          6m5s
daemonset-example-mdqzk   1/1     Running   0          6m5s

[root@server1 ~]# kubectl get pod -o wide
NAME                      READY   STATUS    RESTARTS   AGE     IP            NODE      NOMINATED NODE   READINESS GATES
daemonset-example-ctbgh   1/1     Running   0          7m16s   10.244.2.32   server3   <none>           <none>
daemonset-example-mdqzk   1/1     Running   0          7m16s   10.244.1.25   server2   <none>           <none>

可以看出我們的每個節點(server3和server2)上都運行了一個pod

3.刪除一個pod:

[root@server1 ~]# kubectl delete pod daemonset-example-ctbgh
pod "daemonset-example-ctbgh" deleted
[root@server1 ~]# kubectl get pod -o wide
NAME                      READY   STATUS              RESTARTS   AGE     IP            NODE      NOMINATED NODE   READINESS GATES
daemonset-example-998ck   0/1     ContainerCreating   0          8s      <none>        server3   <none>           <none>
daemonset-example-mdqzk   1/1     Running             0          8m22s   10.244.1.25   server2   <none>           <none>
[root@server1 ~]# kubectl get pod -o wide
NAME                      READY   STATUS    RESTARTS   AGE     IP            NODE      NOMINATED NODE   READINESS GATES
daemonset-example-998ck   1/1     Running   0          24s     10.244.2.33   server3   <none>           <none>
daemonset-example-mdqzk   1/1     Running   0          8m38s   10.244.1.25   server2   <none>           <none>

可以看出刪除後DaemonSet控制器又會幫我們創建pod,以保證每個節點運行一個pod。

實驗後刪除:

[root@server1 ~]# kubectl delete -f daemonset.yaml 
daemonset.apps "daemonset-example" deleted

Job控制器舉例

1.編輯yaml

Job控制器只運行一次

[root@server1 ~]# vim job.yaml 
[root@server1 ~]# cat job.yaml 
apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  template:
    spec:
      containers:
      - name: pi
        image: perl             #利用perl計算圓周率
        command: ["perl",  "-Mbignum=bpi", "-wle", "print      bpi(2000)"]
      restartPolicy: Never
  backoffLimit: 4           #容器啓動失敗重啓4次之後不再重啓。

2.創建

kubectl apply -f job.yaml

由於Job只運行一次,因此運行完後狀態爲Completed,我們可以查看日誌獲取結果:

可以看出計算成功。

實驗後刪除:

[root@server1 ~]# kubectl delete -f job.yaml 
job.batch "pi" deleted

CronJob控制器舉例
CronJob控制器用於定時執行任務:

[root@server1 ~]# vim cronjob.yaml 
[root@server1 ~]# cat cronjob.yaml 
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

Crontab

其中schedule字段與crontab裏面的寫法相同," * "表示每分鐘執行任務。

1.創建pod:

[root@server1 ~]# kubectl apply -f cronjob.yaml 
cronjob.batch/cronjob-example created
root@server1 ~]# kubectl get pod
NAME                               READY   STATUS              RESTARTS   AGE
cronjob-example-1587387120-ngt6n   0/1     ContainerCreating   0          16s
[root@server1 ~]# kubectl get pod       #等待一分鐘
NAME                               READY   STATUS              RESTARTS   AGE
cronjob-example-1587387120-ngt6n   0/1     Completed           0          60s
cronjob-example-1587387180-hbwzb   0/1     ContainerCreating   0          9s

可以看出每分鐘運行一個pod,查看日誌獲取輸出信息:

[root@server1 ~]# kubectl logs cronjob-example-1587387120-ngt6n
Mon Apr 20 12:52:30 UTC 2020
Hello from k8s cluster
[root@server1 ~]# kubectl logs cronjob-example-1587387180-hbwzb
Mon Apr 20 12:53:35 UTC 2020
Hello from k8s cluster

可以看出輸出也是每分鐘輸出一次,也可以使用以下命令查看cronjob的信息:

[root@server1 ~]# kubectl get cronjobs
NAME              SCHEDULE    SUSPEND   ACTIVE   LAST SCHEDULE   AGE
cronjob-example   * * * * *   False     1        16s             3m10s

[root@server1 ~]# kubectl get job -w        #查看job信息並且持續輸出
NAME                         COMPLETIONS   DURATION   AGE
cronjob-example-1587387120   1/1           20s        2m23s
cronjob-example-1587387180   1/1           35s        92s
cronjob-example-1587387240   1/1           20s        32s

實驗後刪除

[root@server1 ~]# kubectl delete -f cronjob.yaml 
cronjob.batch "cronjob-example" deleted
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章