Skip to content
Published on

etcdバックアップ&リストア完全ガイド — CKA試験必須ハンズオン

Authors
  • Name
    Twitter

1. etcdとは何か?

etcdはKubernetesクラスタのすべての状態データを保存する分散Key-Valueストアである。Pod、Service、ConfigMap、Secret、RBACポリシーなど、クラスタに存在するすべてのリソース情報がetcdに格納されている。

簡単に言えば、kubectl getコマンドで表示されるものはすべて、最終的にetcdから取得したデータである。

┌─────────────────────────────────────────────┐
Kubernetes Control Plane│                                             │
│  kube-apiserver ──── etcd (全状態を保存)│       │                                     │
│  kube-scheduler    kube-controller-manager   │
└─────────────────────────────────────────────┘

なぜetcdバックアップが重要なのか?

  • etcdが消失するとクラスタ全体が失われる(Pod、Service、Secretすべて)
  • 不適切なアップグレードや操作ミスでクラスタが壊れた際の唯一の復旧手段
  • CKA試験でほぼ毎回出題される必須トピック

2. 事前準備:etcd情報の確認

2.1 etcd Podの確認

kubeadmでインストールしたクラスタでは、etcdはStatic Podとして実行される:

# etcd Podの確認
kubectl get pods -n kube-system | grep etcd

# 出力例
# etcd-controlplane   1/1   Running   0   45m

2.2 etcd証明書の場所確認(最重要!)

etcdはTLSで通信するため、証明書パスを正確に把握する必要がある:

# etcd Podの実行引数から証明書パスを確認
kubectl describe pod etcd-controlplane -n kube-system | grep -E "cert|key|cacert|data-dir"

一般的なパス:

項目パス
CA証明書/etc/kubernetes/pki/etcd/ca.crt
サーバー証明書/etc/kubernetes/pki/etcd/server.crt
サーバーキー/etc/kubernetes/pki/etcd/server.key
データディレクトリ/var/lib/etcd
エンドポイントhttps://127.0.0.1:2379

2.3 etcdctlのインストール確認

# etcdctlバージョン確認
ETCDCTL_API=3 etcdctl version

# 未インストールの場合(Ubuntu)
apt-get install etcd-client

# またはetcd Pod内部で実行
kubectl exec -it etcd-controlplane -n kube-system -- etcdctl version

CKA試験のヒントETCDCTL_API=3を必ず設定すること。API v2はsnapshotコマンドをサポートしていない。


3. etcdの状態確認

バックアップ前に、現在のetcdクラスタが正常であることを確認する:

# 環境変数の設定(毎回入力する手間を省くため)
export ETCDCTL_API=3
export ETCDCTL_CACERT=/etc/kubernetes/pki/etcd/ca.crt
export ETCDCTL_CERT=/etc/kubernetes/pki/etcd/server.crt
export ETCDCTL_KEY=/etc/kubernetes/pki/etcd/server.key
export ETCDCTL_ENDPOINTS=https://127.0.0.1:2379

# クラスタヘルスチェック
etcdctl endpoint health
# 出力: https://127.0.0.1:2379 is healthy: took = 2.345ms

# メンバー一覧確認
etcdctl member list --write-out=table

# 保存されているキー数の確認
etcdctl get / --prefix --keys-only | wc -l

4. etcdバックアップ(スナップショット)

4.1 スナップショット作成

ETCDCTL_API=3 etcdctl snapshot save /opt/etcd-backup.db \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key

4.2 スナップショット検証

ETCDCTL_API=3 etcdctl snapshot status /opt/etcd-backup.db --write-out=table

出力例:

+----------+----------+------------+------------+
|   HASH   | REVISION | TOTAL KEYS | TOTAL SIZE |
+----------+----------+------------+------------+
| 3e9a843c |    12450 |       1287 |     5.8 MB |
+----------+----------+------------+------------+

注意snapshot verifyコマンドはDBを破損させる可能性があるとの報告があるため、snapshot statusのみで確認すること。

4.3 自動バックアップCronJob

プロダクションではCronJobで定期バックアップを構成する:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: etcd-backup
  namespace: kube-system
spec:
  schedule: '0 */6 * * *'
  jobTemplate:
    spec:
      template:
        spec:
          hostNetwork: true
          containers:
            - name: backup
              image: bitnami/etcd:3.5
              command:
                - /bin/sh
                - -c
                - |
                  etcdctl snapshot save /backup/etcd-$(date +%Y%m%d-%H%M%S).db \
                    --endpoints=https://127.0.0.1:2379 \
                    --cacert=/etc/kubernetes/pki/etcd/ca.crt \
                    --cert=/etc/kubernetes/pki/etcd/server.crt \
                    --key=/etc/kubernetes/pki/etcd/server.key
                  find /backup -name "etcd-*.db" -mtime +7 -delete
              env:
                - name: ETCDCTL_API
                  value: '3'
              volumeMounts:
                - name: etcd-certs
                  mountPath: /etc/kubernetes/pki/etcd
                  readOnly: true
                - name: backup
                  mountPath: /backup
          restartPolicy: OnFailure
          nodeSelector:
            node-role.kubernetes.io/control-plane: ''
          tolerations:
            - effect: NoSchedule
              operator: Exists
          volumes:
            - name: etcd-certs
              hostPath:
                path: /etc/kubernetes/pki/etcd
            - name: backup
              hostPath:
                path: /opt/etcd-backups

5. etcdリストア(復元)

5.1 復元手順(ステップバイステップ)

Step 1:スナップショットを新しいデータディレクトリに復元

ETCDCTL_API=3 etcdctl snapshot restore /opt/etcd-backup.db \
  --data-dir=/var/lib/etcd-from-backup \
  --initial-cluster=controlplane=https://127.0.0.1:2380 \
  --initial-cluster-token=etcd-cluster-1 \
  --initial-advertise-peer-urls=https://127.0.0.1:2380

重要ポイント--data-dirは既存の/var/lib/etcdではなく、新しいパスを指定すること!

Step 2:etcd Podのデータディレクトリを変更

vi /etc/kubernetes/manifests/etcd.yaml

変更箇所:

# Before
volumes:
- hostPath:
    path: /var/lib/etcd
    type: DirectoryOrCreate
  name: etcd-data

# After — 新しいパスに変更!
volumes:
- hostPath:
    path: /var/lib/etcd-from-backup
    type: DirectoryOrCreate
  name: etcd-data

Step 3:etcd Podの再起動を待つ

# Static Podなのでkubeletが自動的に再起動する
watch "kubectl get pods -n kube-system | grep etcd"

# またはcrictlで直接確認
crictl ps | grep etcd

Step 4:復元の確認

kubectl get nodes
kubectl get pods --all-namespaces

ETCDCTL_API=3 etcdctl endpoint health \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key

6. トラブルシューティング

6.1 etcdctl: command not found

# CKA試験でよく発生する問題!
# 解決策1:フルパスを指定
/usr/local/bin/etcdctl version

# 解決策2:etcd Pod内部で実行
kubectl exec -it etcd-controlplane -n kube-system -- sh

# 解決策3:SSHしてsudo
sudo -i
export PATH=$PATH:/usr/local/bin

6.2 復元後にetcd Podが起動しない

# ログを確認
crictl logs $(crictl ps -a | grep etcd | awk '{print $1}')

# よくある原因1:パーミッション問題
chown -R etcd:etcd /var/lib/etcd-from-backup

# よくある原因2:data-dirパスの不一致
# etcd.yamlのvolumes.hostPath.pathと実際の復元パスを確認

# よくある原因3:initial-cluster-tokenの不一致

6.3 "context deadline exceeded"エラー

# 原因:etcdがまだ完全に起動していない
# 解決策:30〜60秒待ってからリトライ

7. CKA試験チートシート

# 1. バックアップ
ETCDCTL_API=3 etcdctl snapshot save /opt/backup.db \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key

# 2. リストア
ETCDCTL_API=3 etcdctl snapshot restore /opt/backup.db \
  --data-dir=/var/lib/etcd-from-backup

# 3. etcd.yamlのdata-dir変更(ワンライナー)
sed -i 's|/var/lib/etcd|/var/lib/etcd-from-backup|g' \
  /etc/kubernetes/manifests/etcd.yaml

# 4. 状態確認
ETCDCTL_API=3 etcdctl snapshot status /opt/backup.db -w table

試験のヒント:証明書パスを暗記せず、kubectl describe pod etcd-controlplane -n kube-systemからそのままコピーすること!


8. 外部etcdクラスタの場合

# kube-apiserverからetcdエンドポイントを確認
cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep etcd-servers

# SSHでetcdノードに接続してバックアップ/リストア
# 証明書パスが異なる場合がある(/etc/etcd/pki/)
# リストア後:systemctl restart etcd

9. 重要ポイントまとめ

操作コマンド注意事項
バックアップetcdctl snapshot saveETCDCTL_API=3必須、証明書3つ
検証etcdctl snapshot statusverifyではなくstatusを使用
リストアetcdctl snapshot restore新しいdata-dirの指定が必須
適用etcd.yamlを編集hostPathパスを変更
確認etcdctl endpoint health再起動後30〜60秒待機

CKAの流れ:describe -> 証明書コピー -> save/restore -> yaml編集。以上!


References