Amazon Web Services ブログ

EKS on Bottlerocket で EFS を永続ストレージに使用する

この記事は Persistent Storage using EFS for EKS on Bottlerocket (記事公開日: 2021 年 7 月 9 日) を翻訳したものです。

この記事では Bottlerocket OS を使用した Amazon Elastic Kubernetes Service (Amazon EKS) クラスターで、Amazon Elastic File System (Amazon EFS) を永続ストレージとして利用する方法について説明します。永続ストレージは、長時間実行されるステートフルアプリケーションが高可用性のために状態を永続化したり、共有データセットを中心にスケールアウトするために必要です。これは機械学習ワークロードを実行し、共有データセットやデータサイエンスのためのホームディレクトリを Amazon EFS に保存するお客様にも当てはまります。Amazon EFS を永続ストレージとして利用することにより、複数のコンテナにまたがって並行してモデルをトレーニングし、個々のデータサイエンスノートブックコンテナからデータにアクセスできます。機械学習用のオープンソースプラットフォームの例としては、MXNetTensorFlowJupyterJupyterhubKubeflow などがあります。

この記事で紹介に入る前に、各コンポーネントとサービスの概要を説明します。

Bottlerocket はオープンソースの Linux ベース OS です。コンテナワークロードを実行するために構築、最小化されています。コンテナセキュリティのベストプラクティスに従った安全な設計になっています。コンテナの実行に必要なツールのみが含まれており、攻撃対象領域 (アタックサーフェス)と脆弱性の影響を大幅に軽減します。最小化されていることで Bottlerocket を実行するノードは起動時間が短く、さまざまなトラフィックパターンやワークロードの変化に基づいてクラスターを迅速に拡張できます。

Amazon Elastic File System (Amazon EFS) は、ストレージのプロビジョニングや管理を行わずにファイルデータを共有できる、シンプルでサーバーレスで伸縮自在なファイルシステムを提供します。AWS のサービスやオンプレミスのリソースと併用でき、アプリケーションを中断することなくオンデマンドでペタバイト規模まで拡張できるように構築されています。

Bottlerocket OS は読み取り専用のファイルシステムを使用して、ホスト OS の全体的なセキュリティ体制 (security posture) を改善します。これを考慮して、クラスターノードとその上で実行されている Pod 間の共有ストレージソリューションを実装するためには特定のステップを踏む必要があります。この記事では、Bottlerocket OS で EFS を活用してステートフルなワークロードを実行し、データを永続化する方法を示します。

図 1: Amazon EFS と Bottlerocket を使用した Amazon EKS クラスター

この例では、Bottlerocket OS を実行し EFS を共有する 3 つのワーカーノードを持つ EKS クラスターを構築しました。busybox アプリケーション app1 と app2 の 2 つをデプロイし、共通/データマウントを共有します。

前提条件

EKS クラスターの使用を開始するにはいくつかの必須の前提条件があります。Amazon EKS の開始方法の内容にしたがって、eksctlkubectlAWS コマンドラインインターフェイス (CLI)Helm CLI をインストールして設定する必要があります。

クラスターを作成するには、適切な IAM ロールとアクセス権限を持つことが重要です。

Bottlerocket を使用した Amazon EKS クラスターをセットアップする手順については、こちらをご覧ください。

1. EKS クラスターのセットアップ後、次のコマンドを実行してノードが Bottlerocket OS 上で実行されていることを確認します。

kubectl get nodes -o=wide

図 2: EKS ワーカーノードの一覧

Amazon EFS CSI ドライバーのインストールと設定手順

2. EFS のファイルシステムを作成します。

EFS ファイルシステムを作成するには次のコマンドを使用します。

aws efs create-file-system --creation-token <name of the file system>

この例では、ファイルシステムに「eks-efs」という名前を付けています。

aws efs create-file-system --creation-token eks-efs

3. EKS クラスターが実行されている VPC の ID を取得します。

次のコマンドを実行して VPC の ID を取得します。

aws eks describe-cluster --name bottlerocket --query "cluster.resourcesVpcConfig.vpcId" --output text --region=us-west-2

4. ステップ 3 で取得した VPC ID を使用して、CIDR ブロックを取得します。

aws ec2 describe-vpcs --vpc-ids vpc-xxxx --query "Vpcs[].CidrBlock" --output text –region=us-west-2

5. ステップ 3 で取得した VPC ID を使用して、セキュリティグループを作成します。

aws ec2 create-security-group --description <description> --group-name <name of security group> —vpc-id <vpc-id>

この例では、セキュリティグループに「efs-test-sg」という名前を付けています。

aws ec2 create-security-group --description efs-test-sg --group-name efs-sg —vpc-id vpc-xxxxxxxx

6. ステップ 4 で取得した CIDR ブロックと、ステップ 5 で出力されたセキュリティグループの ID を使用して、クラスターの VPC の CIDR からのインバウンド NFS トラフィックを許可するインバウンドルールを作成します。

aws ec2 authorize-security-group-ingress --group-id sg-xxxx --protocol tcp --port 2049 —cidr 192.168.0.0/16

7. EFS のマウントターゲットを作成します。

サブネット ID ごとに以下のコマンドを実行してマウントターゲットを作成します。

aws efs create-mount-target --file-system-id <filesystemid> --subnet-id <subnetid> --security-group <sg-xxx>
aws efs create-mount-target --file-system-id fs-xxx --subnet-id subnet-1-xxx --security-group sg-xxx
aws efs create-mount-target --file-system-id fs-xxx --subnet-id subnet-2-xxx --security-group sg-xxx
aws efs create-mount-target --file-system-id fs-xxx --subnet-id subnet-3-xxx --security-group sg-xxx

Helm を使用して CSI ドライバをインストールする手順

helm repo add aws-efs-csi-driver  https://kubernetes-sigs.github.io/aws-efs-csi-driver/
helm install aws-efs-csi-driver aws-efs-csi-driver/aws-efs-csi-driver

次のコマンドを実行して aws-efs-csi-driver が起動したことを確認します。

kubectl get pod -n default -l "app.kubernetes.io/name=aws-efs-csi-driver,app.kubernetes.io/instance=aws-efs-csi-driver“

次の GitHub リポジトリをクローンします。

git clone https://github.com/kubernetes-sigs/aws-efs-csi-driver.git
cd aws-efs-csi-driver

PV (Persistence Volume)、PVC (Persistence Volume Claim)、StorageClass、および PV を使用する Pod を作成します。

kubectl apply -f examples/kubernetes/multiple_pods/specs/storageclass.yaml

pv.yaml のボリュームハンドルの値を、新しい EFS ファイルシステムに一致するように書き換えてから、次のコマンドを実行します。

kubectl apply -f examples/kubernetes/multiple_pods/specs/pv.yaml
kubectl apply -f examples/kubernetes/multiple_pods/specs/claim.yaml
kubectl apply -f examples/kubernetes/multiple_pods/specs/pod1.yaml
kubectl apply -f examples/kubernetes/multiple_pods/specs/pod2.yaml

Pod (pod1 と pod2) が同じ EFS ファイルシステムに同時に書き込みます。

以下のコマンドを使用して Pod が実行されていることを確認します。

Kubectl get pods

両方の Pod からデータが EFS ファイルシステムに書き込まれていることを確認します。

kubectl exec -ti app1 -- tail -f /data/out1.txt
kubectl exec -ti app2 -- tail -f /data/out2.txt

データの永続化の検証

データが維持されているかどうかを確認するには、Pod app1、app2 を再起動し、ファイル out1.txt と out2.txt が /data の下のマウントに残っていることを検証します。

まとめ

Bottlerocket OS で実行されている EKS ワーカーノードと Amazon EFS を統合することで、全体的なセキュリティ体制と基盤となるパフォーマンスを向上させながら、ステートフルなワークロードを実行できます。Amazon EFS では、数千もの Pod または EC2 インスタンスが共有ボリュームに対して同時に読み書きできます。この記事は、EKS ワーカーノード間でセキュアな共有ストレージを必要とするワークロードのデプロイに役立ちます。

翻訳はソリューションアーキテクト加治が担当しました。原文はこちらです。