クラスターの更新 - Amazon EKS

クラスターの更新

既存の Amazon EKS クラスターを新しい Kubernetes バージョンまたはクラスターのシークレット暗号化に更新することができます。

Amazon EKS クラスターの Kubernetes バージョンの更新

Amazon EKS で利用可能な新しい Kubernetes バージョンがある場合には、Amazon EKS クラスターを最新バージョンに更新できます。

重要

新しい Kubernetes バージョンに更新する前に、「Amazon EKS での Kubernetes のバージョン」とこのトピック内の更新手順で、情報を確認することをお勧めします。

新しい Kubernetes バージョンでは、大幅な変更が加えられています。このため、本稼働用クラスターで更新を行う前に、新しいバージョンの Kubernetes に対するアプリケーションの動作をテストしておくことをお勧めします。この際は、継続的な統合ワークフローを構築し、新しい Kubernetes バージョンに移行する前にアプリケーションの動作をテストします。

更新プロセスに含まれている Amazon EKS が、更新された Kubernetes バージョンを使用しながら新しい API サーバーノードを起動することで、既存のバージョンを置き換えます。Amazon EKS は、これらの新しいノードで、ネットワークトラフィックの標準インフラストラクチャと準備状況に関するヘルスチェックを実行し、想定どおりに動作していることを確認します。これらのヘルスチェックのいずれかが失敗すると、Amazon EKS はインフラストラクチャのデプロイを元に戻します。クラスターは前の Kubernetes バージョンのままになります。この際も、実行中のアプリケーションは影響を受けません。また、クラスターが不確定または回復不可能な状態のままになることもありません。Amazon EKS は定期的にすべてのマネージド型クラスターをバックアップします。さらに、必要に応じてクラスターを復元するメカニズムも存在します。Kubernetes インフラストラクチャの管理プロセスは、継続的に評価、改善されています。

クラスターをアップグレードする際、Amazon EKS には、クラスターの作成時に指定したサブネット内に、2~3 の空き IP アドレスが必要となります。これらのサブネットに利用可能な IP アドレスがない場合、アップグレードが失敗することがあります。さらに、クラスターの作成時に指定された、サブネットやセキュリティグループのいずれかが削除された場合も、クラスターのアップグレードが失敗することがあります。

注記

Amazon EKS では、可用性の高いコントロールプレーンが実行されていますが、更新時にはサービスが短時間中断する可能性はあります。例えば、終了直前または終了直後に新しいバージョンの Kubernetes を実行している新しい API サーバーに接続しようとすると、API コールエラーや接続の問題が発生する可能性があります。この場合は、成功するまで API オペレーションを繰り返し実行します。

Amazon EKS クラスターに必要な Kubernetes バージョンの更新方法

クラスターに必要な Kubernetes のバージョンの更新。

クラスターに必要な Kubernetes のバージョンの更新方法

  1. クラスターコントロールプレーンの Kubernetes バージョンと、ノードの Kubernetes バージョンを比較します。

    • 次のコマンドを使用して、クラスターコントロールプレーンの Kubernetes バージョンを取得します。

      kubectl version --short
    • 次のコマンドを使用して、ノードの Kubernetes バージョンを取得します。このコマンドでは、セルフマネージド型およびマネージド型の Amazon EC2 および Fargate ノードがすべて表示されます。各 Fargate ポッドは、独自のノードとしてリストされます。

      kubectl get nodes

    クラスター内の、マネージド型ノードと Fargate ノードの Kubernetes マイナーバージョンは、コントロールプレーンを新しい Kubernetes バージョンに更新する前に、コントロールプレーンの現在のバージョンと同じにする必要があります。例えば、コントロールプレーンがバージョン 1.20 を実行していて、いずれかのノードがバージョン 1.19を実行している場合には、コントロールプレーンの Kubernetes バージョンを 1.21 に更新する前に、ノードのバージョンを 1.20 に更新します。また、コントロールプレーンを更新する前に、セルフマネージド型ノードをコントロールプレーンと同じバージョンに更新することをお勧めします。詳細については、「マネージド型ノードグループの更新」および「セルフマネージド型ノードの更新」を参照してください。Fargate ノードのバージョンを更新するには、ノードと対応しているポッドを削除した上で、コントロールプレーンを更新した後に、ポッドを再デプロイします。

  2. Amazon EKS クラスターのデフォルトでは、ポッドセキュリティポリシーのアドミッションコントローラーが有効化されています。クラスターを更新する際には、事前に適切なポッドセキュリティポリシーが指定されていることを確認して、問題が発生することを防ぎます。以下のコマンドを使用して、デフォルトのポリシーを表示できます。

    kubectl get psp eks.privileged

    以下のエラーが表示された場合は、先に進む前に「デフォルトのポッドセキュリティポリシー」を確認してください。

    Error from server (NotFound): podsecuritypolicies.extensions "eks.privileged" not found
  3. Kubernetes 1.17 以前にクラスターを最初にデプロイした場合は、CoreDNS マニフェストから廃止された単語を削除する必要があります。

    1. CoreDNS マニフェストに、upstream というワードのみの行があるかどうかを確認します。

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

      出力が返されない場合は、マニフェストにこの行が含まれておらず、次のステップに進んでクラスターを更新できます。upstream というワードが返された場合は、その行を削除します。

    2. ConfigMap を編集し、ファイルの先頭付近にある、upstream のみを含む行を削除します。このファイル内の他の部分は変更しないでください。行を削除したら、変更を保存します。

      kubectl edit configmap coredns -n kube-system -o yaml
  4. eksctl、AWS Management Console、またはAWS CLI を使用してクラスターを更新します。

    重要
    • Amazon EKS は可用性の高いコントロールプレーンを実行しているため、一回に更新できるのはマイナーバージョン 1 つのみです。この背後にある論理的根拠については、「Kubernetes Version and Version Skew Support Policy (Kubernetes のバージョンおよびバージョンスキューのサポートポリシー)」を参照してください。したがって、現在のバージョン 1.19 を 1.21にアップグレードする場合には、最初にクラスターを 1.20 に更新した上で、その後に 1.20 から 1.21 への更新を行う必要があります。

    • 更新を行う前に、マネージド型および Fargate ノードの各 kubelet での Kubernetes バージョンは、コントロールプレーンのバージョンと同じにする必要があります。セルフマネージド型ノードのバージョンは、コントロールプレーンの現在のバージョンより最大 1 つ前のものにすることが可能ですが、コントロールプレーンのバージョンと同じにしておくことをお勧めします。

    • いずれかの AWS Fargate ポッドに、1.16 より前の kubelet マイナーバージョンのものがある場合、1.16 から 1.17 へのクラスターの更新が失敗します。クラスターで 1.16 から 1.17 への更新を試みる前に、Fargate ポッドをリサイクルし、‭kubelet‬ を 1.16 にしておく必要があります。

    • 1.16 に更新するには、事前にデプロイ済みのリソースの一部を更新する必要があります。詳細については、「」を参照してくださいKubernetes 1.16 に更新にするための前提条件

    • クラスターを新しいバージョンに更新すると、カスタム設定が上書きされる場合があります。

    eksctl

    この手順には、eksctl バージョン 0.67.0 以降が必要です。 のバージョンは、以下のコマンドを使用して確認できます。

    eksctl version

    eksctl のインストールまたは更新については、「eksctl のインストールまたはアップグレード」を参照してください。

    次のコマンドを使用して、Amazon EKS コントロールプレーンの Kubernetes バージョンを、現在のバージョンより 1 つ後のマイナーバージョンに更新します。<my-cluster> (<>を含む) を自分のクラスター名に置き換えます。

    eksctl upgrade cluster --name <my-cluster> --approve

    この更新は完了までに数分かかることがあります。

    AWS Management Console
    1. https://console.aws.amazon.com/eks/home#/clusters で Amazon EKS コンソールを開きます。

    2. 更新する Amazon EKS クラスター名を選択し、[クラスターバージョンの更新] を選択します。

    3. [Kubernetes version] で、バージョンを選択してクラスターを更新し、[更新] を選択します。

    4. [クラスター名] にクラスター名を入力し、[確認] を選択します。

      この更新は完了までに数分かかることがあります。

    AWS CLI
    1. 次の AWS CLI コマンドを使用して、Amazon EKS クラスターを更新します。<example-values> (<> を含む) を独自の値に置き換えます。

      aws eks update-cluster-version \ --region <region-code> \ --name <my-cluster> \ --kubernetes-version <1.21>

      出力:

      { "update": { "id": "<b5f0ba18-9a87-4450-b5a0-825e6e84496f>", "status": "InProgress", "type": "VersionUpdate", "params": [ { "type": "Version", "value": "1.21" }, { "type": "PlatformVersion", "value": "eks.1" } ], ... "errors": [] } }
    2. クラスター更新のステータスをモニタリングするには、次のコマンドを使用します。前のコマンドから返されたクラスター名と更新 ID を使用します。ステータスが Successful と表示されたら、更新は完了です。この更新は完了までに数分かかることがあります。

      aws eks describe-update \ --region <region-code> \ --name <my-cluster> \ --update-id <b5f0ba18-9a87-4450-b5a0-825e6e84496f>

      出力:

      { "update": { "id": "b5f0ba18-9a87-4450-b5a0-825e6e84496f", "status": "Successful", "type": "VersionUpdate", "params": [ { "type": "Version", "value": "1.21" }, { "type": "PlatformVersion", "value": "eks.1" } ], ... "errors": [] } }
  5. クラスターの更新が完了したら、更新したクラスターでの Kubernetes と同じマイナーバージョンに、ノードを更新する必要があります。詳細については、「セルフマネージド型ノードの更新」または「マネージド型ノードグループの更新」を参照してください。Fargate で起動される新しいポッドであれば、クラスターのバージョンと一致する kubelet バージョンを持っています。それまでに存在していた Fargate ポッドは変更されていません。

  6. (オプション) クラスターを更新する前に、そのクラスターに Kubernetes Cluster Autoscaler をデプロイしてある場合は、更新後の Kubernetes のメジャーバージョンとマイナーバージョンに一致するように、Cluster Autoscaler を最新バージョンに更新します。

    1. ウェブブラウザで Cluster Autoscaler リリースページを開き、クラスターの Kubernetes メジャーバージョンとマイナーバージョンに一致する最新の Cluster Autoscaler バージョンを見つけます。例えば、クラスターの Kubernetes バージョンが 1.21 の場合、1.21 で始まる Cluster Autoscaler リリースを見つけます。次のステップで使用するので、そのリリースのセマンティックバージョン番号 (<1.21.n>) を書き留めておきます。

    2. 次のコマンドを使用して、Cluster Autoscaler イメージタグを、前のステップで書き留めたバージョンに設定します。必要に応じて、1.21.n を独自の値に置き換えます。

      kubectl -n kube-system set image deployment.apps/cluster-autoscaler cluster-autoscaler=k8s.gcr.io/autoscaling/cluster-autoscaler:v1.21.n
  7. (GPU ノードを含むクラスターのみ) クラスターに GPU 対応のノードグループ (p3.2xlarge など) がある場合は、次のコマンドを使用して、クラスターの NVIDIA device plugin for Kubernetes デーモンセットを更新する必要があります。

    kubectl apply -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.9.0/nvidia-device-plugin.yml
  8. VPC CNI、CoreDNS、および kube-proxy アドオンを更新します。

Kubernetes 1.16 に更新にするための前提条件

Kubernetes 1.15 changelog」と「Deprecated APIs Removed In 1.16: Here's What You Need To Know」の各ドキュメントに記述されているように、既存のクラスターがあり、そのクラスターを 1.16 にアップグレードする際には、事前に以下のデプロイ済みリソースの API を変更しておく必要があります。

警告

1.16 に更新する前にこれらの API を変更しない場合は、更新の完了後にワークロードが失敗します。

  • v1.16 では、NetworkPolicy リソースが extensions/v1beta1 から提供されなくなります。v1.8 以降で利用可能な networking.k8s.io/v1 API に移行してください。既存の永続化データは、networking.k8s.io/v1 API を介して取得できます。

  • v1.16 では、PodSecurityPolicy リソースが extensions/v1beta1 から提供されなくなります。v1.10 以降で利用可能な policy/v1beta1 API に移行してください。既存の永続化データは、policy/v1beta1 API を介して取得できます。

  • v1.16 では、DaemonSet、Deployment、StatefulSet、および ReplicaSet の各リソースが extensions/v1beta1apps/v1beta1、または apps/v1beta2 から提供されなくなります。v1.9 以降で利用可能な apps/v1 APIに移行してください。既存の永続化データは、apps/v1 API を介して取得できます。例えば、apps/v1beta1 を現在使用している Deployment を変換するには、次のコマンドを入力します。

    kubectl convert -f ./<my-deployment.yaml> --output-version apps/v1
    注記

    上のコマンドで使用しているデフォルト値は、現在のマニフェストファイルに設定されているデフォルト値とは異なる場合があります。特定のリソースの詳細については、Kubernetes API リファレンスを参照してください。

最初に Kubernetes バージョン 1.11 以前で Amazon EKS クラスターを作成しており、--resource-container DaemonSet から kube-proxy フラグを削除していない場合、Kubernetes 1.16 へのアップデートにより kube-proxy エラーが発生します。このフラグは、Kubernetes 1.16 ではサポートされていません。詳細については、kube-proxy の「Kubernetes 1.16 Deprecations and removals (Kubernetes 1.16 の廃止と削除) 」を参照してください。Kubernetes 1.16 にアップデートする前に、このフラグを削除する必要があります。

1.16 に更新する前に行う必要があること

  • 新しい API を参照するように YAML ファイルを変更します。

  • 新しい API を呼び出すようにカスタムインテグレーションとコントローラーを更新します。

  • 新しい API を呼び出すためのサードパーティー製ツール (イングレスコントローラー、継続的配信システム、その他) の、最新バージョンを使用していることを確認します。

    クラスターで非推奨の API が使用されているかどうかを簡単に確認するには、audit コントロールプレーンログが有効になっていることを確認し、イベントのフィルターとして v1beta を指定します。すべての代替 API は、Kubernetes バージョン 1.10 より後のバージョンにあります。サポートされているバージョンの Amazon EKS に搭載されているアプリケーションであれば、更新済み API を使用できます。

  • クラスターが最初に Kubernetes 1.11 以前でデプロイされている、あるいは kube-proxy 設定ファイルを使用している場合には、--resource-container="" DaemonSet から kube-proxy フラグを削除します (推奨)。このフラグが、kube-proxy の現在のバージョンに含まれているか確認するには、次のコマンドを入力します。

    kubectl get daemonset kube-proxy --namespace kube-system -o yaml | grep 'resource-container='

    出力が表示されない場合には、何も削除する必要はありません。次の --resource-container="" のような出力を表示された場合は、フラグを削除する必要があります。次のコマンドを入力して、現在の kube-proxy 設定を編集します。

    kubectl edit daemonset kube-proxy --namespace kube-system

    エディタを開き、--resource-container="" 行を削除した上でファイルを保存します。この代わりに、kube-proxy 設定ファイルの使用を開始することが推奨されます。そのためには、以下のマニフェストをダウンロードします。

    curl -o kube-proxy-daemonset.yaml https://amazon-eks.s3.us-west-2.amazonaws.com/cloudformation/2020-10-29/2020-06-10/kube-proxy-daemonset.yaml

    次のコマンドを使用して、クラスターのエンドポイントを確認します。

    aws eks describe-cluster \ --name <cluster-name> \ --region <region-code> \ --query 'cluster.endpoint' \ --output text

    出力は次のとおりです。

    https://<A89DBB2140C8AC0C2F920A36CCC6E18C>.sk1.<region-code>.eks.amazonaws.com

    ダウンロードした kube-proxy-daemonset.yaml ファイルを編集します。エディタで、<MASTER_ENDPOINT> (<> を含む) を前のコマンドからの出力に置き換えます。<REGION> をクラスターのリージョンに置き換えます。必要に応じて、同じ行にあるバージョンを、クラスターのバージョンに置き換えます。次のコマンドによりファイルを適用します。

    kubectl apply -f kube-proxy-daemonset.yaml

既存のクラスター上でシークレット暗号化を有効にする

シークレット暗号化を有効にすると、選択した AWS KMS key を使用して Kubernetes シークレットが暗号化されます。KMS キーは対称で、クラスターと同じリージョンで作成する必要があります。KMS キーが別のアカウントで作成されている場合は、ユーザーが KMS キーにアクセスできる必要があります。詳細については、AWS Key Management Serviceデベロッパーガイドの「他のアカウントのユーザーに KMS キーの使用を許可する」を参照してください。

警告

一度有効化したシークレット暗号化は無効化できません。このアクションを元に戻すことはできません。

eksctl

暗号化は次の 2 つの方法のいずれかで有効にできます。

  • 1 つのコマンドでクラスターに暗号化を追加します。

    シークレットの再暗号化を自動的に実行するには:

    eksctl utils enable-secrets-encryption / --cluster <my-cluster> / --key-arn arn:aws:kms:<Region-code>:<account>:key/<key>

    シークレットの自動的な再暗号化をオプトアウトするには:

    eksctl utils enable-secrets-encryption --cluster <my-cluster> / --key-arn arn:aws:kms:<Region-code>:<account>:key/<key> / --encrypt-existing-secrets=false
  • .yaml ファイルを使用してクラスターに暗号化を追加します。

    # cluster.yaml apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: <my-cluster> region: <Region-code> secretsEncryption: keyARN: arn:aws:kms:<Region-code>:<account>:key/<key>

    シークレットの再暗号化を自動的に実行するには:

    eksctl utils enable-secrets-encryption -f kms-cluster.yaml

    シークレットの自動的な再暗号化をオプトアウトするには:

    eksctl utils enable-secrets-encryption -f kms-cluster.yaml --encrypt-existing-secrets=false
AWS Management Console
  1. https://console.aws.amazon.com/eks/home#/clusters で Amazon EKS コンソールを開きます。

  2. KMS 暗号化を追加するクラスターを選択します。

  3. [Configuration (設定)] タブを選択します。

  4. [Secrets encryption (シークレットの暗号化)] セクションまでスクロールダウンし、[Enable (有効化)] ボタンを選択します。

  5. ドロップダウンメニューからキーを選択し、[Enable (有効化)] ボタンを選択します。キーが一覧表示されていない場合は、最初にキーを作成する必要があります。詳細については、「キーの作成」を参照してください。

  6. [Confirm (確認)] ボタンを選択して、指定したキーを使用します。

AWS CLI
  1. 次の AWS CLI コマンドを使用して、シークレット暗号化設定をクラスターに関連付けます。<example-values> (<> を含む) を独自の値に置き換えます。

    aws eks associate-encryption-config \ --cluster-name <my-cluster> \ --encryption-config '[{"resources":["secrets"],"provider":{"keyArn":"arn:aws:kms:<Region-code>:<account>:key/<key>"}}]'

    出力:

    {   "update": {     "id": "<3141b835-8103-423a-8e68-12c2521ffa4d>",     "status": "InProgress",     "type": "AssociateEncryptionConfig",     "params": [       {         "type": "EncryptionConfig",         "value": "[{\"resources\":[\"secrets\"],\"provider\":{\"keyArn\":\"arn:aws:kms:<Region-code>:<account>:key/<key>\"}}]"       }     ],     "createdAt": <1613754188.734>,     "errors": []   } }
  2. 次のコマンドを使用すると、暗号化更新のステータスをモニタリングできます。前のステップのcluster name出力update IDに表示された、 および を使用します。ステータスが Successful と表示されたら、更新は完了です。

    aws eks describe-update \ --region <Region-code> \ --name <my-cluster> \ --update-id <3141b835-8103-423a-8e68-12c2521ffa4d>

    出力:

    {   "update": {     "id": "<3141b835-8103-423a-8e68-12c2521ffa4d>",     "status": "Successful",     "type": "AssociateEncryptionConfig",     "params": [       {         "type": "EncryptionConfig",         "value": "[{\"resources\":[\"secrets\"],\"provider\":{\"keyArn\":\"arn:aws:kms:<region-code>:<account>:key/<key>\"}}]"       }     ],     "createdAt": <1613754188.734>,     "errors": []   } }
  3. クラスターで暗号化が有効になっていることを確認するには、describe-cluster コマンドを実行します。この応答には、EncryptionConfig が含まれます。

    aws eks describe-cluster --region <Region-code> --name <my-cluster>

クラスターで暗号化を有効にしたら、既存のすべてのシークレットを新しいキーで暗号化する必要があります。

注記

eksctl を使用している場合は、シークレットの自動的な再暗号化をオプトアウトしない限り、次のコマンドを実行する必要はありません。

kubectl get secrets --all-namespaces -o json | kubectl annotate --overwrite -f - kms-encryption-timestamp="<time value>"
警告

既存のクラスターで有効にしたシークレット暗号化で、使用する KMS キーが削除された場合には、このクラスターを復旧する手段はありません。KMS キーを削除すると、クラスターは永続的にパフォーマンスが低下した状態になります。詳細については、「AWS KMS キーの削除」を参照してください。

注記

create-key コマンドでは、デフォルトで対称キーが作成されます。この際には、アカウントのルート管理者に AWS KMS アクションとリソースへのアクセスを許可する、キーポリシーが使用されます。アクセス許可の範囲を絞り込む場合は、kms:DescribeKey API を呼び出すプリンシパルのポリシーで、kms:CreateGrant および create-cluster アクションが許可されていることを確認します。

Amazon EKS は、ポリシー条件 kms:GrantIsForAWSResource をサポートしていません。このアクションが KMS キーポリシーステートメントにある場合、クラスターの作成は機能しません。