🐥

kubeadmでStatefulSetをローカルストレージで構築する

2021/09/05に公開

kubeadmでStatefulSetを構築するにはストレージの構築が事前に必要です.
構築されていない場合は Persistent VolumeStorage Class リソースがありません.

% kubectl get pv,sc
No resources found

TL; DR

  • StatefulSetが利用するボリュームを Persistent Volume で用意する
  • Persistent Volume を用意するためのストレージ Storage Class をローカルに構築する.

kubeadmでStatefulSetをローカストレージで構築する

kubeadmはStatefulSetを利用するために Storage Classを事前に設定します.
この例では local volume plugin を利用します.

ストレージの作成

StatefulSetが消費するPersistenVolume用のストレージを作成します.
kubernetes.io/no-provisioner がローカルストレージを表しています.

% cat ext-storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
% kubectl apply -f ext-storageclass.yaml
storageclass.storage.k8s.io/local-storage created
% kubectl get sc
NAME            PROVISIONER                    RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
local-storage   kubernetes.io/no-provisioner   Delete          WaitForFirstConsumer   false                  3s

PersistentVolumeの作成

StatefulSetが消費する Persistent Volume (以下,PV)を作成します.
PVにはローカルストレージ用のlocal volumeで作成します.

StatefulSetのスケールアウト・スケールインを検証するためにworker 2ノードにそれぞれPVを2つ作成します.

ext-local-pv/
  ext-pv-k8s2-pv01.yaml # k8s2 worker node, /mnt/disks/ssd1にマウント
  ext-pv-k8s2-pv02.yaml # k8s2 worker node, /mnt/disks/ssd2にマウント
  ext-pv-k8s3-pv01.yaml # k8s3 worker node, /mnt/disks/ssd1にマウント
  ext-pv-k8s3-pv02.yaml # k8s3 worker node, /mnt/disks/ssd2にマウント

PVはマウント先に合わせて次のパラメータを変更します.

  • metadata.name: 固有のボリューム名
  • spec.storageClassName: 固有のストレージ名
  • spec.local: ボリュームのマウント先,マウント先のノードに予め作っておく
  • spec.nodeAffinity.required.nodeSelectorTerms.matchExpressions[].key[].values[]: ボリュームを配置するノード名
% cat ext-local-pv/ext-pv-k8s2-pv01.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: sample-pv-k8s2-pv01
spec:
  capacity:
    storage: 1Gi
  volumeMode: Filesystem
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Delete
  storageClassName: local-storage
  local:
    path: /mnt/disks/ssd1
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - k8s2

workerノードでマウント先のディレクトリを作っておきます.

% sudo mkdir -p /mnt/disks/ssd{1,2}; sudo chmod 777 /mnt/disks/ssd{1,2}

Manifestを適用すると4つのPVがストレージ名 local-storageAvailable と表示され利用可能なことが分かります.

% kubectl apply -f ext-local-pv
persistentvolume/sample-pv-k8s2-pv01 created
persistentvolume/sample-pv-k8s2-pv02 created
persistentvolume/sample-pv-k8s3-pv01 created
persistentvolume/sample-pv-k8s3-pv02 created
% kubectl get pv
NAME                  CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS    REASON   AGE
sample-pv-k8s2-pv01   1Gi        RWO            Delete           Available           local-storage            4s
sample-pv-k8s2-pv02   1Gi        RWO            Delete           Available           local-storage            4s
sample-pv-k8s3-pv01   1Gi        RWO            Delete           Available           local-storage            4s
sample-pv-k8s3-pv02   1Gi        RWO            Delete           Available           local-storage            4s

StatefulSetの生成

StatefulSet リソースを生成する準備が整ったのでmanifestを用意します.

Kubernetes完全ガイド第5章 の内容にローカルストレージからボリュームを払い出すための spec.storageClassName を追加しています.

% cat sample-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: sample-statefulset
spec:
  serviceName: sample-statefulset
  replicas: 3
  selector:
    matchLabels:
      app: sample-app
  template:
    metadata:
      labels:
        app: sample-app
    spec:
      containers:
      - name: nginx-container
        image: nginx:1.16
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes:
      - ReadWriteOnce
      storageClassName: local-storage
      resources:
        requests:
          storage: 1Gi

Manifestを適用すると,StatefulSetのレプリカ数3に対応して3つのPVが Bond と割り当てられていることが分かります.

% kubectl apply -f sample-statefulset.yaml
statefulset.apps/sample-statefulset created
% kubectl get sts,pv
NAME                                  READY   AGE
statefulset.apps/sample-statefulset   3/3     11s

NAME                                   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM                              STORAGECLASS    REASON   AGE
persistentvolume/sample-pv-k8s2-pv01   1Gi        RWO            Delete           Bound       default/www-sample-statefulset-2   local-storage            8m25s
persistentvolume/sample-pv-k8s2-pv02   1Gi        RWO            Delete           Available                                      local-storage            8m25s
persistentvolume/sample-pv-k8s3-pv01   1Gi        RWO            Delete           Bound       default/www-sample-statefulset-0   local-storage            8m25s
persistentvolume/sample-pv-k8s3-pv02   1Gi        RWO            Delete           Bound       default/www-sample-statefulset-1   local-storage            8m25s

Discussion