🪣

aws-mountpoint-s3-csi-driver v2 アップグレードに関する備忘録

に公開

概要

EKS Addon の aws-mountpoint-s3-csi-driver を v1.x から v2.x にアップグレードしたときに対応が必要だったものを記事にまとめる

v2 の主な変更点

v2 ではアーキテクチャと認証方式に大きな変更がある。

1. アーキテクチャの変更

v2 では Mountpoint プロセスがホスト上の systemd ではなく、専用の Kubernetes Pod として動作するようになった。

公式アップグレードドキュメント より:

Prior to v2, Mountpoint processes were spawned on the host using systemd, with v2, Mountpoint processes will be spawned on dedicated and unprivileged Mountpoint Pods.

変更の目的

この変更の主な目的は以下の通り(設計 Issue より):

  1. SELinux 対応: SELinux が有効な環境(ROSA など)での動作をサポート
  2. リソース分離: 専用の unprivileged Pod で動作することで、ワークロードの分離が向上
  3. 運用改善: systemd リソースを消費せず、kubectl logs でログ確認が可能に
  4. Pod 共有: 同じノードで同じ認証情報を使う複数ワークロード間で Mountpoint Pod を共有可能

v1 と v2 の比較

項目 v1.x v2.x
Mountpoint 実行場所 ホスト上の systemd 専用 Pod(mount-s3 namespace)
権限 root non-root (unprivileged)
ログ確認 journalctl kubectl logs -n mount-s3
SELinux 対応 不可 可能

Mountpoint Pod の確認方法

# Mountpoint Pod の一覧
kubectl get pods -n mount-s3

# 特定ボリュームのログ確認
kubectl logs -n mount-s3 -l s3.csi.aws.com/volume-name=<pv-name>

2. 認証方式の変更

v1 ではワークロード Pod の ServiceAccount(IRSA)が自動的に使われていたが、v2 ではデフォルトで CSI ドライバーの ServiceAccount が使われるようになった。

項目 v1.x v2.x
デフォルト認証 ワークロード Pod の SA CSI ドライバーの SA

authenticationSource の選択肢

認証に使う SA ユースケース
driver(デフォルト) CSI ドライバーの SA クラスター全体で同じ S3 バケットにアクセス
pod ワークロード Pod の SA マルチテナント、Pod ごとに異なるバケット

アップグレード時に発生しうる問題

問題 1: 認証エラー

IRSA を使用している環境で、以下のエラーが発生する。

MountVolume.SetUp failed for volume "xxx-pv" : rpc error: code = Internal desc =
Failed to create S3 client
Caused by: No signing credentials available

原因: v2 ではデフォルトで CSI ドライバーの SA が使われるため、ワークロード Pod の IRSA が使われなくなった。

解決策: PersistentVolume の volumeAttributesauthenticationSource: pod を追加する(設定リファレンス)。

apiVersion: v1
kind: PersistentVolume
metadata:
  name: example-pv
spec:
  csi:
    driver: s3.csi.aws.com
    volumeHandle: s3-csi-driver-volume
    volumeAttributes:
      bucketName: my-bucket
      authenticationSource: pod  # これを追加

問題 2: Mountpoint Pod のスケジュール失敗

以下のエラーが発生する場合がある。

MountVolume.SetUp failed for volume "xxx-pv" : rpc error: code = Internal desc =
Could not mount "bucket-name" at "...": Failed to wait for Mountpoint Pod "mp-xxxxx" to be ready

原因: v2 では Mountpoint Pod がノードの Pod 数としてカウントされる。Mountpoint Pod はワークロード Pod と同じノードに配置される(node affinity)ため、ノードの Pod 上限(ENI 制限)がギリギリの場合、Mountpoint Pod がスケジュールできない。

ワークロード Pod → ノード X にスケジュール (28/29)

CSI driver が Mountpoint Pod を同じノードに作成しようとする

ノードが 29/29 で満杯 → Mountpoint Pod が Pending

マウント失敗

解決策例:

  • VPC CNI の Prefix Delegation を有効化: Pod 上限を大幅に引き上げる(詳細記事
  • より大きなインスタンスタイプを使用: ENI 数が増えるため Pod 上限も上がる
  • max-pods 設定の確認: カスタム設定で制限されている場合は見直す

PV/PVC の再作成

volumeAttributes は immutable なので、変更には PV/PVC の削除・再作成が必要。

finalizer による削除ブロック

PVC/PV には kubernetes.io/pvc-protection / kubernetes.io/pv-protection という finalizer がデフォルトで付与される。これにより、使用中のリソースが誤って削除されるのを防止している。

Linux の umount と同じイメージで理解できる。

Linux Kubernetes
umount /mnt/data kubectl delete pvc
device is busy エラー Terminating 状態で待機
プロセスがファイルを開いている Pod が PVC をマウントしている
lsof /mnt/data で犯人特定 kubectl get pods で犯人特定
プロセス kill → umount 成功 Pod 削除 → PVC 削除完了

Linux では即座にエラーになるが、Kubernetes の finalizer は「削除予約」状態(Terminating)で待機し、使用中の Pod が消えた瞬間に自動で削除が完了する。

削除がブロックされるケース

PVC を kubectl delete しても Terminating 状態のまま消えない場合、その PVC をマウントしている Pod が残っている可能性が高い。

# Terminating 状態の確認
kubectl get pvc -n <namespace>
# STATUS が Terminating のまま

# PVC を使用している Pod を探す
kubectl get pods -n <namespace> --field-selector=status.phase=Running | grep <関連キーワー>

# Pod が PVC をマウントしているか確認
kubectl get pod <pod-name> -n <namespace> -o jsonpath='{.spec.volumes[*].persistentVolumeClaim.claimName}'

再作成手順

  1. PVC をマウントしている Pod を先に削除する
  2. PVC を削除(finalizer が解除され削除される)
  3. PV を削除
  4. 新しいマニフェストを apply
# 1. 必要に応じて Pod を削除
kubectl delete pod <pod-name> -n <namespace>

# 2. PVC を削除(Pod 削除後は即座に消える)
kubectl delete pvc <pvc-name> -n <namespace>

# 3. PV を削除
kubectl delete pv <pv-name>

# 4. 再作成
kubectl apply -k <path-to-kustomization>

# 5. 反映確認
kubectl get pv <pv-name> -o jsonpath='{.spec.csi.volumeAttributes}'
GitHubで編集を提案
Atrae Tech

Discussion