天天看點

怎麼控制節點啟動_Kubernetes Statefulset控制器

一、場景概述

在應用程式中,我們大體稱為有兩類,一種是有狀态應用,一種是無狀态應用

  • 無狀态應用比如Nginx
  • 有狀态應用比如Redis、MySQL、ETCD、zk等都要存儲資料的我們都稱之為有狀态應用

它們不隻有所謂的節點之分,節點還有每個Pod對應的角色之分,有的是主節點,有的是從節點,然後這些從節點不光有所謂的從之分,還有前後順序之分。

不同的分布式系統,它們的運維邏輯、運維管理和運維操作是不盡相同的,是以沒有辦法;有一種控制器把每一種功能都同步進來,讓我們非常簡單的去操作這些有狀态的應用;即便後面有了Statefulset控制器,我們用Statefulset去實作真正的功能控制時,也是極其麻煩的;

;   Statefulset控制器即便在一定程度上能實作有狀态應用的管理技巧,但是需要我們自行把我們對于某個應用的運維管理過程寫成腳本注入到Statefulset應用檔案中才能使用;

在K8S中支援CRD(第三方資源或自定義資源)這種機制,甚至還支援更為複雜的機制,比如:Api聚合(需修改K8S源代碼,增強我們需要的功能),是以使用Statefulset去封裝所有的有狀态應用還是一個難題;後來CoreOS在此基礎之上提供了Operator元件,我們可以把運維操作封裝在此元件當中就可以實作很複雜的運維邏輯了。

二、Statefulset控制器

Statefulset叫做有狀态應用副本集;在無狀态中我們更關注的是群體,任何一個都可以輕易被其他的所取代,換一個或新增一個,我們不需要關注跟原來是否一模一樣,我們隻需要保證應用程式一樣即可,因為它沒有任何資料和自己本地的狀态;但是對于有狀态應用來說,這些我們就需要保證跟原來的一模一樣,有狀态應用更關注的是個體。

Statefulset主要管理以下有特性的服務:

(1)穩定且需要唯一的網絡辨別符

(2)穩定且持久的儲存設備;例如某個節點down了,那麼這個節點重新啟動時,需要保證這個節點存儲的資料還在

(3)要求有序平滑的部署和擴充;例如Redis叢集,我們需要先啟動主節點,然後在啟動從節點,如果從有先後順序,那麼還需要按順序啟動從節點

(4)有序平滑的終止和删除;例如一個一主八從的Redis叢集,那關閉時則需要根據啟動順序關閉從節點,最後關閉主節點

(5)有序的滾動更新;例如Redis叢集,更新時則需要先更新從節點,從節點也是需要逆序的順序進行更新,最後更新主節點

三、Statefulset的元件

1、headless service

無頭服務

例如在使用Deploment控制器去建立Pod時,每一個Pod的名稱是随機字元串,我們無法識别它們的順序,是以它是無序的;但是在Statefulset中必須是有序的,是以每一個節點每一個Pod都不能被随意被取代,此前是什麼狀态重新開機之後還需保證與之前一模一樣;

例如在Redis叢集中,它們有很多的槽位來存儲資料,如果某個節點挂了之後重新開機起來之後的資料沒有順序了,那則出現了嚴重的問題;Pod的IP位址基本上是變化的,是以以Pod節點名稱來識别,進而這個節點名稱不能變,在有狀态集當中每個節點的節點名稱是不能變的,第一次是什麼名稱那麼重建之後的Pod名稱還必須是此前的名稱,因為Pod的名稱是作為識别Pod唯一性的辨別符,這個辨別符必須穩定持久和有效;保證這個Pod辨別符穩定持久有效就需要用到

headless service(無頭服務)

,通過

headless service

來確定我們解析的名稱是直達後端Pod IP位址的,還必須給每個Pod配置一個唯一的Pod名稱。

2、StatefulSet

statefulset控制器

3、volumeClaimTemplate

存儲卷申請模闆

例如建立3節點的Redis叢集中,那麼這3個節點中存儲的資料是不一樣的,是以這3個Pod是不能使用同一個存儲卷的,每個節點必須有自己專用的存儲卷,一定不能共享給其他節點,因為它是放自己的專有資料的;

比如在Deployment的Pod模闆中去定義了存儲卷,那麼建立了5個Pod副本那麼這5個Pod通路是同一個存儲卷,因為是基于Pod模闆建立Pod,這個Pod模闆中定義了存儲卷,那麼基于這個Pod模闆建立的所有Pod都是共享的同一個存儲卷;

但是在Statefulset中,每個Pod的存儲卷都不能共享給其他的Pod,是以我們基于Pod模闆來建立Pod是不适用的,這也就是為啥要給每個Pod定義volumeClaimTemplate的原因,這樣我們每建立一個Pod時,它會自動為每個Pod生成一個專用PVC,進而綁定一個PV,實作每個Pod有自己專用的存儲卷。

四、Statefulset的示例

  • **注意:**每一個Statefulset控制器的服務都有以下三部分組成:

(1)Service:服務,這個Service服務必須為無頭服務

    (2)Statefulset控制器

(3)存儲卷

  • **注意:**需要提前準備PV所綁定的存儲叢集裝置
  • 檢視pv,pvc資源建立情況
怎麼控制節點啟動_Kubernetes Statefulset控制器
  • 檢視sts資源
  • 檢視pod
怎麼控制節點啟動_Kubernetes Statefulset控制器

雲原生之道

可以通過

kubectl get po -w

來動态檢視pod的建立和删除的順序

五、Statefulset擴縮容

1、說明

擴容和縮容,Statefulset控制器服務的擴容縮容都是順序執行的。擴容正序,縮容為逆序

2、擴容

方式1

方式2

3、縮容

方式1

方式2

4、滾動更新

  • Statefulset預設更新政策:RollingUpdate,滾動更新
  • **注意:**sts更新是逆序的

4.1:打更新檔

  • 以下表示為目前的Pod模闆設定

    partition

    ,然後更新時隻有大于該值的Pod才會進行更新,這就實作了金絲雀釋出
怎麼控制節點啟動_Kubernetes Statefulset控制器

雲原生之道

  • **說明:**以上設定2,表示隻有Pod數量大于2的Pod才會進行更新,比如我現在Pods運作了3個,那麼進行更新時,隻會将web-2、web-1中的鏡像進行更新,而web-0則保持原來的;更新是逆序的

4.2:金絲雀釋出

  • 參數說明:
    • sts/web:Statefulset資源下的Pod
    • nginx=nginx:1.16:更新Pod中容器名稱為nginx的容器鏡像版本
怎麼控制節點啟動_Kubernetes Statefulset控制器

雲原生之道

怎麼控制節點啟動_Kubernetes Statefulset控制器

雲原生之道

  • 可以看下

    web-0

    的Pod鏡像版本,是保持原來的版本的
怎麼控制節點啟動_Kubernetes Statefulset控制器

雲原生之道

4.3:滾動更新

  • 滾動更新,則隻需要把

    partition

    值改為0即可,這樣Pod會以逆序的方式先終止Pod然後在進行重建
  • 檢視之前沒有更新版本的web-0的pod的鏡像是不是也已經更新到了1.16版本
怎麼控制節點啟動_Kubernetes Statefulset控制器

雲原生之道