k8s實踐(四):Controller

echa攻城獅 發佈 2020-03-01T17:27:17+00:00

cloud-controller-manager 在 Kubernetes 啟用 Cloud Provider 的時候才需要,用來配合雲服務提供商的控制,如:Node Controller、Route Controller、Service Controller。

一、Kubernetes核心組件

1. 核心組件概述

Kubernetes主要由以下幾個核心組件組成:

  • etcd 保存了整個集群的狀態;
  • apiserver 提供了資源操作的唯一入口,並提供認證、授權、訪問控制、API 註冊和發現等機制;
  • controller manager 負責維護集群的狀態,比如故障檢測、自動擴展、滾動更新等;
  • scheduler 負責資源的調度,按照預定的調度策略將 Pod 調度到相應的機器上;
  • kubelet 負責維護容器的生命周期,同時也負責 Volume(CVI)和網絡(CNI)的管理;
  • Container runtime 負責鏡像管理以及 Pod 和容器的真正運行(CRI);
  • kube-proxy 負責為 Service 提供 cluster 內部的服務發現和負載均衡

部署流程

2. 查看核心組件

Kubelet是唯一一直作為常規系統組件來運行的組件,它把其他組件作為pod來運行。

2.1 查看Kubelet

master和node節點都可查看

[root@master ~]# systemctl status kubelet

2.2 查看其他組件

[root@master ~]# kubectl get po -o custom-columns=POD:metadata.name,NODE:spec.nodeName --sort-by spec.nodeName -n kube-system

!

本文重點介紹核心組件controller manager

各資源簡寫查看:

[root@master ~]# kubectl api-resources 

二、Controller Manager

1. 簡介

    Controller Manager由kube-controller-manager和cloud-controller-manager組成,是Kubernetes的大腦,它通過apiserver監控維護整個集群的狀態,比如故障檢測、自動擴展、滾動更新等並確保集群處於預期的工作狀態。

    cloud-controller-manager 在 Kubernetes 啟用 Cloud Provider 的時候才需要,用來配合雲服務提供商的控制,如:Node Controller、Route Controller、Service Controller。

2. 原理

    Controller Manager是Kubernetes集群內部的管理控制中心, 負責Kubernetes集群內的Node、 Pod、服務端點、 服務、 資源配額、 命名空間 、服務帳號等資源的管理 、 自動化部署、健康監測, 並對異常資源執行自動化修復, 確保集群各資源始終處於預期的工作狀態 。 比如, 當某個Node意外若機時,Controller Manager會根據資源調度策略選擇集群內其他節點自動部署原右機節點上的Pod副本 。

    Controller Manager是 一 個控制器集合, 包含Replication Controller、Deployment Controller、RelicaSet、StatefulSet Controller、Daemon Controller、CronJob Controller、Node Controller、Resourcequota Controller 、Namespace Controller 、ServiceAccount Controller 、Token Controller、Service Controller及Endpoint Controller等多個控制器,Controller Manager是這些控制器的核心管理者。 一般來說, 智能系統和自動系統通常會通過一個操縱系統來不斷修正系統的狀態。 在Kubernetes集群中, 每個控制器的核心工作原理就是:每個控制器通過API伺服器來查看系統的運行狀態, 並嘗試著將系統狀態從「 現有狀態 」修正到「期望狀態」。

三、ReplicationController

1. 簡介

ReplicationController會持續監控正在運行的pod列表,確保pod的數量始終與其標籤選擇器匹配,ReplicationController由三部分組成:

  • label selector(標籤選擇器),用於確定ReplicationController作用域中有哪些pod
  • replica count(副本個數),指定應運行的pod 數量
  • pod template(pod模板),用於創建新的pod 副本

2. 創建ReplicationController

[root@master ~]# more nginx-rc.yaml 
apiVersion: v1
kind: ReplicationController    #類型為ReplicationController
metadata:
  name: nginx        #ReplicationController名字
spec:
  replicas: 3        #pod實例數目
  selector:          #pod選擇器
    app: nginx
  template:          #pod模板
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx

3. 查看ReplicationController

[root@master ~]# kubectl get rc
[root@master ~]# kubectl describe rc nginx 

4. 擴縮容

擴縮容可以採用修改pod模板和直接命令方式

擴容

[root@master ~]# kubectl edit rc nginx 

縮容

[root@master ~]# kubectl scale rc nginx --replicas=4

5. 刪除pod

[root@master ~]# kubectl delete po nginx-2twcf

刪除pod nginx-2twcf,發現該pod被刪除的同時k8s自動新增一個pod nginx-vtmt4,這也印證了之前簡介中講的"ReplicationController會持續監控正在運行的pod列表,確保pod的數量始終與其標籤選擇器匹配"

6. 刪除ReplicationController

[root@master ~]# kubectl delete rc nginx 

刪除ReplicationController會將其管理的pod一併刪除,如果想保留pod,可以添加參數"--cascade = false"

7. 標籤

7.1 新增標籤

[root@master ~]# kubectl label po nginx-28d4k env=prod

7.2 查看標籤

[root@master ~]# kubectl get po --show-labels 

7.3 更改標籤

[root@master ~]# kubectl label po nginx-28d4k app=test --overwrite

更改app=nginx的標籤,這將使該pod不再與ReplicationController的標籤選擇器匹配,只剩兩個匹配的pod,ReplicationController會啟動一個新的pod nginx-64w44將總數量恢復為3個。

四、ReplicaSet

1. 簡介

ReplicaSet的行為與ReplicationController完全相同,但pod選擇器的表達能力更強,是新一代的ReplicationController,並且將其完全替換掉(ReplicationController最終將被棄用).

2. 創建ReplicaSet

[root@master ~]# more httpd-rs.yaml 
apiVersion: apps/v1    #api版本
kind: ReplicaSet
metadata:
  name: httpd 
spec:
  replicas: 3
  selector:
    matchExpressions:
      - key: app        #標籤名為app
        operator: In    #In : Label的值必須與其中一個指定的values匹配
        values:
         - httpd        #標籤值為httpd
  template:             #replicaset模板
    metadata:
      labels:
        app: httpd 
    spec:
      containers:
      - name: httpd 
        image: httpd 

ReplicaSet相對於ReplicationController的主要改進是它更具表達力的標籤選擇器,ReplicaSet的pod選擇器的表達能力更強。

3. 查看ReplicaSet

[root@master ~]# kubectl get rs
[root@master ~]# kubectl describe rs httpd 

4. 刪除ReplicaSet

[root@master ~]# kubectl delete rs httpd

同理,如需保留pod可以添加參數--cascade=false

五、Deployment

1. 簡介

Deployment為Pod和Replica Set(下一代 Replication Controller)提供聲明式更新。你只需要在Deployment中描述你想要的目標狀態是什麼,Deployment controller就會幫你將Pod和Replica Set的實際狀態改變到你的目標狀態。你可以定義一個全新的Deployment,也可以創建一個新的替換舊的Deployment。

Deployment的典型應用場景 包括:

  • 定義Deployment來創建Pod和ReplicaSet
  • 滾動升級和回滾應用
  • 擴容和縮容
  • 暫停和繼續Deployment

2. Deployment實踐

Deployment相關操作詳見:k8s實踐(三):pod常用操作

六、DaemonSet

1. 簡介

與Replicationcontroller和ReplicaSet在Kubemetes集群上運行部署特定數量的pod不同,DaemonSet每個Node上最多只能運行一個副本,如果節點下線,DaemonSet不會在其他地方重新創建pod,當將一個新節點添加到集群中時,DaemonSet會立刻部署一個新的pod實例。如果有人無意刪除了一個pod,它也會從配置的pod模板中創建新的pod。

DaemonSet保證在每個Node上都運行一個容器副本,常用來部署一些集群的日誌、監控或者其他系統管理應用。典型的應用包括:

  • 日誌收集,比如fluentd,logstash等
  • 系統監控,比如Prometheus Node Exporter,collectd,New Relic agent,Gangliagmond等
  • 系統程序,比如kube-proxy, kube-dns, glusterd, ceph等

本文以日誌搜集工具filebeat為例實踐

2. 創建DaemonSet

[root@master ~]# more filebeat-ds.yaml 
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: filebeat-ds
  labels:
    app: filebeat
spec:
  selector:
    matchLabels:
      app: filebeat
  template:
    metadata:
      labels:
        app: filebeat
      name: filebeat
    spec:
      containers:
      - name: filebeat
        image: ikubernetes/filebeat:5.6.5-alpine
        env:
        - name: REDIS_HOST
          value: db.ilinux.io:6379
        - name: LOG_LEVEL
          value: info
[root@master ~]# kubectl apply -f filebeat-ds.yaml 
daemonset.apps/filebeat-ds created

3. 查看DaemonSet

[root@master ~]# kubectl get ds
[root@master ~]# kubectl describe ds filebeat-ds 
[root@master ~]# kubectl get po -o wide 

查看日誌

4. 更新DaemonSet

[root@master ~]# kubectl set image daemonsets filebeat-ds filebeat=ikubernetes/filebeat:5.6.6-alpine

DaemonSet通過刪除和新建方式更新image

5. 回滾DaemonSet

5.1 查詢歷史版本

[root@master ~]# kubectl rollout history ds filebeat-ds 

5.2 查詢某個歷史版本詳細信息

[root@master ~]# kubectl rollout history ds filebeat-ds --revision=1
[root@master ~]# kubectl rollout history ds filebeat-ds --revision=2

5.3 回滾

[root@master ~]# kubectl rollout undo ds filebeat-ds --to-revision=1

5.4 查看DaemonSet狀態

[root@master ~]# kubectl rollout status ds/filebeat-ds
daemon set "filebeat-ds" successfully rolled out
[root@master ~]# kubectl describe ds filebeat-ds |grep Image
    Image:      ikubernetes/filebeat:5.6.5-alpine

6. 刪除DaemonSet

[root@master ~]# kubectl delete ds filebeat-ds 
daemonset.extensions "filebeat-ds" deleted

七、 Job

1. 簡介

從程序的運行形態上來區分,我們可以將Pod分為兩類:長時運行服務(http server、daemon、mysql)和一次性任務(如並行數據計算、測試、批處理程序等)。ReplicationController、 ReplicaSet和DaemonSet創建的Pod都是長時運行服務,而Job創建的Pod都是一次性的服務。

2. 創建job

[root@master ~]# more job.yaml 
apiVersion: batch/v1    #api版本為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    #設置容器失敗後不重啟,即直接新建pod
  backoffLimit: 4    #限制新建pod數目,默認為6
[root@master ~]# kubectl apply -f job.yaml 
job.batch/pi created

3. 查看job

[root@master ~]# kubectl get job
[root@master ~]# kubectl get po -o wide 

查看job運行結果

[root@master ~]# kubectl logs pi-g2499 

該job為求圓周率精確至2000位

4. 並行job

[root@master ~]# more multi-job.yaml 
apiVersion: batch/v1
kind: Job
metadata:
  name: multi-job
spec:
  completions: 10    #設置Job成功完成Pod的總數
  parallelism: 2    #pod並行執行數
  template:
    metadata:
      labels:
        app: multi-job
    spec:
      restartPolicy: OnFailure    #設置容器失敗後重啟
      containers:
      - name: busybox
        image: busybox
[root@master ~]# kubectl apply -f multi-job.yaml 
job.batch/multi-job created

每次同時運行兩個job,最終運行的pod數為10

5. Cronjob

新建cronjob

[root@master ~]# more 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
[root@master ~]# kubectl apply -f cronjob.yaml 
cronjob.batch/hello created

查看cronjob

[root@master ~]# kubectl get cronjobs
[root@master ~]# kubectl get job --watch

每隔一分鐘就會生成一個job

6. 刪除job

[root@master ~]# kubectl delete job pi multi-job
[root@master ~]# kubectl delete cronjobs hello

本文所有腳本和配置文件已上傳github:https://github.com/loong576/k8s-Controller.git

關鍵字: