Controller與Service系列(一) Controller基本概念


一、簡介

  控制器(Controller)是集群上管理和運行容器的對象。Pod就是通過Controller實現應用的運維,如伸縮、滾動升級等,其中Pod與Controller之間通過標簽(Label)以及標簽選擇器(Selector)建立關聯。

控制器(Controller)對象有不同的類型,比較常用的有:

  • Deployment   使用它可以進行應用的部署、應用的升級回滾、彈性伸縮等。
  • StatefulSet  管理有狀態應用,用來管理某 Pod集合的部署和擴縮, 並為這些 Pod 提供持久存儲和持久標識符。
  • DaemonSet  確保全部(或者某些)節點上運行一個 Pod 的副本。
  • Job  一次性任務
  • CronJob 創建基於時隔重復調度的 Jobs

二、Deployment   

(一)應用部署

Deployment常用的場景就是應用的部署、升級、回滾、伸縮等。

1、部署准備

 在之前的操作中直接通過命令行的方式進行應用的部署:

[root@k8smaster ~]# kubectl create development web --image=nginx

但是這樣不利於重用,所以可以采用yaml文件的方式:

# 導出yaml文件
[root@k8smaster ~]# kubectl create deployment web --image=nginx --dry-run -o yaml > web.yam

可以看到yaml文件中的內容:

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: web
  name: web
spec:
  replicas: 1 selector:
 matchLabels: app: web
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
 labels: app: web
    spec:
      containers:
      - image: nginx
        name: nginx
        resources: {}
status: {}

可以看到Deployment控制器中的selector中與Pod中的labels進行匹配,它們之間就是基於此進行關聯。

2、yaml部署

[root@k8smaster ~]# kubectl apply -f web.yaml 
deployment.apps/web created

目前該應用只能集群內部訪問,需要暴露端口到外部,這樣外部才能訪問。

3、應用發布(對外暴露端口)

# 導出yaml文件
[root@k8smaster ~]# kubectl expose deployment web --port=80 --type=NodePort --target-port=80 --name=webOut -o yaml > webOut.yaml
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: "2021-06-18T18:11:36Z"
  labels:
    app: web
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:labels:
          .: {}
          f:app: {}
      f:spec:
        f:externalTrafficPolicy: {}
        f:ports:
          .: {}
          k:{"port":80,"protocol":"TCP"}:
            .: {}
            f:port: {}
            f:protocol: {}
            f:targetPort: {}
        f:selector:
          .: {}
          f:app: {}
        f:sessionAffinity: {}
        f:type: {}
    manager: kubectl
    operation: Update
    time: "2021-06-18T18:11:36Z"
  name: web1
  namespace: default
  resourceVersion: "393318"
  selfLink: /api/v1/namespaces/default/services/web1
  uid: 9cbe6be0-d147-43a4-812f-32ae6722fdf3
spec:
  clusterIP: 10.97.65.66
  externalTrafficPolicy: Cluster
  ports:
  - nodePort: 31681
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: web
  sessionAffinity: None
  type: NodePort
status:
  loadBalancer: {}
web1.yaml

進行部署:

[root@k8smaster ~]# kubectl apply -f web1.yaml 

# 查看
[root@k8smaster ~]# kubectl get pods,svc
NAME                       READY   STATUS    RESTARTS   AGE
pod/web-5dcb957ccc-j2pg4   1/1     Running   0          15m

NAME                 TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
service/kubernetes   ClusterIP   10.96.0.1     <none>        443/TCP        61d
service/web1         NodePort    10.97.65.66   <none>        80:31681/TCP   3m51s

(二)應用升級、回滾

1、應用升級

# 升級
[root@k8smaster ~]# kubectl set image deployment web nginx=nginx:1.15
deployment.apps/web image updated

# 查看升級狀態
[root@k8smaster ~]# kubectl rollout status deployment web
deployment "web" successfully rolled out

2、應用回滾

# 查看回滾版本
[root@k8smaster ~]# kubectl rollout history deployment web
deployment.apps/web 
REVISION  CHANGE-CAUSE
1         <none>
2         <none>

# 回滾到上一個版本
[root@k8smaster ~]# kubectl rollout undo deployment web
deployment.apps/web rolled back

# 回滾到指定版本
[root@k8smaster ~]# kubectl rollout undo deployment web --to-revision=2

(三)彈性伸縮

# 伸縮前查看
[root@k8smaster ~]# kubectl get pods,svc
NAME                       READY   STATUS    RESTARTS   AGE
pod/web-5dcb957ccc-66txn   1/1     Running   0          3m5s

NAME                 TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
service/kubernetes   ClusterIP   10.96.0.1     <none>        443/TCP        61d
service/web1         NodePort    10.97.65.66   <none>        80:31681/TCP   40m

# 進行伸縮
[root@k8smaster ~]# kubectl scale deployment web --replicas=3
deployment.apps/web scaled

# 伸縮后查看
[root@k8smaster ~]# kubectl get pods,svc
NAME                       READY   STATUS              RESTARTS   AGE
pod/web-5dcb957ccc-66txn   1/1     Running             0          3m41s
pod/web-5dcb957ccc-jx4kl   0/1     ContainerCreating   0          2s
pod/web-5dcb957ccc-zvmcm   0/1     ContainerCreating   0          2s

NAME                 TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
service/kubernetes   ClusterIP   10.96.0.1     <none>        443/TCP        61d
service/web1         NodePort    10.97.65.66   <none>        80:31681/TCP   41m

三、StatefulSet  

  StatefulSet 用來管理某 Pod 集合的部署和擴縮, 並為這些 Pod 提供持久存儲和持久標識符。所以相對於Deployment而言它是有狀態的,需要考慮下面的情況:

  • 保持每個Pod獨立、啟動順序、唯一性
  • 唯一的網絡標識、持久存儲

創建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: nginx-statefulset
  namespace: default
spec:
  serviceName: nginx
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80

  它創建了一個 Headless Service nginx用來發布 StatefulSet web中的 Pod 的 IP 地址,表現形式就是clusterIP為None。執行上面的yaml文件:

[root@k8smaster ~]# kubectl apply -f statefulset.yaml 
service/nginx created

上面創建兩個Pod的副本,但是它是按照{0,N-1}的順序來創建Pod的,也就是Pod是有順序的。

其次查看創建的兩個Pod:

[root@k8smaster ~]# kubectl get pods
NAME                  READY   STATUS    RESTARTS   AGE
nginx-statefulset-0   1/1     Running   0          15m
nginx-statefulset-1   1/1     Running   0          14m

每個都是有唯一的名稱,最后看一下網絡標識,每個 Pod 都擁有一個基於其順序索引的穩定的主機名。使用kubectl exec在每個 Pod 中執行hostname。

[root@k8smaster ~]# for i in 0 1; do kubectl exec "nginx-statefulset-$i" -- sh -c 'hostname'; done
nginx-statefulset-0
nginx-statefulset-1

四、DaemonSet  

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

DaemonSet 的一些應用場景:

  • 在每個節點上運行集群守護進程
  • 在每個節點上運行日志收集守護進程
  • 在每個節點上運行監控守護進程

創建 一個日志收集工具的DaemonSet:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: ds-test 
  labels:
    app: filebeat
spec:
  selector:
    matchLabels:
      app: filebeat
  template:
    metadata:
      labels:
        app: filebeat
    spec:
      containers:
      - name: logs
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - name: varlog
          mountPath: /tmp/log
      volumes:
      - name: varlog
        hostPath:
          path: /var/log

執行該yaml文件:

[root@k8smaster ~]# kubectl apply -f ds.yaml 
daemonset.apps/ds-test created

可以看到在各個node節點上已經部署了Pod:

[root@k8smaster ~]# kubectl get pods -o wide
NAME            READY   STATUS    RESTARTS   AGE   IP            NODE       NOMINATED NODE   READINESS GATES
ds-test-6qdwg   1/1     Running   0          84s   10.244.1.23   k8snode1   <none>           <none>
ds-test-m79px   1/1     Running   0          84s   10.244.2.20   k8snode2   <none>           <none>

進入到某個Pod中進行查看:

[root@k8smaster ~]# kubectl exec -it ds-test-6qdwg bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead.
root@ds-test-6qdwg:/# ls /tmp/log/
anaconda  btmp-20210617  dmesg        maillog           pods    secure-20210617     tuned
audit      containers     dmesg.old  maillog-20210617   ppp     spooler         vmware-vmsvc.log
boot.log  cron         firewalld  messages           rhsm    spooler-20210617  wtmp
btmp      cron-20210617  lastlog    messages-20210617  secure  tallylog         yum.log

五、Job  

  Job 會創建一個或者多個 Pods,並將繼續重試 Pods 的執行,直到指定數量的 Pods 成功終止。 隨着 Pods 成功結束,Job 跟蹤記錄成功完成的 Pods 個數。 當數量達到指定的成功個數閾值時,任務(即 Job)結束。 刪除 Job 的操作會清除所創建的全部 Pods。 掛起 Job 的操作會刪除 Job 的所有活躍 Pod,直到 Job 被再次恢復執行。

下面是一個 Job 配置示例。它負責計算 π 到小數點后 2000 位,並將結果打印出來。

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

執行:

[root@k8smaster ~]# kubectl apply -f job.yaml 
job.batch/pi created

查看Pod狀態:

# 因為是一次性任務,所以執行后即結束
[root@k8smaster ~]# kubectl get pods
NAME            READY   STATUS      RESTARTS   AGE
pi-vbmwk        0/1     Completed   0          4m26s

查看結果:

[root@k8smaster ~]# kubectl logs pi-vbmwk 
3.14159265358979323846264338327950...

六、CronJob 

CronJobs 對於創建周期性的、反復重復的任務很有用,例如執行數據備份或者發送郵件。 CronJobs 也可以用來計划在指定時間來執行的獨立任務,例如計划當集群看起來很空閑時 執行某個 Job。如下實例:

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

執行:

[root@k8smaster ~]# kubectl apply -f cronjob.yaml 
cronjob.batch/hello created

可以看到周期性的調用:

[root@k8smaster ~]# kubectl get pods
NAME                     READY   STATUS              RESTARTS   AGE
hello-1624090140-w8xcn   0/1     Completed           0          2m57s
hello-1624090200-m2lng   0/1     ContainerCreating   0          2m21s
hello-1624090260-bwhjj   0/1     ContainerCreating   0          80s
hello-1624090320-bcd7b   0/1     ContainerCreating   0          20s

查看某個Pod里面的內容:

[root@k8smaster ~]# kubectl logs hello-1624090140-w8xcn
Sat Jun 19 08:11:44 UTC 2021
Hello from the Kubernetes cluster

 


免責聲明!

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



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