EKS アップデート手順ざっくりまとめ (2)
事前準備
EKS アップデート手順ざっくりまとめ (1) で調査した情報を参考に、マニフェストなどの修正を事前に済ませ PR などを準備しておく。
手順
例として EKS 1.22 へのアップデート手順をざっくりとまとめる。
監視外し
Kubernetes のリソース監視を行っている場合は、 EKS アップデートの妨げになるため一時的にミュートするなどの対応を済ませておく。
共有
EKS アップデートを速やかに完了させるため、念の為リリース作業などを控えてもらうように関係者へ情報共有しておく。
クラスタバージョンアップ
バージョンアップ前の確認
Client Version と Server Version のマイナーバージョンが +/-1 であれば問題ない。
kubectl config use-context {コンテキスト}
kubectl version --short
pod セキュリティポリシー確認
エラーが出なければ問題ない。
kubectl get psp eks.privileged
ドライラン
メッセージを確認する。
eksctl upgrade cluster --name {クラスタ名}
バージョンアップ実施
10分程度で完了する。
完了後はアプリケーション側に影響が出ていないかログを確認する。
$ eksctl upgrade cluster --name {クラスタ名} --approve
バージョンアップ後の確認
Server Version が、バージョンアップ後のバージョンとなっていることを確認する。
kubectl version --short
kubectl get nodes
サードパーティのバージョンアップ
EKS アップデート手順ざっくりまとめ (1) で事前調査した情報をもとに、アップデートが必要なモジュールに対してバージョンアップを行っていく。
主に使われるモジュールのざっくりとしたバージョンアップ方法は以下。
cluster-autoscaler
基本的にはユーザーガイドの通りやっていく。
マニフェストを Git 上で管理していたりする場合でも似たような感じになる。
curl -O https://raw.githubusercontent.com/kubernetes/autoscaler/master/cluster-autoscaler/cloudprovider/aws/examples/cluster-autoscaler-autodiscover.yaml
# Versionを変更
sed -i '' -e 's|{変更前バージョン}|{変更後バージョン}|' cluster-autoscaler-autodiscover.yaml
# クラスタ名を変更
sed -i '' -e 's|<YOUR CLUSTER NAME>|{クラスタ名}|' cluster-autoscaler-autodis
kubectl apply -f cluster-autoscaler-autodiscover.yaml
アップデート後は再起動完了とバージョンを確認し、アプリケーション側に影響が出ていないかログを確認する。
kubectl get pod -n kube-system -l app="cluster-autoscaler"
kubectl get deployment cluster-autoscaler -n kube-system -o yaml | grep "image:"
Amazon VPC CNI plugin for Kubernetes
基本的にはユーザーガイドの通りやっていく。
セルフマネージド型のアップデートの場合は以下。
curl -O https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/{バージョン}/config/master/aws-k8s-cni.yaml
sed -i.bak -e 's|us-west-2|ap-northeast-1|' aws-k8s-cni.yaml
# 変更内容が問題ないか確認する
diff aws-k8s-cni.yaml.bak aws-k8s-cni.yaml
kubectl apply -f aws-k8s-cni.yaml
アップデート後は再起動完了とバージョンを確認し、アプリケーション側に影響が出ていないかログを確認する。
kubectl get pods -n kube-system -l k8s-app=aws-node
kubectl describe daemonset aws-node -n kube-system | grep amazon-k8s-cni: | cut -d : -f 3
CoreDNS
基本的にはユーザーガイドの通りやっていく。
セルフマネージド型のアップデートの場合は以下。
kubectl set image deployment.apps/coredns -n kube-system \
coredns=602401143452.dkr.ecr.{リージョン}.amazonaws.com/eks/coredns:{バージョン}
アップデート後は再起動完了とバージョンを確認し、アプリケーション側に影響が出ていないかログを確認する。
kubectl get pod -n kube-system -l k8s-app=kube-dns
kubectl describe deployment coredns -n kube-system | grep Image | cut -d ":" -f 3
kube-proxy
基本的にはユーザーガイドの通りやっていく。
セルフマネージド型のアップデートの場合は以下。
kubectl set image daemonset.apps/kube-proxy -n kube-system \
kube-proxy=602401143452.dkr.ecr.{リージョン}.amazonaws.com/eks/kube-proxy:{バージョン}
アップデート後は再起動完了とバージョンを確認し、アプリケーション側に影響が出ていないかログを確認する。
kubectl get pod -n kube-system -l k8s-app=kube-proxy
kubectl describe daemonset kube-proxy -n kube-system | grep Image | cut -d ":" -f 3
新ノードグループの作成
Pod の移動先となるノードグループを作成していく。
既存のノードグループの設定 (managedNodeGroups下) をコピーして作成する。
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: {クラスタ名}
region: ap-northeast-1
version: 1.22
managedNodeGroups:
- name: old-nodegroup
...
- name: new-nodegroup
...
eksctl create nodegroup --config-file={YAMLファイル名} --include='{新ノードグループ名}'
AWS コンソールの CloudFormation > スタック
から新しく作成したノードグループが存在し、ステータスが CREATE_COMPLETE
であることを確認する。
作成したノードグループが存在することを確認する。
eksctl get nodegroups --cluster {クラスタ名}
この段階で、既存のノードグループのノード数と作成したノードグループのノード数が一致するように、AWS コンソールから一時的に変更しておくと良い。
ノードグループ作成後、アプリケーション側に影響が出ていないかログを確認する。
aws-node や kube-proxy などの daemonset が全てのノードで立ち上がっているか確認する。
kubectl describe nodes
Pod の移動
既存のノードグループのノードに対してスケジューリングされない様に cordon する。
kubectl cordon -l alpha.eksctl.io/nodegroup-name={既存のノードグループ名}
既存のノードグループのノードの STATUS
が Ready,SchedulingDisabled
になっていることを確認する。
kubectl get nodes --sort-by=.metadata.creationTimestamp
次のコマンドで drain コマンドを作成し出力された分だけ実行していく流していく。
kubectl get nodes --sort-by=.metadata.creationTimestamp | grep 'SchedulingDisabled' | awk -F' ' '{print "kubectl drain --delete-emptydir-data --ignore-daemonsets "$1}'
Pod の移動後、アプリケーション側に影響が出ていないかログを確認する。
既存のノードグループのノード数と作成したノードグループのノード数が一致するように変更している場合は、AWS コンソールから一時的に変更した最小キャパシティの設定を元に戻す。
旧ノードグループの削除
既存のノードグループのノードが新しく起動していないか確認する。
起動していた場合は、再度 cordon を行う。
kubectl get nodes --sort-by=.metadata.creationTimestamp -o wide
まずはドライラン。
eksctl delete nodegroup --config-file={YAMLファイル名} --include='{既存のノードグループ名}'
削除対象のノードグループが正しいことを確認し、実行する。
eksctl delete nodegroup --config-file={YAMLファイル名} --include='{既存のノードグループ名}' --update-auth-configmap=false --approve
AWS コンソールの CloudFormation > スタック
から削除したノードグループが存在しないことを確認する。
削除したノードグループのノードが存在しないことを確認する。
kubectl get nodes --sort-by=.metadata.creationTimestamp -o wide
削除したノードグループが存在しないことを確認する。
eksctl get nodegroups --cluster {クラスタ名}
アプリケーション側に影響が出ていないかログを確認する。
事後作業
アプリケーション側に影響が出ていないことを確認し、監視外しなどで行った作業をもとに戻す。
共有
アップデート前に関係者へ情報共有している場合は、アップデート作業が完了した旨を関係者へ共有する。
Discussion