がじぇったー

お金と家電とプログラミングのブログ

KubernetesのControllerについて(StatefulSet)

こんにちわ

がじぇったー (@hackmylife7) | Twitter


です。ガジェット情報をいち早くツイートすることを生きがいにしているのでよかったらフォローください。


Controllerの後編ではStatefulSetについて学んでいきます。
(JobとDaemonSetは切り出します)



f:id:gadgeterkun:20190726000743j:plain

TL;DR(要約)

  • StatefulSetは独自の命名規則を使用してPodを作成することができる
  • StatufulSetを使うことにより永続データ(PersitantVolume)との紐付けが容易に行える

StatefulSet

StatefulSetもDeploymentと同様、Controllerではあるが、Deploymentとは異なり、独自の命名規則を使用してPodを作成することができる

例えば、StatefulSetを用いるとcounter-0という名前のPodを作成することができ、複数のレプリカにおいては、counter-0、counter-1、counter-2等、設定した命名規則を元に名前をつけることができる。

ちなみにDeploymentでPodを立ち上げた場合は"counter-sfhoissfab111"みたいにPodの後ろにはIDが付与される。(人間が見ても規則性はわからない)


命名規則を定めてPodを管理することができるのがStatefulSetの大きな特徴である

マニフェストファイルは以下のように記載する
Podを立ち上げると、

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: counter
spec:
  serviceName: "counter-app"
  selector:
    matchLabels:
      app: counter
  replicas: 3
  template:
    metadata:
      labels:
        app: counter


下記の通り命名規則に従ってPodが立ち上がる

$ kubectl get pods
NAME          READY
counter-0    1 / 1
counter-1     1 / 1
counter-2     1 / 1



Deploymentと何が違うのか?


StatefulSetはReplicaSetやReplicationControllerを作成し、Podを管理するわけではないので、以前のバージョンにロールバックすることはできない

なぜ命名規則をつけられること嬉しいのか?

Persistant Volume(永続化ボリューム)との紐付けを容易に行える、というのが一番嬉しいポイントである。


通常、コンテナ内のデータはローカルのエフェメラルストレージに保存される。(Podが死んだら消える)

しかしStatefulSetを用いれば、下記の通りPodを削除し、

$kubectl delete pod sample-nginx0
pod “sample-nginx0” deleted


コンテナも止めても、

$kubectl exec –it sample-nginx0 -- /bin/bash –c ‘kill 1


その後、再びPodを立ち上げると永続ボリューム上に残ったファイルを確認することができる

$kubectl exec –it sample-nginx0 ls /usr/share/nginx/html/index.html
/usr/share/nginx/html/index.html

注目していただきたい点は、Podを落として、立ち上げる時も、"sample-nginx0"というnameを引き続き使用している点である。

Deploymentの場合は、Podを落とし、あげるとnameが変わってしまうため、上記のようなことはできない。

これはPodが落ちて再び上がっても、同一のPersistantVolumeを引き継ぎマウントしていることを意味する


StatefulSetとDeploymentのPersitantVolumeの使い方はその接続方式に大きな違いがある。

下記のページがとてもわかりやすかったので、(特に図のところ)参考にしていただきたいが、
Kubernetes PVC と Deployment, StatefulSet の関係を検証してみた - Qiita


Deploymentが複数のPodで共通のPersitantVolumeをマウントするのに対し、StatefulSetはPod毎に専用のPersistantVolumeをマウントする


これには以下の利点がある


たとえばDBのマスタースレーブ構成を作るとか。ひとつがマスターで、それ以外がスレーブであることを確実に担保しないといけないでしょ。それに、起動してくる順番も制御したくない?
そういうことをしたい時、普通のPodではできない以下のような機能が必要になるはず。
わかりやすい名前: スレーブ1,スレーブ2みたいな名前は普通にPodを作っただけではつかない。
固定のIPアドレスDNS名: マスターのIPとDNSがコロコロ変わるとスレーブから接続できないでしょ。
グループ内での固定のリンク: あるPodを再作成した時に必ずマスター用の永続ボリュームを掴み直してくれないといけない。

StatefulSetっていつ使うの?PersistentVolumesでいいんじゃないの? - blackawa
より引用





Kubernetesの他の記事へは下記の一覧から飛べるようにしているので参照ください。

gadgeterkun.hatenablog.com



参考(Kubernetesの最強参考書)

Kubernetes完全ガイド (impress top gear)

Kubernetes完全ガイド (impress top gear)



参考

K8s: Deployments vs StatefulSets vs DaemonSets - Stakater - Medium


kubernetes - Why StatefulSets? Can't a stateless Pod use persistent volumes? - Stack Overflow