# 發現、初談 StatefulSet

### StatefulSet 特色：

過去談過 Deployment、ReplicaSet 所創建的 Pod 皆屬於 stateless 的情況。\
但如要建立 stateful 特性的服務資源物件，可以透過 StatefulSet 完成建立。\
對於想要實現下列服務目的者，使用 StatefulSet 是最恰當的～

* 穩定的唯一性網路標誌       Stable, unique network identifiers.
* 穩定的持久化儲存服務       Stable, persistent storage.
* 有序性的實現部署和擴充   Ordered, graceful deployment and scaling.
* 有序性的滾動更新               Ordered, automated rolling updates.

以上，除了服務 stateful & stateless 重要差異之外，\
特別凸顯了 Stable 穩定、Ordered 有序的字眼，這就是與 Deployment 之間最大差別。

### StatefulSet 條件限制：

1. K8s 版本必須是 1.9 版本之後
2. 用於 Pod 的儲存必須由 PersistentVolume Provisioner 根据 storage class 進行配置或者管理員事先配置。
3. 刪除或者擴容 StatefulSet 時不會刪除相關的儲存區；這是為了確保資料的安全。
4. StatefulSets 目前需要 Headless Service 來負責 Pod 網路定義。
5. StatefulSets 刪除時，並不保證 pod 完美的終止服務。
6. StatefulSets 中實現 pod 的有序性和正常終止，可以在刪除之前將 StatefulSet 縮小到 0。

### 展示 StatefulSet 配置

配置中分三項說明：

1. Headless Service：名稱 nginx，用於控制網路
2. StatefulSet：名稱 web，有指定三個副本 replicas
3. volumeClaimTemplates：透過 PersistentVolumes provisioned 提供穩定的儲存服務

```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:
  selector:
    matchLabels:
      app: nginx # has to match .spec.template.metadata.labels
  serviceName: "nginx"
  replicas: 3 # by default is 1
  template:
    metadata:
      labels:
        app: nginx # has to match .spec.selector.matchLabels
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: k8s.gcr.io/nginx-slim:0.8
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "my-storage-class"
      resources:
        requests:
          storage: 1Gi
```

#### 注意 Pod Selector：

* 在 StatefulSet yaml 定義中，必須有 .spec.template.metadata.labels；
* 在 K8s 1.8 版本之前，Pod Selector 是可以被省略的；
* 在 K8s 1.9 版本之後，如沒有設定正確的 Pod Selector 是會造成建立 StatefulSet 失敗。

{% hint style="info" %}
參考書籍\文章出處：\
Kubernetes 建置與執行 書中 P.180\~181 內容。\
<https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/>\
<https://jimmysong.io/kubernetes-handbook/concepts/statefulset.html>\
<https://feisky.gitbooks.io/kubernetes/concepts/statefulset.html>
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://fufu.gitbook.io/kk8s/statefulset-1.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
