1. ステートフル アプリケーションとは
永続ストレージを使用するとPersistentVolume
、アプリケーションは実行時にいくつかの重要なデータをディスクに置くことができます。これは「保険」を持つことと同じです。予期しないクラッシュがPod
発生したVolume
。そして元のデータをロードして全血で復活させ、以前の「状態」を復元して実行を続けます。
したがって、この観点から、理論的にはすべてのアプリケーションはステートフルです。
ただ、一部のアプリケーションの状態情報はあまり重要ではなく、状態を復元しなくても正常に実行できるアプリケーションもあり、これを「ステートレス アプリケーション」と呼んでいます。「ステートレス アプリケーション」の典型Nginx
的Web
、HTTP
リクエストを状態を保存する必要がなく、状態に関係なく外部サービスを提供できます。で再開。
一部のアプリケーションでは、実行中のステータス情報が非常に重要です. 再起動によって状態が失われることは絶対に許されません. このようなアプリケーションは「ステートフルなアプリケーション」です.
「ステートフルなアプリケーション」の例もたくさんあります. 例えばRedis
,MySQL
そのようなデータベースでは, それらの「状態」はメモリ上またはディスク上に生成されたデータであり, これがアプリケーションの核となる価値です. これらのデータをアプリケーションで保存および復元できない場合時間、そして絶対に悲惨な結果。
これを理解したら、これまでに学んだ知識に基づいて考えてみましょう:Deployment
さらにPersistentVolume
、Kubernetes
で?
確かにDeployment
、高可用性を確保し、PersistentVolume
データを保存するために使用すると、「ステートフル アプリケーション」を管理するという目的を部分的に達成できます。
ただしKubernetes
、ビジョンはより包括的で長期的なものであり、「状態」はデータの永続性だけではないと考えています. クラスター化および分散シナリオでは、複数インスタンスの依存関係、起動シーケンス、ネットワーク識別などの問題も必要です.これらの問題はDeployment
私たちの手の届か。
使うだけなのでDeployment
、複数のインスタンスが関係なく、起動順序が固定されておらず、アプリケーションのPod
名前、アドレス、ドメイン名が完全にランダムであり、まさに「ステートレス アプリケーション」の特徴です。IP
ただし、「ステートフル アプリケーション」の場合、複数のインスタンス間に依存関係がある場合があります。たとえばmaster/slave
、active/passive
アプリケーションの正常な動作を保証するために、 を順番に開始する必要があり、外部クライアントも固定のネットワーク識別子を使用してインスタンスにアクセスする場合があります。Pod
再起動。
そのため、新しいオブジェクトKubernetes
はDeployment
にAPI
、その名前もわかりやすく、StatefulSet
ステートフル アプリケーションを管理するために特別に使用される と呼ばれます。
2. YAML を使用して StatefulSet を記述する
まず、コマンドを使用してkubectl api-resources
のStatefulSet
基本情報を表示します。その略語は でありsts
、YAML
ファイル ヘッダー情報は次のとおりです。
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: xxx-sts
DaemonSet
と同様に のStatefulSet
特殊なDeployment
ケース、kubectl create
テンプレート ファイルの作成に直接使用することはできませんが、そのオブジェクトの記述はDeployment
と同様であり、オブジェクトDeployment
になるように適切に変更することもできます。StatefulSet
ここで の使い方Redis
をStatefulSet
。それと の違いDeployment
を。
# redis-sts.yml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: redis-sts
spec:
serviceName: redis-svc
replicas: 2
selector:
matchLabels:
app: redis-sts
template:
metadata:
labels:
app: redis-sts
spec:
containers:
- image: redis:5-alpine
name: redis
ports:
- containerPort: 6379
mustYAML
be in the file に加えて、 には追加のフィールドがあり、残りは、などの とまったく同じであることがわかります。kind
StatefulSet
spec
serviceName
Deployment
replicas
selector
template
これら 2 つの違いは、StatefulSet
実際にDeployment
は と の主な違いです。これを本当に理解するには、そこで使用されている方法と組み合わせて分析するStatefulSet
必要があります。Kubernetes
3. Kubernetes で StatefulSet を使用する
でオブジェクトをkubectl apply
作成し、最初に でどのように見えるか見てみましょう:StatefulSet
kubectl get
kubectl apply -f redis-sts.yml
kubectl get sts
kubectl get pod
StatefulSet
スクリーンショットから、マネージド がランダムな名前でPod
はなく、0 から始まり、それぞれ名前が付けられた連番を持ちredis-sts-0
、この順序で作成されることを確認できるはずです (番号 0 は番号 1 より多いredis-sts-1
です。Kubernetes
AGE はもう少し長くなります)。これにより、「ステートフル アプリケーション」の最初の問題である起動順序が解決されます。
起動の順序で、アプリケーションはどのように自分の ID を認識し、それらの間の依存関係を判断するのでしょうか?
Kubernetes
与えられた方法は、を使用することですhostname
。つまり、Pod
各の。kubectl exec
ログインしてPod
内部ましょう。
kubectl exec -it redis-sts-0 -- sh
この名前は環境変数を表示するか、Pod
で$HOSTNAME
コマンドを実行することで取得できます。hostname
Pod
redis-sts-0
この一意の名前を使用すると、アプリケーションは依存関係を独自に判断できます。たとえば、このRedis
例最初のインスタンス 0 をPod
マスター インスタンスに、2 番目のインスタンス 1 をスレーブ インスタンスPod
にできます。
起動シーケンスと依存関係を解決しても、まだ 3 番目の問題があります。それは、Service
オブジェクト。
しかし、ここで別の奇妙なことがあります。コマンドを使用して を直接生成するkubectl expose
ことはできません。手動でしか記述できません。StatefulSet
Service
YAML
オブジェクトは自動的に生成されないため、 Service
objectです。metadata.name
StatefulSet
serviceName
selector
StatefulSet
# redis-svc.yml
apiVersion: v1
kind: Service
metadata:
name: redis-svc
spec:
selector:
app: redis-sts
ports:
- port: 6379
protocol: TCP
targetPort: 6379
を書き込んService
だ後、次のようにkubectl apply
オブジェクトを作成します。
これには特別なService
こと。また、ラベル セレクターを使用してStatefulSet
2 つの管理対象を見つけPod
、次にそれらのIP
アドレス。
しかし、StatefulSet
最大の謎はそのドメイン名にあります。
Service
「オブジェクト名.名前空間」の形式のドメイン名があり、それぞれに「IP アドレス.名前空間」の形式のドメイン名Pod
もあります。ただし、IP
アドレス、Pod
のドメイン名は実用的ではなく、一般的には の安定したService
ドメイン名。
Service
オブジェクトを に適用するStatefulSet
と、状況が異なります。
Service
これらは通常のアプリケーションPod
ではなくため、Pod
新しいドメイン名はそれ以上作成されず、形式はPod 名. 服务名. 名字空间.svc.cluster.local
. もちろん、このドメイン名はPod 名. 服务名
.
kubectl exec
内部に入りPod
、ping
コマンドを確認します。
kubectl exec -it redis-sts-0 -- sh
明らかに、これらはどちらStatefulSet
もPod
独自のドメイン名、つまり安定したネットワーク ID を持っています。次に、外部クライアントがStatefulSet
オブジェクトを、固定番号を使用して特定のインスタンスにアクセスできます. のアドレスPod
は変更される可能性がありますが、番号付きドメイン名はオブジェクトによって維持され、安定しています.IP
Service
これまでのところStatefulSet
、Service
と を併用することで、Kubernetes
「ステートフル アプリケーション」の依存関係、起動シーケンス、ネットワーク識別の 3 つの問題が解決されていますが、残りの内部通信と複数のインスタンス間の調整は、アプリケーション自体で解決する必要があります。と。
についてService
、もう一つ特筆すべき点があります。
Service
本来の目的はロード バランシングであり、Pod
の前でが、StatefulSet
の場合、この機能は不要です。これは、Pod
すでに安定したドメイン名があり、外部アクセス サービスがService
この層を通過してはならないためです。したがって、セキュリティとシステム リソースの節約の観点からService
、このオブジェクトにアドレスを割り当てる必要がないことclusterIP: None
を示すフィールドを追加できます。Kubernetes
IP
StatefulSet オブジェクトと Service オブジェクトの関係を示す図を描きました。これらのフィールド間の相互参照を参照できます。
4. StatefulSet のデータ永続性を実現する
StatefulSet
名前、起動順序、ネットワーク識別子が決まったので、そこにデータ永続化機能を追加すれば、「ステートフルなアプリケーション」の管理が実現できます。
前のレッスンで学んPersistentVolume
だNFS
. 簡単に定義しStorageClass
、書きPVC
、Pod
マウントすることができますVolume
.
ただし、永続ストレージとStatefulSet
の間の、フィールドはKubernetes
のためにStatefulSet
特別にvolumeClaimTemplates
、PVC
その定義はのファイルStatefulSet
に直接埋め込まれます。YAML
これにより、 がStatefulSet
作成される、それぞれがPod
自動的に作成され、PVC
の可用性が高くなります。StatefulSet
volumeClaimTemplates
この分野はちょっとわかりにくそうですがPod
、と比べてみるとわかりますtemplate
。Job
jobTemplate
StorageClass
PVC
今すぐRedis StatefulSet
オブジェクト、永続的なストレージ機能を追加しましょう:
# redis-pv-sts.yml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: redis-pv-sts
spec:
serviceName: redis-pv-svc
volumeClaimTemplates:
- metadata:
name: redis-100m-pvc
spec:
storageClassName: nfs-client
accessModes:
- ReadWriteMany
resources:
requests:
storage: 100Mi
replicas: 2
selector:
matchLabels:
app: redis-pv-sts
template:
metadata:
labels:
app: redis-pv-sts
spec:
containers:
- image: redis:5-alpine
name: redis
ports:
- containerPort: 6379
volumeMounts:
- name: redis-100m-pvc
mountPath: /data
まず、StatefulSet
オブジェクトの名前は ですredis-pv-sts
。これは、PV
ストレージ。次に、1 つがvolumeClaimTemplates
でPVC
、名前は でredis-100m-pvc
、100MB のNFS
ストレージ。これはPod
テンプレートで参照され、ネットワーク ディスクはのデータ ディレクトリであるディレクトリにマウントされます。volumeMounts
PVC
/data
Redis
次の図は、このStatefulSet
オブジェクト:
最初に上記のセクションを実行します
kubectl apply -f rbac.yml
kubectl apply -f class.yml
kubectl apply -f deployment.yml
次に実行
kubectl apply -f redis-pv-svc.yml
最後に、これらのオブジェクトkubectl apply
を作成すると、永続化機能を備えた「ステートフル アプリケーション」が実行されます。
kubectl apply -f redis-pv-sts.yml
次のコマンドを使用してkubectl get pvc
、StatefulSet
関連するストレージ ボリュームのステータスを表示できます。
この2つPVC
の、ランダムではなく規則的で、PVC
名前StatefulSet
+名前で構成されているPod
ので、破壊されても名前が変わらないので、再びPVC
バインドする前にこれを見つけることができます。保存されたデータ。
次に、その場で確認して、kubectl exec
実行Redis
中のクライアントを使用してKV
データ。
kubectl exec -it redis-pv-sts-0 -- redis-cli
ここでは、a=111 と b=222 の 2 つの値を設定します。
不測の事態をシミュレートしたので、これを削除しますPod
。
kubectl delete pod redis-pv-sts-0
は のようなStatefulSet
ため、の数が少ないことが判明した場合、新しいインスタンスがすぐに作成され、名前とネットワーク ID は以前とまったく同じに。Deployment
Pod
Pod
Pod
Pod
Redis
そこに保存されたデータはどうなりましたか? 永続ストレージは本当に使用され、完全に復元されていますか?
Redis
クライアントで再度ログインして、以下を確認できます。
kubectl exec -it redis-pv-sts-0 -- redis-cli
のディレクトリにNFS
ネットワークストレージをマウントしたので、定期的にデータをディスクに保存しますので、新しく作成したディレクトリを再度バックアップファイルからデータが復元され、メモリ内のデータが復元されます。元の状態に復元されました。Pod
/data
Redis
Pod
5. まとめ
このセクションでは、「ステートフル アプリケーション」の展開専用のAPI
オブジェクトStatefulSet
。これはオブジェクトにDeployment
非常が、違いPod
は、固定された名前、起動シーケンス、およびネットワーク ID を持つことです。同値関係の適用は非常に重要です。 .
StatefulSet
のYAML
説明はDeployment
とほぼ同じですが、もう 1 つのキー フィールドがありますserviceName
。StatefulSet
の安定したドメイン名を生成するには、 の名前と一致する名前のオブジェクトPod
を定義する必要があります。Service
StatefulSet
serviceName
- アクセスで
StatefulSet
はPod
、 の形式でPod 名. 服务名
、それぞれに個別のドメイン名を使用する必要があり、Service
の。 StatefulSet
フィールドを使用しvolumeClaimTemplates
て直接定義できるのでPVC
、永続的なデータ ストレージPod
を実現できます。
volumeClaimTemplates
インライン定義を使用しない場合PVC
、複数のコピーが同じネットワーク ストレージ デバイスをマウントする可能性があり、データが失われる可能性があります。
Pod
サービス担当、Job
スケジューリング担当、
Daemon/Deployment
ステートレスな展開を担当し、StatefulSet
ステートフルな展開を担当し、
Service
4 層アクセス (負荷分散、IP 割り当て、ドメイン名アクセス) を担当し、Ingress
アプリケーション層 (7 層) アクセス (ルーティング ルール) を担当します。
PVC/PV
信頼性の高いストレージを担当します。