OpenShift / Kubernetesクラスタのバックアップと復元
今回は、OpenShiftのドキュメントから、クラスタのバックアップと復元について紹介します。
ディザスタリカバリーを想定したドキュメントですが、OpenShiftやKubernetesのバージョンをアップデートするとき、新しいクラスタを立ててから古いクラスタを削除するというBlueGreen的なアプローチで行うときにもこの手順が参考になります。
概要
Kubernetesは(OpenShiftも)、クラスタの状態は全てetcd
に格納されています。
クラスタのバックアップと復元というのは、etcd
のバックアップと復元を意味します。
なので、このドキュメントの大部分はetcdの復元方法について記載されています。
しかし、OpenShiftの場合、oc export all
でProject(namespace)の全部をエクスポートできるので、それでバックアップを取ることもできます。
Kubernetesでも、kubectl get --export
を駆使すれば同じようにyamlでクラスタをエクスポートできます。
「クラスタのバックアップと復元」の方法として、大きく以下の二つがあるわけです。
- [低レベル方式] 普段etcdをバックアップしておく。Kubernetesクラスタ復元の際は、まずetcdを復元し、クラスタを再インストールする復元したetcdを参照する新規クラスタを立てる
- [高レベル方式] クラスタの状態をyamlにexportしてバックアップしておく。Kubernetes復元の際は、新規Kubernetesクラスタを立てて、そこにバックアップしたyamlをインポートする
Kubernetesだと、export
するAPIオブジェクトの種別が増えたり減ったりするかもしれないですし、低レベル方式のほうが安心感がありますね。
(ただ、etcdのバックアップと復元は、KubernetesノードのIPが変わると復元したクラスタの動作がうまく行かなかったりしたので、不安が残る)
OpenShift Container Platformでは、クラスタレベルでのバックアップ(現在の状態を隔離されたストレージに保存)し、復元(隔離されたストレージからクラスタの状態を再現する)ことができます。
また、補助的なものとして、プロジェクトごとのバックアップも可能です。
「クラスタの状態」を構成するものは以下の4つです。
- etcdのデータ
- APIオブジェクト
- イメージレジストリのストレージ
- Volumeのストレージ
ここでは、永続ストレージのバックアップと復元については触れません。ストレージの実装に依存するからです。
しかし、アプリケーションデータのバックアップをどのように行うかの一般的な例を紹介します。
Kubernetes上で動いているアプリケーションはPVを通して永続ストレージを使用している場合があり、
その場合はもちろん、永続ストレージも復元する必要があります。
永続ストレージは、バックエンドの製品ごとに様々なバックアップ方法があるわけですが、
このドキュメントでは「コンテナの永続状態はアタッチされているボリュームにのみ保存されているはず」という観点から、
デプロイ設定のPVのパスに対してrsyncでバックアップと復元を行なっています。
! 注意
このドキュメントは、アプリケーションとOpenShiftクラスタのバックアップ方法について、一般論的に記載したものです。
様々な特殊な要件について考慮されているわけではありません。
実際には、そのような要件も考慮して、独自の完全なバックアップ手順を確率しなければなりません。
データの紛失を防ぐために、必要な予防措置を取ってください。etcdのバックアップには、ストレージボリュームの参照情報が含まれていることに注意してください。
etcdをバックアップから復元すると、OpenShiftは、バックアップ時のpodをノード上で起動し、また同じストレージをアタッチしようとします。
これは実際、OpenShiftからノードを削除してから新しいノードを追加したときの挙動と変わりません。
ノードにアタッチされていた全てのストレージは、podがどのノードに再スケジュールされても再度podにアタッチされます。! 注意
バックアップと復元は、特に保証のあるプロセスではなく、自分のデータを保全する責任はユーザーにあります。
前提条件
- 復元処理は完全な再インストールを伴うので、最初のインストール時に使用したすべてのファイルを保存しておいてください。 これには、以下のものが含まれます。
~/.config/openshift/installer.cfg.yml
(クイックインストールの場合)- Ansibleのplaybookとインベントリファイル (アドバンスドインストールの場合)
/etc/yum.repos.d/ose.repo
(ネットワークが繋がらない環境でインストールした場合)- インストールした後に何か追加処理を実施した場合、その手順を再現できるようにバックアップを取っておいてください。インストーラーに含まれていないインストール処理が実施されているかもしれません。例えば、OpenShiftの制御下にない外部サービスの変更や、監視エージェントのような追加サービスのインストールなどです。さらに、アドバンスドインストールでもサポートされていないOpenShiftの設定を変更した場合も気をつける必要があります。例えば、複数の認証方法のサポートなどです。
- 必要なコマンドラインツールをパッケージからインストールしておきます。
yum install etcd
4: コンテナベースのインストーラーを使っている場合は、代わりにetcdのイメージをpullしておきます。
docker pull rhel7/etcd
etcdのデータディレクトリ(以下のセクションでの
$ETCD_DATA_DIR
)は、どのようにetcdをデプロイしたかでパスが変わってくるので注意してください。
デプロイの種類 データディレクトリ all-in-one cluster /var/lib/origin/openshift.local.etcd 外部etcd(masterや他のホストにある場合) /var/lib/etcd ! 注意
組み込みのetcdは、OpenShift Container Platform 3.7からサポートされなくなりました。
詳しくは組み込みのetcdを外部etcdに移行するを参照してください。
OpenShift Container Platformの3.6までは、OpenShiftのmasterに組み込まれたetcdでOpenShiftのクラスタを構築することができ、別途etcdクラスタを用意しなくていいというオプションがありました。
OpenShift 3.7からはそのオプションはサポートされなくなり、OpenShiftと別にetcdクラスタを用意する必要があります。
(OpenShiftのインストーラーは、etcdクラスタもいっしょに構築できるのでインストール時にはあまり意識しないかもしれませんが)
組み込みのetcdの場合、etcdのデータディレクトリが普通のetcdと違う場所にあるので、気をつけましょうという記載です。
クラスタのバックアップ
Masterのバックアップ
各masterにある証明書を全て保存してください。
cd /etc/origin/master tar cf /tmp/certs-and-keys-$(hostname).tar *.key *.crt
etcdのバックアップ
etcdが一つ以上のホストで動作している場合は、それぞれのetcdを以下のように停止してください。
sudo systemctl stop etcd
厳密には、このステップは必須というわけではないですが、こうしておくとetcdのデータが同期された状態になります。
etcdのバックアップを作成する
以下コマンドで、etcdのバックアップを作成します。
etcdctl backup \ --data-dir $ETCD_DATA_DIR \ --backup-dir $ETCD_DATA_DIR.bak
! メモ
etcdクラスタが複数のホストで構成されている場合も、各インスタンスは定期的にデータを同期しているので、いずれか
のホストでバックアップを作成すれば大丈夫です。! メモ:
コンテナを使ってインストールしている場合、コンテナ内のetcdctlを実行するためにdocker execコマンドを使用します。dbファイルを作成したバックアップディレクトリにコピーします
cp "$ETCD_DATA_DIR"/member/snap/db "$ETCD_DATA_DIR.bak"/member/snap/db
-
etcd
のv3からは、(v3形式のデータは)snapshot
コマンドでオンラインでバックアップと復元ができる - OpenShiftのv3.7からは、
etcd
のv3形式のデータが必須
ことから、snapshot
でバックアップと復元をしても大丈夫そうです。
ただし、flannel
など、一部アプリケーションはv2形式のデータモデルを使用することがあるので、etcd v2とv3、複数形式のデータモデルが混在している場合、backup
コマンドであれば両方の形式のバックアップが取れるので安全かもしれません。
レジストリの証明書をバックアップする
レジストリの全証明書を全てのmasterおよびノードホストで保存します
cd /etc/docker/certs.d/ tar cf /tmp/docker-registry-certs-$(hostname).tar *
! メモ
セキュアな外部レジストリを使用している場合、podを実行するには、イメージをpullしたりpushしたりする全てのホストでレジストリの証明書を信頼しなければなりません
クラスタの復元(etcdがシングルノードの場合)
OpenShiftのクラスタを復元するには、
- OpenShiftを再インストールします。これは、前回インストールした時と同じ方法で実施してください。
- インストール後の独自処理がある場合は、それを実行します。
masterノード全てで、証明書と鍵を復元します。
cd /etc/origin/master tar xvf /tmp/certs-and-keys-$(hostname).tar
etcdのバックアップを復元します。
mv $ETCD_DATA_DIR $ETCD_DATA_DIR.orig cp -Rp $ETCD_DATA_DIR.bak $ETCD_DATA_DIR chcon -R --reference $ETCD_DATA_DIR.orig $ETCD_DATA_DIR chown -R etcd:etcd $ETCD_DATA_DIR
シングルノードのetcdクラスタを、
--force-new-cluster
オプションをつけて新しく作成します。/etc/etcd/etcd.conf
を使うか、一時的にsystemd
のユニットファイルを書き換えてetcdを通常通り開始します。つまり、/usr/lib/systemd/system/etcd.service
で以下のように--force-new-cluster
を追加します。sed -i '/ExecStart/s/"$/ --force-new-cluster"/' /usr/lib/systemd/system/etcd.service systemctl show etcd.service --property ExecStart --no-pager # -> ExecStart=/bin/bash -c "GOMAXPROCS=$(nproc) /usr/bin/etcd --force-new-cluster"
それから、etcdを再起動します。
systemctl daemon-reload systemctl start etcd
etcdが正しく起動したら、
/usr/lib/systemd/system/etcd.service
を再度書き換え、--force-new-cluster
オプションを削除しておきます。sed -i '/ExecStart/s/ --force-new-cluster//' /usr/lib/systemd/system/etcd.service systemctl show etcd.service --property ExecStart --no-pager # -> ExecStart=/bin/bash -c "GOMAXPROCS=$(nproc) /usr/bin/etcd"
etcdを再起動し、etcdクラスタが正しく実行されていることとOpenShiftの設定が正しく表示されることを確認してください。
systemctl daemon-reload systemctl restart etcd
クラスタの復元(etcdがマルチノードの場合)
外部のetcdホストを使用している場合、まず新しいシングルノードのetcdクラスタを作成してバックアップを復元する必要があります。
etcdをマルチノードで構成するのであれば、そのあとで新しいetcdメンバーを一つずつ追加します。最初のetcdメンバーとなるシステムを選び、そこでバックアップと設定を復元します。
次のコマンドをetcdホストで実行します
ETCD_DIR=/var/lib/etcd/ mv $ETCD_DIR /var/lib/etcd.orig cp -Rp /var/lib/origin/etcd-backup-<timestamp>/ $ETCD_DIR chcon -R --reference /var/lib/etcd.orig/ $ETCD_DIR chown -R etcd:etcd $ETCD_DIR
/etc/etcd/etcd.conf
をバックアップから、または.rpmsave
からリストアします。環境に応じて、次セクションのコンテナ化されたetcdのデプロイまたは非コンテナ環境でのetcdのデプロイのどちらかを実行します。
OpenShiftのインストールでは、Atomic Hostにインストールする場合など、etcd
をコンテナで動かす(docker run registry.access.redhat.com/rhel7/etcd
)オプションがあります。
以下では、コンテナ化されたetcdとコンテナでないetcdの2パターンの記載が続きますが、コマンド名など細部が変わるくらいで手順としてはほぼ同じです。
コンテナ化されたetcdのデプロイ
etcdの
--force-new-cluster
オプションを使って、新しいシングルノードクラスタを作成します。/etc/etcd/etcd.conf
またはユニットファイルの書き換えでさらに複雑なコマンドを使うこともできます。以下のように、/etc/systemd/system/etcd_container.service
を編集して--force-new-cluster
オプションを追加します。sed -i '/ExecStart=/s/$/ --force-new-cluster/' /etc/systemd/system/etcd_container.service # -> ExecStart=/usr/bin/docker run --name etcd --rm -v \ # -> /var/lib/etcd:/var/lib/etcd:z -v /etc/etcd:/etc/etcd:ro --env-file=/etc/etcd/etcd.conf \ # -> --net=host --entrypoint=/usr/bin/etcd rhel7/etcd:3.1.9 --force-new-cluster
それから、etcdを再起動します。
systemctl daemon-reload systemctl start etcd_container
etcdサービスが正しく起動したのを確認したら、再度
/etc/systemd/system/etcd_container.service
を編集して、--force-new-cluster
オプションを削除します。sed -i '/ExecStart=/s/ --force-new-cluster//' /etc/systemd/system/etcd_container.service # -> ExecStart=/usr/bin/docker run --name etcd --rm -v /var/lib/etcd:/var/lib/etcd:z -v \ # -> /etc/etcd:/etc/etcd:ro --env-file=/etc/etcd/etcd.conf --net=host \ # -> --entrypoint=/usr/bin/etcd rhel7/etcd:3.1.9
etcdを再起動し、正しく起動すること、OpenShiftの設定が正しく表示されることを確認します。
systemctl daemon-reload systemctl restart etcd_container etcdctl --cert-file=/etc/etcd/peer.crt \ --key-file=/etc/etcd/peer.key \ --ca-file=/etc/etcd/ca.crt \ --peers="https://172.16.4.18:2379,https://172.16.4.27:2379" \ ls /
etcdのクラスタにメンバーを追加するときは、etcdメンバーを追加するを実施してください。そうではなく、シングルノードのetcdでよいのであれば、OpenShiftをオンラインに戻すに進んでください。
非コンテナ環境でのetcdのデプロイ
etcdの
--force-new-cluster
オプションを使って、新しいシングルノードクラスタを作成します。/etc/etcd/etcd.conf
またはユニットファイルの書き換えでさらに複雑なコマンドを使うこともできます。そのために、
/usr/lib/systemd/system/etcd.service
を編集し、--force-new-cluster
を追加します。/usr/lib/systemd/system/etcd.service# sed -i '/ExecStart/s/"$/ --force-new-cluster"/' /usr/lib/systemd/system/etcd.service # systemctl show etcd.service --property ExecStart --no-pager ExecStart=/bin/bash -c "GOMAXPROCS=$(nproc) /usr/bin/etcd --force-new-cluster"
それから、etcdを再起動します。
systemctl daemon-reload systemctl start etcd
etcdサービスが正しく起動したのを確認したら、再度
/usr/lib/systemd/system/etcd.service
を編集して、--force-new-cluster
オプションを削除します。/usr/lib/systemd/system/etcd.service# sed -i '/ExecStart/s/ --force-new-cluster//' /usr/lib/systemd/system/etcd.service # systemctl show etcd.service --property ExecStart --no-pager ExecStart=/bin/bash -c "GOMAXPROCS=$(nproc) /usr/bin/etcd"
etcdを再起動し、正しく起動すること、OpenShiftの設定が正しく表示されることを確認します。
systemctl daemon-reload systemctl restart etcd_container etcdctl --cert-file=/etc/etcd/peer.crt \ --key-file=/etc/etcd/peer.key \ --ca-file=/etc/etcd/ca.crt \ --peers="https://172.16.4.18:2379,https://172.16.4.27:2379" \ ls /
もし、クラスタにetcdメンバーを追加するなら、etcdメンバーを追加するを実施してください。そうではなく、シングルノードのetcdでよいのであれば、OpenShiftをオンラインに戻すに進んでください。
etcdメンバーを追加する
メンバーの追加は、etcdctl member add
を実行してから、対応するetcdサービスを立ち上げる、という順序で実行します。
あと、そのときは「一つmember add」-> 「一つetcd起動」を一個ずつやっていくのがベストプラクティスとされています。
クラスタが機能するために過半数のetcdノードが必要で、1つのetcdノードに対してmember add
した状態だと、実際に新メンバーがオンラインになるまで過半数の合意が取れなくなるという理由です。
etcdメンバーをクラスタに追加するには、まず上記で起動した最初のメンバーが、
peerURLs
にlocalhost
で登録されているのを修正します。
最初のメンバーのメンバーIDを
member list
で取得します。etcdctl --cert-file=/etc/etcd/peer.crt \ --key-file=/etc/etcd/peer.key \ --ca-file=/etc/etcd/ca.crt \ --peers="https://172.18.1.18:2379,https://172.18.9.202:2379,https://172.18.0.75:2379" \ member list
etcdctl member update
コマンドに前ステップで取得したメンバーIDを渡して、peerURLsの値を更新します。etcdctl --cert-file=/etc/etcd/peer.crt \ --key-file=/etc/etcd/peer.key \ --ca-file=/etc/etcd/ca.crt \ --peers="https://172.18.1.18:2379,https://172.18.9.202:2379,https://172.18.0.75:2379" \ member update 511b7fb6cc0001 https://172.18.1.18:2380
または、
curl
を使うこともできます。curl --cacert /etc/etcd/ca.crt \ --cert /etc/etcd/peer.crt \ --key /etc/etcd/peer.key \ https://172.18.1.18:2379/v2/members/511b7fb6cc0001 \ -XPUT -H "Content-Type: application/json" \ -d '{"peerURLs":["https://172.18.1.18:2380"]}'
member list
コマンドを再実行して、peerURLsにlocalhostが含まれていないことを確認してください。終わったら、クラスタに新しいメンバーを一つずつ追加していきます。
! 注意
etcdのメンバーは、クラスタに追加してから起動する、という手順を一つずつ、確実に実施していく必要があります。
新しいメンバーがetcdのクラスタに追加されたら、peerURLsのリストはその時点で新しいメンバーを含めた正しいものになっていなければなりません。そのため、peerURLsはメンバーが追加されるたびに一つずつ大きくなっていく形になります。
以下の手順で記載されている通り、新しいメンバーを起動する際にetcd.conf
に設定する値は、etcdctl member add
コマンドを実行したときに出力されます。
etcdのメンバーを追加するには、システムの
etcd.conf
にある値を参照して、etcdctl member add
を発行します。etcdctl --cert-file=/etc/etcd/peer.crt \ --key-file=/etc/etcd/peer.key \ --ca-file=/etc/etcd/ca.crt \ --peers="https://172.16.4.18:2379,https://172.16.4.27:2379" \ member add 10.3.9.222 https://172.16.4.27:2380 Added member named 10.3.9.222 with ID 4e1db163a21d7651 to cluster ETCD_NAME="10.3.9.222" ETCD_INITIAL_CLUSTER="10.3.9.221=https://172.16.4.18:2380,10.3.9.222=https://172.16.4.27:2380" ETCD_INITIAL_CLUSTER_STATE="existing"
メンバーのシステム自身にある
/etc/etcd/etcd.conf
ファイルを編集し、ファイル内の設定とetcdctl member add
コマンドで出力された設定が一致するようにします。 1新しいetcdメンバーを起動します。
rm -rf /var/lib/etcd/member systemctl enable etcd systemctl start etcd
サービスが正しく開始され、etcdクラスタがhealtyになっていることを確認します。
etcdctl --cert-file=/etc/etcd/peer.crt \ --key-file=/etc/etcd/peer.key \ --ca-file=/etc/etcd/ca.crt \ --peers="https://172.16.4.18:2379,https://172.16.4.27:2379" \ member list 51251b34b80001: name=10.3.9.221 peerURLs=https://172.16.4.18:2380 clientURLs=https://172.16.4.18:2379 d266df286a41a8a4: name=10.3.9.222 peerURLs=https://172.16.4.27:2380 clientURLs=https://172.16.4.27:2379 etcdctl --cert-file=/etc/etcd/peer.crt \ --key-file=/etc/etcd/peer.key \ --ca-file=/etc/etcd/ca.crt \ --peers="https://172.16.4.18:2379,https://172.16.4.27:2379" \ cluster-health cluster is healthy member 51251b34b80001 is healthy member d266df286a41a8a4 is healthy
このプロセスを、次にクラスタに追加するメンバーにも繰り返します。
全てのetcdメンバーを追加し終わったら、OpenShiftをオンラインに戻すに進んでください。
新しいetcdホストの追加
etcdメンバーがエラーになっても、まだ過半数のメンバーが実行されているのであれば、その残ったメンバーを使ってダウンタイムなしでetcdメンバーを追加できます。
推奨されるクラスタサイズ
etcdのフォールトトレランスは、奇数個のetcdホストを持つことで実現されています。
奇数個にしてもクオラムに必要なホスト数は変わりませんが、エラーで落ちても大丈夫なホスト数が増えます。
例えば、クラスタが3台で構成されている場合、クオラムは2で、エラーで落ちても大丈夫な台数は1です。
これは、2つのメンバーがhealthyであれば、クラスタの動作が保証されるということです。プロダクション環境では3台のetcdホストでクラスタを構築することを推奨します。
! 注意
以下の手順は、/etc/etcd
の設定のバックアップがあることを前提にしています。
- もし新しいetcdメンバーがOpenShiftのノードとしても実行される場合、希望する数のホストをクラスターに追加するを参照してください。この手順ではホストを一つ追加しますが、複数のホストを追加する場合はそれぞれのホストで全てのステップを繰り返してください。
生き残っているノードでetcdとiptablesをアップグレードします。
yum update etcd iptables-services
etcd-2.3.7-4.el7.x86_64かそれ以上のバージョンのetcdがインストールされ、また全てのホストでetcdのバージョンが同じになっていることを確認します。
etcdとiptablesを新しいホストでインストールします。
yum install etcd iptables-services
etcd-2.3.7-4.el7.x86_64かそれ以上のバージョンのetcdがインストールされ、新しいホストで、既存のetcdと同じバージョンがインストールされていることを確認します。
クラスタの設定を変更する前に、必ずetcdデータのバックアップを実行してください。
エラーになっているetcdメンバーを置き換える場合は、新しいetcdメンバーを追加する前にそのetcdメンバーを削除してください。
etcdctl -C https://<surviving host IP>:2379 \ --ca-file=/etc/etcd/ca.crt \ --cert-file=/etc/etcd/peer.crt \ --key-file=/etc/etcd/peer.key cluster-health etcdctl -C https://<surviving host IP>:2379 \ --ca-file=/etc/etcd/ca.crt \ --cert-file=/etc/etcd/peer.crt \ --key-file=/etc/etcd/peer.key member remove <failed member identifier>
そして、エラーになったetcdを停止します。
systemctl stop etcd
新しいホストで、適切なiptablesのルールを追加します。
systemctl enable iptables.service --now iptables -N OS_FIREWALL_ALLOW iptables -t filter -I INPUT -j OS_FIREWALL_ALLOW iptables -A OS_FIREWALL_ALLOW -p tcp -m state \ --state NEW -m tcp --dport 2379 -j ACCEPT iptables -A OS_FIREWALL_ALLOW -p tcp -m state \ --state NEW -m tcp --dport 2380 -j ACCEPT iptables-save > /etc/sysconfig/iptables
新しいetcdホストに必要な証明書を作成します。既存のetcdホストで以下を実行します。
/etc/etcd/ca/
ディレクトリのバックアップを取ってください。証明書を生成するための環境変数と作業ディレクトリを用意し、
PREFIX
ディレクトリが作成されていない場合は作成します。cd /etc/etcd export NEW_ETCD="<NEW_HOST_NAME>" export CN=$NEW_ETCD export SAN="IP:<NEW_HOST_IP>" export PREFIX="./generated_certs/etcd-$CN/"
$PREFIX
ディレクトリを作成します。mkdir -p $PREFIX
server.csrとserver.crt、二つの証明書を作成します。
openssl req -new -keyout ${PREFIX}server.key \ -config ca/openssl.cnf \ -out ${PREFIX}server.csr \ -reqexts etcd_v3_req -batch -nodes \ -subj /CN=$CN openssl ca -name etcd_ca -config ca/openssl.cnf \ -out ${PREFIX}server.crt \ -in ${PREFIX}server.csr \ -extensions etcd_v3_ca_server -batch
peer.csrとpeer.crt、二つの証明書を作成します。
openssl req -new -keyout ${PREFIX}peer.key \ -config ca/openssl.cnf \ -out ${PREFIX}peer.csr \ -reqexts etcd_v3_req -batch -nodes \ -subj /CN=$CN openssl ca -name etcd_ca -config ca/openssl.cnf \ -out ${PREFIX}peer.crt \ -in ${PREFIX}peer.csr \ -extensions etcd_v3_ca_peer -batch
etcd.confとca.crtをコピーし、ディレクトリをアーカイブします。
cp etcd.conf ${PREFIX} cp ca.crt ${PREFIX} tar -czvf ${PREFIX}${CN}.tgz -C ${PREFIX} .
このファイルを、新しいetcdホストに転送します。
scp ${PREFIX}${CN}.tgz $CN:/etc/etcd/
引き続き、既存のホスト上で作業し、新しいホストをクラスタに追加します。
新しいホストをクラスタに追加します。
export ETCD_CA_HOST="<SURVIVING_ETCD_HOSTNAME>" export NEW_ETCD="<NEW_ETCD_HOSTNAME>" export NEW_ETCD_IP="<NEW_HOST_IP>" etcdctl -C https://${ETCD_CA_HOST}:2379 \ --ca-file=/etc/etcd/ca.crt \ --cert-file=/etc/etcd/peer.crt \ --key-file=/etc/etcd/peer.key member add ${NEW_ETCD} https://${NEW_ETCD_IP}:2380 ETCD_NAME="<NEW_ETCD_HOSTNAME>" ETCD_INITIAL_CLUSTER="<NEW_ETCD_HOSTNAME>=https://<NEW_HOST_IP>:2380,<SURVIVING_ETCD_HOST>=https:/<SURVIVING_HOST_IP>:2380 ETCD_INITIAL_CLUSTER_STATE="existing"
etcdctl member add
の出力にある三つの環境変数をコピーしておいてください。後で使用します。新しいホストの上で、転送された設定データを解凍し、パーミッションを設定してください。
tar -xf /etc/etcd/<NEW_ETCD_HOSTNAME>.tgz -C /etc/etcd/ --overwrite chown -R etcd:etcd /etc/etcd/*
新しいホストで、全てのetcdデータを削除します。
rm -rf /var/lib/etcd/member chown -R etcd:etcd /var/lib/etcd
新しいホストのetcd.confは、
- 前の手順で作った値で次のものを置き換えます
* ETCD_NAME * ETCD_INITIAL_CLUSTER * ETCD_INITIAL_CLUSTER_STATE 以下のものは、IPアドレスを`NEW_ETCD`の値で置き換えます。 * ETCD_LISTEN_PEER_URLS * ETCD_LISTEN_CLIENT_URLS * ETCD_INITIAL_ADVERTISE_PEER_URLS * ETCD_ADVERTISE_CLIENT_URLS エラーになったetcdメンバーを置き換える場合、そのメンバーをetcdの設定から削除してください。
etcdを新しいホストで開始します。
systemctl enable etcd --now
新しいメンバーがちゃんと追加されていることを確認します。
etcdctl -C https://${ETCD_CA_HOST}:2379 --ca-file=/etc/etcd/ca.crt \ --cert-file=/etc/etcd/peer.crt \ --key-file=/etc/etcd/peer.key cluster-health
Masterの設定を全てのmasterホストで更新し、新しいetcdホストをポイントするように修正します。
- クラスタ内の全てのmasterで、
/etc/origin/master/master-config.yml
を編集するetcdClientInfo
セクションを見つける- 新しいetcdホストを、urlsリストに加える
失敗したetcdホストを入れ替える場合は、リストからそれを削除する
すべてのmasterで以下を実行してください。
systemctl restart atomic-openshift-master-api atomic-openshift-master-controllers
これで、etcdメンバーを追加する手順は完了です。
OpenShiftをオンラインに戻す
全てのOpenShiftのmasterで、masterとノードの設定をバックアップからリストアし、関連する全てのサービスをenable、retartします。
cp /etc/sysconfig/atomic-openshift-master-api.rpmsave /etc/sysconfig/atomic-openshift-master-api cp /etc/sysconfig/atomic-openshift-master-controllers.rpmsave /etc/sysconfig/atomic-openshift-master-controllers cp /etc/origin/master/master-config.yaml.<timestamp> /etc/origin/master/master-config.yaml cp /etc/origin/node/node-config.yaml.<timestamp> /etc/origin/node/node-config.yaml systemctl enable atomic-openshift-master-api systemctl enable atomic-openshift-master-controllers systemctl enable atomic-openshift-node systemctl start atomic-openshift-master-api systemctl start atomic-openshift-master-controllers systemctl start atomic-openshift-node
ノードのほうは、
node-config.yaml
をバックアップからリストアし、atomic-openshift-node
サービスをenable、restartしてください。cp /etc/origin/node/node-config.yaml.<timestamp> /etc/origin/node/node-config.yaml systemctl enable atomic-openshift-node systemctl start atomic-openshift-node
これで、OpenShiftクラスタはオンラインに戻るはずです。
プロジェクトのバックアップ
将来的には、OpenShiftでプロジェクトのバックアップと復元を行う機能をサポートする予定です。
今のところは、プロジェクトレベルのAPIオブジェクトをバックアップするには、保存したいオブジェクトに対して
oc export
をそれぞれ実行してください。
例えば、frontend
のデプロイ設定をYAML形式で保存するには、以下のようにします。oc export dc frontend -o yaml > dc-frontend.yaml
プロジェクトの全て(namespacesやprojectsのようなクラスタレベルのオブジェクト以外)をバックアップするには、以下のようにします。
oc export all -o yaml > project.yaml
Role Bindings
ときどき、プロジェクトでロールバインディングのポリシーをカスタマイズしている場合があります。例えば、プロジェクトの管理者が他のユーザーに特定のロールを与え、プロジェクトにアクセスできるようにするときなどです。
このようなロールバインディングは、以下のようにエクスポートできます。
oc get rolebindings -o yaml --export=true > rolebindings.yaml
Service Accounts
カスタムのService Accountがある場合は、それをエクスポートする必要があります。
oc get serviceaccount -o yaml --export=true > serviceaccount.yaml
Secrets
独自のSecretsを使用している場合、例えば、ソースコード管理システムの秘匿情報(SSHの公開鍵/ユーザー名とパスワード)などをSecretsで提供している場合、それらをエクスポートしなければなりません。
oc get secret -o yaml --export=true > secret.yaml
Persistent Volume Claims
プロジェクト内のアプリケーションが、
Persisitent Volume Claim(PVC)
を使ってPersistent Volume
使用しているなら、そのPVCもバックアップする必要があります。oc get pvc -o yaml --export=true > pvc.yaml
プロジェクトの復元
プロジェクトを復元するには、プロジェクトを再作成し、バックアップ時にエクスポートした全てのオブジェクトを再作成します。
oc new-project myproject oc create -f project.yaml oc create -f secret.yaml oc create -f serviceaccount.yaml oc create -f pvc.yaml oc create -f rolebindings.yaml
! メモ
いくつかのリソースは作成に失敗する可能性があります(podやデフォルトのService Account)
アプリケーションデータのバックアップ
クラスタの状態が戻っても、アプリケーションの永続データをPVで保存している場合、そのPVも復旧しなければなりません。
PVのバックエンドとなるネットワークストレージ側でバックアップをとることも必要ですが、ここでは、コンテナに対してoc rsync
でrsyncを使う方法が紹介されています。
(Kubernetesの場合、kubectl cpが使えそうです)
rsyncの対象となるパスを、デプロイ設定のmountPathから取得しているのが面白いところです。
多くの場合、アプリケーションデータは
oc rsync
コマンドでバックアップできます。コンテナイメージにrsync
がインストールされている想定ですが、Red Hatのrhel7のベースイメージにはrsync
が含まれています。
したがって、rhel7をベースにした全てのイメージにもrsync
は含まれています。CLI操作のトラブルシューティングとデバッグ - rsyncを参照してください。! 注意
これはアプリケーションデータの一般的なバックアップ方法であり、アプリケーション固有のバックアップ手順(データベースの特殊なエクスポート/インポート手順など)は考慮していません。また、PVの種類(例えば、CinderやNFS、Glusterなど)によっては、他のバックアップ手順があるかもしれません。
バックアップ対象のファイルパスも、アプリケーションごとに異なります。DeploymentConfigの
mountPath
を見れば、どのパスのデータをバックアップすべきか判断できます。
Jenkinsのアプリケーションデータをバックアップする例
DeploymentConfigから、アプリケーションデータの
mountPath
を取得します。oc get dc/jenkins -o jsonpath='{ .spec.template.spec.containers[?(@.name=="jenkins")].volumeMounts[?(@.name=="jenkins-data")].mountPath }' # -> /var/lib/jenkins
現在実行されているpodの名前を取得します。
oc get pod --selector=deploymentconfig=jenkins -o jsonpath='{ .metadata.name }' # -> jenkins-1-37nux
oc rsync
コマンドでアプリケーションデータをバックアップします。oc rsync jenkins-1-37nux:/var/lib/jenkins /tmp/
! メモ
このアプリケーションデータのバックアップ方法は、現在実行されているアプリケーションのpodに対してしか実行できません。
記載されている通り、アプリケーションが稼働しているときにしか実行できない方法です。
アプリケーションが死んでからデータを救出するような用途には使えません。
アプリケーションデータの復元
アプリケーションデータのリストア手順は、
oc rsync
を使ったアプリケーションのバックアップ手順と似たような手順になります。
制限事項も同じです。このアプリケーションデータのリストア手順も、PVがアタッチされていることが前提になっています。
Jenkinsのアプリケーションデータをリストアする例
バックアップを検証します。
ls -la /tmp/jenkins-backup/ total 8 drwxrwxr-x. 3 user user 20 Sep 6 11:14 . drwxrwxrwt. 17 root root 4096 Sep 6 11:16 .. drwxrwsrwx. 12 user user 4096 Sep 6 11:14 jenkins
oc rsync
を使って、データを実行中のpodにコピーします。oc rsync /tmp/jenkins-backup/jenkins jenkins-1-37nux:/var/lib
! メモ
アプリケーションによっては、ここでアプリケーションの再起動が必要になるかもしれません新しいデータでアプリケーションを再起動します(オプショナル)。
oc delete pod jenkins-1-37nux
または、そのデプロイをレプリカ数0になるまでスケールダウンし、再度スケールアップしてもかまいません。
oc scale --replicas=0 dc/jenkins oc scale --replicas=1 dc/jenkins
-
etcdctl member add
の結果は、値がダブルクォーテーションで囲まれた形式で出力されますが、etcd.conf
に結果を貼り付けるときはダブルクォーテーションを外さないとうまくいかなかったです。 ↩