1. 程式人生 > 其它 >k8s——pod控制器

k8s——pod控制器

目錄

一、Pod控制器介紹

1.1 Pod控制器及其功用

Pod控制器,又稱之為工作負載(workload),是用於實現管理pod的中間層,確保pod資源符合預期的狀態,pod的資源出現故障時,會嘗試進行重啟,當根據重啟策略無效,則會重新新建pod的資源。

1.3 pod控制器有多種型別

1.ReplicaSet: 代使用者建立指定數量的pod副本數量,確保pod副本數量符合預期狀態,並且支援滾動式自動擴容和縮容功能。
ReplicaSet主要三個元件組成:
(1)使用者期望的pod副本數量
(2)標籤選擇器,判斷哪個pod歸自己管理
(3)當現存的pod數量不足,會根據pod資源模板進行新建
幫助使用者管理無狀態的pod資源,精確反應使用者定義的目標數量,但是RelicaSet不是直接使用的控制器,而是使用Deployment
2、Deployment:工作在ReplicaSet之上,用於管理無狀態應用,目前來說最好的控制器。支援滾動更新和回滾功能,還提供宣告式配置。
ReplicaSet 與Deployment 這兩個資源物件逐步替換之前RC的作用。
3、DaemonSet:用於確保叢集中的每一個節點只執行特定的pod副本,通常用於實現系統級後臺任務。比如ELK服務
特性:服務是無狀態的
服務必須是守護程序
4、StatefulSet:管理有狀態應用
5、Job:只要完成就立即退出,不需要重啟或重建
6、Cronjob:週期性任務控制,不需要持續後臺執行

1.3 Pod與控制器之間的關係

1.controllers:在叢集上管理和執行容器的 pod 物件,pod通過label-selector 相關聯。
2.Pod通過控制器實現應用的運維,如伸縮,升級等。

二、Pod控制器種類及yaml格式

2.1 Deployment

部署無狀態應用
管理Pod和ReplicaSet
具有上線部署、副本設定、滾動升級、回滾等功能
提供宣告式更新,例如只更新一個新的image
應用場景:web服務
//示例:
vim nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx	
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.15.4
        ports:
        - containerPort: 80

kubectl create -f nginx-deployment.yaml

kubectl get pods,deploy,rs
//檢視控制器配置
kubectl edit deployment/nginx-deployment
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
  creationTimestamp: "2021-04-19T08:13:50Z"
  generation: 1
  labels:
    app: nginx					#Deployment資源的標籤
  name: nginx-deployment
  namespace: default
  resourceVersion: "167208"
  selfLink: /apis/extensions/v1beta1/namespaces/default/deployments/nginx-deployment
  uid: d9d3fef9-20d2-4196-95fb-0e21e65af24a
spec:
  progressDeadlineSeconds: 600
  replicas: 3					#期望的pod數量,預設是1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: nginx
  strategy:
    rollingUpdate:
      maxSurge: 25%				#升級過程中會先啟動的新Pod的數量不超過期望的Pod數量的25%,也可以是一個絕對值
      maxUnavailable: 25%		#升級過程中在新的Pod啟動好後銷燬的舊Pod的數量不超過期望的Pod數量的25%,也可以是一個絕對值
    type: RollingUpdate			#滾動升級
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx				#Pod副本關聯的標籤
    spec:
      containers:
      - image: nginx:1.15.4				#映象名稱
        imagePullPolicy: IfNotPresent	#映象拉取策略
        name: nginx
        ports:
        - containerPort: 80				#容器暴露的監聽埠
          protocol: TCP
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always				#容器重啟策略
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
......
//檢視歷史版本
kubectl rollout history deployment/nginx-deployment
deployment.extensions/nginx-deployment 
REVISION  CHANGE-CAUSE
1         <none>

2.2 StatefulSet

部署有狀態應用
穩定的持久化儲存,即Pod重新排程後還是能訪問到相同的持久化資料,基於PVC來實現
穩定的網路標誌,即Pod重新排程後其PodName和HostName不變,基於Headless Service(即沒有Cluster IP的Service)來實現
有序部署,有序擴充套件,即Pod是有順序的,在部署或者擴充套件的時候要依據定義的順序依次進行(即從0到N-1,在下一個Pod執行之前所有之前的Pod必須都是Running和Ready狀態),基於init containers來實現
有序收縮,有序刪除(即從N-1到0)

常見的應用場景:資料庫
https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/
apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx # has to match .spec.template.metadata.labels
  serviceName: "nginx"
  replicas: 3 # by default is 1
  template:
    metadata:
      labels:
        app: nginx # has to match .spec.selector.matchLabels
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: k8s.gcr.io/nginx-slim:0.8
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "my-storage-class"
      resources:
        requests:
          storage: 1Gi
==========================================================
從上面的應用場景可以發現,StatefulSet由以下幾個部分組成:
●Headless Service(無頭服務):用於為Pod資源識別符號生成可解析的DNS記錄。
●volumeClaimTemplates(儲存卷申請模板):基於靜態或動態PV供給方式為Pod資源提供專有的固定儲存。
●StatefulSet:用於管控Pod資源。
==========================================================
為什麼要有headless?
在deployment中,每一個pod是沒有名稱,是隨機字串,是無序的。而statefulset中是要求有序的,每一個pod的名稱必須是固定的。當節點掛了,重建之後的識別符號是不變的,每一個節點的節點名稱是不能改變的。pod名稱是作為pod識別的唯一識別符號,必須保證其識別符號的穩定並且唯一。
為了實現識別符號的穩定,這時候就需要一個headless service 解析直達到pod,還需要給pod配置一個唯一的名稱。
==========================================================
為什麼要有volumeClainTemplate?
大部分有狀態副本集都會用到持久儲存,比如分散式系統來說,由於資料是不一樣的,每個節點都需要自己專用的儲存節點。而在 deployment中pod模板中建立的儲存卷是一個共享的儲存卷,多個pod使用同一個儲存卷,而statefulset定義中的每一個pod都不能使用同一個儲存卷,由此基於pod模板建立pod是不適應的,這就需要引入volumeClainTemplate,當在使用statefulset建立pod時,會自動生成一個PVC,從而請求繫結一個PV,從而有自己專用的儲存卷。
==========================================================
服務發現:就是應用服務之間相互定位的過程。
應用場景:
●動態性強:Pod會飄到別的node節點
●更新發布頻繁:網際網路思維小步快跑,先實現再優化,老闆永遠是先上線再慢慢優化,先把idea變成產品掙到錢然後再慢慢一點一點優化
●支援自動伸縮:一來大促,肯定是要擴容多個副本

K8S裡服務發現的方式---DNS,使K8S叢集能夠自動關聯Service資源的“名稱”和“CLUSTER-IP”,從而達到服務被叢集自動發現的目的。

實現K8S裡DNS功能的外掛:
●skyDNS:Kubernetes 1.3之前的版本
●kubeDNS:Kubernetes 1.3至Kubernetes 1.11
●CoreDNS:Kubernetes 1.11開始至今
==========================================================
//安裝CoreDNS,僅二進位制部署環境需要安裝CoreDNS
方法一:
下載連結:https://github.com/kubernetes/kubernetes/blob/master/cluster/addons/dns/coredns/coredns.yaml.base

vim transforms2sed.sed
s/__DNS__SERVER__/10.0.0.2/g
s/__DNS__DOMAIN__/cluster.local/g
s/__DNS__MEMORY__LIMIT__/170Mi/g
s/__MACHINE_GENERATED_WARNING__/Warning: This is a file generated from the base underscore template file: coredns.yaml.base/g

sed -f transforms2sed.sed coredns.yaml.base > coredns.yaml

方法二:上傳 coredns.yaml 檔案

kubectl create -f coredns.yaml

kubectl get pods -n kube-system
==========================================================
vim nginx-service.yaml
apiVersion: v1  
kind: Service  
metadata:
  name: nginx-service
  labels:
    app: nginx  
spec:
  type: NodePort  
  ports:
  - port: 80
    targetPort: 80  
  selector:
    app: nginx

kubectl create -f nginx-service.yaml

kubectl get svc
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes      ClusterIP   10.96.0.1       <none>        443/TCP        5d19h
nginx-service   NodePort    10.96.173.115   <none>        80:31756/TCP   10s
=========================================================
vim pod6.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: dns-test
spec:
  containers:
  - name: busybox
    image: busybox:1.28.4
    args:
    - /bin/sh
    - -c
    - sleep 36000
  restartPolicy: Never
  
kubectl create -f pod6.yaml 

//解析kubernetes和nginx-service名稱
kubectl exec -it dns-test sh
/ # nslookup kubernetes
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      kubernetes
Address 1: 10.96.0.1 kubernetes.default.svc.cluster.local
/ # nslookup nginx-service
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      nginx-service
Address 1: 10.96.173.115 nginx-service.default.svc.cluster.local
==========================================================
//檢視statefulset的定義
kubectl explain statefulset
KIND:     StatefulSet
VERSION:  apps/v1

DESCRIPTION:
     StatefulSet represents a set of pods with consistent identities. Identities
     are defined as: - Network: A single stable DNS and hostname. - Storage: As
     many VolumeClaims as requested. The StatefulSet guarantees that a given
     network identity will always map to the same storage identity.

FIELDS:
   apiVersion	<string>
   kind	<string>
   metadata	<Object>
   spec	<Object>
   status	<Object>

kubectl explain statefulset.spec
KIND:     StatefulSet
VERSION:  apps/v1

RESOURCE: spec <Object>

DESCRIPTION:
     Spec defines the desired identities of pods in this set.

     A StatefulSetSpec is the specification of a StatefulSet.

FIELDS:
   podManagementPolicy	<string>  #Pod管理策略
   replicas	<integer>    #副本數量
   revisionHistoryLimit	<integer>   #歷史版本限制
   selector	<Object> -required-    #選擇器,必選項
   serviceName	<string> -required-  #服務名稱,必選項
   template	<Object> -required-    #模板,必選項
   updateStrategy	<Object>       #更新策略
   volumeClaimTemplates	<[]Object>   #儲存卷申請模板,必選項
=========================================================
//清單定義StatefulSet
如上所述,一個完整的 StatefulSet 控制器由一個 Headless Service、一個 StatefulSet 和一個 volumeClaimTemplate 組成。如下資源清單中的定義:

vim stateful-demo.yaml
apiVersion: v1
kind: Service
metadata:
  name: myapp-svc
  labels:
    app: myapp-svc
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: myapp-pod
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: myapp
spec:
  serviceName: myapp-svc
  replicas: 3
  selector:
    matchLabels:
      app: myapp-pod
  template:
    metadata:
      labels:
        app: myapp-pod
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v1
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: myappdata
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: myappdata
	  annotations:          #動態PV建立時,使用annotations在PVC裡宣告一個StorageClass物件的標識進行關聯
        volume.beta.kubernetes.io/storage-class: nfs-client-storageclass
    spec:
      accessModes: ["ReadWriteOnce"]
      resources:
        requests:
          storage: 2Gi

解析上例:由於 StatefulSet 資源依賴於一個實現存在的 Headless 型別的 Service 資源,所以需要先定義一個名為 myapp-svc 的 Headless Service 資源,用於為關聯到每個 Pod 資源建立 DNS 資源記錄。接著定義了一個名為 myapp 的 StatefulSet 資源,它通過 Pod 模板建立了 3 個 Pod 資源副本,並基於 volumeClaimTemplates 向前面建立的PV進行了請求大小為 2Gi 的專用儲存卷。
==========================================================
//建立pv
//stor01節點
mkdir -p /data/volumes/v{1,2,3,4,5}

vim /etc/exports
/data/volumes/v1 192.168.80.0/24(rw,no_root_squash)
/data/volumes/v2 192.168.80.0/24(rw,no_root_squash)
/data/volumes/v3 192.168.80.0/24(rw,no_root_squash)
/data/volumes/v4 192.168.80.0/24(rw,no_root_squash)
/data/volumes/v5 192.168.80.0/24(rw,no_root_squash)


systemctl restart rpcbind
systemctl restart nfs

exportfs -arv

showmount -e

//定義PV
vim pv-demo.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv001
  labels:
    name: pv001
spec:
  nfs:
    path: /data/volumes/v1
    server: stor01
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 1Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv002
  labels:
    name: pv002
spec:
  nfs:
    path: /data/volumes/v2
    server: stor01
  accessModes: ["ReadWriteOnce"]
  capacity:
    storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv003
  labels:
    name: pv003
spec:
  nfs:
    path: /data/volumes/v3
    server: stor01
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv004
  labels:
    name: pv004
spec:
  nfs:
    path: /data/volumes/v4
    server: stor01
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv005
  labels:
    name: pv005
spec:
  nfs:
    path: /data/volumes/v5
    server: stor01
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 2Gi


kubectl apply -f pv-demo.yaml

kubectl get pv
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM     STORAGECLASS   REASON    AGE
pv001     1Gi        RWO,RWX        Retain           Available                                      7s
pv002     2Gi        RWO            Retain           Available                                      7s
pv003     2Gi        RWO,RWX        Retain           Available                                      7s
pv004     2Gi        RWO,RWX        Retain           Available                                      7s
pv005     2Gi        RWO,RWX        Retain           Available                           			7s


//建立statefulset
kubectl apply -f stateful-demo.yaml 

kubectl get svc  #檢視建立的無頭服務myapp-svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)             AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP             50d
myapp-svc    ClusterIP   None             <none>        80/TCP              38s

kubectl get sts    #檢視statefulset
NAME      DESIRED   CURRENT   AGE
myapp     3         3         55s

kubectl get pvc    #檢視pvc繫結
NAME                STATUS    VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
myappdata-myapp-0   Bound     pv002     2Gi        RWO                           1m
myappdata-myapp-1   Bound     pv003     2Gi        RWO,RWX                       1m
myappdata-myapp-2   Bound     pv004     2Gi        RWO,RWX                       1m

kubectl get pv    #檢視pv繫結
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM                       STORAGECLASS   REASON    AGE
pv001     1Gi        RWO,RWX        Retain           Available                                                        6m
pv002     2Gi        RWO            Retain           Bound       default/myappdata-myapp-0                            6m
pv003     2Gi        RWO,RWX        Retain           Bound       default/myappdata-myapp-1                            6m
pv004     2Gi        RWO,RWX        Retain           Bound       default/myappdata-myapp-2                            6m
pv005     2Gi        RWO,RWX        Retain           Available                                                        6m

kubectl get pods   #檢視Pod資訊
NAME                     READY     STATUS    RESTARTS   AGE
myapp-0                  1/1       Running   0          2m
myapp-1                  1/1       Running   0          2m
myapp-2                  1/1       Running   0          2m

kubectl delete -f stateful-demo.yaml	

//當刪除的時候是從myapp-2開始進行刪除的,關閉是逆向關閉
kubectl get pods -w

//此時PVC依舊存在的,再重新建立pod時,依舊會重新去繫結原來的pvc
kubectl apply -f stateful-demo.yaml

kubectl get pvc
NAME                STATUS    VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
myappdata-myapp-0   Bound     pv002     2Gi        RWO                           5m
myappdata-myapp-1   Bound     pv003     2Gi        RWO,RWX                       5m
myappdata-myapp-2   Bound     pv004     2Gi        RWO,RWX


//滾動更新
//StatefulSet 控制器將在 StatefulSet 中刪除並重新建立每個 Pod。它將以與 Pod 終止相同的順序進行(從最大的序數到最小的序數),每次更新一個 Pod。在更新其前身之前,它將等待正在更新的 Pod 狀態變成正在執行並就緒。如下操作的滾動更新是按照2-0的順序更新。
vim stateful-demo.yaml  		#修改image版本為v2
.....
image: ikubernetes/myapp:v2
....

kubectl apply -f stateful-demo.yaml

kubectl get pods -w   #檢視滾動更新的過程
NAME      READY   STATUS        RESTARTS   AGE
myapp-0   1/1     Running       0          29s
myapp-1   1/1     Running       0          27s
myapp-2   0/1     Terminating   0          26s
myapp-2   0/1     Terminating   0          30s
myapp-2   0/1     Terminating   0          30s
myapp-2   0/1     Pending       0          0s
myapp-2   0/1     Pending       0          0s
myapp-2   0/1     ContainerCreating   0          0s
myapp-2   1/1     Running             0          31s
myapp-1   1/1     Terminating         0          62s
myapp-1   0/1     Terminating         0          63s
myapp-1   0/1     Terminating         0          66s
myapp-1   0/1     Terminating         0          67s
myapp-1   0/1     Pending             0          0s
myapp-1   0/1     Pending             0          0s
myapp-1   0/1     ContainerCreating   0          0s
myapp-1   1/1     Running             0          30s
myapp-0   1/1     Terminating         0          99s
myapp-0   0/1     Terminating         0          100s
myapp-0   0/1     Terminating         0          101s
myapp-0   0/1     Terminating         0          101s
myapp-0   0/1     Pending             0          0s
myapp-0   0/1     Pending             0          0s
myapp-0   0/1     ContainerCreating   0          0s
myapp-0   1/1     Running             0          1s


//在建立的每一個Pod中,每一個pod自己的名稱都是可以被解析的
kubectl exec -it myapp-0 /bin/sh
Name:      myapp-0.myapp-svc.default.svc.cluster.local
Address 1: 10.244.2.27 myapp-0.myapp-svc.default.svc.cluster.local
/ # nslookup myapp-1.myapp-svc.default.svc.cluster.local
nslookup: can't resolve '(null)': Name does not resolve

Name:      myapp-1.myapp-svc.default.svc.cluster.local
Address 1: 10.244.1.14 myapp-1.myapp-svc.default.svc.cluster.local
/ # nslookup myapp-2.myapp-svc.default.svc.cluster.local
nslookup: can't resolve '(null)': Name does not resolve

Name:      myapp-2.myapp-svc.default.svc.cluster.local
Address 1: 10.244.2.26 myapp-2.myapp-svc.default.svc.cluster.local

//從上面的解析,我們可以看到在容器當中可以通過對Pod的名稱進行解析到ip。其解析的域名格式如下:
pod_name.service_name.ns_name.svc.cluster.local


//總結
無狀態:
1)deployment 認為所有的pod都是一樣的
2)不用考慮順序的要求
3)不用考慮在哪個node節點上執行
4)可以隨意擴容和縮容 

有狀態
1)例項之間有差別,每個例項都有自己的獨特性,元資料不同,例如etcd,zookeeper
2)例項之間不對等的關係,以及依靠外部儲存的應用。

常規service和無頭服務區別
service:一組Pod訪問策略,提供cluster-IP群集之間通訊,還提供負載均衡和服務發現。
Headless service:無頭服務,不需要cluster-IP,直接繫結具體的Pod的IP


vim pod6.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: dns-test
spec:
  containers:
  - name: busybox
    image: busybox:1.28.4
    args:
    - /bin/sh
    - -c
    - sleep 36000
  restartPolicy: Never


vim sts.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1beta1  
kind: StatefulSet  
metadata:
  name: nginx-statefulset  
  namespace: default
spec:
  serviceName: nginx  
  replicas: 3  
  selector:
    matchLabels:  
       app: nginx
  template:  
    metadata:
      labels:
        app: nginx  
    spec:
      containers:
      - name: nginx
        image: nginx:latest  
        ports:
        - containerPort: 80  


kubectl apply -f sts.yaml

kubectl apply -f pod6.yaml

kubectl get pods,svc

kubectl exec -it dns-test sh
/ # nslookup nginx-statefulset-0.nginx.default.svc.cluster.local
/ # nslookup nginx-statefulset-1.nginx.default.svc.cluster.local
/ # nslookup nginx-statefulset-2.nginx.default.svc.cluster.local

kubectl exec -it nginx-statefulset-0 bash
/# curl nginx-statefulset-0.nginx
/# curl nginx-statefulset-1.nginx
/# curl nginx-statefulset-2.nginx


//擴充套件伸縮
kubectl scale sts myapp --replicas=4  #擴容副本增加到4個

kubectl get pods -w  #動態檢視擴容

kubectl get pv  #檢視pv繫結

kubectl patch sts myapp -p '{"spec":{"replicas":2}}'  #打補丁方式縮容

kubectl get pods -w  #動態檢視縮容

2.3 DaemonSet

DaemonSet 確保全部(或者一些)Node 上執行一個 Pod 的副本。當有 Node 加入叢集時,也會為他們新增一個 Pod 。當有 Node 從叢集移除時,這些 Pod 也會被回收。刪除 DaemonSet 將會刪除它建立的所有 Pod。

使用 DaemonSet 的一些典型用法:
●執行叢集儲存 daemon,例如在每個 Node 上執行 glusterd、ceph。
●在每個 Node 上執行日誌收集 daemon,例如fluentd、logstash。
●在每個 Node 上執行監控 daemon,例如 Prometheus Node Exporter、collectd、Datadog 代理、New Relic 代理,或 Ganglia gmond。
應用場景:Agent
//官方案例(監控)
https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/
示例:
vim ds.yaml 
apiVersion: apps/v1
kind: DaemonSet 
metadata:
  name: nginx-daemonSet
  labels:
    app: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.15.4
        ports:
        - containerPort: 80


kubectl apply -f ds.yaml

//DaemonSet會在每個node節點都建立一個Pod
kubectl get pods
nginx-deployment-4kr6h   1/1     Running     0          35s
nginx-deployment-8jrg5   1/1     Running     0          35s

2.4 Job

Job分為普通任務(Job)和定時任務(CronJob)
常用於執行那些僅需要執行一次的任務
應用場景:資料庫遷移、批處理指令碼、kube-bench掃描、離線資料處理,視訊解碼等業務
https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/	
示例:
vim job.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  template:
    spec:
      containers:
      - name: pi
        image: perl
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never
  backoffLimit: 4

//引數解釋
.spec.template.spec.restartPolicy該屬性擁有三個候選值:OnFailure,Never和Always。預設值為Always。它主要用於描述Pod內容器的重啟策略。在Job中只能將此屬性設定為OnFailure或Never,否則Job將不間斷執行。

.spec.backoffLimit用於設定job失敗後進行重試的次數,預設值為6。預設情況下,除非Pod失敗或容器異常退出,Job將不間斷的重試,此時Job遵循 .spec.backoffLimit上述說明。一旦.spec.backoffLimit達到,作業將被標記為失敗。


//在所有node節點下載perl映象,因為映象比較大,所以建議提前下載好
docker pull perl

kubectl apply -f job.yaml 

kubectl get pods
pi-bqtf7                 0/1     Completed   0          41s

//結果輸出到控制檯
kubectl logs pi-bqtf7
3.14159265......

//清除job資源
kubectl delete -f job.yaml 
==========================================================
//backoffLimit
vim job-limit.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: busybox
spec:
  template:
    spec:
      containers:
        - name: busybox
          image: busybox
          command: ["/bin/sh", "-c", "sleep 10;date;exit 1"]
      restartPolicy: Never
  backoffLimit: 2
  
kubectl apply -f job-limit.yaml

kubectl get job,pods
NAME                COMPLETIONS   DURATION   AGE
job.batch/busybox   0/1           4m34s      4m34s

NAME                READY   STATUS   RESTARTS   AGE
pod/busybox-dhrkt   0/1     Error    0          4m34s
pod/busybox-kcx46   0/1     Error    0          4m
pod/busybox-tlk48   0/1     Error    0          4m21s

kubectl describe job busybox
......
Warning  BackoffLimitExceeded  43s    job-controller  Job has reached the specified backoff limit

2.5 CronJob

週期性任務,像Linux的Crontab一樣。
週期性任務
應用場景:通知,備份
https://kubernetes.io/docs/tasks/job/automated-tasks-with-cron-jobs/
示例:
//每分鐘列印hello
vim cronjob.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            args:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure
		  
//其它可用引數的配置
spec:
  concurrencyPolicy: Allow			#要保留的失敗的完成作業數(預設為1)
  schedule: '*/1 * * * *'			#作業時間表。在此示例中,作業將每分鐘執行一次
  startingDeadlineSeconds: 15		#pod必須在規定時間後的15秒內開始執行,若超過該時間未執行,則任務將不執行,且標記失敗
  successfulJobsHistoryLimit: 3		#要保留的成功完成的作業數(預設為3)
  terminationGracePeriodSeconds: 30	#job存活時間 預設不設定為永久
  jobTemplate:						#作業模板。這類似於工作示例


kubectl create -f cronjob.yaml 

kubectl get cronjob
NAME    SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
hello   */1 * * * *   False     0        <none>          25s

kubectl get pods
NAME                     READY   STATUS      RESTARTS   AGE
hello-1621587180-mffj6   0/1     Completed   0          3m
hello-1621587240-g68w4   0/1     Completed   0          2m
hello-1621587300-vmkqg   0/1     Completed   0          60s

kubectl logs hello-1621587180-mffj6
Fri May 21 09:03:14 UTC 2021
Hello from the Kubernetes cluster
//如果報錯:Error from server (Forbidden): Forbidden (user=system:anonymous, verb=get, resource=nodes, subresource=proxy) ( pods/log hello-1621587780-c7v54)
//解決辦法:繫結一個cluster-admin的許可權
kubectl create clusterrolebinding system:anonymous --clusterrole=cluster-admin --user=system:anonymous