logo

2024620

非EKSなK8sクラスターでmountpoint-s3-csi-driverを試す

AWS が公開している mountpoint-s3-csi-driver を使うと Kubernetes 上のコンテナから S3 オブジェクトをファイルシステム的に扱えるようになるみたいなので、(EKS クラスターは持っていないので自宅のクラスタで)試してみました。

画像などのファイルをキャッシュとして置いているアプリケーションをコードの書き換えなしで S3 に置くようにしたり、大きめの(コンテナイメージには含めたくない)ファイルを S3 に置いておいて読み込むようにしたりとか、便利に使えるシチュエーションがありそうです。

環境

  • Kubernetes 1.29.4
  • Kubectl 1.29.1
  • Helm 3.15.2
  • awslabs/mountpoint-s3-csi-driver 1.7.0

準備

S3 バケット作成

任意の名前でバケットを作成します。管理コンソールからデフォルトの設定のままで作りました。

IAM 設定

ドキュメントに記載のサンプルを参考に、IAM ポリシーを作ります。YOUR-BUCKET-NAME-HERE 部分には作ったバケットの名前を入れます。

{
   "Version": "2012-10-17",
   "Statement": [
        {
            "Sid": "MountpointFullBucketAccess",
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::YOUR-BUCKET-NAME-HERE"
            ]
        },
        {
            "Sid": "MountpointFullObjectAccess",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:AbortMultipartUpload",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::YOUR-BUCKET-NAME-HERE/*"
            ]
        }
   ]
}

IAM ユーザーを作成して、上記ポリシーをアタッチします。

Secret の作成

IAM ユーザーのアクセスキーを発行して、secret として保存します。名前は helm でデフォルト値として設定されているのでそのまま作ってください。

kubectl create secret generic aws-secret \
    --namespace kube-system \
    --from-literal "key_id=${AWS_ACCESS_KEY_ID}" \
    --from-literal "access_key=${AWS_SECRET_ACCESS_KEY}"

今回は検証なので secret を作りましたが、ちゃんとやるなら IAM Roles Anywhere を使ったほうがいいかも。

Using a secret object: create an IAM user, attach the policy to it, then create a generic secret in the kube-system namespace with the IAM user's credentials. We don't recommend this option because it requires long-lived credentials.

https://github.com/awslabs/mountpoint-s3-csi-driver/blob/main/docs/install.md#configure-access-to-s3

CSI ドライバーのインストール

Helm でデプロイします。IAM ユーザーのアクセスキーを発行して環境変数に入れておきます。

helm repo add aws-mountpoint-s3-csi-driver https://awslabs.github.io/mountpoint-s3-csi-driver
helm repo update
helm upgrade --install aws-mountpoint-s3-csi-driver \
    --namespace kube-system \
    aws-mountpoint-s3-csi-driver/aws-mountpoint-s3-csi-driver

Pod が実行されているか検証します。

kubectl get pods -n kube-system -l app.kubernetes.io/name=aws-mountpoint-s3-csi-driver
NAME                READY   STATUS    RESTARTS   AGE
s3-csi-node-9mc24   3/3     Running   0          17s
s3-csi-node-ghzhg   3/3     Running   0          17s
s3-csi-node-jrrr9   3/3     Running   0          17s
s3-csi-node-vcj4h   3/3     Running   0          17s

Pod に persistent volume をマウントしてオブジェクトを書き込み

mountpoint-s3-csi-driver/examples/kubernetes/static_provisioning に色んな例が載っているのでみてみると良いと思います。

とりあえず一番シンプルな static_provisioning.yaml を試します。

ダウンロードして PV の spec.mountOptionsspec.csi.volumeAttributes.bucketName を編集しました。

curl -LO https://raw.githubusercontent.com/awslabs/mountpoint-s3-csi-driver/main/examples/kubernetes/static_provisioning/static_provisioning.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: s3-pv
spec:
  capacity:
    storage: 1200Gi # ignored, required
  accessModes:
    - ReadWriteMany # supported options: ReadWriteMany / ReadOnlyMany
  mountOptions:
    - allow-delete
    - region ap-northeast-1
  csi:
    driver: s3.csi.aws.com # required
    volumeHandle: s3-csi-driver-volume
    volumeAttributes:
      bucketName: YOUR-BUCKET-NAME-HERE
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: s3-claim
spec:
  accessModes:
    - ReadWriteMany # supported options: ReadWriteMany / ReadOnlyMany
  storageClassName: "" # required for static provisioning
  resources:
    requests:
      storage: 1200Gi # ignored, required
  volumeName: s3-pv
---
apiVersion: v1
kind: Pod
metadata:
  name: s3-app
spec:
  containers:
    - name: app
      image: centos
      command: ["/bin/sh"]
      args: ["-c", "echo 'Hello from the container!' >> /data/$(date -u).txt; tail -f /dev/null"]
      volumeMounts:
        - name: persistent-storage
          mountPath: /data
  volumes:
    - name: persistent-storage
      persistentVolumeClaim:
        claimName: s3-claim
kubectl apply -f static_provisioning.yaml

バケットにファイルが作成されていることを確認します。

aws s3 ls s3://YOUR-BUCKET-NAME-HERE
2024-06-20 18:42:18         26 Thu Jun 20 09:42:17 UTC 2024.txt

オブジェクトの中身を見てみます。

aws s3 cp s3://YOUR-BUCKET-NAME-HERE/"Thu Jun 20 09:42:17 UTC 2024.txt" ./
cat "Thu Jun 20 09:42:17 UTC 2024.txt"
Hello from the container!

良さそうですね。

お片付け

kubectl delete -f static_provisioning.yaml
helm uninstall aws-mountpoint-s3-csi-driver --namespace kube-system
kubectl delete secret aws-secret --namespace kube-system

参考文献