Kubernetes:控制器

Kubernetes控制器

Deployment -- 兩層控制器

通過(guò)ReplicaSet個(gè)數(shù)描述應(yīng)用版本(滾動(dòng)升級(jí)),再通過(guò)ReplicaSet屬性控制Pod數(shù)量(水平擴(kuò)展)

image
  1. Deployment 的控制器,實(shí)際上控制的是 ReplicaSet 的數(shù)目,以及每個(gè) ReplicaSet 的屬性。
  2. 一個(gè)應(yīng)用的版本,對(duì)應(yīng)的是一個(gè) ReplicaSet。這個(gè)版本應(yīng)用的 Pod 數(shù)量,則由 ReplicaSet 通過(guò)它自己的控制器(ReplicaSet Controller)來(lái)保證。
  3. 通過(guò)這樣的多個(gè) ReplicaSet 對(duì)象,Kubernetes 項(xiàng)目就實(shí)現(xiàn)了對(duì)多個(gè)“應(yīng)用版本”的描述。

有狀態(tài)應(yīng)用編排 -- Stateful

  1. 拓?fù)錉顟B(tài):應(yīng)用多實(shí)例有多種關(guān)系。主從、主備順序等。
  2. 存儲(chǔ)狀態(tài):應(yīng)用多實(shí)例分別綁定不同存儲(chǔ)數(shù)據(jù)。比如容器當(dāng)前讀取到的數(shù)據(jù)和半小時(shí)后讀取的數(shù)據(jù)是同一份數(shù)據(jù)。
  3. Stateful的實(shí)現(xiàn)方式就是記錄下這些狀態(tài),然后當(dāng)Pod被重建時(shí),恢復(fù)這些狀態(tài)。

Stateful 如何實(shí)現(xiàn)拓?fù)錉顟B(tài)?

外界如何訪問(wèn)Pod -- Service

Service就是外界連接Pod的網(wǎng)絡(luò)機(jī)制。比如一個(gè)Deployment控制了多個(gè)Pod,這是定義一個(gè)Service就能訪問(wèn)到這三個(gè)Pod。

那Service又是如何怎么被訪問(wèn)的呢

  1. 通過(guò)虛擬IP(virtual IP),當(dāng)訪問(wèn)一個(gè)預(yù)先定義好的VIP時(shí),K8s就會(huì)把這次的訪問(wèn)請(qǐng)求路由到Service上。
  2. 通過(guò)Service DNS,比如:test-service.test-namespace.svc.cluster.test。在DNS解析時(shí)有兩種處理方式
    1. 一種是通過(guò)test-service.test-namespace.svc.cluster.test解析到VIP從而找到Pod
    2. 另一種是訪問(wèn)時(shí),解析出來(lái)的就是直接暴露出來(lái)的Pod IP而不是VIP, 這種解析方式叫做Headless Service。(Headless Service的定義其實(shí)就是將cluster IP字段置為None,從而讓這個(gè)Service沒有一個(gè)VIP 作為頭信息,從而暴露出Pod IP)

Stateful如何保持Pod拓?fù)錉顟B(tài)

  1. 當(dāng)定義Stateful時(shí)指定serviceName,比如如下,讓Stateful在控制循環(huán)的時(shí)候使用test-sf來(lái)保證Pod的可解析身份
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: test-sf
spec:
  serviceName: "test"
  replicas: 2
  selector:
    matchLabels:
      app: test-pod
  template:
    metadata:
      labels:
        app: test-pod
    spec:
      containers:
      - name: test-pod
        image: xxx
        ports:
        - containerPort: 80
          name: testPod
  1. 當(dāng)啟動(dòng)test這個(gè)svc和stateful后,Stateful就會(huì)創(chuàng)建兩個(gè)testPod,并為它們命名為 testPod-0 與 testPod-1 。然后Stateful就會(huì)把兩個(gè)Pod及其名稱存儲(chǔ)下來(lái),以后不管是testPod-0或1被刪除了,只要在Stateful生命周期內(nèi),這些順序關(guān)系就不會(huì)失效。

Stateful 如何實(shí)現(xiàn)存儲(chǔ)狀態(tài)?

Persistent Volume Claim
  1. 定義一個(gè) PVC,聲明想要的 Volume 的屬性:在這個(gè) PVC 對(duì)象里,不需要任何關(guān)于 Volume 細(xì)節(jié)的字段,只有描述性的屬性和定義。比如,storage: 1Gi,表示我想要的 Volume 大小至少是 1 GiB;accessModes: ReadWriteOnce,表示這個(gè) Volume 的掛載方式是可讀寫,并且只能被掛載在一個(gè)節(jié)點(diǎn)上而非被多個(gè)節(jié)點(diǎn)共享
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: pv-claim-test
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  1. 在應(yīng)用的 Pod 中,聲明使用這個(gè) PVC,只要我們創(chuàng)建這個(gè) PVC 對(duì)象,Kubernetes 就會(huì)自動(dòng)為它綁定一個(gè)符合條件的 Volume 即 pv
apiVersion: v1
kind: Pod
metadata:
  name: pv-pod
spec:
  containers:
    - name: pv-container
      image: nginx
      ports:
        - containerPort: 80
          name: "http-server"
      volumeMounts:
        - mountPath: "/usr/share/nginx/html"
          name: pv-storage
  volumes:
    - name: pv-storage
      persistentVolumeClaim:
        claimName: pv-claim-test
  1. Kubernetes 中 PVC 和 PV 的設(shè)計(jì),實(shí)際上類似于接口實(shí)現(xiàn)。開發(fā)者只要知道并會(huì)使用接口,即:PVC;而運(yùn)維人員則負(fù)責(zé)給接口綁定具體的實(shí)現(xiàn),即:PV。這種解耦,就避免了因?yàn)橄蜷_發(fā)者暴露過(guò)多的存儲(chǔ)系統(tǒng)細(xì)節(jié)而帶來(lái)的隱患。此外,這種職責(zé)的分離,往往也意味著出現(xiàn)事故時(shí)可以更容易定位問(wèn)題和明確責(zé)任

StatefulSet存儲(chǔ)狀態(tài)

  1. 回到StatefulSet對(duì)存儲(chǔ)狀態(tài)管理上來(lái)
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: test-sf
spec:
  serviceName: "test"
  replicas: 2
  selector:
    matchLabels:
      app: test-pod
  template:
    metadata:
      labels:
        app: test-pod
    spec:
      containers:
      - name: test-pod
        image: xxx
        ports:
        - containerPort: 80
          name: xxx
        volumeMounts:
        - name: testVM
          mountPath: /usr/share/xxx
  volumeClaimTemplates:
  - metadata:
      name: testVM
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi
  1. 這個(gè) StatefulSet 額外添加了一個(gè) volumeClaimTemplates 字段。它跟 Deployment 里 Pod 模板(PodTemplate)的作用類似 => 凡是被這個(gè) StatefulSet 管理的 Pod,都會(huì)聲明一個(gè)對(duì)應(yīng)的 PVC;而這個(gè) PVC 的定義,就來(lái)自于 volumeClaimTemplates 這個(gè)模板字段。更重要的是,這個(gè) PVC 的名字,會(huì)被分配一個(gè)與這個(gè) Pod 完全一致的編號(hào)。這個(gè)自動(dòng)創(chuàng)建的 PVC,與 PV 綁定成功后,就會(huì)進(jìn)入 Bound 狀態(tài),這就意味著這個(gè) Pod 可以掛載并使用這個(gè) PV 了。
  2. 通過(guò)kubectl get pvc -l app=nginx,可以看到,這些 PVC,都以<PVC 名字 >-<StatefulSet 名字 >-< 編號(hào) >的方式命名,并且處于 Bound 狀態(tài)。
  3. 這個(gè) StatefulSet 創(chuàng)建出來(lái)的所有 Pod,都會(huì)聲明使用編號(hào)的 PVC。比如,在名叫 test-pod-0 的 Pod 的 volumes 字段,它會(huì)聲明使用名叫 testVM 的 PVC,從而掛載到這個(gè) PVC 所綁定的 PV。

守護(hù)進(jìn)程 -- DaemonSet

  1. 舉個(gè)例子: 我們很多組件,比如網(wǎng)絡(luò)插件、存儲(chǔ)插件、監(jiān)控和日志組件都需要agent來(lái)幫助處理容器的網(wǎng)絡(luò),存儲(chǔ)目錄掛載、收集節(jié)點(diǎn)監(jiān)控?cái)?shù)據(jù)。而這個(gè)agent就是我們節(jié)點(diǎn)的守護(hù)進(jìn)程。
  2. 在K8s中,它也是一種編排對(duì)象 -- DaemonSet,它比其他所有對(duì)象的啟動(dòng)時(shí)機(jī)都要早。
  3. DaemonSetController通過(guò)給node打污點(diǎn)的方式來(lái)保證 同樣能容忍這個(gè)污點(diǎn)的Pod 也就是 DaemonSet 的Pod 是第一個(gè)關(guān)聯(lián)到node上的。
參考:

《深入剖析Kubernetes》 - 張磊

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容