StatefulSet の PersistentVolume のバックアップを取る方法はいくつかあります。個人的には AWS ブログでも紹介されている Velero が良いと思いますが、導入が少し面倒です。もう少し手軽な方法として、EBS ボリュームのスナップショットによるバックアップとリストアを試してみたので備忘録。AWS の機能だけで手軽にバックアップが取れるので、選択肢として知っておくとよいかと思います。
動作確認をした EKS のバージョンは 1.25 です。
目次
- StatefulSet を作成する
- ストレージへデータを書き込む
- PersistentVolumeClaim(PVC) の情報を取得する
- PersistentVolume(PV) の情報を取得する
- EBS ボリュームのスナップショットを作成する
- スナップショットから新しい EBS ボリュームを作成する
- リソースを削除する
- PV を作成する
- PVC を作成する
- StatefulSet を再作成する
StatefulSet を作成する
StatefulSet Basics | Kubernetes のサンプルを参考に動作確認用の StatefulSet を作成します。
web.yaml を作成します。
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx"
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: registry.k8s.io/nginx-slim:0.8
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi
StatefulSet を作成します。
kubectl apply -f web.yaml
動作確認
kubectl get po
Pod が Running になっていれば OK です。
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 2m
ストレージへデータを書き込む
index.html を作成します。これで EBS にデータが書き込まれます。
kubectl exec web-0 -- sh -c 'echo "$(hostname)" > /usr/share/nginx/html/index.html'
リクエストを送信して index.html の内容を確認します。web-0 とホスト名が表示されれば OK です。
kubectl exec -i -t web-0 -- curl http://localhost/
web-0
PersistentVolumeClaim(PVC) の情報を取得する
StatefulSet により作成された PVC の情報をファイルに出力しておきます。
kubectl get pvc www-web-0 -o yaml > pvc.yaml
PersistentVolume の情報を後で使うのでメモしておきます。
kubectl get pvc www-web-0 -o jsonpath='{.spec.volumeName}'
pvc-c573891d-7e86-4186-b4b4-39a3bfc2a126
PersistentVolume(PV) の情報を取得する
StatefulSet により作成された PV の情報をファイルに出力しておきます。
kubectl get pv pvc-c573891d-7e86-4186-b4b4-39a3bfc2a126 -o yaml > pv.yaml
EBS の VolumeID と zone を後で使うのでメモしておきます。
kubectl get pv pvc-c573891d-7e86-4186-b4b4-39a3bfc2a126 -o jsonpath='{.spec.awsElasticBlockStore.volumeID} {.metadata.labels.topology\.kubernetes\.io/zone}'
vol-03ca5f9fa09254358 ap-northeast-1a
EBS ボリュームのスナップショットを作成する
スナップショットを作成します。AWS マネジメントコンソールでスナップショットを作成しても良いです。
aws ec2 create-snapshot --volume-id vol-03ca5f9fa09254358 --region ap-northeast-1 --description 'Created from pvc www-web-0' --tag-specifications 'ResourceType=snapshot,Tags=[{Key=Name,Value=pvc-www-web-0}]'
作成されたスナップショット ID をメモしておきます。
{
...
"SnapshotId": "snap-04da0777d3afe3a8e",
...
}
スナップショットから新しい EBS ボリュームを作成する
ここからがリストアの手順になります。
先程メモしたスナップショット ID を使って、新しい EBS ボリュームを作成します。AWS マネジメントコンソールから EBS を作成しても良いです。
aws ec2 create-volume --snapshot-id snap-04da0777d3afe3a8e --volume-type gp2 --region ap-northeast-1 --availability-zone ap-northeast-1a --tag-specifications 'ResourceType=volume,Tags=[{Key=Name,Value=pvc-www-web-0}]'
作成された EBS のボリューム ID をメモします。
{
...
"VolumeId": "vol-0c56be5881814274a",
...
}
リソースを削除する
StatefulSet を削除します。
kubectl delete sts web
PVC を削除します。PV も削除されるので最初に作成された EBS ボリュームが削除されます。
kubectl delete pvc www-web-0
PV を作成する
以下のコマンドを参考に PV を作成します。spec.volumeID
はスナップショットから作成した EBS ボリュームの ID にします。zone
スナップショットから作成した EBS の AZ と同じにします。そのほかの内容は先程ファイルに出力した pv.yaml を参考に置き換えます。
cat <<'EOF' | kubectl create -f -
apiVersion: v1
kind: PersistentVolume
metadata:
labels:
topology.kubernetes.io/region: ap-northeast-1
topology.kubernetes.io/zone: ap-northeast-1a
name: pvc-c573891d-7e86-4186-b4b4-39a3bfc2a126
spec:
accessModes:
- ReadWriteOnce
awsElasticBlockStore:
fsType: ext4
volumeID: vol-0c56be5881814274a
capacity:
storage: 1Gi
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: topology.kubernetes.io/zone
operator: In
values:
- ap-northeast-1a
- key: topology.kubernetes.io/region
operator: In
values:
- ap-northeast-1
persistentVolumeReclaimPolicy: Delete
storageClassName: gp2
volumeMode: Filesystem
EOF
PVC を作成する
PVC を作成します。spec.volumeName
は一つ前の手順で作成した PV の metadata.name
と同じにします。その他の内容は先程ファイルに出力した pvc.yaml を参考にして合わせます。
cat <<'EOF' | kubectl create -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
labels:
app: nginx
name: www-web-0
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: gp2
volumeMode: Filesystem
volumeName: pvc-c573891d-7e86-4186-b4b4-39a3bfc2a126
EOF
PVC の STATUS が Bound になるまで待ちます。
kubectl get pvc www-web-0
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
www-web-0 Bound pvc-c573891d-7e86-4186-b4b4-39a3bfc2a126 1Gi RWO gp2 11m
StatefulSet を再作成する
もう一度 StatefulSet を作ります。
kubectl apply -f web.yaml
Pod の STATUS が Running になるまで待ちます。
kubectl get po
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 2m
書き込んだ情報が復元されているか確認します。ホスト名が表示されれば EBS の情報が復元されています。
kubectl exec -i -t web-0 -- curl http://localhost/
web-0