ASCP
AWS Secrets Manager で管理しているシークレットの情報を Amazon EKS の Pod から取得させるには、AWS Secrets and Config Provider (ASCP) を使用します。
動作環境
- ASCP は EC2 ノードグループを実行する EKS 1.17 以降で動作します。
- Fargate ノードグループはサポートされていません。
設定
クラスターの準備
クラスターを準備
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: cluster-test
region: ap-northeast-1
version: "1.27"
iam:
withOIDC: true
nodeGroups:
- name: node-ec2
privateNetworking: true
instanceType: t3.small
desiredCapacity: 1
minSize: 1
maxSize: 2
fargateProfiles:
- name: node-fargate
selectors:
- namespace: default
eksctl create cluster -f ClusterConfig.yaml
クラスターが作成されたことを確認
eksctl get cluster
NAME REGION EKSCTL CREATED
cluster-fargate ap-northeast-1 True
ノードを確認
kubectl get node
NAME STATUS ROLES AGE VERSION
ip-192-168-138-24.ap-northeast-1.compute.internal Ready <none> 60m v1.27.7-eks-e71965b
secrets-store-csi-driver と ASCP を インストールする
secrets-store-csi-driver と ASCP を Helm を使用してインストールします。
helm repo add secrets-store-csi-driver https://kubernetes-sigs.github.io/secrets-store-csi-driver/charts
helm install -n kube-system csi-secrets-store secrets-store-csi-driver/secrets-store-csi-driver
helm repo add aws-secrets-manager https://aws.github.io/secrets-store-csi-driver-provider-aws
helm install -n kube-system secrets-provider-aws aws-secrets-manager/secrets-store-csi-driver-provider-aws
テスト用の Secrets Manager のシークレットの作成
テスト用の Secrets Manager のシークレットを準備しておきます。
aws --region ap-northeast-1 secretsmanager create-secret --name Secret001 --secret-string '{"username":"user001", "password":"pass001"}'
{
"ARN": "arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:Secret001-Yqs0Iu",
"Name": "Secret001",
"VersionId": "b8fe16a4-b03d-43e1-9196-0c9f1081420a"
}
Pod のリソースポリシーの作成
Pod が Secret Manager のシークレットにアクセスするためのリソースポリシーを作成します。
POLICY_ARN=$(aws --region ap-northeast-1 --query Policy.Arn --output text iam create-policy --policy-name nginx-deployment-policy --policy-document '{
"Version": "2012-10-17",
"Statement": [ {
"Effect": "Allow",
"Action": ["secretsmanager:GetSecretValue", "secretsmanager:DescribeSecret"],
"Resource": ["arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:Secret001-Yqs0Iu"]
} ]
}')
サービスアカウントの作成
Pod が使用するサービスアカウントを作成し、リソースポリシーをそのサービスアカウントに関連付けます。
eksctl create iamserviceaccount --name nginx-deployment-sa --region=ap-northeast-1 --cluster cluster-test --attach-policy-arn "$POLICY_ARN" --approve --override-existing-serviceaccounts
ちなみにサービスアカウントについては、こちら の記事も参考に。
サービスアカウントが作成されていることの確認
kubectl get sa
NAME SECRETS AGE
nginx-deployment-sa 0 4m11s
SecretProviderClass
SecretProviderClass を作成して、Pod にマウントするシークレットを指定します。
ここでは、先程 Secret Manager で作成したシークレット Secret001 を指定します。
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: nginx-deployment-aws-secrets
spec:
provider: aws
parameters:
objects: |
- objectName: "Secret001"
objectType: "secretsmanager"
kubectl apply -f ExampleSecretProviderClass.yaml
secretproviderclass.secrets-store.csi.x-k8s.io/nginx-deployment-aws-secrets created
SecretProviderClass の確認
kubectl get SecretProviderClass
NAME AGE
nginx-deployment-aws-secrets 70s
Pod のデプロイ
kind: Service
apiVersion: v1
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
serviceAccountName: nginx-deployment-sa
volumes:
- name: secrets-store-inline
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: "nginx-deployment-aws-secrets"
containers:
- name: nginx-deployment
image: nginx
ports:
- containerPort: 80
volumeMounts:
- name: secrets-store-inline
mountPath: "/mnt/secrets-store"
readOnly: true
まず、わざと fargate にデプロイし、Pod の詳細を確認してみます。
kubectl apply -f ExampleDeployment.yaml
kubectl describe pod/nginx-deployment-7bb889c877-2fx28
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 6m6s fargate-scheduler Pod not supported on Fargate: volumes not supported: secrets-store-inline is of an unsupported volume Type
では、fargateprofile は削除し、EC2 ノードで動作させるように再度、apply してみます。
eksctl delete fargateprofile --name node-fargate --cluster cluster-fargate
kubectl apply -f ExampleDeployment.yaml
kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-deployment-7bb889c877-6krlq 1/1 Running 0 4h9m
nginx-deployment-7bb889c877-988zf 1/1 Running 0 4h9m
Pod のデプロイが完了したので動作確認してみます。
kubectl exec -it nginx-deployment-7bb889c877-6krlq
cat /mnt/secrets-store/Secret001
{"username":"user001", "password":"pass001"}