【Kubernetesリソース】StatefulSetステートレスサービス管理入門 実践詳細解説

1. StatefulSet の理論的知識

中国語の公式参照文書

1. StatefulSet ポッド コントローラーの機能

StatefulSet (略称 sts) も K8S クラスターの Pod リソース マネージャーであり、デプロイメント Pod コントローラーとは異なり、StatefulSet はステートレス プログラムの管理に使用されます。その機能は次のとおりです。

  • 安定したネットワーク識別子: マネージド ポッドには安定したネットワーク識別子があります。ネットワーク識別子を介してアクセスできます。
  • 規則正しいデプロイメントと拡張: StatefulSet は、指定された順序で Pod を 1 つずつデプロイします。各 Pod には固有のシリアル番号があり、ライフサイクル全体を通じて変更されません。拡張する場合、Pod も指定した順序で 1 つずつ追加されます。
  • 安定したストレージ: 各ポッドは、NFS などの独立した永続ボリューム ストレージを使用します。
  • ステートフル サービス: StatefulSet は、安定したネットワーク識別子と永続的なストレージを必要とするデータベース、キャッシュなどのステートフル サービスに適しています。

つまり、StatefulSet は、安定したネットワーク識別子と永続的なストレージを必要とするステートフル サービスに適した、信頼性が高く、秩序正しく、ステートフルなサービスの展開および拡張方法を提供します。

2. ステートフル サービスとステートレス サービスとは何ですか?

ステートレス サービスとは、Web サーバー、API サーバーなど、永続的なストレージと状態を必要としないサービスを指しますこれらのサービスは、異なるノード間でデータを共有する必要がなく、ノード障害が発生した場合の迅速な回復も必要ないため、どのノードでも実行できます。ステートレス サービスは水平方向に拡張して、パフォーマンスと可用性を向上させることができます。

ステートフル サービスとは、データベースやキャッシュなど、永続的なストレージと状態の維持を必要とするサービスを指しますこれらのサービスは、異なるノード間でデータの同期を維持する必要があり、ノードに障害が発生した場合に迅速に回復できる必要があります。

3. デプロイメントと StatefulSet の違い

Deployment と StatefulSet は、Kubernetes で一般的に使用される 2 つのコントローラーであり、主な違いは次のとおりです。

  • Deployment はステートレス アプリケーションを管理するためのコントローラーであり、StatefulSet はステートフル アプリケーションを管理するためのコントローラーです。

  • デプロイメントでは複数の Pod コピーを作成できます。これらの Pod コピー間に順序関係はなく、自由にスケジュールしたり置き換えたりできます。StatefulSet によって作成される Pod コピーには固定の順序があり、各 Pod コピーには一意の識別子が付いているため、ステートフル アプリケーションのデータの永続性と安定性が確保されます。

  • デプロイメントでは、ローリング更新を実行できます。つまり、更新プロセス中にアプリケーションの可用性を維持できます。ただし、StatefulSet の更新プロセスは手動で制御する必要があり、古い Pod コピーを削除してから新しい Pod コピーを作成する必要があるため、更新プロセス中に一定のダウンタイムが発生します。

  • デプロイメントではローリング更新に RollingUpdate 戦略を使用できますが、StatefulSet では更新に OnDelete および RollingUpdate 戦略を使用できます。

つまり、Deployment はステートレス アプリケーションの管理に適しており、StatefulSet はステートフル アプリケーションの管理に適しています。アプリケーションがデータの永続性と安定性を確保する必要がある場合は、StatefulSet を使用することをお勧めします。

2. 事例: StatefulSet リソースの実践的なデモンストレーション

1. WEBサイトを作成してStatefulSetの特性を確認する

ステップ 1:sts-web-svcという名前の SVC を作成します。これは、ステートフルセット リソースを作成するときにサービスに関連付ける必要があります。YAML は次のとおりです。

cat sts-web-svc.yaml 
---
apiVersion: v1
kind: Service
metadata:
  name: sts-web-svc
spec:
  selector:
    app: web-nginx
  ports:
  - port: 80
    targetPort: 80
  clusterIP: None     # 设置无IP地址

svc リソースを作成します。

kubectl apply -f sts-web-svc.yaml

次の図に示すように、作成された svc リソースを表示すると、作成された svc に IP アドレスが割り当てられていないことがわかります。

kubectl get svc sts-web-svc

[外部リンク画像の転送に失敗しました。ソース サイトには盗難防止リンク メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-Mh2GSqBh-1687429873545) (D:\MD Archives\IMG\image-20230622124156022)。 png)]

ステップ 2: ステートフルセット リソースを作成する

cat sts-web.yaml 
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: sts-web
  namespace: default
spec:
  serviceName: sts-web-svc  # 关联SVC资源
  replicas: 2               # 副本数
  selector:
    matchLabels:            # 关联具有app=web-nginx标签的Pod
      app: web-nginx
  volumeClaimTemplates:        # 卷申请模板 
  - metadata:
      name: www                # 卷申请模板名称
    spec:
      accessModes: ["ReadWriteOnce"] # 访问模式
      storageClassName: nfs          # 指定供应商,前提是需要存在此供应商
      resources:
        requests:
          storage: 1Gi               # 存储大小1G
  template:
    metadata:
      labels:
        app: web-nginx
    spec:
      containers:
      - name: web-nginx
        image: nginx:1.18.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www             # 指定卷申请模板名称
          mountPath: /usr/share/nginx/html
        startupProbe:           # 启动探测
          tcpSocket:
            port: 80

YAML を実行します。

kubectl apply -f sts-web.yaml

ステップ 3: 機能テスト

1. ポッドには一意のシリアル番号があります。以下の図に示すように、ポッド名はこの順序で並んでいます。

kubectl get pods -l app=web-nginx -o wide

[外部リンク画像の転送に失敗しました。ソース サイトには盗難防止リンク メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-oEhdYVet-1687429873546) (D:\MD Archives\IMG\image-20230622170004961. png)]

sts-web-0 を削除しても、Pod の後に自動的に作成される Pod 名は変更されません

kubectl delete pod sts-web-0

[外部リンク画像の転送に失敗しました。ソース サイトには盗難防止リンク メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-ZR18brWr-1687429873547) (D:\MD Archives\IMG\image-20230622172250665. png)]

2. ポッド独立永続ボリュームストレージ: PVC を表示し、相互に分離された 2 つの PVC を自動的に生成します。

kubectl get pvc -l app=web-nginx
ls /data/nfs_pro|grep default-www-sts-web-*

[外部リンク画像の転送に失敗しました。ソース サイトにはリーチ防止メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-lCl6BCXF-1687429873547) (D:\MD Archives\IMG\image-20230622170316050.png) )]

3. 安定したネットワーク識別子: ポッドの実行にはbusyboxを使用し、分析にはnslookupを使用します。

kubectl run busybox --image docker.io/library/busybox:1.28 --rm -it busybox -- sh

[外部リンク画像の転送に失敗しました。ソース サイトには盗難防止リンク メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-JAVuvfgk-1687429873547)(D:\MD Archives\IMG\image-20230622171854741. png)]

2. StatefulSet ローリング アップデート

ローリング アップデートはspec.updateStrategyフィールドを使用して定義されます。現在、statefulset は次の 2 つの更新戦略をサポートしています。

  • RollingUpdate: ローリングアップデート
  • OnDelete: 自動的には更新されません。Pod を手動で削除した後に更新されます。

以下は、ローリング アップデートを示しています。

ステップ 1: statefulset リソースを作成して実行する

cat web-svc.yaml 
---
apiVersion: v1
kind: Service
metadata:
  name: web
spec:
  selector:
    app: web
  ports:
  - port: 80
    targetPort: 80
  clusterIP: None

ステートフルセットを作成し、nginx:1.18ミラーを使用します

cat web.yaml 
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
  namespace: default
spec:
  serviceName: web
  replicas: 5   
  selector:
    matchLabels:           
      app: web
  updateStrategy:
    rollingUpdate:
      maxUnavailable: 0 # 最多不可用Pod,0表示2个Pod可用 
      partition: 2      # 只更新序号大于等于partition值的Pod
  volumeClaimTemplates:       
  - metadata:
      name: web               
    spec:
      accessModes: ["ReadWriteOnce"] 
      storageClassName: nfs          
      resources:
        requests:
          storage: 1Gi               
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: web
        image: nginx:1.18.0    # 使用1.18.0版本镜像
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: web           
          mountPath: /usr/share/nginx/html

YAMLファイルを実行する

kubectl apply -f web-svc.yaml
kubectl apply -f web.yaml

ステップ 2:nginx:latestミラーを使用して更新する

[外部リンク画像の転送に失敗しました。ソース サイトにはリーチ防止メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-nwAHriLC-1687429873547) (D:\MD Archives\IMG\image-20230622182033324.png) )]

YAML を少し再構築します。

kubectl apply -f web.yaml

検証: 私たちのせいで、partition: 2すべての Pod は更新されず、2 を含む 2 より大きいシリアル番号を持つ Pod のみが更新されます。

[外部リンク画像の転送に失敗しました。ソース サイトには盗難防止リンク メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-l7VHSbpv-1687429873548) (D:\MD Archives\IMG\image-20230622182419919. png)]

3. まとめ

  • statefulset で管理される Pod 名は順序付けされており、自動作成された Pod は指定した Pod が削除された後も名前が変更されません。
  • ステートフルセットの作成時にサーバー名を指定する必要があります。サーバーに IP アドレスがない場合は、サーバー上で DNS 分析が実行され、対応する Pod ドメイン名が検索されます。
  • statefulset には volumeclaimtemplate ボリューム管理テンプレートがあり、作成された Pod はすべて独立したボリュームを持ち、相互に影響しません。
  • statefulset によって作成された Pod には独立したドメイン名が付いています。Pod リソースへのアクセスを指定するときに、ドメイン名を使用して指定できます。IP は変更されますが、ドメイン名は変更されません (ドメイン名: Pod name svc name.svc namespace) .svc.cluster.local )

おすすめ

転載: blog.csdn.net/weixin_45310323/article/details/131343346