Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
39
Help us understand the problem. What is going on with this article?
@sugimount

Kubernetes PVC と Deployment, StatefulSet の関係を検証してみた

More than 1 year has passed since last update.

はじめに

Persistent Volume とは、Kubernetes の Pod でストレージを管理・使用するためのものです。
Persistent Volume を、Deployment・StatefulSet で使用したときに、どのようにPodへ紐づけられるかが不明だったため、検証を通じて理解を深めていきます。
Master1台・Node2台のKubernetesクラスタに対して、NFSを使用してPersistent Volume の検証をします。

NFSサーバの準備

適当にNFSサーバを準備する
以下のURLを参照

NFS Clientの準備

Node が NFSマウントを実施するため、Nodeに NFS Client の事前準備を行う
念のため、Master と Node全台 で install をしておく

以下のURLを参照

Persistent VolumeとDeploymentの紐づけ検証

Persistent Volumeの作成

KubernetesMaster上で、Persistent Volume を定義するYAMLファイルを作成します

cat <<'EOF' > /root/kube_yaml/persistent_volume/persistent_volume.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv0001
spec:
  capacity:
    storage: 1Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: slow
  mountOptions:
    - hard
  nfs:
    server: 192.168.120.230
    path: /mnt/nfsserv
EOF

特徴的な各パラメータは以下の通りです

項目 パラメータ概要 内容
spec.capacity.storage ストレージ容量 PVの容量を定義
spec.volumeMode PVボリュームの種類 PVボリュームの種類を指定。"Filesystem" or "Block" の2種類を指定可能。何も指定しない場合は、"FileSystem"がDefaultとなる。
Kubernetes 1.9 より、 "Block" がサポートされたため、volumeMode を指定出来るようになった
spec.accessModes アクセスモード PVへアクセスするモードを定義する。選択可能なアクセスモードは、PVのVolumePluginに依存している。
ReadWriteOnce : 1つのNodeがPVをmountすることが出来る。読み書き可能。
ReadOnlyMany : 複数のNodeがPVをmountすることが出来る。読み取り専用。
ReadWriteMany : 複数のNodeがPVをmountすることが出来る。読み書き可能
spec.storageClassName ストレージクラス名 Kubernetesクラスタ管理者が定義しているストレージのクラスから、1種類を選択します。
ストレージの性質をクラスタ管理者が定義するものが、ストレージクラスです。
例えば、fast class は高価な早いストレージと定義し、slow class は安価な遅めなストレージと定義する運用が考えられます
spec.persistentVolumeReclaimPolicy 削除時の動作 PVを削除したときの動作を指定します。
Retain : 削除しない。手動で削除を行う
Recycle : 削除して再利用する "rm -rf /voluma_path/*" のイメージ
Delete : Volumeを削除

PV を作成します

kubectl create -f /root/kube_yaml/persistent_volume/persistent_volume.yaml

確認します

[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl get pv -o wide
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM     STORAGECLASS   REASON    AGE
pv0001    1Gi        RWO            Recycle          Available             slow                     22s

現在の段階では、NFS上には何もFileは作成されていません

[root@sugi-nfs nfsserv]# pwd
/mnt/nfsserv
[root@sugi-nfs nfsserv]# 
[root@sugi-nfs nfsserv]# ls -la
total 0
drwxr-xr-x  2 root root  6 Jun  1 11:59 .
drwxr-xr-x. 3 root root 21 Jun  1 11:50 ..

Persistent Volume Claims を作成

PVC(Persistent Volume Claims)とは、PVを要求するためのKubernetesリソースです。
PVには、ストレージ提供側の固有の情報(IPアドレスや、NFSエクスポートポイントなど)が含まれています。
Kubernetesクラスタの利用者がPVを作成しようとすると、ストレージ提供側の固有の情報を知る必要があります。

ストレージ固有の情報を抽象化するために、PVCが存在しています。
PVをKubernetesクラスタの管理者が作成し、PVCを利用者が作成することが想定されています。

PVCを作成するために、以下のYAMLファイルを作成します

cat <<'EOF' > /root/kube_yaml/persistent_volume/persistent_volume_claims.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: test-claim
  annotations:
    volume.kubernetes.io/storage-class: "nfs"
spec:
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  storageClassName: slow
  resources:
    requests:
      storage: 1Gi
EOF

PVCを作成します

kubectl create -f /root/kube_yaml/persistent_volume/persistent_volume_claims.yaml

確認します

[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl get pvc -o wide
NAME         STATUS    VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
test-claim   Bound     pv0001    1Gi        RWO            slow           17s

describe で pvc の詳細を確認すると、pv0001 が 使用されている事がわかります

[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl describe pvc test-claim 
Name:          test-claim
Namespace:     default
StorageClass:  slow
Status:        Bound
Volume:        pv0001
Labels:        <none>
Annotations:   pv.kubernetes.io/bind-completed=yes
               pv.kubernetes.io/bound-by-controller=yes
               volume.kubernetes.io/storage-class=nfs
Finalizers:    [kubernetes.io/pvc-protection]
Capacity:      1Gi
Access Modes:  RWO
Events:        <none>

PVを確認すると、Available だった STATUS が、 Bound と変化しており、PVCに紐づけられています

[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl get pv -o wide
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS    CLAIM                STORAGECLASS   REASON    AGE
pv0001    1Gi        RWO            Recycle          Bound     default/test-claim   slow                     2h

Deployment の作成

Deploymentのために、以下のYAMLファイルを作成します

spec.template.spec.volumes.persistentVolumeClaim.claimName でDeploymentで使用するPVCを指定しています。
実際のコンテナに割り当てるためにspec.template.spec.containers.volumeMountsを指定しています。
PVCをコンテナ内の /persistent-volume に mount する設定となっています。

cat <<'EOF' > /root/kube_yaml/persistent_volume/persistent_deployment.yaml
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: persistent-deployment
spec:
  selector:
    matchLabels:
      app: persistest_test
  replicas: 1
  template:
    metadata:
      labels:
        app: persistest_test
    spec:
      containers:
      - name: master
        image: nginx
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        ports:
        - containerPort: 80
        volumeMounts:
        - mountPath: /persistent-volume
          name: pvc-volume
      volumes:
      - name: pvc-volume
        persistentVolumeClaim:
          claimName: test-claim
      restartPolicy: Always
EOF

deployment を作成します

kubectl create -f /root/kube_yaml/persistent_volume/persistent_deployment.yaml

deploymentが作成され、Pod が作成されます

[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl get pods -o wide
NAME                                    READY     STATUS    RESTARTS   AGE       IP            NODE
persistent-deployment-b9db64785-7fq4z   1/1       Running   0          47s       10.244.1.29   sugi-kubernetes110-node01.localdomain

node01 上で df を確認すると、NFSサーバをmount していることがわかります

[root@sugi-kubernetes110-node01 ~]# df -h
Filesystem                    Size  Used Avail Use% Mounted on
/dev/mapper/cl-root            14G  3.5G   10G  26% /
devtmpfs                      1.9G     0  1.9G   0% /dev
tmpfs                         1.9G     0  1.9G   0% /dev/shm
tmpfs                         1.9G  129M  1.8G   7% /run
tmpfs                         1.9G     0  1.9G   0% /sys/fs/cgroup
/dev/sda1                    1014M  289M  726M  29% /boot
tmpfs                         1.9G   12K  1.9G   1% /var/lib/kubelet/pods/436d9ed6-4ae3-11e8-bbe9-0050569817ee/volumes/kubernetes.io~secret/kube-proxy-token-c9qtq
tmpfs                         1.9G   12K  1.9G   1% /var/lib/kubelet/pods/436dce14-4ae3-11e8-bbe9-0050569817ee/volumes/kubernetes.io~secret/flannel-token-6pnqp
tmpfs                         380M     0  380M   0% /run/user/0
tmpfs                         1.9G   12K  1.9G   1% /var/lib/kubelet/pods/2f404ff6-6562-11e8-8767-0050569817ee/volumes/kubernetes.io~secret/default-token-q65hj
192.168.120.230:/mnt/nfsserv   14G  1.5G   12G  11% /var/lib/kubelet/pods/2f404ff6-6562-11e8-8767-0050569817ee/volumes/kubernetes.io~nfs/pv0001

なお、node01 上で docker 一覧を確認し

[root@sugi-kubernetes110-node01 ~]# docker ps
CONTAINER ID        IMAGE                                                                                     COMMAND                  CREATED             STATUS              PORTS               NAMES
b7dea7029d25        docker.io/nginx@sha256:0fb320e2a1b1620b4905facb3447e3d84ad36da0b2c8aa8fe3a5a81d1187b884   "nginx -g 'daemon ..."   4 minutes ago       Up 4 minutes                            k8s_master_persistent-deployment-b9db64785-7fq4z_default_2f404ff6-6562-11e8-8767-0050569817ee_0
13deb2cc4164        k8s.gcr.io/pause-amd64:3.1                                                                "/pause"                 4 minutes ago       Up 4 minutes                            k8s_POD_persistent-deployment-b9db64785-7fq4z_default_2f404ff6-6562-11e8-8767-0050569817ee_0
b9d65d4ddb1c        2b736d06ca4c                                                                              "/opt/bin/flanneld..."   4 weeks ago         Up 4 weeks                              k8s_kube-flannel_kube-flannel-ds-d92qj_kube-system_436dce14-4ae3-11e8-bbe9-0050569817ee_1
5592ed89cbe0        77019aa0531a                                                                              "/usr/local/bin/ku..."   4 weeks ago         Up 4 weeks                              k8s_kube-proxy_kube-proxy-khhwf_kube-system_436d9ed6-4ae3-11e8-bbe9-0050569817ee_1
496d9d63cddd        k8s.gcr.io/pause-amd64:3.1                                                                "/pause"                 4 weeks ago         Up 4 weeks                              k8s_POD_kube-flannel-ds-d92qj_kube-system_436dce14-4ae3-11e8-bbe9-0050569817ee_1
fab2fd0c0a3b        k8s.gcr.io/pause-amd64:3.1                                                                "/pause"                 4 weeks ago         Up 4 weeks                              k8s_POD_kube-proxy-khhwf_kube-system_436d9ed6-4ae3-11e8-bbe9-0050569817ee_1

該当のコンテナの詳細情報を表示すると、NFSでmount しているvolume を使用していることが分かります

# docker inspect b7dea7029d25

... snip ....

        "Mounts": [
            {
                "Type": "bind",
                "Source": "/var/lib/kubelet/pods/2f404ff6-6562-11e8-8767-0050569817ee/etc-hosts",
                "Destination": "/etc/hosts",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            },
            {
                "Type": "bind",
                "Source": "/var/lib/kubelet/pods/2f404ff6-6562-11e8-8767-0050569817ee/containers/master/1abcb732",
                "Destination": "/dev/termination-log",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            },
            {
                "Type": "bind",
                "Source": "/var/lib/kubelet/pods/2f404ff6-6562-11e8-8767-0050569817ee/volumes/kubernetes.io~nfs/pv0001",
                "Destination": "/persistent-volume",    ← ココを見る
                "Mode": "rslave",
                "RW": true,
                "Propagation": "rslave"
            },

nginx pod にログインします

[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl exec -it persistent-deployment-b9db64785-7fq4z bash
root@persistent-deployment-b9db64785-7fq4z:/# 

pod 内でも正常にmountされていることを確認できます

pod内からNFSサーバのIPアドレスが見えますね。StorageのTypeにもよりますが、Pod利用者にストレージ側のIPアドレスが知られても問題ないようにする観点も必要かもしれません

root@persistent-deployment-b9db64785-7fq4z:/# df -h
Filesystem                    Size  Used Avail Use% Mounted on
overlay                        14G  3.5G   10G  26% /
tmpfs                         1.9G     0  1.9G   0% /dev
tmpfs                         1.9G     0  1.9G   0% /sys/fs/cgroup
192.168.120.230:/mnt/nfsserv   14G  1.5G   12G  11% /persistent-volume
/dev/mapper/cl-root            14G  3.5G   10G  26% /etc/hosts
shm                            64M     0   64M   0% /dev/shm
tmpfs                         1.9G   12K  1.9G   1% /run/secrets/kubernetes.io/serviceaccount
tmpfs                         1.9G     0  1.9G   0% /proc/scsi
tmpfs                         1.9G     0  1.9G   0% /sys/firmware

pod 内でファイルを作成します

root@persistent-deployment-b9db64785-7fq4z:/persistent-volume# touch test_from_pod
root@persistent-deployment-b9db64785-7fq4z:/persistent-volume# pwd
/persistent-volume
root@persistent-deployment-b9db64785-7fq4z:/persistent-volume# 
root@persistent-deployment-b9db64785-7fq4z:/persistent-volume# ls -la
total 0
drwxr-xr-x 2 root root 27 Jun  1 06:26 .
drwxr-xr-x 1 root root 53 Jun  1 06:08 ..
-rw-r--r-- 1 root root  0 Jun  1 06:26 test_from_pod

NFSサーバ上でも、上記の作成されたファイルが確認できます
NFSサーバのExportPointと、PVは1対1で対応している事がわかります (NFSのDynamicProvisionerを使用すると、ExportPointが自動的に作成されるのかな?)

[root@sugi-nfs nfsserv]# ls -la
total 0
drwxr-xr-x  2 root root 27 Jun  1 15:26 .
drwxr-xr-x. 3 root root 21 Jun  1 11:50 ..
-rw-r--r--  1 root root  0 Jun  1 15:26 test_from_pod
[root@sugi-nfs nfsserv]# 
[root@sugi-nfs nfsserv]# pwd
/mnt/nfsserv

ここで、DeploymentのReplicaを1から2にするとどうなるのでしょうか。

cat <<'EOF' > /root/kube_yaml/persistent_volume/persistent_deployment.yaml
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: persistent-deployment
spec:
  selector:
    matchLabels:
      app: persistest_test
  replicas: 2
  template:
    metadata:
      labels:
        app: persistest_test
    spec:
      containers:
      - name: master
        image: nginx
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        ports:
        - containerPort: 80
        volumeMounts:
        - mountPath: /persistent-volume
          name: pvc-volume
      volumes:
      - name: pvc-volume
        persistentVolumeClaim:
          claimName: test-claim
      restartPolicy: Always
EOF

apply で更新する

[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl apply -f /root/kube_yaml/persistent_volume/persistent_deployment.yaml
Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply
deployment.apps "persistent-deployment" configured

確認

[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl get replicaset 
NAME                              DESIRED   CURRENT   READY     AGE
persistent-deployment-b9db64785   2         2         2         44m

podも確認

[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl get pods -o wide
NAME                                    READY     STATUS    RESTARTS   AGE       IP            NODE
persistent-deployment-b9db64785-7fq4z   1/1       Running   0          44m       10.244.1.29   sugi-kubernetes110-node01.localdomain
persistent-deployment-b9db64785-rtbk7   1/1       Running   0          2m        10.244.2.28   sugi-kubernetes110-node02.localdomain

なんと、PVを ReadWriteOnceとして作成していましたが、複数のNodeに接続がされています。
node01 と node02 のそれぞれのコンテナ上でファイルを作成することが出来ます。
バグなのかなんなのかはよくわかりません。。。

2番目のPodでも正常に書き込める

root@persistent-deployment-b9db64785-rtbk7:/persistent-volume# touch test_from_pod02
root@persistent-deployment-b9db64785-rtbk7:/persistent-volume# ls -la
total 0
drwxr-xr-x 2 root root 50 Jun  1 06:59 .
drwxr-xr-x 1 root root 53 Jun  1 06:50 ..
-rw-r--r-- 1 root root  0 Jun  1 06:26 test_from_pod
-rw-r--r-- 1 root root  0 Jun  1 06:59 test_from_pod02
root@persistent-deployment-b9db64785-rtbk7:/persistent-volume# 
root@persistent-deployment-b9db64785-rtbk7:/persistent-volume# pwd
/persistent-volume

Pod をオートヒーリングしたときのPVとの関係を確認

Podの1個目を削除して、ReplicaSetによりオートヒーリングを発生させます。

[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl delete pod persistent-deployment-b9db64785-7fq4z
pod "persistent-deployment-b9db64785-7fq4z" deleted

新たなPodが作成されます

[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl get pods -o wide
NAME                                    READY     STATUS    RESTARTS   AGE       IP            NODE
persistent-deployment-b9db64785-rtbk7   1/1       Running   0          53m       10.244.2.28   sugi-kubernetes110-node02.localdomain
persistent-deployment-b9db64785-vfcd5   1/1       Running   0          27s       10.244.1.30   sugi-kubernetes110-node01.localdomain

オートヒーリングされたPodを確認すると、こちらでも引き続き PV を使用していることがわかります。
削除前に作っていたファイルが確認できます

[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl exec -it persistent-deployment-b9db64785-vfcd5 bash
root@persistent-deployment-b9db64785-vfcd5:/# ls -la /persistent-volume/
total 0
drwxr-xr-x 2 root root 50 Jun  1 06:59 .
drwxr-xr-x 1 root root 53 Jun  1 07:43 ..
-rw-r--r-- 1 root root  0 Jun  1 06:26 test_from_pod
-rw-r--r-- 1 root root  0 Jun  1 06:59 test_from_pod02

DeploymentとPVCの関係まとめ

Deploymentで作成されたPodは全て、同一のPVを参照する動作となる。
今回はNFSをPVとして作成したため、ReadWriteAnyが許されており、複数PodからMountが出来ている。
しかし、AWSElasticBlockStoreやAWSElasticBlockStoreでは、ReadWriteManyが出来ないため、
DeploymentにPVを紐づけると、Replicaを2以上にすることは出来ないと予想出来る。

001.png

Pod に障害が発生して、オートヒーリングを実施した際にも、PV は引き続き同じものをmountすることが出来ます。

002.png

Persistent VolumeとStatefulSetの紐づけ検証

NFSサーバでPV用の領域をExport

StatefulSet として2個のPod を作成します。その前準備として、PV を2個作成するために、NFS Export を2個設定します

[root@sugi-nfs mnt]# mkdir /mnt/pv002
[root@sugi-nfs mnt]# mkdir /mnt/pv003
[root@sugi-nfs mnt]# vi /etc/exports
/mnt/pv002 *(rw,async,no_root_squash)
/mnt/pv003 *(rw,async,no_root_squash)

export point を再読み込み

[root@sugi-nfs mnt]# exportfs -ra
[root@sugi-nfs mnt]# exportfs -v
/mnt/pv002      <world>(rw,async,wdelay,hide,no_subtree_check,sec=sys,secure,no_root_squash,no_all_squash)
/mnt/pv003      <world>(rw,async,wdelay,hide,no_subtree_check,sec=sys,secure,no_root_squash,no_all_squash)

Persistent Volume の作成

cat <<'EOF' > /root/kube_yaml/persistent_volume/persistent_volume_002.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv002
spec:
  capacity:
    storage: 1Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  # storageClassName: slow
  mountOptions:
    - hard
  nfs:
    server: 192.168.120.230
    path: /mnt/pv002
EOF
cat <<'EOF' > /root/kube_yaml/persistent_volume/persistent_volume_003.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv003
spec:
  capacity:
    storage: 1Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  # storageClassName: slow
  mountOptions:
    - hard
  nfs:
    server: 192.168.120.230
    path: /mnt/pv003
EOF

PVを作成します

[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl create -f /root/kube_yaml/persistent_volume/persistent_volume_002.yaml
persistentvolume "pv002" created
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl create -f /root/kube_yaml/persistent_volume/persistent_volume_003.yaml
persistentvolume "pv003" created

確認します

[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl get pv
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM                STORAGECLASS   REASON    AGE
pv0001    1Gi        RWO            Recycle          Bound       default/test-claim   slow                     4h
pv002     1Gi        RWO            Recycle          Available                                                 8s
pv003     1Gi        RWO            Recycle          Available                                                 6s

StatefulSetの作成

StatefulSet の YAML を定義します

cat <<'EOF' > /root/kube_yaml/persistent_volume/persistent_volume_statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: persistent-stateset
spec:
  serviceName: nginx-service
  replicas: 2
  selector:
    matchLabels:
      app: persistent-stateful
  template:
    metadata:
      labels:
        app: persistent-stateful
    spec:
      containers:
        - name: nginx-container
          image: nginx
          ports:
            - containerPort: 80
          volumeMounts:
          - name: pvc-volume
            mountPath: /persistent-volume
  volumeClaimTemplates:
  - metadata:
      name: pvc-volume
    spec:
      accessModes:
      - ReadWriteOnce
      volumeMode: Filesystem
      resources:
        requests:
          storage: 1Gi
EOF

StatefulSet を作成します

kubectl create -f /root/kube_yaml/persistent_volume/persistent_volume_statefulset.yaml
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl get statefulset -o wide
NAME                  DESIRED   CURRENT   AGE       CONTAINERS        IMAGES
persistent-stateset   2         2         29s       nginx-container   nginx

pvcが自動的に作成されています

[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl get pvc -o wide
NAME                               STATUS    VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
pvc-volume-persistent-stateset-0   Bound     pv002     1Gi        RWO                           1m
pvc-volume-persistent-stateset-1   Bound     pv003     1Gi        RWO                           51s
test-claim                         Bound     pv0001    1Gi        RWO            slow           2h

PVの一覧でも、PVCに bound されていることを確認できます

Deployment とは違い、Pod ごとに PV が接続されています

[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl get pv -o wide
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS    CLAIM                                      STORAGECLASS   REASON    AGE
pv0001    1Gi        RWO            Recycle          Bound     default/test-claim                         slow                     4h
pv002     1Gi        RWO            Recycle          Bound     default/pvc-volume-persistent-stateset-0                            18m
pv003     1Gi        RWO            Recycle          Bound     default/pvc-volume-persistent-stateset-1                            18m

StatefulSet の Pod も作成されています

[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl get pods -o wide
NAME                    READY     STATUS    RESTARTS   AGE       IP            NODE
persistent-stateset-0   1/1       Running   0          2m        10.244.1.32   sugi-kubernetes110-node01.localdomain
persistent-stateset-1   1/1       Running   0          2m        10.244.2.31   sugi-kubernetes110-node02.localdomain

Pod に割り当てられている PVC を確認すると、PVC が紐づけされていることがわかります

# kubectl describe pod persistent-stateset-0

snip 

Volumes:
  pvc-volume:
    Type:       PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
    ClaimName:  pvc-volume-persistent-stateset-0
    ReadOnly:   false
  default-token-q65hj:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-q65hj
    Optional:    false
# kubectl describe pod persistent-stateset-1

snip

Volumes:
  pvc-volume:
    Type:       PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
    ClaimName:  pvc-volume-persistent-stateset-1
    ReadOnly:   false
  default-token-q65hj:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-q65hj
    Optional:    false

それぞれのPodにログインし、test file を作成します

[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl exec -it persistent-stateset-0 bash
root@persistent-stateset-0:/# df -h
Filesystem                  Size  Used Avail Use% Mounted on
overlay                      14G  3.5G   10G  26% /
tmpfs                       1.9G     0  1.9G   0% /dev
tmpfs                       1.9G     0  1.9G   0% /sys/fs/cgroup
192.168.120.230:/mnt/pv002   14G  1.5G   12G  11% /persistent-volume
/dev/mapper/cl-root          14G  3.5G   10G  26% /etc/hosts
shm                          64M     0   64M   0% /dev/shm
tmpfs                       1.9G   12K  1.9G   1% /run/secrets/kubernetes.io/serviceaccount
tmpfs                       1.9G     0  1.9G   0% /proc/scsi
tmpfs                       1.9G     0  1.9G   0% /sys/firmware
root@persistent-stateset-0:/# touch /persistent-volume/testfile-frompod-0 
root@persistent-stateset-0:/# ls -la /persistent-volume/
total 0
drwxr-xr-x 2 root root 32 Jun  1 08:57 .
drwxr-xr-x 1 root root 65 Jun  1 08:48 ..
-rw-r--r-- 1 root root  0 Jun  1 08:57 testfile-frompod-0
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl exec -it persistent-stateset-1 bash
root@persistent-stateset-1:/# df -h
Filesystem                  Size  Used Avail Use% Mounted on
overlay                      14G  4.1G  9.4G  31% /
tmpfs                       1.9G     0  1.9G   0% /dev
tmpfs                       1.9G     0  1.9G   0% /sys/fs/cgroup
192.168.120.230:/mnt/pv003   14G  1.5G   12G  11% /persistent-volume
/dev/mapper/cl-root          14G  4.1G  9.4G  31% /etc/hosts
shm                          64M     0   64M   0% /dev/shm
tmpfs                       1.9G   12K  1.9G   1% /run/secrets/kubernetes.io/serviceaccount
tmpfs                       1.9G     0  1.9G   0% /proc/scsi
tmpfs                       1.9G     0  1.9G   0% /sys/firmware
root@persistent-stateset-1:/# touch /persistent-volume/testfile-frompod-1
root@persistent-stateset-1:/# ls -la /persistent-volume/
total 0
drwxr-xr-x 2 root root 32 Jun  1 08:57 .
drwxr-xr-x 1 root root 53 Jun  1 08:48 ..
-rw-r--r-- 1 root root  0 Jun  1 08:57 testfile-frompod-1

NFSサーバを確認すると、それぞれの Export Point で、test file が作成されていることを確認できます

[root@sugi-nfs mnt]# ls -la /mnt/pv002/
total 0
drwxr-xr-x  2 root root 32 Jun  1 17:57 .
drwxr-xr-x. 5 root root 47 Jun  1 17:10 ..
-rw-r--r--  1 root root  0 Jun  1 17:57 testfile-frompod-0
[root@sugi-nfs mnt]# 
[root@sugi-nfs mnt]# ls -la /mnt/pv003/
total 0
drwxr-xr-x  2 root root 32 Jun  1 17:57 .
drwxr-xr-x. 5 root root 47 Jun  1 17:10 ..
-rw-r--r--  1 root root  0 Jun  1 17:57 testfile-frompod-1

Pod をオートヒーリングしたときのPVとの関係を確認

Podの1個目を削除して、StatefulSet によりオートヒーリングを発生させます。

削除した直後に Pod がオートヒーリングされることを確認できます

[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl delete pod persistent-stateset-0
pod "persistent-stateset-0" deleted
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# 
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl get pod
NAME                    READY     STATUS        RESTARTS   AGE
persistent-stateset-0   0/1       Terminating   0          14m
persistent-stateset-1   1/1       Running       0          14m
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# 
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl get pod
NAME                    READY     STATUS        RESTARTS   AGE
persistent-stateset-0   0/1       Terminating   0          14m
persistent-stateset-1   1/1       Running       0          14m
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# 
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl get pod
NAME                    READY     STATUS        RESTARTS   AGE
persistent-stateset-0   0/1       Terminating   0          14m
persistent-stateset-1   1/1       Running       0          14m
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# 
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl get pod
NAME                    READY     STATUS    RESTARTS   AGE
persistent-stateset-0   0/1       Pending   0          0s
persistent-stateset-1   1/1       Running   0          14m
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# 
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl get pod
NAME                    READY     STATUS              RESTARTS   AGE
persistent-stateset-0   0/1       ContainerCreating   0          2s
persistent-stateset-1   1/1       Running             0          14m
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# 
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl get pod
NAME                    READY     STATUS              RESTARTS   AGE
persistent-stateset-0   0/1       ContainerCreating   0          3s
persistent-stateset-1   1/1       Running             0          14m

オートヒーリングされたPodを確認すると、こちらでも引き続き PV を使用していることがわかります。
削除前に作っていたファイルが確認できます

[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl exec -it persistent-stateset-0 bash
root@persistent-stateset-0:/# ls -la /persistent-volume/
total 0
drwxr-xr-x 2 root root 32 Jun  1 08:57 .
drwxr-xr-x 1 root root 53 Jun  1 09:02 ..
-rw-r--r-- 1 root root  0 Jun  1 08:57 testfile-frompod-0

StatefulSet と PVC の関係まとめ

StatefulSet で作成された Pod は、それぞれ単一の PV をマウントしています
Deployment では、全てのPodで1個のPV をマウントしている違いがあります

003.png

Pod に障害が発生し、オートヒーリングを実施した際にも、同一のPVを引き続き mount するため、データの永続性を担保することが出来ます。

004.png

参考URL

39
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
sugimount
投稿している内容は個人的な見解なので、所属組織とは関係ありません

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
39
Help us understand the problem. What is going on with this article?