GeekFactory

int128.hatenablog.com

Kubernetes nodesをMulti-AZからSingle-AZに移行した

kopsで運用しているKubernetes nodesをMulti-AZからSingle-AZに移行したので作業メモを残しておきます。

us-west-2b や us-west-2c にあるNodesとPersistent Volumesを us-west-2a に移行します。Masterは us-west-2a のままにします。

kops 1.8.0, Kubernetes 1.8.4で確認しています。

Nodesの移行

kops

NodesのAvailability Zoneを us-west-2a,us-west-2b,us-west-2c から us-west-2a のみに変更します。

% kops get ig
Using cluster from kubectl context: kops.hidetake.org

NAME            ROLE    MACHINETYPE MIN MAX ZONES
master-us-west-2a   Master  t2.micro    1   1   us-west-2a
nodes           Node    t2.micro    2   2   us-west-2a,us-west-2b,us-west-2c

% kops edit ig nodes
Using cluster from kubectl context: kops.hidetake.org

% kops get ig
Using cluster from kubectl context: kops.hidetake.org

NAME            ROLE    MACHINETYPE MIN MAX ZONES
master-us-west-2a   Master  t2.micro    1   1   us-west-2a
nodes           Node    t2.micro    2   2   us-west-2a

Clusterのサブネットも us-west-2a,us-west-2b,us-west-2c から us-west-2a のみに変更します。

% kops edit cluster

変更内容を適用します。

% kops update cluster
Using cluster from kubectl context: kops.hidetake.org

I1228 10:58:37.403838   77384 executor.go:91] Tasks: 0 done / 73 total; 31 can run
I1228 10:58:38.933794   77384 executor.go:91] Tasks: 31 done / 73 total; 24 can run
I1228 10:58:40.071632   77384 executor.go:91] Tasks: 55 done / 73 total; 16 can run
I1228 10:58:41.554352   77384 executor.go:91] Tasks: 71 done / 73 total; 2 can run
I1228 10:58:41.711652   77384 executor.go:91] Tasks: 73 done / 73 total; 0 can run
Will modify resources:
  AutoscalingGroup/nodes.kops.hidetake.org
    Subnets                  [id:subnet-67dc353d, id:subnet-2daa9a4b, id:subnet-5210431a] -> [name:us-west-2a.kops.hidetake.org id:subnet-5210431a]

Must specify --yes to apply changes

% kops update cluster --yes
Using cluster from kubectl context: kops.hidetake.org

I1228 10:58:54.651294   77386 executor.go:91] Tasks: 0 done / 73 total; 31 can run
I1228 10:58:56.218052   77386 executor.go:91] Tasks: 31 done / 73 total; 24 can run
I1228 10:58:57.354869   77386 executor.go:91] Tasks: 55 done / 73 total; 16 can run
I1228 10:58:58.727423   77386 executor.go:91] Tasks: 71 done / 73 total; 2 can run
I1228 10:58:59.248501   77386 executor.go:91] Tasks: 73 done / 73 total; 0 can run
I1228 10:58:59.248636   77386 dns.go:153] Pre-creating DNS records
I1228 10:59:00.687645   77386 update_cluster.go:248] Exporting kubecfg for cluster
kops has set your kubectl context to kops.hidetake.org

Cluster changes have been applied to the cloud.


Changes may require instances to restart: kops rolling-update cluster

% kops rolling-update cluster
Using cluster from kubectl context: kops.hidetake.org

NAME            STATUS  NEEDUPDATE  READY   MIN MAX NODES
master-us-west-2a   Ready   0       1   1   1   1
nodes           Ready   0       4   2   2   4

No rolling-update required.

上記を実行するとAuto Scaling Groupの設定が変更されます。

AWS management console

EC2インスタンスの一覧を見ていると、Nodesが以下のように変化することが分かります。

  • us-west-2a で新しいnodeが起動する。
  • us-west-2a で新しいnodeが起動する。
  • us-west-2b にある既存のnodeがterminateする。
  • us-west-2c にある既存のnodeがterminateする。

すべて終わるまで10分ぐらいかかりました。

Kubernetes Dashboard

Podsが以下のように変化することが分かります。

  • us-west-2b や us-west-2c で実行されているPodsが終了する。
  • 上記Podsが us-west-2a で実行される。

Persistent Volumesの移行

すべてのNodesが us-west-2a に移行したため、us-west-2b や us-west-2c に存在するPersistent Volumes(EBS)に依存するPodを実行しようとすると、以下のエラーが発生します。

No nodes are available that match all of the predicates: NoVolumeZoneConflict (3), PodToleratesNodeTaints (1).

動的に確保された(Dynamically provisioned)Persistent Volumesを移行するには細心の注意が必要です。移行に先立って、あらかじめ以下の関係を書き出しておきます。

  • Deployment
  • Persistent Volume Claim
  • Persistent Volume
  • EBS Volume

Persistent Volumesを別のAZに移行するには以下の手順が必要です。

  1. Persistent Volumeの persistentVolumeReclaimPolicyRetain に変更する。これはPersistent Volume Claimを削除した時にEBS Volumeも一緒に削除されるのを防ぐため。
  2. Persistent Volumeに依存するPersistent Volume ClaimとDeploymentを削除する。
  3. Persistent Volumeのステータスが Released になったことを確認する。
  4. EBS Volumeのステータスが available になったことを確認する。
  5. 旧AZのEBS VolumeからSnapshotを作成する。
  6. Snapshotから新AZでEBS Volumeを作成する。
  7. Persistent Volumeの以下の属性を変更する。この時点では新しいEBS Volumeはアタッチされない。
    • failure-domain.beta.kubernetes: 新しいAZ(例:us-west-2a
    • volume-id: 新しいEBS Volume(例:aws://us-west-2a/vol-0123456789
  8. Persistent Volume Claimを再作成する。Persistent Volumeを紐付けるため、以下の属性を指定しておく。
    • volumeName: Persistent Volumeの名前(例:pvc-1801704a-eb70-11e7-a258-060098a4bc1c)
  9. Persistent Volumeの以下の属性を変更する。逆方向の紐付けも直さないと正しくアタッチされない。
    • claimRef: uid: Persistent Volume Claimの uid
    • claimRef: resourceVersion: Persistent Volume Claimの resourceVersion
  10. Persistent Volumeのステータスが Bound になったことを確認する。
  11. EBS Volumeのステータスが in-use になったことを確認する。

順を追ってコマンドを説明します。

Persistent Volumeの紐付け解除とPersistent Volume Claimの削除

# Persistent Volumeの `persistentVolumeReclaimPolicy` を `Retain` に変更
kubectl edit pv

# Persistent Volumeに依存するPersistent Volume ClaimとDeploymentを削除
kubectl delete pvc/example deployment/example

# Persistent Volumeのステータスが Released になったことを確認
kubectl get pv

EBS VolumeのAZ移行

# 旧Volumeの確認(Nameの確認)
aws ec2 describe-volumes

# 旧AZのEBS VolumeからSnapshotを作成
aws ec2 create-snapshot --volume-id vol-0123456789 --description kops.example.com-dynamic-pvc-1801704a-eb70-11e7-a258-060098a4bc1c

タグは移行しなくても問題ないようですが、後から何のVolumeか分からなくなると辛いので、タグもそのまま移行することをおすすめします。

# 旧Volumeの確認(Tagsの確認)
aws ec2 describe-volumes

# 新Volumeの作成
aws ec2 create-volume --snapshot-id snap-0123456789 --availability-zone us-west-2a --volume-type gp2 --size 10 --tag-specifications '[{"ResourceType": "volume", "Tags": [上記でダンプした旧ボリュームのTags]}]'

Persistent Volumeの再紐付け

# Persistent Volumeの属性を変更
kubectl edit pv

# Persistent Volume Claimを再作成(volumeName指定)
vim example.yaml
kubectl apply -f example.yaml

# Persistent Volumeの属性を変更
kubectl edit pv

# Persistent Volumeのステータスが Bound になったことを確認
kubectl get pv

まとめ

  • NodesのAZ移行は kops で簡単にできる。
  • Persistent VolumesのAZ移行は辛い。特に、dynamically provisionedのものは関連を壊さないように細心の注意が必要になる。