SMARTCAMP Engineer Blog

スマートキャンプ株式会社(SMARTCAMP Co., Ltd.)のエンジニアブログです。業務で取り入れた新しい技術や試行錯誤を知見として共有していきます。

プロダクトのEKSを4バージョン一気にアップデートした話

スマートキャンプ、エンジニアの井上です。

現在私が開発しているBALES CLOUDのインフラ基盤はEKSが採用されています。
そのEKSのバージョンは1.15でサポートが2021年5月に切れてしまうので、EKSのアップデート作業を行いました。
今回の記事ではそのときのアップデート作業の詳細やその目的、また、アップデートによって出来るようになったことなどをご紹介できればと思います。

なぜ、一気に4バージョンもアップデートしたのか?

EKSは、そのバージョンが利用可能になってから14ヶ月間サポートされます。
これだけ見ると、1バージョンあげれば1年間は安心して過ごせそうに見えます。

しかし、この話にはEKSとKubernetesのサポートの2軸があり、EKS側では下記のように書かれています。

Kubernetes バージョンに対する Kubernetes コミュニティのサポートに沿って、Amazon EKS は Kubernetes の少なくとも 4 つの本番稼働対応バージョンをいつでもサポートするよう努めています。Kubernetes の特定のマイナーバージョンのサポート終了日については、サポート終了日の最低 60 日前に発表します。Kubernetes の新しいバージョンの Amazon EKS の認定およびリリースプロセスにより、Amazon EKS の Kubernetes バージョンのサポート終了日は、Kubernetes プロジェクトがバージョンアップストリームのサポートを停止した日以降になります。

docs.aws.amazon.com

このようにKubernetesがサポート終了してもEKSのバージョンはサポートが切れずに使い続けることができるケースがあります。
しかし、本家であるKubernetesがサポートしてないバージョンを使用するのはリスクが高く不安です。
このためアップデートは本家Kubernetesのサポート期限に追従する形にしていきたいと考えました。

Kubernetesでは最新3つのマイナーリリースについてリリースブランチを管理しています (2021/0426現在では1.21, 1.20, 1.19)。
EKSでの最新バージョンは1.19なので、できれば1.19までアップデートしてEKS、Kubernetesのどちらにもサポートされているバージョンとしたかったのが今回一気に4バージョンアップデートすることにした理由です。

とはいえAWSも本家KubernetesのバージョンとEKSがサポートしているバージョン間のギャップは減ってきているので、 今後はこういったことを考える必要はないかもしれません。

EKSのアップデートの前提情報

では、実際にアップデートするにあたっての注意点などをご紹介できればと思います。

EKSは1バージョンずつしかあげられない

たとえば、1.15から1.17にアップデートする場合、1.15から1.16にあげて、その後1.16から1.17に上げる作業が必要になります。

クラスター更新時にKubernetesのアドオンは変更されない

コンソール画面でクラスターの更新が可能ですが、更新対象にKubernetesアドオンは含まれません。
そのため下記のKubernetesアドオンは手動で更新をしていく必要があります。

  • Amazon VPC CNI プラグイン
  • CoreDNS
  • KubeProxy

EKSバージョンごとに対応するアドオンのバージョン

EKS アップデート作業でやったことの紹介

どのバージョンでも共通して行う必要のある作業

EKSクラスター アップデート

クラスターのアップデートはコンソール画面とコマンドのどちらでも実行可能です。
このアップデートは30分ほどかかります。

nodeのAMIをEKS バージョンに合わせたAMIに変更する

EKSのバージョンに合わせてAMIのバージョンも指定されています。

過去にAMIのバージョンが古いせいで問題になったケースがあるので、EKSのバージョンに合わせた最新のAMIに変更することをお勧めします。

github.com

EKSのバージョンに合わせたKubeProxyに変更する

EKS1.16~EKS1.19まではバージョンごとにKubeProxyの推奨バージョンが異なるため、各バージョンでアップデートする必要があります。

kubectlのアップデート

kubectlもクラスターの更新時に更新されないため、バージョンごとに手動で更新する必要があります。
こちらは別ページで丁寧に書いてあるので、書かれている通り実行すれば問題ありません。

docs.aws.amazon.com

EKS1.16のみ行う必要のある作業

EKS1.16はアップデートするまえの前提条件が書かれるほど、変更作業が多いアップデートになります。
手動で変更する箇所が多いため、前提条件をしっかり確認した上で進めることをおすすめします。
また、EKSの状態によっては他にも対応する必要のある工程がありますが、今回はBALES CLOUDで必要だった対応を紹介します。

docs.aws.amazon.com

apps/v1への変更

1.16からDaemonSet、Deploymentは「extensions/v1beta1」や「apps/v1beta1」が廃止され「apps/v1」にする必要があります。

2020年8月17日より前にデプロイされている場合はマルチアーキテクチャ対応が必要です。

  • kube-proxyの設定にarm64を追加する
kubectl edit -n kube-system daemonset/kube-proxy
- key: "beta.kubernetes.io/arch"
                    operator: In
                    values:
                      - amd64
                      - arm64 <-追加
  • CoreDNSの設定にarm64を追加する
kubectl edit -n kube-system deployment/coredns
- key: "beta.kubernetes.io/arch"
                    operator: In
                    values:
                      - amd64
                      - arm64 <-追加

CoreDNSのマニフェストのupstreamオプションが非推奨になるため削除する

下記のエラーissueから手順に取り込まれたものです。

github.com

下記のコマンドを実行してupstreamの文字列が含まれていたら変更が必要になります。

kubectl get configmap coredns -n kube-system -o jsonpath='{$.data.Corefile}' | grep upstream

upstreamの文字列が有った場合修正していきます。

kubectl edit configmap coredns -n kube-system -o yaml
Corefile: |
  .:53 {
      errors
      health
      kubernetes cluster.local in-addr.arpa ip6.arpa {
        pods insecure
        upstream <=ここを削除
        fallthrough in-addr.arpa ip6.arpa
      }

Amazon VPC CNI Plugin for Kubernetesの推奨バージョンへのアップデート

1.16からAmazon VPC CNIの推奨バージョンが変わるためアップデート対応をします。
ここはus-west-2からap-northeast-1に変換するというちょっと面倒な作業があります。

curl -o aws-k8s-cni.yaml https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/v1.7.5/config/v1.7/aws-k8s-cni.yaml
sed -i -e 's/us-west-2/ap-northeast-1/' aws-k8s-cni.yaml
kubectl apply -f aws-k8s-cni.yaml

1.18、1.19のみ行う必要のある作業

1.18, 1.19でのみ推奨されるCoreDNSのバージョンが異なるため、
それぞれCoreDNSのイメージを更新する必要があります。
コマンドは現在のバージョン確認で出力された内容で書き換え、x.x.xの部分に対象のバージョンを指定して実行します。

  1. 現在のバージョンを確認する
kubectl get deployment coredns --namespace kube-system -o=jsonpath='{$.spec.template.spec.containers[:1].image}'
  1. 現在のバージョン確認の際に出力された値と602401143452.dkr.ecr.us-west-2.amazonaws.comの部分を置き換えx.x.xを対象のバージョンに指定する
kubectl set image --namespace kube-system deployment.apps/coredns \
            coredns=602401143452.dkr.ecr.us-west-2.amazonaws.com/eks/coredns:vx.x.x>-eksbuild.1

EKS1.19まであげたことにより、できるようになったこと

EKSを1.19まであげたことにより、プロダクトのインフラ基盤が圧倒的に改善されたわけではありませんが、
バージョンをあげたことによって今後安定性の高いインフラに変化させるための手段が増えたので、それらの例を一部ご紹介できればと思います。

1.19からKubernetesのサポート期間が1年に

これまでKubernetesのサポート期間は9ヶ月だったので、9ヶ月以内に次のバージョンにアップデートする必要がありましたが、1.19からはサポート期間が1年に変更されました!
(サポート期間9ヶ月間のバージョンでは、期間内にアップデートすることができたユーザーが限られていたことが理由のようです。https://kubernetes.io/blog/2020/08/26/kubernetes-release-1.19-accentuate-the-paw-sitive/#major-themes
これで、少し余裕をもってバージョンを追従することが可能になりました。

kubectl alpha debugの追加

Kubernetes 1.16で一部の機能がalphaとして提供されました。
kubectl alpha debugは、実行中のPodにエフェメラルコンテナと呼ばれるデバック用の一時的なコンテナを後から追加するコマンドです。
これにより既存のPodに調査用のmoduleなどをインストールせずともデバッグ用のコンテナにインストールして調査などが可能になります。

StartupProbe

StartupProbeは、コンテナの起動時のみに使用される新しいProbeです。
これまで起動にある程度時間がかかるコンテナではLivenessProbeやinitialDelaySecondでの調整が難しく、失敗すると強制終了されるリスクもありました。
StartupProbeは、このProbeが成功するまでLivenessProbeとReadinessProbeの2つのProbeが開始されません。
これにより起動時の調整がやりやすくなったかと思います。

HorizontalPodAutoscaler

HorizontalPodAutoscalerにspec.behaviorフィールドが追加されました。
これにより1回のスケーリングでどの程度スケールしてほしいかなどが設定できるようになり、
かなり柔軟なスケールアップ/スケールダウンそれぞれの挙動を設定できるようになりました。

※ autoscaling/v2beta2からの機能になります。

まとめ

今回はBALES CLOUDで行ったEKSアップデート作業を紹介しました。
可能な限り最新バージョンに追従していくことで開発や改善の手段を増やして、よりモダンな環境を構築していきたいと思います!