最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

K8s之StatefulSet控制器使用實例

 更新時間:2026年04月28日 10:07:47   作者:A-劉晨陽  
在Kubernetes實戰(zhàn)中,StatefulSet控制器用于部署和管理有狀態(tài)應(yīng)用,這些應(yīng)用需要穩(wěn)定的持久化存儲、有序的部署和擴展、以及唯一的網(wǎng)絡(luò)標(biāo)識,這篇文章主要介紹了K8s之StatefulSet控制器使用的相關(guān)資料,需要的朋友可以參考下

一、StatefulSet 是什么?

StatefulSet 是 Kubernetes 中專門用于管理有狀態(tài)應(yīng)用(Stateful Applications) 的工作負(fù)載控制器(Controller)。與 Deployment 等無狀態(tài)控制器不同,StatefulSet 為需要穩(wěn)定身份標(biāo)識、持久化存儲和有序生命周期管理的分布式系統(tǒng)提供了原生支持。

1.1 什么是有狀態(tài)應(yīng)用(Stateful)?

定義:應(yīng)用的實例具有獨特的身份和記憶,依賴本地持久化的數(shù)據(jù)或維護的上下文狀態(tài),不同實例處理相同輸入可能產(chǎn)生不同結(jié)果。
簡單理解:就像一個有記憶的人,記得過去發(fā)生的事情,并且這些記憶會影響他未來的行為。

核心特征

  • 身份唯一性:每個實例有固定 ID,集群中角色不同(主/從/分片)
  • 數(shù)據(jù)持久化:本地存儲包含業(yè)務(wù)數(shù)據(jù)、配置狀態(tài)或會話信息
  • 拓?fù)涿舾?/strong>:實例間存在固定的通信關(guān)系(如主從復(fù)制)
  • 生命周期復(fù)雜:擴縮容需考慮數(shù)據(jù)重分布,故障恢復(fù)需保證數(shù)據(jù)一致性

典型例子

  • MySQL/PostgreSQL 數(shù)據(jù)庫(存儲業(yè)務(wù)數(shù)據(jù))
  • Redis/Memcached 緩存(雖然數(shù)據(jù)可重建,但通常視為有狀態(tài))
  • Kafka/RabbitMQ 消息隊列(消息持久化)
  • ZooKeeper/etcd 協(xié)調(diào)服務(wù)(維護集群元數(shù)據(jù))
  • Elasticsearch(索引數(shù)據(jù)分片)

1.2 什么是無狀態(tài)應(yīng)用(Stateless)?

定義:應(yīng)用的每個實例都是完全對等且可互換的,不依賴本地存儲的任何歷史信息或上下文,任何請求都可以由任意實例處理,結(jié)果完全相同。
簡單理解:就像一個"金魚記憶"的人,每3秒都忘記之前發(fā)生的事,每次都是全新的開始。

核心特征

  • 無本地依賴:不保存會話、不緩存用戶數(shù)據(jù)、不記錄處理歷史
  • 即拋即用:實例可以隨時創(chuàng)建或銷毀,用戶無感知
  • 水平擴展簡單:增加實例即可提升性能,無需數(shù)據(jù)同步
  • 故障自愈快:實例故障后立即重建,無需數(shù)據(jù)恢復(fù)

典型例子

  • Nginx/Apache 反向代理(僅轉(zhuǎn)發(fā)請求)
  • REST API 服務(wù)(每次請求攜帶完整認(rèn)證信息)
  • 靜態(tài)資源服務(wù)器
  • 函數(shù)計算(Serverless)

1.3 關(guān)鍵區(qū)別對比

維度無狀態(tài)(Stateless)有狀態(tài)(Stateful)
數(shù)據(jù)存儲不保存數(shù)據(jù),或僅使用臨時緩存(emptyDir必須持久化數(shù)據(jù)到磁盤(數(shù)據(jù)庫、日志、配置)
實例身份無身份,完全對等,隨機命名有唯一固定身份(ID、hostname、角色)
請求處理任意實例可處理任意請求,結(jié)果一致特定請求必須由特定實例處理(如分片查詢)
擴縮容秒級擴縮容,簡單增加/減少副本數(shù)需數(shù)據(jù)遷移、重新分片、集群拓?fù)渥兏?/td>
故障影響實例故障=服務(wù)短暫降級,重建即可實例故障=可能數(shù)據(jù)丟失,需復(fù)雜恢復(fù)流程
網(wǎng)絡(luò)依賴僅需入口負(fù)載均衡需實例間直接通信(如復(fù)制、選舉、心跳)
K8s 控制器Deployment、ReplicaSet、DaemonSetStatefulSet、Operator
存儲需求無需 PVC,或使用共享只讀存儲必須獨立 PVC,ReadWriteOnce 模式

1.4 StatefulSet 的核心特征

  1. 穩(wěn)定的網(wǎng)絡(luò)標(biāo)識:為每個 Pod 分配唯一、有序的序號(如 web-0, web-1),并提供基于 DNS 的服務(wù)發(fā)現(xiàn)
  2. 持久化存儲管理:通過 volumeClaimTemplates 自動為每個 Pod 創(chuàng)建獨立的 PVC,實現(xiàn)存儲與 Pod 生命周期解耦
  3. 有序生命周期管理:嚴(yán)格保證 Pod 的創(chuàng)建、刪除、擴縮容和滾動更新的順序性
  4. 優(yōu)雅狀態(tài)管理:支持優(yōu)雅終止(Graceful Termination)和啟動后鉤子(Post-start),確保狀態(tài)一致性

二、StatefulSet 和 Deployment 的區(qū)別

對比維度Deployment(無狀態(tài)應(yīng)用)StatefulSet(有狀態(tài)應(yīng)用)
Pod 名字隨機生成,如 web-abc123、web-def456
每次重建名字都變
固定序號,如 web-0、web-1、web-2
重建后名字不變
網(wǎng)絡(luò)身份只有 IP 會變,像個"流浪漢"
其他 Pod 很難找到它
固定的網(wǎng)絡(luò)標(biāo)識pod-name.service-name
其他 Pod 總能找到它
數(shù)據(jù)存儲一般不存數(shù)據(jù),或都用共享存儲
Pod 掛了數(shù)據(jù)丟了無所謂
每人一個獨立存儲空間
Pod 掛了數(shù)據(jù)還在,重建后自動掛載
啟動順序大家一起上,誰先啟動都行
像餐廳所有窗口同時開
排隊啟動:0號先上,準(zhǔn)備好后1號再上
像銀行柜臺一個一個開
關(guān)閉順序隨便關(guān),關(guān)哪個都行從后往前關(guān):最后一個先關(guān),依次往前
保證主節(jié)點最后退出
擴縮容想擴就擴,想縮就縮
新 Pod 和老 Pod 沒區(qū)別
按序號擴縮:擴容從下一個序號開始
縮容從最大序號開始刪
更新方式可以一次性全更新
或者滾動更新,順序無所謂
從后往前更新
支持暫停在某個版本(partition)
適用場景Web服務(wù)、API網(wǎng)關(guān)
前端應(yīng)用、計算任務(wù)
數(shù)據(jù)庫(MySQL、Redis)
消息隊列(Kafka、ZooKeeper)

2.1 詳解:Pod 身份與網(wǎng)絡(luò)標(biāo)識

特性DeploymentStatefulSet
Pod 命名規(guī)則隨機哈希后綴
nginx-7564c8f6b4-9xv5r
固定有序序號
web-0, web-1, web-2
Hostname 穩(wěn)定性每次重建都變化永久固定,與序號綁定
DNS 解析通過 Service 解析到隨機 Pod IP支持直接 Pod DNS 解析
<pod-name>.<service-name>.<namespace>.svc.cluster.local
Headless Service可選,通常不需要必須,用于提供穩(wěn)定網(wǎng)絡(luò)標(biāo)識
網(wǎng)絡(luò)身份示例無固定身份mysql-0.mysql.default.svc.cluster.local 始終指向 mysql-0

關(guān)鍵差異說明

  • Deployment:Service 通過 ClusterIP 做負(fù)載均衡,請求隨機分發(fā)到后端 Pod,Pod 重建后 IP 和名稱都變
  • StatefulSet:必須配合 clusterIP: None 的 Headless Service,DNS 直接解析到 Pod IP,且 Pod 重建后 DNS 記錄保持不變

2.2 詳解:存儲與數(shù)據(jù)管理

特性DeploymentStatefulSet
存儲定義方式在 Pod 模板中直接定義 volumes 或引用現(xiàn)有 PVC使用 volumeClaimTemplates 動態(tài)為每個 Pod 創(chuàng)建獨立 PVC
PVC 與 Pod 關(guān)系多個 Pod 可共享同一個 PVC(需支持多掛載)
或每個 Pod 手動掛載相同 PVC
每個 Pod 獨占一個 PVC,一對一綁定,命名規(guī)則:<pvc-name>-<statefulset-name>-<ordinal>
數(shù)據(jù)持久性Pod 刪除,數(shù)據(jù)可能丟失(取決于卷類型)Pod 刪除,PVC 保留,數(shù)據(jù)持久化;新 Pod 自動掛載原 PVC
存儲擴容需手動修改 PVC需手動修改 PVC,或依賴 StorageClass 支持在線擴容
數(shù)據(jù)隔離性低(共享存儲)或手動管理高(自動隔離,每個 Pod 獨立存儲)

存儲綁定示例

# StatefulSet 會自動創(chuàng)建:
# PVC: disk-ssd-web-0 → PV: pv-001 (綁定)
# PVC: disk-ssd-web-1 → PV: pv-002 (綁定)
# 即使 web-0 被刪除重建,disk-ssd-web-0 仍會重新掛載到原 PV

2.3 詳解:部署與擴縮容行為

操作DeploymentStatefulSet
創(chuàng)建順序并行創(chuàng)建,所有 Pod 同時啟動串行創(chuàng)建,按序號 0→1→2→…,前一個 Ready 后才創(chuàng)建下一個
擴容行為并行擴容,新 Pod 立即創(chuàng)建按序號遞增順序創(chuàng)建,保證集群拓?fù)渲鸩綌U展
縮容行為隨機刪除 Pod按序號遞減刪除(先刪 N-1,再刪 N-2…),保證有序縮減
滾動更新隨機替換,可設(shè)置 maxSurge/maxUnavailable逆序替換(先更新 N-1,最后更新 0),可設(shè)置 partition 進行灰度發(fā)布
更新策略RollingUpdate(默認(rèn))、RecreateRollingUpdate(默認(rèn))、OnDelete(手動刪除后重建)

有序性意義

  • 主從架構(gòu):先啟動主節(jié)點(0),再啟動從節(jié)點(1,2…),避免從節(jié)點找不到主而崩潰
  • 數(shù)據(jù)安全:縮容時先移除高序號節(jié)點,避免破壞集群的法定人數(shù)(Quorum)
  • 灰度發(fā)布:通過 partition 控制只更新部分節(jié)點,如 partition: 2 表示只更新序號 ≥2 的 Pod

2.4 運維與故障處理對比

場景DeploymentStatefulSet
Pod 故障重建立即創(chuàng)建新 Pod,隨機命名,無狀態(tài)恢復(fù)按原序號重建,掛載原 PVC,自動恢復(fù)數(shù)據(jù)和身份
節(jié)點遷移快速調(diào)度到新節(jié)點需等待原 PVC 在目標(biāo)節(jié)點可用(依賴存儲拓?fù)洌?/td>
版本回滾kubectl rollout undo 快速回滾需手動控制,逆序回滾,需關(guān)注數(shù)據(jù)兼容性
數(shù)據(jù)備份通常無需備份 Pod 級數(shù)據(jù)必須制定備份策略,PVC 獨立存在需單獨管理
監(jiān)控重點整體吞吐量、錯誤率單節(jié)點狀態(tài)、存儲容量、復(fù)制延遲、集群拓?fù)渫暾?/td>

三、StatefulSet 的使用 - 實例

部署一個Nginx StatefulSet

  • 先創(chuàng)建一個nginx的namespace
kubectl create ns nginx

3.1 檢查是否有 storageclass 資源

kubectl get storageclass -A

如果有資源(任何都行,只要不提示No resources found就行),在 nginx-StatefulSet.yaml中的storageClassName請?zhí)顚懗捎械?,如果沒有,可按照如下添加storageclass;

可地址直接安裝:kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml

如果地址拉取不到可使用如下:

  • vi local-path-storage.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: local-path-storage

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: local-path-provisioner-service-account
  namespace: local-path-storage

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: local-path-provisioner-role
  namespace: local-path-storage
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list", "watch", "create", "patch", "update", "delete"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: local-path-provisioner-role
rules:
  - apiGroups: [""]
    resources: ["nodes", "persistentvolumeclaims", "configmaps", "pods", "pods/log"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["persistentvolumes"]
    verbs: ["get", "list", "watch", "create", "patch", "update", "delete"]
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["create", "patch"]
  - apiGroups: ["storage.k8s.io"]
    resources: ["storageclasses"]
    verbs: ["get", "list", "watch"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: local-path-provisioner-bind
  namespace: local-path-storage
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: local-path-provisioner-role
subjects:
  - kind: ServiceAccount
    name: local-path-provisioner-service-account
    namespace: local-path-storage

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: local-path-provisioner-bind
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: local-path-provisioner-role
subjects:
  - kind: ServiceAccount
    name: local-path-provisioner-service-account
    namespace: local-path-storage

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: local-path-provisioner
  namespace: local-path-storage
spec:
  replicas: 1
  selector:
    matchLabels:
      app: local-path-provisioner
  template:
    metadata:
      labels:
        app: local-path-provisioner
    spec:
      serviceAccountName: local-path-provisioner-service-account
      containers:
        - name: local-path-provisioner
          image: rancher/local-path-provisioner:v0.0.35
          imagePullPolicy: IfNotPresent
          command:
            - local-path-provisioner
            - --debug
            - start
            - --config
            - /etc/config/config.json
          volumeMounts:
            - name: config-volume
              mountPath: /etc/config/
          env:
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
            - name: CONFIG_MOUNT_PATH
              value: /etc/config/
      volumes:
        - name: config-volume
          configMap:
            name: local-path-config

---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: local-path
provisioner: rancher.io/local-path
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Delete

---
kind: ConfigMap
apiVersion: v1
metadata:
  name: local-path-config
  namespace: local-path-storage
data:
  config.json: |-
    {
            "nodePathMap":[
            {
                    "node":"DEFAULT_PATH_FOR_NON_LISTED_NODES",
                    "paths":["/opt/local-path-provisioner"]
            }
            ]
    }
  setup: |-
    #!/bin/sh
    set -eu
    mkdir -m 0777 -p "$VOL_DIR"
  teardown: |-
    #!/bin/sh
    set -eu
    rm -rf "$VOL_DIR"
  helperPod.yaml: |-
    apiVersion: v1
    kind: Pod
    metadata:
      name: helper-pod
    spec:
      priorityClassName: system-node-critical
      tolerations:
        - key: node.kubernetes.io/disk-pressure
          operator: Exists
          effect: NoSchedule
      containers:
      - name: helper-pod
        image: busybox
        imagePullPolicy: IfNotPresent

在進行創(chuàng)建

kubectl apply -f local-path-storage.yaml

查看是否創(chuàng)建成功

kubectl get storageclass

看到如下內(nèi)容即可

3.2 創(chuàng)建Headless Service

Headless Service(clusterIP: None)會為每個 Pod 創(chuàng)建獨立的 DNS 記錄:

  • vi nginx-Headless.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx
  namespace: nginx
  labels:
    app: nginx
spec:
  type: ClusterIP
  selector:
    app: nginx
  clusterIP: None
  sessionAffinity: None
  ports:
    - name: web
      port: 80
      protocol: TCP

3.3 創(chuàng)建StatefulSet

  • vi nginx-StatefulSet.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: nginx
  namespace: nginx
spec:
  serviceName: nginx
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      initContainers:
      - name: init-html
        image: busybox
        command: 
          - sh
          - -c
          - |
            # 檢查是否已初始化
            if [ ! -f /mnt/html/.initialized ]; then
              echo "First boot - creating initial content"
              echo "Welcome to nginx - $(hostname) - $(date)" > /mnt/html/index.html
              echo "This is a test page" >> /mnt/html/index.html
              touch /mnt/html/.initialized  # 創(chuàng)建標(biāo)記文件
            else
              echo "Already initialized, keeping existing content"
            fi
        volumeMounts:
        - name: www
          mountPath: /mnt/html
      containers:
      - name: nginx
        image: nginx:1.24
        imagePullPolicy: IfNotPresent
        ports:
        - name: web
          containerPort: 80
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
        livenessProbe:
          initialDelaySeconds: 10
          periodSeconds: 10
          tcpSocket:
            port: 80
        readinessProbe:
          initialDelaySeconds: 10
          periodSeconds: 10
          httpGet:
            path: /
            port: 80
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: "local-path"  # 根據(jù)storageclass集群修改
      resources:
        requests:
          storage: 1Gi

3.4 使用StatefulSet部署nginx服務(wù)

  • 部署nginx Headless Service
kubectl apply -f nginx-Headless.yaml
  • 查看是否創(chuàng)建成功
kubectl get svc -n nginx

  • 部署nginx StatefulSet
kubectl apply -f nginx-StatefulSet.yaml
  • 查看是否創(chuàng)建成功
# 查看nginx pvc
kubectl get pvc -n nginx -w
# 查看nginx pod
kubectl get pod -n nginx -w
# 查看nginx StatefulSet
kubectl get sts -n nginx -o wide

3.5 驗證StatefulSet特性

創(chuàng)建完成后,可以觀察到以下現(xiàn)象:

  1. Pod有序創(chuàng)建
[root@k8s-master StatefulSet]# kubectl  get pods -n nginx -o wide
NAME      READY   STATUS    RESTARTS   AGE     IP                NODE        NOMINATED NODE   READINESS GATES
nginx-0   1/1     Running   0          3m37s   192.168.36.94     k8s-node1   <none>           <none>
nginx-1   1/1     Running   0          3m19s   192.168.36.99     k8s-node1   <none>           <none>
nginx-2   1/1     Running   0          3m      192.168.169.143   k8s-node2   <none>           <none>
  1. 穩(wěn)定的網(wǎng)絡(luò)標(biāo)識
[root@k8s-master StatefulSet]# kubectl exec -n nginx nginx-0 -- hostname
nginx-0
# 通過DNS解析訪問(這里需要注意,指定nginx部署的ns,要不然會報無法解析)
[root@k8s-master StatefulSet]# kubectl run -it --rm busybox --image=busybox:1.28 --restart=Never -n nginx -- nslookup nginx-0.nginx 2>/dev/null || echo "測試失敗"
Server:    10.0.0.2
Address 1: 10.0.0.2 kube-dns.kube-system.svc.cluster.local
Name:      nginx-0.nginx
Address 1: 192.168.36.94 nginx-0.nginx.nginx.svc.cluster.local
  1. 獨立的持久化存儲
# 查看自動創(chuàng)建的PVC
[root@k8s-master StatefulSet]# kubectl get pvc -n nginx
NAME          STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
www-nginx-0   Bound    pvc-67c250d5-3e78-4c69-a4ad-2bfacf84c54b   1Gi        RWO            local-path     5d
www-nginx-1   Bound    pvc-13f90069-60b5-4c93-86c3-76e1377b5098   1Gi        RWO            local-path     5d
www-nginx-2   Bound    pvc-2ba2e9e5-5794-4b6e-af5b-b940ccb414e1   1Gi        RWO            local-path     5d
  1. Pod重建后保持?jǐn)?shù)據(jù)
# 查看nginx-0 默認(rèn)的index.html數(shù)據(jù)
kubectl exec -n nginx nginx-0 -- bash -c "cat /usr/share/nginx/html/index.html"
# 在nginx-0中寫入數(shù)據(jù)
kubectl exec -n nginx nginx-0 -- bash -c 'echo "Hello Nginx, Im's nginx-0 pod !!! " > /usr/share/nginx/html/index.html'
# 查看nginx-0 修改后的index.html數(shù)據(jù)
kubectl exec -n nginx nginx-0 -- bash -c "cat /usr/share/nginx/html/index.html"
# 刪除nginx-0
kubectl delete pods -n nginx nginx-0
# StatefulSet會自動重建,查看nginx-o pod是否重建
kubectl get pods -n nginx -w
# 重建成功再次查看nginx-0 pod容器里index.html里的內(nèi)容
kubectl exec -n nginx nginx-0 -- bash -c "cat /usr/share/nginx/html/index.html"

注意:如果數(shù)據(jù)被覆蓋為最初的數(shù)據(jù)了,可能是因為創(chuàng)建pod的時候會直接寫入默認(rèn)的配置,導(dǎo)致把后來修改的數(shù)據(jù)重寫了。
這里我在創(chuàng)建nginx-StatefulSet的時候是先手動添加數(shù)據(jù)了,因為默認(rèn)沒有index.html,會導(dǎo)致啟動失敗,所以需要先寫入數(shù)據(jù)才可以;并且加了個判斷,如果存在這個文件那么就不會寫入數(shù)據(jù),這樣就不會在重建pod的時候數(shù)據(jù)重寫了。

四、StatefulSet的更新策略

StatefulSet支持兩種更新策略,通過spec.updateStrategy.type 字段控制:

策略類型行為適用場景
RollingUpdate (默認(rèn))按順序從后向前滾動更新 Pod? 大多數(shù)場景
OnDelete手動刪除 Pod 后才更新?? 需要完全控制更新時機的場景

4.1 RollingUpdate 策略(默認(rèn))

4.1.1 基本更新寫法

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: nginx
spec:
  updateStrategy:
    type: RollingUpdate  # 默認(rèn)值,可不寫
  # ... 其他配置

更新順序

  1. 序號最大的 Pod 開始更新(從后向前)
  2. 依次向前推進(nginx-2 → nginx-1 → nginx-0)
  3. 每個 Pod 更新成功并進入 Ready 狀態(tài)后,才更新下一個

為什么從后往前?

  • 保證主節(jié)點(通常是序號0)最后更新
  • 對于主從架構(gòu)的應(yīng)用,先更新從節(jié)點,最后更新主節(jié)點
  • 減少對服務(wù)的影響

4.1.2 分區(qū)更新(Partition)-重要特性

RollingUpdate 支持 partition 參數(shù),可以控制更新的范圍

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: nginx
spec:
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      partition: 2  # 只更新序號 >= 2 的 Pod
  # ... 其他配置

分區(qū)規(guī)則

  • 序號 >= partition 的 Pod 會被更新
  • 序號 < partition 的 Pod 保持舊版本

4.1.3 分區(qū)更新實例:

假設(shè)有 3 個副本:nginx-0, nginx-1, nginx-2

partition 值哪些 Pod 被更新哪些 Pod 保持不變
partition: 0nginx-2, nginx-1, nginx-0 (全部)
partition: 1nginx-2, nginx-1nginx-0
partition: 2nginx-2nginx-0, nginx-1
partition: 3nginx-0, nginx-1, nginx-2 (全部)
  • 場景1:金絲雀發(fā)布(Canary Release)
# 第一步:只更新最后一個 Pod 做測試
updateStrategy:
  type: RollingUpdate
  rollingUpdate:
    partition: 2  # 只更新 nginx-2

測試 nginx-2 沒問題后,更新其他所有的pod:

# 第二步:更新所有 Pod
updateStrategy:
  type: RollingUpdate
  rollingUpdate:
    partition: 0  # 更新全部
  • 場景2:維護主節(jié)點不更新
# 主節(jié)點是 nginx-0,保持不更新
updateStrategy:
  type: RollingUpdate
  rollingUpdate:
    partition: 1  # 只更新 nginx-1, nginx-2
  • 場景3:分批發(fā)布
# 第1批:更新 30%(最后一個)更新完需測試
partition: 2

# 第2批:更新 60%(后兩個)更新完需測試
partition: 1

# 第3批:更新 100%       更新完需測試
partition: 0

4.2 OnDelete 策略(手動觸發(fā))

  • OnDelete 策略寫法
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: nginx
spec:
  updateStrategy:
    type: OnDelete  # 手動模式
  # ... 其他配置
  • 行為特點
  1. K8s 不會自動更新任何 Pod
  2. 只有當(dāng)你手動刪除 Pod 時,重建的 Pod 才會使用新配置
  3. 你可以控制每個 Pod 的更新時機
  • 適用場景
  • 數(shù)據(jù)庫版本升級:需要逐個節(jié)點手動操作,確保數(shù)據(jù)同步
  • 核心業(yè)務(wù):需要在業(yè)務(wù)低峰期逐個更新
  • 需要手動驗證:每個節(jié)點更新后都要手動驗證
  • 配合外部工具:與 Ansible、Jenkins 等工具集成
  • 實際操作示例
# 1. 修改 StatefulSet 鏡像版本(但不會立即生效)
kubectl patch sts -n nginx nginx -p '{"spec":{"template":{"spec":{"containers":[{"name":"nginx","image":"nginx:1.25"}]}}}}'

# 2. 手動刪除要更新的 Pod
kubectl delete pod -n nginx nginx-2  # 先更新最后一個
## 更新完成查看版本號,確認(rèn)是否更新成功
kubectl exec -n nginx nginx-2 -- nginx -v

# 3. 驗證 nginx-2 沒問題后
kubectl delete pod -n nginx nginx-1  # 更新中間
## 更新完成查看版本號,確認(rèn)是否更新成功
kubectl exec -n nginx nginx-2 -- nginx -v

# 4. 最后更新主節(jié)點
kubectl delete pod -n nginx nginx-0
## 更新完成查看版本號,確認(rèn)是否更新成功
kubectl exec -n nginx nginx-2 -- nginx -v

  • 控制器不會自動更新Pod
  • 需要手動刪除Pod才能觸發(fā)重建更新
  • 適用于需要完全控制更新時機的場景,如核心應(yīng)用的流量無損升級

4.3 更新策略對比

特性RollingUpdateOnDelete
自動更新? 是? 否
更新順序從后往前由你控制
分區(qū)控制? 支持 (partition)? 不支持
回滾方式重新設(shè)置 image 或 partition手動刪除重建
適用場景Web服務(wù)、緩存、一般應(yīng)用數(shù)據(jù)庫、核心應(yīng)用、特殊需求

4.4 更新策略選擇建議

  • 選擇 RollingUpdate 當(dāng):
    ? 應(yīng)用無狀態(tài)或能優(yōu)雅處理滾動重啟
    ? 想要自動化更新
    ? 需要金絲雀發(fā)布(配合 partition)
    ? 更新風(fēng)險較低

  • 選擇 OnDelete 當(dāng):
    ? 數(shù)據(jù)庫等有狀態(tài)核心應(yīng)用
    ? 需要手動干預(yù)每個節(jié)點的更新
    ? 更新風(fēng)險高,需要逐個驗證
    ? 有外部編排工具(Ansible、Operator)

五、StatefulSet vs. Deployment:如何選擇?

特性StatefulSetDeployment
Pod命名固定有序名稱(xxx-0, xxx-1)隨機名稱(xxx-隨機字符串)
網(wǎng)絡(luò)標(biāo)識穩(wěn)定,Pod重建不變變化,每次重建新IP
存儲支持PVC模板,持久化存儲通常使用共享存儲或臨時存儲
順序控制有序部署、更新、刪除并行操作
適用場景數(shù)據(jù)庫、消息隊列、有狀態(tài)服務(wù)Web服務(wù)、API網(wǎng)關(guān)、無狀態(tài)應(yīng)用

選擇建議

  • 應(yīng)用需要穩(wěn)定的網(wǎng)絡(luò)標(biāo)識 → 選擇StatefulSet
  • 應(yīng)用需要獨立的持久化存儲 → 選擇StatefulSet
  • 應(yīng)用要求有序的部署和更新 → 選擇StatefulSet
  • 否則,優(yōu)先考慮Deployment或ReplicaSet

六、注意事項

  1. 數(shù)據(jù)安全:StatefulSet刪除時不會自動刪除PVC,需手動清理不再需要的存儲卷,避免資源浪費

  2. Headless Service必須:StatefulSet必須關(guān)聯(lián)Headless Service才能保證網(wǎng)絡(luò)標(biāo)識的穩(wěn)定性

  3. 存儲類選擇:根據(jù)性能需求選擇合適的StorageClass,生產(chǎn)環(huán)境推薦使用SSD或高性能云盤

  4. 備份策略:雖然StatefulSet保證了Pod重建后的數(shù)據(jù)持久性,但仍需建立定期備份機制,防止數(shù)據(jù)損壞或誤刪除

  5. 縮容謹(jǐn)慎:縮容StatefulSet會導(dǎo)致Pod被刪除,但PVC保留。如果希望徹底清理,需要手動刪除對應(yīng)的PVC

七、總結(jié)

StatefulSet是Kubernetes中管理有狀態(tài)應(yīng)用的核心控制器,通過穩(wěn)定的網(wǎng)絡(luò)標(biāo)識、獨立的持久化存儲有序的生命周期管理,為數(shù)據(jù)庫、消息隊列等有狀態(tài)應(yīng)用提供了完善的運行環(huán)境。掌握StatefulSet的使用,意味著你能夠?qū)⒏嗟膫鹘y(tǒng)應(yīng)用平滑地遷移到Kubernetes平臺,充分發(fā)揮容器編排的優(yōu)勢。

在實際應(yīng)用中,需要根據(jù)業(yè)務(wù)需求合理選擇更新策略和Pod管理策略,同時注意數(shù)據(jù)安全和備份,才能構(gòu)建出穩(wěn)定可靠的有狀態(tài)應(yīng)用系統(tǒng)。

到此這篇關(guān)于K8s之StatefulSet控制器的文章就介紹到這了,更多相關(guān)K8s之StatefulSet控制器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • K8s內(nèi)存溢出問題剖析之排查與解決過程

    K8s內(nèi)存溢出問題剖析之排查與解決過程

    這篇文章主要介紹了K8s內(nèi)存溢出問題剖析之排查與解決過程,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-07-07
  • K8S部署lnmp項目全過程

    K8S部署lnmp項目全過程

    這篇文章主要介紹了K8S部署lnmp項目全過程,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • k8s?series初級calico使用介紹

    k8s?series初級calico使用介紹

    這篇文章主要為大家介紹了k8s?series初級calico使用介紹,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • 云服務(wù)器Jenkins部署Springboot項目及Vue項目的詳細(xì)過程

    云服務(wù)器Jenkins部署Springboot項目及Vue項目的詳細(xì)過程

    本文詳細(xì)介紹了如何在云服務(wù)器上使用Jenkins部署Springboot和Vue項目,包括創(chuàng)建Springboot項目并上傳到Git倉庫、安裝Maven和配置Maven插件、安裝Gitee插件、配置Jenkins任務(wù)以及創(chuàng)建自由風(fēng)格項目等步驟,感興趣的朋友一起看看吧
    2025-02-02
  • 新版k8s拉取鏡像失敗問題解決辦法

    新版k8s拉取鏡像失敗問題解決辦法

    隨著Kubernetes?1.23版本的發(fā)布,Docker作為默認(rèn)容器運行時被棄用,轉(zhuǎn)而默認(rèn)采用Containerd,這一改變意味著用戶在使用Kubernetes時,將不再通過Docker來拉取鏡像,文中jiang,需要的朋友可以參考下
    2024-10-10
  • k8s平臺本地數(shù)據(jù)遷移整改過程

    k8s平臺本地數(shù)據(jù)遷移整改過程

    文章主要介紹了對k8s平臺默認(rèn)數(shù)據(jù)存儲位置進行優(yōu)化,將數(shù)據(jù)統(tǒng)一管理并存至指定目錄和云磁盤的整個過程,包括新磁盤的創(chuàng)建掛載、配置更改生效、環(huán)境檢查、清理舊環(huán)境等步驟,強調(diào)在集群所有節(jié)點上進行優(yōu)化,并提醒配置更改生效后建議重啟機器以確保變更生效
    2026-05-05
  • k8s中容器創(chuàng)建的全過程實踐

    k8s中容器創(chuàng)建的全過程實踐

    這篇文章主要介紹了k8s中容器創(chuàng)建的全過程,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-07-07
  • k8s的架構(gòu)組成操作代碼

    k8s的架構(gòu)組成操作代碼

    k8s是一個輕便的和可擴展的開源平臺,用于管理容器化應(yīng)用和服務(wù),通過k8s能夠進行應(yīng)用的自動化部署和擴縮容,這篇文章主要介紹了k8s的架構(gòu)組成,需要的朋友可以參考下
    2024-05-05
  • Rainbond云原生部署SpringCloud應(yīng)用架構(gòu)實踐

    Rainbond云原生部署SpringCloud應(yīng)用架構(gòu)實踐

    這篇文章主要為大家介紹了Rainbond云原生部署SpringCloud應(yīng)用架構(gòu)實踐,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-04-04
  • 教你在k8s上部署HADOOP-3.2.2(HDFS)的方法

    教你在k8s上部署HADOOP-3.2.2(HDFS)的方法

    這篇文章主要介紹了k8s-部署HADOOP-3.2.2(HDFS)的方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-04-04

最新評論

广宗县| 西畴县| 类乌齐县| 苍南县| 大洼县| 通渭县| 东辽县| 濮阳县| 通许县| 乌兰察布市| 都兰县| 陕西省| 昌都县| 华坪县| 玉树县| 惠来县| 宜黄县| 柞水县| 麻栗坡县| 三门峡市| 石台县| 密云县| 白玉县| 蓝山县| 松溪县| 黄陵县| 哈尔滨市| 格尔木市| 新安县| 英吉沙县| 十堰市| 通河县| 泾川县| 阳东县| 崇文区| 唐河县| 通渭县| 通州区| 额济纳旗| 自贡市| 托里县|