Amazon Web Services ブログ
Amazon EKS クラスターの EBS ボリュームを gp2 から gp3 に移行する
本投稿は Jens-Uwe Walther による記事 “Migrating Amazon EKS clusters from gp2 to gp3 EBS volumes” の日本語翻訳文です。翻訳文は CNCF アンバサダー いんだくたー氏より寄稿されました。
Kubernetes (K8s) はオープンソースのコンテナオーケストレーションエンジンで、Cloud Native Computing Foundation (CNCF) がホストする成長の速いプロジェクトです。K8s はオンプレミス上やクラウド上でステートフルからステートレスまでコンテナワークロードを動かすために広く採用されています。ステートフルワークロードでは永続ストレージが必要です。Kubernetes においては、ストレージやネットワークのようなオンプレないしはクラウドに固有のインフラ要素をサポートすることを目的として、旧来から「in-tree プラグイン」と呼ばれる構成要素がソースコード内部に含まれていました。ストレージやクラウドの事業者が新しいストレージシステムを追加したり、バグ修正や新機能を追加したい場合、これまでは Kubernetes のリリースサイクルに頼る必要がありました。このような Kubernetes のライフサイクルを事業者に固有の実装から開放するために、Container Storage Interface (CSI) の開発が始まりました。これは、Kubernetes のようなコンテナオーケストレーションシステム上でブロックストレージやファイルストレージを利用するための標準仕様です。これを通じることによって、顧客は Kubernetes の新しいバージョンのリリースを待つこと無く最新の CSI ドライバーの恩恵を受けられるようになりました。
AWS は re:Invent 2017 においてマネージドの Kubernetes サービスである Amazon Elastic Kubernetes Service (Amazon EKS) をローンチしました。2019 年の 9 月には、Amazon EKS において Amazon Elastic Block Store (Amazon EBS) の CSI ドライバーをサポートしたことを発表しました。さらに 2021 年 5 月にはこの CSI プラグインの GA (一般提供開始)をアナウンスしました。Kubernetes 本体にも “kubernetes.io/aws-ebs” プロビジョナーとして知られる Amazon EBS 向けのプラグインが存在しましたが、この in-tree ストレージプラグインは io1、gp2、sc1、そして st1 の EBS タイプのみをサポートしており、ボリュームスナップショットに関連する機能はサポートしていません。
gp3 や io2 のような新しいボリュームタイプや Kubernetes のボリュームスナップショットのような新機能を活用したい AWS のお客様は、いつ、そしてどのようにして EKS クラスターで利用している Amazon EBS 向けの Kubernetes in-tree プラグインを Amazon EBS CSI ドライバーに移行すれば良いのかという質問を私たちに投げかけてきます。
In-tree プラグインから Container Storage Interface (CSI) に移行するための機能 (CSI Migration) は Kubernetes v1.17 から beta 機能として利用可能であり、その詳細はこちらのブログ記事に記されています。この CSI Migration は、将来的に in-tree プラグインが Kubernetes のソースコードから削除され、すべての移行されたボリュームが CSI ドライバーによって管理されるようになることを目的としており、移行した PV リソースが CSI ドライバーから提供される新しい機能や属性を使えるようになるわけではありません。こちらの GitHub コメントでも示されているように、あくまでも in-tree ドライバーによって提供されていた機能をそのまま使えるようにすることが目的です。
本ブログ記事では、移行のシナリオや概要について一通り確認し、必要なステップの詳細を示します。
前提条件
利用中の Kubernetes クラスターバージョンが 1.17 以上で、kubectl も同様であることを確認してください。また、Amazon EBS CSI に関連したオブジェクトがインストールされ、機能していることを確認してください。
Kubernetes ではストレージ移行を実装するために「フィーチャーゲート」と呼ばれる機能を使っています。Amazon EBS 用の CSIMigration
と CSIMigrationAWS
を有効にすると、すべてのプラグイン操作を既存の in-tree プラグインから ebs.csi.aws.com
CSI ドライバーにリダイレクトします。Amazon EKS では CSIMigration
及び CSIMigrationAWS
機能が有効化されていないことにご注意ください。とはいえ、CSI ドライバーと in-tree プラグインを並行して利用することは現時点でも可能です。
まずはデモ目的で、後ほど移行対象とする動的な PersistentVolume (PV) リソースを作成します。
ここでは、K8s ドキュメントに記載されている「ボリュームの動的プロビジョニング」を使うことにします。
In-tree ストレージドライバーを利用したデフォルトの StorageClass (SC) である gp2 を使って PersistentVolumeClaim (PVC) リソースを作成します。
PVC が作成され、ステータスが “pending” になっています。これは gp2 の StorageClass が Volume Binding Mode (フィールド内における volumeBindingMode) が WaitForFirstConsumer であり、まだ PVC を利用する Pod が作成されていないためです。
それでは、PVC を利用するデモアプリの Pod を作成しましょう。
数秒すると Pod が作成されます。
このとき、基盤となる PV pvc-646fef81-c677-46f4-8f27-9d394618f236 が動的に用意され、PVC “ebs-gp2-claim” として Pod に紐付けられます。
ボリュームが含むデータをさくっと確認します。
PV の詳細を見てみましょう。
この PV は (期待通り) “kubernetes.io/aws-ebs” プロビジョナーによって作成され、アノテーションに記録されています。Spec 内の “awsElasticBlockStore.volumeId” フィールドには実体となる EBS の ID “vol-03d3cd818a2c2def3” が、EBS ボリュームが作成された AWS アベイラビリティゾーン (AZ) とともに表示されています(この場合は eu-central-1c)。EBS ボリュームと EC2 インスタンスはリージョンではなく単一ゾーンで動いています。K8s 公式ドキュメントの nodeAffinity 項では kube-scheduler が Pod と PV を同じ AZ で用意するようにするための必要事項について記されています。
以下のコマンドは Amazon EBS の詳細情報を表示するための便利コマンドです。
我々は、この PV をのちに説明するストレージ移行シナリオで使います。この PV を使っている PVC が削除されてしまったとしても PV 自体は削除されないように、“VolumeReclaimPolicy” を “Retain” に変更しておきます。これは PV レベルの変更であり、SC レベルではないことに注意してください。
Amazon EBS CSI ドライバーをインストールする際は、GitHub リポジトリのドキュメントに従ってください。おおまかなステップは以下のとおりです。
- EBS の操作に必要な IAM 権限をインスタンスプロファイルにアタッチするか、最小権限の原則に従うためにIRSA (IAM roles for service accounts / サービスアカウントの IAM ロール) を使って適切なサービスアカウントにアノテーションを付与します
- YAML を用いて external-snapshotter に関連する K8s オブジェクト (CRD、RBAC、Deployment、Validating Webhook) をインストールします
- YAML を用いて Amazon EBS CSI ドライバー をインストールするか、それに対応した Helm chart をデプロイします (IRSA を使う場合、既存のサービスアカウントを使うように設定します)
Amazon EBS CSI ドライバーに関連した Kubernetes コンポーネントが K8s API サーバーに登録されていることをダブルチェックします。
インストールしたコンポーネントが動作していることを確認します。
移行シナリオ
まずは移行シナリオについて抽象的な議論をしてみましょう。
これから、我々は in-tree ベースの PV で作成された物理ストレージ領域のデータを、in-tree プラグインにとっての “外部のスナップショット機構” である Amazon EBS のスナップショット機能を使って移行していきます (注意: in-tree の Amazon EBS ストレージプラグインではボリュームスナップショットはサポートされていません!)。そして、そのデータを Amazon EBS CSI ドライバーの CSI Volume Snapshot 機能を使ってインポートします。
ここからは、詳細な移行手順を説明していきます。
まず、in-tree プラグインベースの PV である pvc-646fef81-c677-46f4-8f27-9d394618f236 のスナップショットを、AWS API 経由で取ります。
スナップショットのステータスが “completed” になるまで待ちます。
スナップショット作成が終わったので、VolumeSnapshotClass リソースを作成します。
次に、AWS 側のスナップショットデータ snap-06fb1faafc1409cc5 を使い、なおかつ次のステップで利用する VolumeSnapshot リソースを参照するような VolumeSnapshotContent リソースを作成する必要があります。変な感じがするかもしれませんが、既存のスナップショットの VolumeSnapshotContent と VolumeSnapshot の相互的な紐付けに必要です!
そうしたら、作成した VolumeSnapshotContent オブジェクトに紐づく VolumeSnapshot を作成します。
移行作業をする上で、せっかく新しく使えるようになった Amazon EBS の gp3 タイプの恩恵にあずかりたいですよね。そのためには、CSI ベースの gp3 StorageClass リソースを作成する必要があります!これが今後デフォルトの SC リソースとなってほしいので、Amazon EKS のデフォルト gp2 SC から以下のアノテーションを取り除きます。
先程のステップで作成した VolumeSnapshot は、PersistentVolumeClaim の作成に使えます。StorageClass には、CSI ベースの新しい gp3 SC を使います。
この PVC はまだ Pending のステータスのままであることに注意してください。これは、gp3 SC が volumeBindingMode を WaitForFirstConsumer で設定されているためです。PV を実際に作成するためには、アプリケーション (Pod) の作成が必要です。今回はデモのため、作成する Pod では新規データの書き込みは行わず、スナップショットから作られマウントされた PVC 中のデータを “kubectl exec”を使って確認するだけにします。
PV リソース pvc-25d2d19d-6ede-47d2-bd2e-32d45832ec20 が自動的に作成され、Pod が移行後のデータとともに立ち上がってきたことが確認できました。
PVC に関しては、期待通り、CSI ベースの gp3 SC を使っています。
お掃除
余計なコストがかからないように、デモの確認が終わったらご自身の環境から削除しましょう。
将来また使えるように、CSI ドライバー及び EKS クラスターは残しておいてもよいでしょう。
結論
Amazon EKS はマネージドなコントロールプレーン、データプレーンを管理するための選択肢 (マネージド型ノードグループ)、そして AWS VPC CNI や CoreDNS、kube-proxy といった重要なコンポーネントを管理するためのマネージドなクラスター用アドオンをお客様に提供しています。Amazon EBS CSI の移行に関するすべての機能が仕上がれば、今回示した手順の多くを AWS からマネージドで提供できるようになる予定です!
本記事では、ご自身のワークロードを Amazon EBS CSI ドライバーが提供する新しい機能を使える PVs に移行するための今日から始められる手順をご紹介しました。
この記事が皆様の Kubernetes プロジェクトに役立つことを願っています。ご質問やご提案がございましたら、GitHub パブリックロードマップリポジトリやソーシャルでのコメントなどにてぜひお聞かせください。