AWS EBS CSI ドライバー@Amazon EKS アドオン¶
はじめに¶
本サイトにつきまして、以下をご認識のほど宜しくお願いいたします。
01. AWS EBS CSI ドライバー¶
アーキテクチャ¶
PersistentVolume に AWS EBS を紐付け、Pod が AWS EBS を PersistentVolume として使用できるようにする。
ステートレスなアプリケーションでは、AWS EBS にデータを永続化する必要はないため、AWS EBS CSI ドライバーは不要である。

02. セットアップ¶
EKS アドオンとして¶
▼ Terraform の場合¶
Terraform を使用する。
Terraform の aws_eks_addon で EKS アドオンをインストールし、AWS EBS CSI ドライバーに関する Kubernetes リソースを作成する。
# Amazon EKSアドオンをインストールする。
resource "aws_eks_addon" "aws_ebs_csi_driver" {
cluster_name = data.aws_eks_cluster.cluster.name
addon_name = "aws-ebs-csi-driver"
addon_version = "<バージョン>"
service_account_role_arn = module.iam_assumable_role_ebs_csi_driver[0].iam_role_arn
# Terraformで設定を上書きできるようにする
resolve_conflicts_on_update = "OVERWRITE"
}
module "iam_assumable_role_with_oidc_ebs_csi_driver" {
source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role-with-oidc"
version = "<バージョン>"
# AWS EBS CSI ControllerのPodに紐付けるIAMロール
create_role = true
role_name = "foo-ebs-csi-driver"
# Amazon EKS ClusterのOIDCプロバイダーURLからhttpsプロトコルを除いたもの
# ArgoCDは、デプロイ専用のAmazon EKS Cluster上で稼働している
provider_url = replace(module.eks.cluster_oidc_issuer_url, "https://", "")
# AWS IAMロールに紐付けるIAMポリシー
role_policy_arns = [
"arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy"
]
# AWS EBS CSI ControllerのPodのServiceAccount名
# ServiceAccountは、Terraformではなく、マニフェストで定義したほうが良い
oidc_fully_qualified_subjects = [
"system:serviceaccount:kube-system:foo-ebs-csi-controller"
]
}
また、StorageClass を定義する必要があるが、Terraform かマニフェストでよい。
# KubernetesのStorageClassをTerraformで作成する。
# マニフェストとして定義しても良い。
resource "kubernetes_storage_class" "gp3_encrypted" {
metadata {
name = "gp3-encrypted"
annotations = {
"storageclass.kubernetes.io/is-default-class" = "true"
}
}
# AWS EBS CSIドライバーをプロビジョナーに設定する
storage_provisioner = "ebs.csi.aws.com"
parameters = {
encrypted = "true"
fsType = "ext4"
type = "gp3"
}
reclaim_policy = "Delete"
volume_binding_mode = "WaitForFirstConsumer"
}
別途、AWS EBS CSI ドライバーの Pod に紐付ける ServiceAccount を作成し、IAM ロールの ARN を設定する。
ServiceAccount は、Terraform ではなくマニフェストで定義したほうがよい。
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
eks.amazonaws.com/role-arn: <IAMロールのARN>
name: foo-ebs-csi-controller
namespace: kube-system
IRSA により、ServiceAccount を介して Pod と AWS IAM ロールが紐づく。
▼ Helm の場合¶
Helm を使用する。
Kubernetes よりも AWS に依存している要素が多いため、Terraform によるセットアップのほうが個人的にはおすすめである。
$ helm repo add <チャートリポジトリ名> https://kubernetes-sigs.github.io/aws-ebs-csi-driver
$ helm repo update
$ helm install <Helmリリース名> <リポジトリ名>/aws-ebs-csi-driver -n kube-system --version=<バージョンタグ>
02-02. マニフェスト¶
マニフェストの種類¶
AWS EBS CSI ドライバーは、Deployment (ebs-csi-controller) 、ServiceAccount などのマニフェストから構成される。
Deployment 配下の Pod¶
記入中...
ServiceAccount¶
IRSA の仕組みで、Pod と IAM ロールを紐付ける。
apiVersion: v1
kind: ServiceAccount
metadata:
name: foo-foo-ebs-csi-controller
namespace: kube-system
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::<アカウントID>:role/foo-ebs-csi-controller-role
secrets:
- name: foo-ebs-csi-controller-token
03. プロビジョニング¶
静的プロビジョニング¶
▼ AWS EBS¶
AWS EBS を手動で作成する必要がある。
▼ PersistentVolume¶
*実装例*
apiVersion: v1
kind: PersistentVolume
metadata:
name: foo-persistent-volume
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
csi:
# AWS EBS CSI ドライバーをプロビジョナーに設定する
driver: ebs.csi.aws.com
# 手動で作成した AWS EBS の ID を設定する。
volumeHandle: vol-*****
▼ PersistentVolumeClaim¶
PersistentVolumeClaim で Volume を要求する。
PersistentVolumeClaim で Volume を要求すると、AWS EBS CSI ドライバーは、PersistentVolume とそれに紐づく AWS EBS を自動的に作成する。
Pod の .spec.nodeSelector キーも不要である。
*実装例*
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: foo-persistent-volume-claim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
# デフォルトの動的プロビジョニングを確実に無効化する
storageClassName: ""
apiVersion: apps/v1
kind: Deployment
metadata:
name: foo
spec:
replicas: 2
selector:
matchLabels:
app: foo
template:
metadata:
labels:
app: foo
spec:
containers:
- name: foo
image: busybox
command:
- /bin/bash
- -c
- sleep 10000
volumeMounts:
- mountPath: /app/data
name: data
nodeSelector:
topology.ebs.csi.aws.com/zone: ap-northeast-1a
volumes:
- name: data
persistentVolumeClaim:
claimName: foo-persistent-volume-claim
動的プロビジョニング¶
▼ AWS EBS¶
AWS EBS は、AWS EBS CSI ドライバーが自動で作成するため、作成は不要である。
▼ StorageClass¶
自動的に PersistentVolume を作成する動的プロビジョニングの場合、StorageClass が必要である。
要求する AWS EBS のタイプを StorageClass で指定する。
reclaimPolicy が Delete になっている PersistentVolumeClaim を削除すれば、StorageClass が EBS もよしなに削除してくれる。
*実装例*
マニフェストまたは Terraform で定義する。
# マニフェストで定義した場合
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: foo-storage-class
parameters:
type: gp3
provisioner: ebs.csi.aws.com
# PersistentVolumeClaim が削除された時に、AWS EBS も自動的に削除できるようにする
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
# Terraformで定義した場合
resource "kubernetes_storage_class" "gp3_encrypted" {
metadata {
name = "foo-storage-class"
}
# AWS EBS CSIドライバーをプロビジョナーに設定する
storage_provisioner = "ebs.csi.aws.com"
parameters = {
encrypted = "true"
fsType = "ext4"
type = "gp3"
}
volume_binding_mode = "WaitForFirstConsumer"
}
▼ PersistentVolumeClaim¶
PersistentVolumeClaim で StorageClass を指定し、外部サービスが提供する Volume を要求する。
StorageClass が指定された PersistentVolumeClaim で Volume を要求すると、AWS EBS CSI ドライバーは、PersistentVolume とそれに紐づく AWS EBS を自動的に作成する。
Pod の .spec.nodeSelector キーも不要である。
*実装例*
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: foo-persistent-volume-claim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
# AWS EBS CSI ドライバーがプロビジョナーに指定された StorageClass を要求する
storageClassName: foo-storage-class
apiVersion: apps/v1
kind: Deployment
metadata:
name: foo
spec:
replicas: 2
selector:
matchLabels:
app: foo
template:
metadata:
labels:
app: foo
spec:
containers:
- name: foo
image: busybox
command:
- /bin/bash
- -c
- sleep 10000
volumeMounts:
- mountPath: /app/data
name: data
volumes:
- name: data
persistentVolumeClaim:
claimName: foo-persistent-volume-claim