はじめに
EKS でクラスターを構築していると、kubernetes (以下 k8s) のバージョンアップなどを安全に行いたいといったニーズからクラスターごと新しく作って DNS の切り替えでクラスターを更新したいという事があると思います (事前に新しいバージョンでの動作確認などを行いたいといった理由から、DROBE ではそれが良さそうという結論になりました)
この記事では、クラスター切り替え時に考える事になる external-dns の挙動について解説します
External-DNS とは
external-dns とは k8s の ingress や service と外部の DNS と紐付けを行ってくれる k8s object です
Helm を使って cluster に install すると、external-dns の deployments に加えて service account なども一緒に作られます
external-dns の動作は非常にシンプルです
監視対象となる k8s resource を設定しておくと、その resource の生き死にを検知して DNS のレコードを調整してくれるといった挙動になります
AWS であれば対象となる Route53 の Zone やレコードに対して read / write が行えるような IAM を発行して Service アカウントに紐づけておく事で AWS リソースの編集を行ってくれます
DROBE では監視対象として Service:Loadbalancer
に加えて istio の istio-gateway
と istio-virtualservice
も監視対象としています (istio が作る Loadbalancer
に domain を向けたいため)
external-dns によって Cluster を切り替える
冒頭で説明したように EKS cluster を 2 つ作って Cluster1 から Cluster2 に切り替える事を想定してみます
Step1
まず Cluster1 が作業開始時点での primary (domain への traffic が向いている Cluster) だとすると、Cluster2 を作る際には external-dns だけは作らないでおいておく必要があります
この時点で Route53 の record の管理は Cluster1 の external-dns が行っています
Step2
次に、Cluster1 の external-dns を削除します
ここで external-dns の policy
を upsert-only
にしておく事で external-dns が削除されても Route53 にレコードは残ります (policy
を sync
にしてしまうと Route53 のレコードが消えてしまうので注意が必要です)
Step3
最後に Cluster2 の external-dns を作ります
この時点で Route53 のレコードの書き換えが発生し、domain にきた traffic は Cluster2 に向くようになります
あとは Cluster1 を削除してしまえば切り替えが完了になります
注意点
注意点として Cluster1 と Cluster2 の external-dns の txtOwnerId
を同じにしておかないと DNS レコードの上書きが発生しません
txtOwnerId
はもともと意図しない DNS レコードの上書きなどを防ぐものだと思いますが、この場合には同じにしておかないと意図した動作にならないので注意が必要です
さいごに
external-dns を利用した EKS Cluster の切り替えについて記載しました
eks はバージョンの更新にしっかりついていく事が必要になる一方で、稼働中のクラスターのバージョンをあげるのがやっかいな部分もあると思います
この手法を使う事で、新しい Cluster に traffic を向ける事なく動作確認を行って、ある程度安全に切り替える事が出来ると思います