😸

EKS アップデート手順ざっくりまとめ (2)

2023/05/19に公開

事前準備

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 上で管理していたりする場合でも似たような感じになる。
https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/autoscaling.html#cluster-autoscaler

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
基本的にはユーザーガイドの通りやっていく。
https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/managing-vpc-cni.html

セルフマネージド型のアップデートの場合は以下。

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
基本的にはユーザーガイドの通りやっていく。
https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/managing-coredns.html

セルフマネージド型のアップデートの場合は以下。

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
基本的にはユーザーガイドの通りやっていく。
https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/managing-kube-proxy.html

セルフマネージド型のアップデートの場合は以下。

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={既存のノードグループ名}

既存のノードグループのノードの STATUSReady,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