記事ディレクトリ
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
ステップ 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
sts-web-0 を削除しても、Pod の後に自動的に作成される Pod 名は変更されません
kubectl delete pod sts-web-0
2. ポッド独立永続ボリュームストレージ: PVC を表示し、相互に分離された 2 つの PVC を自動的に生成します。
kubectl get pvc -l app=web-nginx
ls /data/nfs_pro|grep default-www-sts-web-*
3. 安定したネットワーク識別子: ポッドの実行にはbusyboxを使用し、分析にはnslookupを使用します。
kubectl run busybox --image docker.io/library/busybox:1.28 --rm -it busybox -- sh
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
ミラーを使用して更新する
YAML を少し再構築します。
kubectl apply -f web.yaml
検証: 私たちのせいで、partition: 2
すべての Pod は更新されず、2 を含む 2 より大きいシリアル番号を持つ Pod のみが更新されます。
3. まとめ
- statefulset で管理される Pod 名は順序付けされており、自動作成された Pod は指定した Pod が削除された後も名前が変更されません。
- ステートフルセットの作成時にサーバー名を指定する必要があります。サーバーに IP アドレスがない場合は、サーバー上で DNS 分析が実行され、対応する Pod ドメイン名が検索されます。
- statefulset には volumeclaimtemplate ボリューム管理テンプレートがあり、作成された Pod はすべて独立したボリュームを持ち、相互に影響しません。
- statefulset によって作成された Pod には独立したドメイン名が付いています。Pod リソースへのアクセスを指定するときに、ドメイン名を使用して指定できます。IP は変更されますが、ドメイン名は変更されません (ドメイン名: Pod name svc name.svc namespace) .svc.cluster.local )