YasuBlog

中年インフラエンジニアの備忘録です。

EKS Cluster のバージョンアップ

Kubernetes と EKS のバージョンの整理と、EKS Cluster のバージョンアップ手順について整理しました。

1. Kubernetes のバージョン

まずは Kubernetes のバージョンについて整理します。

  • バージョンは x.y.z 形式で表現され、x はメジャーバージョン、y はマイナーバージョン、z はパッチバージョンを指す
  • 最新 3 つのマイナーバージョンのみサポート
    • 2022/02/08 時点では 1.23,1.22,1.21 のみサポート
  • 4 ヶ月に一回の頻度で新しいマイナーバージョンがリリースされる
  • だいたい月に一回の頻度で新しいパッチバージョンがリリースされる
  • 各マイナーバージョンのサポート期間は一年(1.18 以前は 9 ヶ月)
    • 一年経つと 2 ヶ月間のメンテナンスモードに入る
    • セキュリティや重大なコンポーネントの問題が発生した際はメンテナンスモード中もパッチがリリースされる
    • メンテナンスモードが終了すると EOL となり、パッチはリリースされなくなる
    • メンテナンスモードと EOL は毎月 28 日としている(全ての月にある日のため)
  • 直近のマイナーバージョンリリース
マイナーバージョン リリース日 メンテナンスモードに入る日 EOL
1.24 2022/4 予定
1.23 2021/12/7 2022/12/28 2023/2/28
1.22 2021/8/4 2022/8/28 2022/10/28
1.21 2021/4/8 2022/4/28 2022/6/28
1.20 2020/12/8 2021/12/28 2022/2/28

理想はタイムリーに 4 ヶ月に一回、最低でも年に一回は Kubernetes Cluster のバージョンアップが必要となります。

2. EKS のバージョン

つづいて EKS のバージョンについて整理します。

  • 2022/02/08 時点でサポートされている Kubernetes バージョンは 1.21.2,1.20.7,1.19.8,1.18.16
  • Kubernetes バージョンは、Amazon EKS で最初に利用可能になってから 14 か月間は完全にサポートされる
    • Kubernetes 側でサポートを終了していても EKS にバックポートされる
  • 特定のマイナーバージョンのサポート終了日については、サポート終了日の最低 60 日前に AWS Personal Health Dashboard に通知される
  • サポート終了日の挙動
    • 対象バージョンで新しいクラスターを作成できなくなる
    • 既存のコントロールプレーン(Master)は、サポートされている最も古いバージョンに自動的に更新される(タイミングは指定できない)
    • コントロールプレーンの自動更新後は、クラスターアドオンとデータプレーン(Node)を手動で更新する必要がある
  • 少なくとも 4 つの Kubernetes バージョンをサポートするよう努めている
  • 直近のリリース
Kubernetes バージョン Kubernetes リリース日 EKS リリース日 EKS のサポート終了日
1.23 2021/12/7 未定 未定
1.22 2021/8/4 2022/3 予定 2023/5
1.21 2021/4/8 2021/7/19 2023/2
1.20 2020/12/8 2021/5/18 2022/7
1.19 2020/8/26 2021/2/16 2022/4
1.18 2020/3/23 2020/10/13 2022/2/18
  • 特別な要件がない限り最新バージョンで Cluster を作成する事を推奨
  • 新しいバージョンがリリースされたら速やかに Cluster をバージョンアップする事を推奨
  • 実績としては、Kubernetes の新しいマイナーバージョンがリリースされて EKS がそのバージョンをサポートするまでに半年ぐらいかかっている
  • バージョンアップについて
    • Master のバージョンアップ中にダウンタイムは発生しない
    • Master のバージョンアップ後、ロールバックはできない
    • Master のバージョンアップ後は、EKS アドオン(VPC CNI、CoreDNS、および kube-proxy アドオン)と Node を手動でバージョンアップする必要がある
    • バージョンアップ前の Master と Node の Kubernetes バージョンは同じにする必要がある
    • Cluster 作成時に指定したサブネット内に、2~3 の空き IP アドレスが必要
    • 一回にバージョンアップできるマイナーバージョンは一つのみ(例えば 1.20 から 1.22 に上げたい場合は、最初に 1.21 に更新した後に 1.22 に更新する必要がある)
    • バージョンアップするとカスタム設定が上書きされる場合がある

3. EKS Cluster のバージョンアップ

バージョンアップ方法としては以下 3 パターンがあります。

# 方法 pros cons
Master/NodeGroup 共に In Place ・公式ドキュメントに記載の方法
・作業がシンプルで簡単
・EKS アドオンの更新が必要
・NodeGroup をロールバックできない
・更新中は見守るしかできない(EKS が自動で更新するため Pod の停止/起動タイミングをコントロールできない)
Master は In Place、NodeGroup は Blue/Green ・NodeGroup をロールバックできる
・Pod の停止/起動タイミングをコントロールできる
・EKS アドオンの更新が必要
・①より作業が多い
Cluster を Blue/Green ・Master/NodeGroup 共にロールバックできる
・EKS アドオンの更新が不要
・作業が複雑になる
 ・CI/CD で参照しているクラスタエンドポイントの移行
 ・StatefulSet 等のステートフルなデータの移行
 ・アプリのエンドポイント切り替えの考慮等

①より②の方が安心、③は面倒、という事で今回は②の方法で検証します。バージョンは 1.20 から 1.21 に上げます。

3.1. EKS Cluster 作成

まずは 1.20 バージョンの EKS Cluster を作成します。

eksctl コマンドで EKS Cluster を作成する - YasuBlog の記事で作成した yaml を以下のように一部変更して Cluster を作成し、EKS アドオンをインストールします。

---
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: ekstest
  region: ap-northeast-1
  version: "1.20"

vpc:
  id: "vpc-063b58ff16344acfd"
  subnets:
    public:
      ap-northeast-1a:
          id: "subnet-06324dcadf5706acb"
      ap-northeast-1c:
          id: "subnet-048cad38a6c49de67"
      ap-northeast-1d:
          id: "subnet-0bb85370bb4b4528d"

managedNodeGroups:
  - name: managed-ng-20
    instanceType: t3.medium
    desiredCapacity: 3
    volumeSize: 30
    availabilityZones: ["ap-northeast-1a", "ap-northeast-1c", "ap-northeast-1d"]
    maxPodsPerNode: 20
    ssh:
      allow: true
      publicKeyName: ekstest

EKS アドオンインストール後のバージョンは以下です。

$ eksctl get addon --cluster ekstest
NAME        VERSION         STATUS  ISSUES  IAMROLE                                             UPDATE AVAILABLE
coredns     v1.8.3-eksbuild.1 ACTIVE  0
kube-proxy  v1.20.7-eksbuild.1    ACTIVE  0
vpc-cni     v1.10.1-eksbuild.1    ACTIVE  0  arn:aws:iam::544880603668:role/eksctl-ekstest-addon-iamserviceaccount-kube-Role1-A4OVEJ0N035E

EKS アドオンのバージョンは Kubernetes バージョンごとに異なります。Kubernetes をバージョンアップすると手動でアドオンをバージョンアップする必要があり、今回のケースだと CoreDNS と kube-proxy が手動更新対象となります。

EKS アドオン Kubernetes 1.20 Kubernetes 1.21
VPC CNI 1.10.1-eksbuild.1 1.10.1-eksbuild.1
CoreDNS 1.8.3 1.8.4
kube-proxy 1.20.4-eksbuild.2 1.21.2-eksbuild.2

3.2. ワークロード作成

本番環境で何も起動していない Cluster をバージョンアップするケースはないと思うので、検証用に適当な Deployment と StatefulSet を起動します。

deployment 用 yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: app
  template:
    metadata:
      labels:
        app: app
    spec:
      containers:
      - name: amazonlinux
        image: public.ecr.aws/amazonlinux/amazonlinux:latest
        command:
          - "bin/bash"
          - "-c"
          - "sleep 3600"

statefulset 用 yaml

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: statefulset
spec:
  serviceName: statefulset-a
  replicas: 3
  selector:
    matchLabels:
      app: stateful-app
  template:
    metadata:
      labels:
        app: stateful-app
    spec:
      containers:
      - name: amazonlinux
        image: public.ecr.aws/amazonlinux/amazonlinux:latest
        command:
          - "bin/bash"
          - "-c"
          - "sleep 3600"
        volumeMounts:
        - name: hoge
          mountPath: /hoge
  volumeClaimTemplates:
  - metadata:
      name: hoge
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 10G

それぞれ起動します。

$ kubectl apply -f test-deployment.yaml
deployment.apps/deployment created
$ kubectl apply -f test-statefulset.yaml
statefulset.apps/statefulset created
$ kubectl get pods -o wide
NAME                          READY   STATUS    RESTARTS   AGE   IP             NODE                                              NOMINATED NODE   READINESS GATES
deployment-6bb985c8c9-2nxzb   1/1     Running   0          94s   10.0.102.164   ip-10-0-102-121.ap-northeast-1.compute.internal   <none>           <none>
deployment-6bb985c8c9-m8kvw   1/1     Running   0          94s   10.0.103.40    ip-10-0-103-198.ap-northeast-1.compute.internal   <none>           <none>
deployment-6bb985c8c9-x6nhz   1/1     Running   0          94s   10.0.101.46    ip-10-0-101-193.ap-northeast-1.compute.internal   <none>           <none>
statefulset-0                 1/1     Running   0          56s   10.0.101.77    ip-10-0-101-193.ap-northeast-1.compute.internal   <none>           <none>
statefulset-1                 1/1     Running   0          29s   10.0.102.72    ip-10-0-102-121.ap-northeast-1.compute.internal   <none>           <none>
statefulset-2                 1/1     Running   0          15s   10.0.103.217   ip-10-0-103-198.ap-northeast-1.compute.internal   <none>           <none>

以下のような構成が作成できました。

f:id:dunkshoot:20220213214818p:plain

3.3. バージョンアップ

作成した 1.20 の Cluster を 1.21 にバージョンアップします。

3.3.1. バージョン確認

まずは Master と Node の Kubernetes バージョンが揃っていることを確認します。ズレている場合は Node のバージョンをあげて Master に合わせる必要があります。

# Master のバージョン確認
$ kubectl version --short
Client Version: v1.21.3
Server Version: v1.20.11-eks-f17b81
# Node のバージョン確認
$ kubectl get nodes
NAME                                              STATUS   ROLES    AGE     VERSION
ip-10-0-101-193.ap-northeast-1.compute.internal   Ready    <none>   48m   v1.20.11-eks-f17b81
ip-10-0-102-121.ap-northeast-1.compute.internal   Ready    <none>   48m   v1.20.11-eks-f17b81
ip-10-0-103-198.ap-northeast-1.compute.internal   Ready    <none>   48m   v1.20.11-eks-f17b81

3.3.2. ポッドセキュリティポリシーの確認

つづいて、Pod のセキュリティポリシーを確認します。ここはエラーが出なければ OK のようです。

$ kubectl get psp eks.privileged
NAME             PRIV   CAPS   SELINUX    RUNASUSER   FSGROUP    SUPGROUP   READONLYROOTFS   VOLUMES
eks.privileged   true   *      RunAsAny   RunAsAny    RunAsAny   RunAsAny   false            *

3.3.3. Master のバージョンアップ

EKS は、eksctl, マネジメントコンソール、AWS CLI の 3 パターンの方法でバージョンアップできます。今回は eksctl を使用します。

まずは eksctl のバージョンを確認します。0.77.0 以降が必要です。

$ eksctl version
0.71.0
# 低いためバージョンアップ
$ brew upgrade eksctl && brew link --overwrite eksctl
$ eksctl version
0.82.0

upgrade cluster コマンドを実行します。Master が現在のバージョンより 1 つ後のマイナーバージョンに更新されます。

$ eksctl upgrade cluster --name ekstest --approve
2022-02-13 17:30:35 []  eksctl version 0.82.0
2022-02-13 17:30:35 []  using region ap-northeast-1
2022-02-13 17:30:36 []  will upgrade cluster "ekstest" control plane from current version "1.20" to "1.21"
2022-02-13 17:30:38 []  waiting for requested "VersionUpdate" in cluster "ekstest" to succeed
2022-02-13 17:30:55 []  waiting for requested "VersionUpdate" in cluster "ekstest" to succeed

~省略~

2022-02-13 17:58:24 []  waiting for requested "VersionUpdate" in cluster "ekstest" to succeed
2022-02-13 17:58:43 []  waiting for requested "VersionUpdate" in cluster "ekstest" to succeed
2022-02-13 17:58:44 []  cluster "ekstest" control plane has been upgraded to version "1.21"
2022-02-13 17:58:44 []  you will need to follow the upgrade procedure for all of nodegroups and add-ons
2022-02-13 17:58:45 []  re-building cluster stack "eksctl-ekstest-cluster"
2022-02-13 17:58:45 []  all resources in cluster stack "eksctl-ekstest-cluster" are up-to-date
2022-02-13 17:58:45 []  checking security group configuration for all nodegroups
2022-02-13 17:58:45 []  all nodegroups have up-to-date cloudformation templates
# Master のバージョン確認
$ kubectl version --short
Client Version: v1.21.3
Server Version: v1.21.5-eks-bc4871b

Master を 1.20 から 1.21 に更新するのに 30 分ほどかかりました。

Master をバージョンアップすると EKS アドオンの UPDATE AVAILABLE 列に新しいバージョンが表示されます。今回の場合だと CoreDNS と kube-proxy の新しいバージョンが利用可能なことがわかります。

$ eksctl get addon --cluster ekstest
2022-02-13 18:05:12 []  eksctl version 0.82.0
2022-02-13 18:05:12 []  using region ap-northeast-1
2022-02-13 18:05:12 []  Kubernetes version "1.21" in use by cluster "ekstest"
2022-02-13 18:05:12 []  getting all addons
2022-02-13 18:05:14 []  to see issues for an addon run `eksctl get addon --name <addon-name> --cluster <cluster-name>`
NAME        VERSION         STATUS  ISSUES  IAMROLE                                             UPDATE AVAILABLE
coredns     v1.8.3-eksbuild.1 ACTIVE  0                                                  v1.8.4-eksbuild.1
kube-proxy  v1.20.7-eksbuild.1    ACTIVE  0                                                  v1.21.2-eksbuild.2
vpc-cni     v1.10.1-eksbuild.1    ACTIVE  0  arn:aws:iam::544880603668:role/eksctl-ekstest-addon-iamserviceaccount-kube-Role1-A4OVEJ0N035E

3.3.4. 新 NodeGroup の作成

つづいて Node 側のバージョンアップです。流れとしては新しいバージョンの NodeGroup を作成して Pod を移行した後に 旧 NodeGroup を削除します。

まずは既存の NodeGroup を確認します。

$ eksctl get nodegroup --cluster ekstest
2022-02-13 17:32:47 []  eksctl version 0.82.0
2022-02-13 17:32:47 []  using region ap-northeast-1
CLUSTER NODEGROUP   STATUS  CREATED         MIN SIZE    MAX SIZE    DESIRED CAPACITY    INSTANCE TYPE   IMAGE ID    ASG NAME
ekstest managed-ng-20   ACTIVE  2022-02-13T07:39:38Z    3      3      3          t3.medium   AL2_x86_64  eks-48bf7902-e8cc-5e14-42af-54c664189abe

つづいて新しいバージョン(1.21)の NodeGroup を作成します。設定は既存(1.20)の NodeGroup と同じにします。create nodegroup コマンドにバージョンを指定するオプションはなく、Master と同じバージョンの NodeGroup が作成されるようです。

$ eksctl create nodegroup --cluster ekstest --region ap-northeast-1 --name managed-ng-21 --node-type t3.medium --nodes 3 --nodes-min 3 --nodes-max 3 --ssh-access --ssh-public-key ekstest
2022-02-13 18:10:07 []  eksctl version 0.82.0
2022-02-13 18:10:07 []  using region ap-northeast-1
2022-02-13 18:10:07 []  will use version 1.21 for new nodegroup(s) based on control plane version
2022-02-13 18:10:08 []  nodegroup "managed-ng-21" will use "" [AmazonLinux2/1.21]
2022-02-13 18:10:08 []  using EC2 key pair %!q(*string=<nil>)
2022-02-13 18:10:09 []  1 existing nodegroup(s) (managed-ng-20) will be excluded
2022-02-13 18:10:09 []  1 nodegroup (managed-ng-21) was included (based on the include/exclude rules)
2022-02-13 18:10:09 []  will create a CloudFormation stack for each of 1 managed nodegroups in cluster "ekstest"
2022-02-13 18:10:10 []
2 sequential tasks: { fix cluster compatibility, 1 task: { 1 task: { create managed nodegroup "managed-ng-21" } }
}
2022-02-13 18:10:10 []  checking cluster stack for missing resources
2022-02-13 18:10:10 []  cluster stack has all required resources
2022-02-13 18:10:11 []  building managed nodegroup stack "eksctl-ekstest-nodegroup-managed-ng-21"
2022-02-13 18:10:11 []  deploying stack "eksctl-ekstest-nodegroup-managed-ng-21"
2022-02-13 18:10:11 []  waiting for CloudFormation stack "eksctl-ekstest-nodegroup-managed-ng-21"
2022-02-13 18:10:27 []  waiting for CloudFormation stack "eksctl-ekstest-nodegroup-managed-ng-21"

~省略~

2022-02-13 18:13:46 []  waiting for CloudFormation stack "eksctl-ekstest-nodegroup-managed-ng-21"
2022-02-13 18:14:04 []  waiting for CloudFormation stack "eksctl-ekstest-nodegroup-managed-ng-21"
2022-02-13 18:14:04 []  no tasks
2022-02-13 18:14:04 []  created 0 nodegroup(s) in cluster "ekstest"
2022-02-13 18:14:05 []  nodegroup "managed-ng-21" has 3 node(s)
2022-02-13 18:14:05 []  node "ip-10-0-101-208.ap-northeast-1.compute.internal" is ready
2022-02-13 18:14:05 []  node "ip-10-0-102-86.ap-northeast-1.compute.internal" is ready
2022-02-13 18:14:05 []  node "ip-10-0-103-214.ap-northeast-1.compute.internal" is ready
2022-02-13 18:14:05 []  waiting for at least 3 node(s) to become ready in "managed-ng-21"
2022-02-13 18:14:05 []  nodegroup "managed-ng-21" has 3 node(s)
2022-02-13 18:14:05 []  node "ip-10-0-101-208.ap-northeast-1.compute.internal" is ready
2022-02-13 18:14:05 []  node "ip-10-0-102-86.ap-northeast-1.compute.internal" is ready
2022-02-13 18:14:05 []  node "ip-10-0-103-214.ap-northeast-1.compute.internal" is ready
2022-02-13 18:14:05 []  created 1 managed nodegroup(s) in cluster "ekstest"
2022-02-13 18:14:05 []  checking security group configuration for all nodegroups
2022-02-13 18:14:05 []  all nodegroups have up-to-date cloudformation templates
# 作成されている事を確認
$ eksctl get nodegroup --cluster ekstest
2022-02-13 18:14:20 []  eksctl version 0.82.0
2022-02-13 18:14:20 []  using region ap-northeast-1
CLUSTER NODEGROUP   STATUS  CREATED         MIN SIZE    MAX SIZE    DESIRED CAPACITY    INSTANCE TYPE   IMAGE ID    ASG NAME
ekstest managed-ng-20   ACTIVE  2022-02-13T07:39:38Z    3      3      3          t3.medium   AL2_x86_64  eks-48bf7902-e8cc-5e14-42af-54c664189abe
ekstest managed-ng-21   ACTIVE  2022-02-13T09:11:10Z    3      3      3          t3.medium   AL2_x86_64  eks-managed-ng-21-6cbf792c-cfa3-8215-20ef-7eae8033569f
# Node のバージョンを確認
$ kubectl get nodes
NAME                                              STATUS   ROLES    AGE   VERSION
ip-10-0-101-193.ap-northeast-1.compute.internal   Ready    <none>   93m   v1.20.11-eks-f17b81
ip-10-0-101-208.ap-northeast-1.compute.internal   Ready    <none>   85s   v1.21.5-eks-9017834
ip-10-0-102-121.ap-northeast-1.compute.internal   Ready    <none>   93m   v1.20.11-eks-f17b81
ip-10-0-102-86.ap-northeast-1.compute.internal    Ready    <none>   85s   v1.21.5-eks-9017834
ip-10-0-103-198.ap-northeast-1.compute.internal   Ready    <none>   93m   v1.20.11-eks-f17b81
ip-10-0-103-214.ap-northeast-1.compute.internal   Ready    <none>   87s   v1.21.5-eks-9017834

新しい NodeGroup の作成に 4 分ほどかかりました。以下の構成が作成できました。

f:id:dunkshoot:20220213215121p:plain

3.3.5. Pod の移行

旧 Node を drain して Pod を新 Node で起動させます。NodeGroup をまるごと drain する事も可能ですがちょっと怖いので Node を 1 台ずつ drain します。

※ drain は Pod に SIGTERM を送るため、SIGTERM を受けて正常に終了するように作られているアプリケーションが前提となります

# Node の確認
$ kubectl get nodes
NAME                                              STATUS   ROLES    AGE   VERSION
ip-10-0-101-193.ap-northeast-1.compute.internal   Ready    <none>   93m   v1.20.11-eks-f17b81
ip-10-0-101-208.ap-northeast-1.compute.internal   Ready    <none>   85s   v1.21.5-eks-9017834
ip-10-0-102-121.ap-northeast-1.compute.internal   Ready    <none>   93m   v1.20.11-eks-f17b81
ip-10-0-102-86.ap-northeast-1.compute.internal    Ready    <none>   85s   v1.21.5-eks-9017834
ip-10-0-103-198.ap-northeast-1.compute.internal   Ready    <none>   93m   v1.20.11-eks-f17b81
ip-10-0-103-214.ap-northeast-1.compute.internal   Ready    <none>   87s   v1.21.5-eks-9017834
# Pod の確認(全て 1.20 の Node で起動)
$ kubectl get pods -o wide
NAME                          READY   STATUS    RESTARTS   AGE   IP             NODE                                              NOMINATED NODE   READINESS GATES
deployment-6bb985c8c9-2nxzb   1/1     Running   0          25m   10.0.102.164   ip-10-0-102-121.ap-northeast-1.compute.internal   <none>           <none>
deployment-6bb985c8c9-m8kvw   1/1     Running   0          25m   10.0.103.40    ip-10-0-103-198.ap-northeast-1.compute.internal   <none>           <none>
deployment-6bb985c8c9-x6nhz   1/1     Running   0          25m   10.0.101.46    ip-10-0-101-193.ap-northeast-1.compute.internal   <none>           <none>
statefulset-0                 1/1     Running   0          25m   10.0.101.77    ip-10-0-101-193.ap-northeast-1.compute.internal   <none>           <none>
statefulset-1                 1/1     Running   0          24m   10.0.102.72    ip-10-0-102-121.ap-northeast-1.compute.internal   <none>           <none>
statefulset-2                 1/1     Running   0          24m   10.0.103.217   ip-10-0-103-198.ap-northeast-1.compute.internal   <none>           <none>
# 1.20 の Node を一台ずつ drain
$ kubectl drain ip-10-0-102-121.ap-northeast-1.compute.internal --ignore-daemonsets --delete-emptydir-data
node/ip-10-0-102-121.ap-northeast-1.compute.internal cordoned
WARNING: ignoring DaemonSet-managed Pods: kube-system/aws-node-pgfsx, kube-system/kube-proxy-mfxsj
evicting pod default/statefulset-1
evicting pod default/deployment-6bb985c8c9-2nxzb
pod/deployment-6bb985c8c9-2nxzb evicted
pod/statefulset-1 evicted
node/ip-10-0-102-121.ap-northeast-1.compute.internal evicted
$ kubectl drain ip-10-0-101-193.ap-northeast-1.compute.internal --ignore-daemonsets --delete-emptydir-data
$ kubectl drain ip-10-0-103-198.ap-northeast-1.compute.internal --ignore-daemonsets --delete-emptydir-data
# Node の確認
$ kubectl get nodes
NAME                                              STATUS                     ROLES    AGE    VERSION
ip-10-0-101-193.ap-northeast-1.compute.internal   Ready,SchedulingDisabled   <none>   105m   v1.20.11-eks-f17b81
ip-10-0-101-208.ap-northeast-1.compute.internal   Ready                      <none>   13m    v1.21.5-eks-9017834
ip-10-0-102-121.ap-northeast-1.compute.internal   Ready,SchedulingDisabled   <none>   105m   v1.20.11-eks-f17b81
ip-10-0-102-86.ap-northeast-1.compute.internal    Ready                      <none>   13m    v1.21.5-eks-9017834
ip-10-0-103-198.ap-northeast-1.compute.internal   Ready,SchedulingDisabled   <none>   105m   v1.20.11-eks-f17b81
ip-10-0-103-214.ap-northeast-1.compute.internal   Ready                      <none>   14m    v1.21.5-eks-9017834
# Pod の確認
$ kubectl get pods -o wide
NAME                          READY   STATUS    RESTARTS   AGE     IP             NODE                                              NOMINATED NODE   READINESS GATES
deployment-6bb985c8c9-9sp8k   1/1     Running   0          66s     10.0.103.177   ip-10-0-103-214.ap-northeast-1.compute.internal   <none>           <none>
deployment-6bb985c8c9-ccbms   1/1     Running   0          2m34s   10.0.102.231   ip-10-0-102-86.ap-northeast-1.compute.internal    <none>           <none>
deployment-6bb985c8c9-d656x   1/1     Running   0          3m46s   10.0.101.182   ip-10-0-101-208.ap-northeast-1.compute.internal   <none>           <none>
statefulset-0                 1/1     Running   0          3m14s   10.0.101.12    ip-10-0-101-208.ap-northeast-1.compute.internal   <none>           <none>
statefulset-1                 1/1     Running   0          118s    10.0.102.206   ip-10-0-102-86.ap-northeast-1.compute.internal    <none>           <none>
statefulset-2                 1/1     Running   0          30s     10.0.103.105   ip-10-0-103-214.ap-northeast-1.compute.internal   <none>           <none>

全ての Pod が新 Node で起動しました。

3.3.6. 旧 NodeGroup の削除

旧 Node 上で動く Pod がなくなったので旧 NodeGroup を削除します。

$ eksctl delete nodegroup --cluster ekstest --region ap-northeast-1 --name managed-ng-20
2022-02-13 18:28:34 []  eksctl version 0.82.0
2022-02-13 18:28:34 []  using region ap-northeast-1
2022-02-13 18:28:34 []  1 nodegroup (managed-ng-20) was included (based on the include/exclude rules)
2022-02-13 18:28:34 []  will drain 1 nodegroup(s) in cluster "ekstest"
2022-02-13 18:28:34 [!]  ignoring DaemonSet-managed Pods: kube-system/aws-node-plgkj, kube-system/kube-proxy-x9b6h
2022-02-13 18:28:34 [!]  ignoring DaemonSet-managed Pods: kube-system/aws-node-pgfsx, kube-system/kube-proxy-mfxsj
2022-02-13 18:28:34 [!]  ignoring DaemonSet-managed Pods: kube-system/aws-node-qswdg, kube-system/kube-proxy-fzk28
2022-02-13 18:28:34 []  drained all nodes: [ip-10-0-101-193.ap-northeast-1.compute.internal ip-10-0-102-121.ap-northeast-1.compute.internal ip-10-0-103-198.ap-northeast-1.compute.internal]
2022-02-13 18:28:34 []  will delete 1 nodegroups from cluster "ekstest"
2022-02-13 18:28:35 []  1 task: { 1 task: { delete nodegroup "managed-ng-20" [async] } }
2022-02-13 18:28:35 []  will delete stack "eksctl-ekstest-nodegroup-managed-ng-20"
2022-02-13 18:28:35 []  will delete 0 nodegroups from auth ConfigMap in cluster "ekstest"
2022-02-13 18:28:35 []  deleted 1 nodegroup(s) from cluster "ekstest"
# 削除されている事を確認
$ eksctl get nodegroup --cluster ekstest
2022-02-13 18:32:50 []  eksctl version 0.82.0
2022-02-13 18:32:50 []  using region ap-northeast-1
CLUSTER NODEGROUP   STATUS  CREATED         MIN SIZE    MAX SIZE    DESIRED CAPACITY    INSTANCE TYPE   IMAGE ID    ASG NAME
ekstest managed-ng-21   ACTIVE  2022-02-13T09:11:10Z    3      3      3          t3.medium   AL2_x86_64  eks-managed-ng-21-6cbf792c-cfa3-8215-20ef-7eae8033569f
# Node のバージョンを確認
$ kubectl get nodes
NAME                                              STATUS   ROLES    AGE   VERSION
ip-10-0-101-208.ap-northeast-1.compute.internal   Ready    <none>   19m   v1.21.5-eks-9017834
ip-10-0-102-86.ap-northeast-1.compute.internal    Ready    <none>   19m   v1.21.5-eks-9017834
ip-10-0-103-214.ap-northeast-1.compute.internal   Ready    <none>   19m   v1.21.5-eks-9017834

Master と Node のバージョンが 1.21 になりました。

f:id:dunkshoot:20220213215332p:plain

3.2.7. EKS アドオンの更新

最後に EKS アドオンをバージョンアップします。

# バージョン確認
$ eksctl get addon --cluster ekstest
2022-02-13 18:34:06 []  eksctl version 0.82.0
2022-02-13 18:34:06 []  using region ap-northeast-1
2022-02-13 18:34:06 []  Kubernetes version "1.21" in use by cluster "ekstest"
2022-02-13 18:34:06 []  getting all addons
2022-02-13 18:34:08 []  to see issues for an addon run `eksctl get addon --name <addon-name> --cluster <cluster-name>`
NAME        VERSION         STATUS  ISSUES  IAMROLE                                             UPDATE AVAILABLE
coredns     v1.8.3-eksbuild.1 ACTIVE  0                                                  v1.8.4-eksbuild.1
kube-proxy  v1.20.7-eksbuild.1    ACTIVE  0                                                  v1.21.2-eksbuild.2
vpc-cni     v1.10.1-eksbuild.1    ACTIVE  0  arn:aws:iam::544880603668:role/eksctl-ekstest-addon-iamserviceaccount-kube-Role1-A4OVEJ0N035E
# CoreDNS バージョンアップ
$ eksctl update addon --name coredns --version v1.8.4-eksbuild.1 --cluster ekstest --force
2022-02-13 18:34:51 []  Kubernetes version "1.21" in use by cluster "ekstest"
2022-02-13 18:34:52 []  new version provided v1.8.4-eksbuild.1
2022-02-13 18:34:52 []  updating addon
# kube-proxy バージョンアップ
$ eksctl update addon --name kube-proxy --version v1.21.2-eksbuild.2 --cluster ekstest --force
2022-02-13 18:35:26 []  Kubernetes version "1.21" in use by cluster "ekstest"
2022-02-13 18:35:27 []  new version provided v1.21.2-eksbuild.2
2022-02-13 18:35:27 []  updating addon
# バージョン確認
$ eksctl get addon --cluster ekstest
2022-02-13 18:36:14 []  eksctl version 0.82.0
2022-02-13 18:36:14 []  using region ap-northeast-1
2022-02-13 18:36:14 []  Kubernetes version "1.21" in use by cluster "ekstest"
2022-02-13 18:36:14 []  getting all addons
2022-02-13 18:36:16 []  to see issues for an addon run `eksctl get addon --name <addon-name> --cluster <cluster-name>`
NAME        VERSION         STATUS  ISSUES  IAMROLE                                             UPDATE AVAILABLE
coredns     v1.8.4-eksbuild.1 ACTIVE  0
kube-proxy  v1.21.2-eksbuild.2    ACTIVE  0
vpc-cni     v1.10.1-eksbuild.1    ACTIVE  0  arn:aws:iam::544880603668:role/eksctl-ekstest-addon-iamserviceaccount-kube-Role1-A4OVEJ0N035E

4. まとめ

本番環境を想定するとバージョンアップ方法は Master は In Place, Node は Blue/Green が安全かと思います。 今回は検証のため単純な Deployment と StatefulSet が起動している Cluster で検証したので簡単でしたが、実際の本番環境で実施する場合は結構怖い作業ですね。何かにハマるケースもあるかと思います。

5. 参考

Kubernetesバージョンとバージョンスキューサポートポリシー | Kubernetes

website/patch-releases.md at main · kubernetes/website · GitHub

Patch Releases | Kubernetes

Releases | Kubernetes

Amazon EKS Kubernetes versions - Amazon EKS

クラスターの更新 - Amazon EKS

マネージド型ノードグループの作成 - Amazon EKS

マネージド型ノードグループの更新 - Amazon EKS

マネージド型ノードグループの削除 - Amazon EKS

eksctl のインストール - Amazon EKS