1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

EKSなしIRSAへの道 ― 第5回:EBS CSI Driverを導入してボリュームをマウントする

1
Posted at

はじめに

この記事では、AWSのEC2インスタンス上にkubeadmで構築したKubernetesクラスターにEBS CSI Driverをデプロイし、IRSA(IAM Roles for Service Accounts)を使ってEBSボリュームを利用できることを検証します。

注意いただきたいのは、検証環境はEKSではなくて「素のEC2インスタンスに構築したKubernetes」という点です。そのため、EKSだと最初から用意されているコンポーネント(OIDCエンドポイントやAWS Cloud Controller Managerなど)を自分で揃える必要があります。

この取り組みに関しては、以下の記事で書いてきました。ご興味のあるかたは、是非ご一読ください。

環境情報

EC2インスタンス1台を使って、kubeadmでKubernetesクラスターを構築しています。

$ kubectl get nodes
NAME          STATUS   ROLES           AGE   VERSION
ip-10-0-0-4   Ready    control-plane   17d   v1.36.5

このマシンは、Control PlaneとWorkerを兼ねています。

これまでの第1回から第4回までの試みを通して、この1台のEC2インスタンスにさまざまなコンポーネントがデプロイされています。

kubectl コマンドでPodを確認すると、一つのノードに沢山のPodが「すし詰め」になっている状態です。

$ kubectl get pods -A -o custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,STATUS:.status.phase'
NAMESPACE              NAME                                              STATUS
cert-manager           cert-manager-cainjector-6dccbccc6-vj58x           Running
cert-manager           cert-manager-df898748d-d4zrx                      Running
cert-manager           cert-manager-startupapicheck-gplgg                Succeeded
cert-manager           cert-manager-webhook-cd8d5b6bf-xkbqp              Running
default                apiserver-gateway-zpmsj                           Running
envoy-gateway-system   envoy-gateway-5cfd9b9c6c-njw8t                    Running
kube-system            amazon-eks-pod-identity-webhook-796dbf55c-fd62x   Running
kube-system            aws-cloud-controller-manager-jnlcz                Running
kube-system            cilium-envoy-rqljv                                Running
kube-system            cilium-n6zbb                                      Running
kube-system            cilium-operator-7757bfd756-b5w2j                  Running
kube-system            coredns-589f44dc88-nx8bg                          Running
kube-system            coredns-589f44dc88-pt299                          Running
kube-system            etcd-ip-10-0-0-4                                  Running
kube-system            kube-apiserver-ip-10-0-0-4                        Running
kube-system            kube-controller-manager-ip-10-0-0-4               Running
kube-system            kube-proxy-nhhvl                                  Running
kube-system            kube-scheduler-ip-10-0-0-4                        Running

これまでEC2のインスタンスタイプはt3a.small(2vCPU、2GiB)、ルートボリュームのサイズは10GiBでまかなえてきました。

しかし、さらにEBS CSI Driverをデプロイするとリソースが枯渇して、一部のPodがReadyにならない事態となりました。

そこで、インスタンスタイプは一つ上のt3a.medium(2vCPU、4GiB)にして、ルートボリュームのサイズも15GiBに上げて検証ができる状態にしています。

EBS CSI Driverをデプロイする手順

IAMロールの作成

次の手順でデプロイするEBS CSI Driverには、EBSボリュームの作成や削除などを行うための権限が必要となります。そこで、これを実現するためのIAMロールを作成します。

IAMロールの作成には、以下のAWS公式ドキュメントの「AWS CLI」に書かれた内容を参考にします。

まずは、IAMロールに割り当てる信頼ポリシーのドキュメントを、以下のように作成します。

aws-ebs-csi-driver-trust-policy.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::123456789012:oidc-provider/[kube-apiserverのホスト名]"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "[kube-apiserverのホスト名]:sub": "system:serviceaccount:kube-system:ebs-csi-controller-sa",
                    "[kube-apiserverのホスト名]:aud": "sts.amazonaws.com"
                }
            }
        }
    ]
}

[kube-apiserverのホスト名] と書かれた部分は、第1回で設定したOIDCエンドポイントのFQDN名を入力します。自分がGitHubに作成しているk8s-irsa-without-eksだと、terraform/route53/terraform.tfvarsのroute53_a_record_nameと同じ値が入ります。

またsubのキーに書いている値は、「namespace が kube-system の、ebs-csi-controller-sa という ServiceAccount リソース」を表します。次の手順でEBS CSI Driverをデプロイする際に作成するServiceAccountは、これと一致する必要があるので注意してください。

この信頼ポリシーのドキュメントを使って、IAMロールを作成します。今回はEBS_CSI_DriverRoleという名前にします。

aws iam create-role \
--role-name EBS_CSI_DriverRole \
--assume-role-policy-document file://"aws-ebs-csi-driver-trust-policy.json"

作成したIAMロールに、アクセス許可に関するポリシーを付与します。今回はAWSが管理するAmazonEBSCSIDriverPolicyを付与します。

aws iam attach-role-policy \
--policy-arn arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy \
--role-name EBS_CSI_DriverRole

EBS CSI Driverのデプロイ

続いて、KubernetesクラスターにEBS CSI Driverをデプロイします。本記事では、以下のHelmfileを使って実現します。

ebs-csi-driver.yaml
repositories:
  - name: aws-ebs-csi-driver
    url: https://kubernetes-sigs.github.io/aws-ebs-csi-driver

releases:
  - name: aws-ebs-csi-driver
    namespace: kube-system
    chart: aws-ebs-csi-driver/aws-ebs-csi-driver
    version: 2.66.1
    values:
    - controller:
        replicaCount: 1
        serviceAccount:
          create: true                  # チャートデプロイ時にServiceAccountを作成する
          name: ebs-csi-controller-sa   # 信頼ポリシーの sub の記述と同じ名前を指定する
          annotations:
            # IRSAを使ってIAM Roleを引き受けるための記述
            eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/EBS_CSI_DriverRole
          automountServiceAccountToken: true

以下が、インストールコマンドです。

helmfile apply -f ebs-csi-driver.yaml

次のように、ebs-csi-controller のPodと、各ノード向けの ebs-csi-node のPodがデプロイされるのを確認します。

$ kubectl get deploy,ds -n kube-system -l app.kubernetes.io/name=aws-ebs-csi-driver
NAME                                 READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/ebs-csi-controller   1/1     1            1           10s

NAME                                  DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR              AGE
daemonset.apps/ebs-csi-node           1         1         1       1            1           kubernetes.io/os=linux     10s
daemonset.apps/ebs-csi-node-windows   0         0         0       0            0           kubernetes.io/os=windows   10s
$ kubectl get po -n kube-system -l app.kubernetes.io/name=aws-ebs-csi-driver
NAME                                      READY   STATUS    RESTARTS   AGE
pod/ebs-csi-controller-59d5456f97-m6pmq   5/5     Running   0          21s
pod/ebs-csi-node-thx7j                    3/3     Running   0          21s

PVCを使ってEBSボリュームを調達してみる

下準備が出来たので、Kubernetesの各リソースを使ってEBSボリュームが使えるのかを確認します。

Kubernetesに詳しい人にはさほど真新しさがないかと思いますが、以下の手順を実施します。

  • (1) EBSボリューム用のStorageClassを作成
  • (2) PVC(PersistentVolumeClaim)を作成
  • (3) PVCを参照して、EBSボリュームをマウントするPodをデプロイ

(1) EBSボリューム用のStorageClassを作成

以下のマニフェストを用意します。
わかりやすさ重視で、必要最低限の設定にしています。

storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ebs-sc
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer

上記マニフェストをデプロイし、StorageClassが作成されたのを確認します。

$ kubectl apply -f storageclass.yaml
storageclass.storage.k8s.io/ebs-sc created

$ kubectl get sc
NAME     PROVISIONER       RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
ebs-sc   ebs.csi.aws.com   Delete          WaitForFirstConsumer   false                  5s

(2) PVC(PersistentVolumeClaim)を作成

以下のマニフェストを用意します。

pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: ebs-claim
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: ebs-sc
  resources:
    requests:
      storage: 1Gi

上記マニフェストをデプロイし、PVCが作成されたのを確認します。

$ kubectl apply -f pvc.yaml
persistentvolumeclaim/ebs-claim created

$ kubectl get pvc -n default
NAME        STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
ebs-claim   Pending                                      ebs-sc         <unset>                 10s

(3) PVCを参照して、EBSボリュームをマウントするPodをデプロイ

最後に、EBSボリュームをマウントするPodを、以下のマニフェストで作成します。

pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: app
spec:
  containers:
  - name: app
    image: public.ecr.aws/amazonlinux/amazonlinux
    command: ["/bin/sh"]
    args: ["-c", "while true; do echo $(date -u) >> /data/out.txt; sleep 5; done"]
    volumeMounts:
    - name: persistent-storage
      mountPath: /data
  volumes:
  - name: persistent-storage
    persistentVolumeClaim:
      claimName: ebs-claim

以下のコマンドでPodを作成します。

$ kubectl apply -f pod.yaml
pod/app created

EBSボリュームがPodで使えることを確認

Podをデプロイすると、これまでPendingだったPVCにボリュームが割り当てられて、Boundになったことを確認できます。

$ kubectl get pvc -n default
NAME        STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
ebs-claim   Bound    pvc-d9e4a0b7-0a1a-4a20-8c0a-e12ffae902b3   1Gi        RWO            ebs-sc         <unset>                 5m4s

$ kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM               STORAGECLASS   VOLUMEATTRIBUTESCLASS   REASON   AGE
pvc-d9e4a0b7-0a1a-4a20-8c0a-e12ffae902b3   1Gi        RWO            Delete           Bound    default/ebs-claim   ebs-sc         <unset>                          31s

AWS CLIで、以下のように1GiBのEBSボリュームが作成されたのを確認できます。

$ aws ec2 describe-volumes \
  --filters 'Name=tag-key,Values=CSIVolumeName' \
  --query "Volumes[].{ID:VolumeId,Size:Size,State:State,Type:VolumeType}" \
  --output table
-----------------------------------------------------
|                  DescribeVolumes                  |
+------------------------+-------+---------+--------+
|           ID           | Size  |  State  | Type   |
+------------------------+-------+---------+--------+
|  vol-0b95c76f3b9f4565e |  1    |  in-use |  gp3   |
+------------------------+-------+---------+--------+

そして、PodでもEBSボリュームを問題なく使えていることを、以下のように確認できます。

$ kubectl get po -n default app
NAME   READY   STATUS    RESTARTS   AGE
app    1/1     Running   0          71s
$ kubectl exec -it -n default pod/app -- df -h
Filesystem      Size  Used Avail Use% Mounted on
overlay          14G  7.5G  6.1G  56% /
tmpfs            64M     0   64M   0% /dev
/dev/nvme1n1    974M   32K  958M   1% /data        # EBSボリュームをマウントできている
/dev/root        14G  7.5G  6.1G  56% /etc/hosts
shm              64M     0   64M   0% /dev/shm
tmpfs           3.7G   12K  3.7G   1% /run/secrets/kubernetes.io/serviceaccount
tmpfs           1.9G     0  1.9G   0% /proc/acpi
tmpfs           1.9G     0  1.9G   0% /proc/scsi
tmpfs           1.9G     0  1.9G   0% /sys/firmware

$ kubectl exec -it -n default pod/app -- tail -n 8 /data/out.txt
Fri Oct 30 01:58:37 UTC 2026
Fri Oct 30 01:58:42 UTC 2026
Fri Oct 30 01:58:47 UTC 2026
Fri Oct 30 01:58:52 UTC 2026
Fri Oct 30 01:58:57 UTC 2026
Fri Oct 30 01:59:02 UTC 2026
Fri Oct 30 01:59:07 UTC 2026
Fri Oct 30 01:59:12 UTC 2026

おわりに

ようやく、非EKSの環境で、IRSAを使って実用的なAWSリソースを使うところまで到達できました。

自前で構築したKubernetes環境で、EKSと同等のことがどこまでできるのか、今後も試していきたいです。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?