跳轉到

18章節:深入理解 StatefulSet(一):拓樸狀態

前言

在 K8s 的 Deployment 應用中做了一個假設:發佈應用的 pod 每一個是相同的,沒有相依性、順序性,更無所謂要運行在哪個 K8s node 上。依照需求,可以透過 Deployment 任意進行 pod scale-out scale-in。

此可以稱為:無狀態應用(Stateless Application)諸如最廣泛的是 WEB service。

但是有些場景,並不適用於 Deployment 如此方式來部署應用。例如:

* 主從關係
* 需要資料持久化(唯一性)

符合上述兩特性其一者,皆可稱為有狀態應用(Stateful Application),此應用部署於 K8s 中是透過 StatefulSet 方式進行。

StatefulSet 觀念

StatefulSet 觀念中有其二最為重要:

1. 拓樸狀態:這意味著同一個服務不同的 pod 之間,有相依性、順序性。
2. 儲存狀態:這意味著該 pod 目前所存取到的數據資料,過了 n 個時間點,或哪怕 pod 重啟了,仍然存取相同一份資料。

關於 拓樸狀態

關於 1. 拓樸狀態,看下列 Service、StatefulSet yaml 檔案

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:
  serviceName: "nginx"  # << 這是特別之處
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.9.1
        ports:
        - containerPort: 80
          name: web

上述 kind: StatefulSet 與先前介紹 Deployment yaml 檔案之間最主要差異是 serviceName 此定義。

觀察部署

透過上述 kind: StatefulSet yaml 檔案進行部署後,可透過下列觀察發現,web 名稱上有 -0 -1 編號作為 pod name 規則特徵。

重點:web-0 優先完成部署,才依順序進行 web-1

kubectl get pod -w
#NAME      READY   STATUS    RESTARTS   AGE
web-0      0/1     Pending   0           <invalid>
web-0      0/1     Pending   0           <invalid>
web-0      0/1     ContainerCreating   0     <invalid>
web-0      1/1     Running   0           10s
# 上面已經完成 web-0 服務部署,下面才接著進行 web-1 服務部署。
web-1      0/1     Pending   0           <invalid>
web-1      0/1     Pending   0           <invalid>
web-1      0/1     ContainerCreating   0     <invalid>
web-1      1/1     Running   0           12s

觀察服務解析

在上面 yaml 檔案中關於 Kind: Service,特別定義了 clusterIP: None 即代表此服務並不會取得 clusterIP 也無法進行服務名稱解析,而是直接針對 pod_name 完成服務解析。 執行下列 DNS 解析,可以發現 StatefulSet 的服務域名規則是:

<pod_name>.<service_name>.<namespace>.svc.cluster.local

kubectl exec -it busybox -- sh
/ nslookup web-0.nginx

Server:    10.89.0.10
Address 1: 10.89.0.10 kube-dns.kube-system.svc.cluster.local

Name:      web-0.nginx
Address 1: 10.24.1.26 web-0.nginx.default.svc.cluster.local

回顧下 Deployment 的服務域名解析,其服務域名規則是:

<service_name>.<namespace>.svc.cluster.local

上述談到的 nginx service,其實就是應用到 Headless Service

重點回顧

回顧此篇拓樸狀態重點,談到兩個特色:

* pod_name 命名規則有 `-0` `-1` 順序性編號。
* 採用 Headless Service 特色,直接對 pod_name 完成服務解析。

K8s 透過這兩個特色,實現了 StatefulSet(Stateful Service)所強調的「拓樸狀態」。