column

コラム

Mountpoint for Amazon S3 CSI driverを試してみた

こんにちは。クラウドCoEの宮國です。

最近登場したMountpoint for Amazon S3 CSI driverを試してみたので、紹介したいと思います。

Mountpoint for Amazon S3 CSI driverとは 

Mountpoint for Amazon S3はファイルインターフェイスを介して Amazon S3にアクセスすることができるオープンソースのクライアントツールです。2023年8月に一般公開されました。

そして2023年11月のアップデートで登場したのがMountpoint for Amazon S3 CSI driverです。(CSIについては過去に少し取り上げたのでリンクを貼ります。)

これにより、Kubernetes Podからもファイルインターフェイスを介してS3バケットにアクセスできるようになりました。

参考: https://aws.amazon.com/jp/about-aws/whats-new/2023/11/mountpoint-amazon-s3-csi-driver/

実際に試した様子を記載します。

クラスタ構築

今までのコラムではEKS接続用の踏み台サーバを立ててeksctlでクラスタを作成していたのですが、最近AWSのコンソールでできる事も増えてきたので、気分を変えてAWSコンソール&Cloud Shellでセットアップしていきたいと思います。Mountpoint for Amazon S3 CSI driverもコンソールからEKSアドオンとして導入します。

アカウントの都合上オレゴンリージョンで実施しています。

mountpoint-s3-csi-testという名前のEKSクラスタを作成します。

今回は検証用なので、デフォルトのVPC&各AZのパブリックサブネットを指定してクラスタを作成します。

クラスタ構築時にS3 CSI driverのアドオン指定できるわけではなさそうです。

 

15分ほどで作成が完了しました。

 

接続環境セットアップ

前述の通り接続環境は今まで踏み台用のサーバを立てていました。旧EKSワークショップを踏襲してCloud9から接続する事が多かったです。

今回はCloudShellで接続してみたいと思います。

CloudShell環境にデフォルトでkubectlが入っているのは今回初めて知りました。バージョンも1.28なのでこのまま進めていきます。

[cloudshell-user@ip-10-134-76-71 ~]$ kubectl version
Client Version: v1.28.1-eks-43840fb
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
The connection to the server localhost:8080 was refused - did you specify the right host or port?

現時点ではkubeconfigは空ですが、

[cloudshell-user@ip-10-134-76-71 ~]$ kubectl config view
apiVersion: v1
clusters: null
contexts: null
current-context: ""
kind: Config
preferences: {}
users: null

以下のコマンドを実施すると、

aws eks update-kubeconfig --region us-west-2 --name mountpoint-s3-csi-test

kubeconfigが設定されている事を確認できます。

kubectl config view

参考:https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/create-kubeconfig.html

 

ノードグループ作成

ノードグループも検証に必要な最小限のリソースで作成していきます。

バケット作成

Mountpoint for Amazon S3 CSI driverは静的プロビジョニングのみをサポートしており、新しいバケットの作成はできないので、検証用のS3バケットを作成します。

CloudShellから簡易的に作成します。

[cloudshell-user@ip-10-134-76-71 ~]$ aws s3 mb s3://mountpoint-s3-csi-test-20240108
make_bucket: mountpoint-s3-csi-test-20240108

アドオン導入前提条件セットアップ

アドオンの導入に必要な事前設定を行います。正直この作業をやっていく中でeksctlならもっと楽なのに…と感じてしまいました。

 

OIDCプロバイダー作成

参考: https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html

 

執筆時点ではまだEKS Pod Identityには対応していないため、従来通りIRSA前提で権限を付与していく形のようです。ただし近い将来対応されると思います。(EKS Pod Identityも重要なアップデートなので、いずれキャッチアップがてら記事にしたいと思います。)

 

IAMポリシー作成

参考: https://docs.aws.amazon.com/eks/latest/userguide/s3-csi.html

参考: https://github.com/awslabs/mountpoint-s3/blob/main/doc/CONFIGURATION.md#iam-permissions

 

Policy名:AmazonS3CSIDriverPolicy-20240108

{
   "Version": "2012-10-17",
   "Statement": [
        {
            "Sid": "MountpointFullBucketAccess",
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::mountpoint-s3-csi-test-20240108"
            ]
        },
        {
            "Sid": "MountpointFullObjectAccess",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:AbortMultipartUpload",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::mountpoint-s3-csi-test-20240108/*"
            ]
        }
   ]
}

 

IAMロール作成

参考: https://docs.aws.amazon.com/eks/latest/userguide/s3-csi.html#s3-create-iam-role

Role名:AmazonEKS_S3_CSI_DriverRole-20240108

信頼されたエンティティタイプをウェブアイデンティティとし、アイデンティティプロバイダーとして先ほど作成したOIDCプロバイダーを指定します。

信頼ポリシーの編集も忘れずに実施します。

 

EKSアドオンによるMountpoint for Amazon S3 CSI driver導入

参考: https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/eks-add-ons.html

参考: https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/managing-add-ons.html#creating-an-add-on

 

さて、準備が整ったところでいよいよMountpoint for Amazon S3 CSI driverの導入です。冒頭で記載した通り、今回はeksctlを使わない手順になるため、コンソールからアドオンを追加していきます。

もちろんeksctlをご利用の場合はeksctlでeks addonとして導入するやり方もありますし、HelmやKustomizeでKubernetesライクに導入するやり方もあります。他のアドオンとの兼ね合いも考慮して選択するような形になると思います。

参考: https://eksctl.io/usage/addons/

参考: https://github.com/awslabs/mountpoint-s3-csi-driver/blob/main/docs/install.md

コンソールでの導入方法は以下の通りで非常に簡単に導入できました。

 

先ほど作成したIAMロールを選択します。

 

導入後CloudShellでPodを確認するとs3-csi-node-*というPodが作成されている事が確認できました。

[cloudshell-user@ip-10-134-76-71 ~]$ kubectl get pods -n kube-system
NAME                           READY   STATUS    RESTARTS   AGE
aws-node-4m5m9                 2/2     Running   0          45m
coredns-59754897cf-b6gxr       1/1     Running   0          59m
coredns-59754897cf-bshqq       1/1     Running   0          59m
eks-pod-identity-agent-dbnx5   1/1     Running   0          45m
kube-proxy-p6dv6               1/1     Running   0          45m
s3-csi-node-22r9p              3/3     Running   0          2m41s

また、該当のPodがサービスアカウントと紐づいている事、サービスアカウントのアノテーションにIAMロールのARNが記載されている事が確認できます。

[cloudshell-user@ip-10-134-76-71 ~]$ kubectl get pod -o yaml -n kube-system s3-csi-node-22r9p | grep -i serviceaccount:
  serviceAccount: s3-csi-driver-sa


[cloudshell-user@ip-10-134-76-71 ~]$ kubectl get sa -n kube-system s3-csi-driver-sa -o yaml | grep -i role-arn
    eks.amazonaws.com/role-arn: arn:aws:iam::<ACCOUNTID>:role/AmazonEKS_S3_CSI_DriverRole-20240108

準備は以上です。

サンプルアプリケーションのデプロイ

参考: https://github.com/awslabs/mountpoint-s3-csi-driver/blob/main/examples/kubernetes/static_provisioning/non_root.yaml

公式のサンプルアプリケーションをデプロイします。今回はstatic_provisioning.yamlではなくnon_root.yamlの方で実施したいと思います。

[cloudshell-user@ip-10-134-76-71 ~]$ wget https://raw.githubusercontent.com/awslabs/mountpoint-s3-csi-driver/main/examples/kubernetes/static_provisioning/non_root.yaml

yamlを取得して、一部資材を修正しました。

[cloudshell-user@ip-10-134-76-71 ~]$ sdiff -s non_root.yaml non_root.yaml.org 
    - allow-delete                                            <
    - region us-west-2                                        <
      bucketName: mountpoint-s3-csi-test-20240108             |       bucketName: s3-csi-driver

他の非 root ユーザーがマウントされたディレクトリにアクセスできるために必要なオプションであるallow-otherは元から付与されていますが、

参考: https://github.com/awslabs/mountpoint-s3/blob/main/doc/CONFIGURATION.md#file-and-directory-permissions

ファイルの削除を許可するためのオプションであるallow-deleteが付与されていなかったため追加しています。

参考: https://github.com/awslabs/mountpoint-s3/blob/main/doc/CONFIGURATION.md#file-modifications-and-deletions

また、バケット名を先ほど作成したバケット名に変更し、念のためregionも指定しました。

[cloudshell-user@ip-10-134-76-71 ~]$ kubectl apply -f non_root.yaml
persistentvolume/s3-pv created
persistentvolumeclaim/s3-claim created
pod/s3-app created


[cloudshell-user@ip-10-134-76-71 ~]$ kubectl get pv,pvc,pod 
NAME                     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM              STORAGECLASS   REASON   AGE
persistentvolume/s3-pv   1200Gi     RWX            Retain           Bound    default/s3-claim                           30s
 
NAME                             STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/s3-claim   Bound    s3-pv    1200Gi     RWX                           30s
 
NAME         READY   STATUS    RESTARTS   AGE
pod/s3-app   1/1     Running   0          30s
 

特に問題なくRunningとなり、Podの中に入ってみると、s3バケットがマウントされていることを確認できました。削除操作も可能です。

[cloudshell-user@ip-10-134-76-71 ~]$ kubectl exec -it s3-app -- bash
bash-4.4$ mount | grep s3
mountpoint-s3 on /data type fuse (rw,nosuid,nodev,noatime,user_id=0,group_id=0,default_permissions,allow_other)


bash-4.4$ cd /data/
bash-4.4$ ls
'Mon Jan  8 13:36:27 UTC 2024.txt'
bash-4.4$ cat 'Mon Jan  8 13:36:27 UTC 2024.txt' 
Hello from the container!
bash-4.4$ rm 'Mon Jan  8 13:36:27 UTC 2024.txt'
bash-4.4$ ls
 

実際にAWS CLIと比べてどの程度早くなっているのだろう?という感覚が持てなかったため簡易的なベンチマークも試してみたところ、

小さいファイルの書き込みが遅く、大きいファイルの書き込みが速いというオブジェクトストレージの傾向はそのままでしたが、AWS CLIでコピーするよりMountpoint for S3でコピーする方が高い性能が出ている事が確認できました。

おわりに

制約事項も多いですが、S3をファイルシステムライクに扱えて、かつ高性能で利用できることは大きなメリットだと思います。

また、CSIに準拠したドライバーとしてアドオンが提供され、EKSアドオンとしても手軽に導入できるという点から、EKS環境でも積極的に採用できそうな下地が整っているなと感じました。

適切なワークロードに直面したら、採用していきたいと思いました。