EKSクラスタのバージョンアップ手順

f:id:cloudfish:20200116173700p:plain
3/10にEKSでKubernetesのバージョン1.15のサポートが開始されたことに伴いバージョン1.12が5/11でサポート対象外となります。そのため、現在のバージョンが1.12の場合は速やかなアップデートが必要になります。Kubernetesについてはリリースサイクルが早く、最新の3つまでしかサポートされないため可能な限り追従していく必要があります。今回はバージョン1.12のクラスタをアップデートしましたのでその手順について紹介したいと思います。

バージョンアップに関しての考慮ポイント

EKSのリリースサイクル

Kubernetesのリリースサイクルは年4回となっておりおよそ3ヶ月に1回新しいバージョンがリリースされます。EKSもこれに追従しているため、ほぼ同じようなサイクルとなっています。

サポートバージョン

サポートについては最新の3つのバージョンをサポートします。今回であれば、1.15、1.14、1.13がサポートされ、1.12については2020/05/11でサポート廃止となります。そのため、最低、年に1回はバージョンアップが必要となります。

サポート停止日以降に古いバージョンで実行している場合は自動更新

今回のケースでは2020/05/12以降にバージョン1.12のままであれば自動的に1.13に更新されます。
ただし、自動で更新されるのはコントロールプレーンのみとなるためワーカーノードについては自分で更新する必要があります。

クラスタの更新中のアプリケーションへの影響

実行中のアプリケーションは影響を受けないとありますが、注意書きにもあるとおりAPIサービスが短時間中断する場合があるとのことなので、軽微かもしれませんが全く影響を受けないわけではないと思います。実際のアップデート作業ではメンテナンス時間帯を設定しておいた方が安全かと思います。

クラスタの更新に失敗するケース

クラスタの更新については自動で更新されるとはいえ必ず成功するわけではなく失敗する場合もあります。更新に失敗した場合は、そのままの状態で放置されることはなく必ずロールバックされます。以下の条件が満たされない場合は更新に失敗する場合があるようです。

  • クラスターの作成時に指定したサブネットから、2~3の空きIP アドレスがない場合。
  • クラスターの作成時に指定されたいずれかのサブネットやセキュリティグループが削除された場合

マスターとワーカーノードの互換性

Kubernetes では、少なくとも 2 つのマイナーバージョンにおいて、マスターとワーカーノード間の互換性をサポートしています。
例として
マスター(kube-apiserver)が1.15の場合
ワーカーノード(kubelet)は1.15、1.14および1.13がサポートされます。

バージョンアップ手順

今回はバージョン1.12から1.14へ以下の手順でアップデートを行いました。1.15はリリースされたばかりということもあり、1.14へアップデートを行いました。

手順概略

アップデート手順の概略については以下のような流れになります。
1.クラスタアップデート
2.kube-proxyアップデート
3.corednsアップデート
4.cniアップデート
5.(新バージョン)ノードグループ追加
6.(旧バージョン)ノードグループ削除

事前準備

バージョン確認

まずは現行のバージョンを確認しましょう。以下のコマンドを実行してバージョンを確認してください。

#クラスタバージョン
kubectl version --short
#ワーカーノードバージョン
kubectl get nodes
#kube-proxyバージョン
kubectl describe daemonset kube-proxy --namespace kube-system | grep Image | cut -d "/" -f 3
#corednsバージョン
kubectl describe deployment coredns --namespace kube-system | grep Image | cut -d "/" -f 3
#CNIバージョン
kubectl describe daemonset aws-node --namespace kube-system | grep Image | cut -d "/" -f 2

確認結果

マスター ワーカーノード cni kube-proxy coredns
現行バージョン Server Version: v1.12.10-eks-aae39f v1.5.0 v1.12.7 v1.12.6 v1.2.2

クラスタのバージョンアップ後にアドオンについてもバージョンアップを行う必要があります。各種アドオンのバージョンアップが必要かどうかは以下の表を確認してください。上記のケースの場合全てのアドオンのバージョンアップが必要となります。

Kubernetes Version 1.15 1.14 1.13 1.12
Amazon VPC CNI plug-in 1.5.5 1.5.5 1.5.5 1.5.5
DNS (CoreDNS) 1.6.6 1.6.6 1.6.6 1.6.6
KubeProxy 1.15.10 1.14.9 1.13.12 1.12.10

上記の表からアップデート後の想定バージョンは以下となります。

マスター ワーカーノード cni kube-proxy coredns
更新後バージョン Server Version 1.14.9 v1.4.9 v1.5.5 v1.4.9 v1.6.6
ポッドセキュリティポリシーの設定確認
kubectl get psp eks.privileged

以下のようなエラーが出た場合は、ポッドセキュリティポリシーをインストールする必要があります。

Error from server (NotFound): podsecuritypolicies.extensions "eks.privileged" not found

ポッドセキュリティポリシーのインストールは以下を参照してインストールしてください。
https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/pod-security-policy.html#install-default-psp

バージョンアップ

バージョンアップ作業については、マネジメントコンソール、eksctl、aws-cliの3つで作業が可能ですが、今回はeksctlコマンドでの手順を紹介します。なお、eksctlコマンドのバージョンは0.14以降となります。また、可能ならサービスは止める調整をしておいたほうがいいと思います。

クラスタのバージョンアップ(1.12→1.13)

まずはクラスタを1.12から1.13へバージョンアップを行いますので、以下のコマンドを実行してください。時間は10~15分程度かかりました。

eksctl update cluster --name ${eks-cluster-name} --approve

完了後に以下のコマンドでバージョンを確認してください。

kubectl version --short
クラスタのバージョンアップ(1.13→1.14)

1.13へのバージョンアップが完了したら、次は1.14へバージョンアップを行います。先ほどと同様に以下のコマンドを実行してください。時間は20-25分程度かかりました。

eksctl update cluster --name ${eks-cluster-name} --approve

完了後に以下のコマンドでバージョンを確認してください。

kubectl version --short
kube-proxyバージョンアップ(→1.14.9)

クラスタのバージョンが1.14なのでそれに対応するkube-proxyのバージョンは1.14.9となります。以下のコマンドでバージョンアップを実行します。

kubectl set image daemonset.apps/kube-proxy \
    -n kube-system \
    kube-proxy=602401143452.dkr.ecr.us-west-2.amazonaws.com/eks/kube-proxy:v1.14.9

以下のコマンドでバージョンアップされているか確認します。

kubectl describe daemonset kube-proxy --namespace kube-system | grep Image | cut -d "/" -f 3
corednsバージョンアップ(→1.6.6)

corednsの現行バージョンが1.2.2のため、1.6.6へバージョンアップを行います。以下のコマンドを実行します。

kubectl set image --namespace kube-system deployment.apps/coredns \
coredns=602401143452.dkr.ecr.ap-northeast-1.amazonaws.com/eks/coredns:v1.6.6

以下のコマンドでバージョンアップされているか確認します。

kubectl describe deployment coredns --namespace kube-system | grep Image | cut -d "/" -f 3
cniバージョンアップ(1.5.5)

cniの現行バージョンが1.12.7のため、1.5.5へバージョンアップを行います。以下のコマンドを実行します。

kubectl apply -f https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/release-1.5/config/v1.5/aws-k8s-cni.yaml

以下のコマンドでバージョンアップされているか確認します。

kubectl describe daemonset aws-node --namespace kube-system | grep Image | cut -d "/" -f 2
新バージョンでノードグループ作成

以下のコマンドで新しくノードグループを作成します。
パラメータは必要に応じて変更してください。cluster.yamlファイルを作成している場合は、バージョンを変更して実行してください。

eksctl create nodegroup \
--cluster default \
--version 1.14 \
--name ${eks-cluster-name} \
--node-type m5.large \
--nodes 2 \
--nodes-min 1 \
--nodes-max 4 \
--node-ami auto

ワーカーノードのバージョン確認

kubectl get nodes
旧バージョンのノードグループ削除
eksctl delete nodegroup --cluster= ${eks-cluster-name} --name= ${eks-workernode-name}

バージョン1.12から1.15へバージョンアップ

もし1.12から1.15へバージョンアップを行う場合は、マスターとワーカーノードの互換性を考慮して作業手順を考える必要があります。クラスタのバージョンを一気に1.15に上げると、ワーカーノードのバージョンが1.12なので互換性が保証されていない状態となります。そのため、以下のように1.15にアップする前に一度ワーカーノードのバージョンをアップしておくほうが安全かと思います。

  • クラスタのバージョンアップ(1.12→1.13)
  • クラスタのバージョンアップ(1.13→1.14)
  • ワーカーノードのバージョンアップ(1.12→1.14)
  • クラスタのバージョンアップ(1.14→1.15)
  • ワーカーノードのバージョンアップ(1.14→1.15)

まとめ

バージョンアップについては、可能であればブルー・グリーンデプロイで切り替える方が安全にバージョンアップが可能だと思います。今回は諸々の制約により現行のEKSクラスタをアップデートする手法を選択しました。
Kubernetesのリリースに追従していく必要があるとはいえ、バージョンアップ作業については、作業手順の確立や関係者の調整なども含めて対応に時間がかかるので先送りにしがちではないでしょうか。
しかしながら、Kubernetesを使うのであれば定期的なバージョンアップ作業も運用の一環として考えていく必要があると思いますので、ぜひ手順を確立するようにしてみてください。