将 S3 对象挂载到 Kubernetes Pod
本文介绍如何将 S3 存储桶挂载到 EKS 集群中的所有节点,并使其作为hostPath 卷可供 Pod 访问。我们当然知道 hostPath 卷存在安全隐患,但在此情况下,这并非主要问题——因为实际访问权限授予的是 S3 存储桶(而非主机文件系统),并且访问权限是按服务帐户分配的。
高飞
我们使用goofys作为挂载工具。它是一个“用 Go 语言编写的高性能、类 POSIX 的 Amazon S3 文件系统”,基于FUSE(用户空间文件系统)技术。
守护进程集
为了透明地提供挂载点,我们需要运行一个守护进程集——这样就可以在集群中的所有节点上创建挂载点。
Dockerfile 和 Helm Chart
我们基于Alpine Linux和 Helm chart 构建了自己的 goofys Docker 镜像,该镜像安装了 DaemonSet。
该镜像文件位于我们的 Docker Hub 仓库中,地址为:https://hub.docker.com/r/otomato/goofys
Dockerfile 和 Helm chart 文件可以在这里找到:https://github.com/otomato-gh/s3-mounter
每个服务帐户的 S3 访问权限
目前,Helm Chart 假定 S3 访问权限是通过附加到 Kubernetes 服务帐户的 IAM 角色提供的。如有需要,我们将来可能会添加对 API 访问密钥的支持。
操作方法:
以下是具体设置方法:
1. EKS 的 OIDC 提供商
请确保您的集群拥有 IAM OIDC 身份提供程序。如果没有,您可以使用以下命令(需要先eksctl安装):
aws eks describe-cluster --name cluster_name --query "cluster.identity.oidc.issuer" --output text`
示例输出:
https://oidc.eks.region-code.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E
列出您帐户中的 IAM OIDC 提供程序。将“EXAMPLED539D4633E53DE1B716D3041E提供程序”替换为上一个命令返回的值。
aws iam list-open-id-connect-providers | grep EXAMPLED539D4633E53DE1B716D3041E
示例输出
"Arn": "arn:aws:iam::111122223333:oidc-provider/oidc.eks.region-code.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E"
如果上一个命令返回了输出,则说明您的集群已经存在提供程序。如果没有返回输出,则必须使用以下命令创建 IAM OIDC 提供程序。请将 `<provider>` 替换cluster_name为您自己的值。
eksctl utils associate-iam-oidc-provider --cluster cluster_name --approve
2. 创建存储桶访问的托管策略
创建一个名为 `<pucket_name>` 的 JSON 文件,policy.json其中包含相应的策略定义。例如,以下代码片段创建一个 JSON 文件,允许对名为 `<bucket_name>` 的存储桶进行完全访问my-kubernetes-bucket:
read -r -d '' MY_POLICY <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:*",
],
"Resource": [
"arn:aws:s3:::my-kubernetes-bucket"
]
}
]
}
EOF
echo "${MY_POLICY}" > policy.json
运行以下命令创建托管策略:
aws iam create-policy --policy-name kubernetes-s3-access --policy-document file://policy.json
示例输出:
{
"策略": {
"策略名称": "kubernetes-s3-access",
"策略 ID": "ANPAS3DOMWSIX73USJOHK",
"Arn":"arn:aws:iam::04968064045764:policy/kubernetes-s3-access",
记下保单 ARN,以便进行下一步操作。
3. 创建 S3 访问权限角色
使用以下命令将您的 AWS 账户 ID 设置为环境变量:
ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)
使用以下命令将 OIDC 身份提供程序设置为环境变量。请将示例值替换为您自己的值:
OIDC_PROVIDER=$(aws eks describe-cluster --name cluster-name --query "cluster.identity.oidc.issuer" --output text | sed -e "s/^https:\/\///")
将以下代码块复制到您的计算机,并将示例值替换为您自己的值。
read -r -d '' TRUST_RELATIONSHIP <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::${ACCOUNT_ID}:oidc-provider/${OIDC_PROVIDER}"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"${OIDC_PROVIDER}:sub": "system:serviceaccount:my-namespace:my-service-account"
}
}
}
]
}
EOF
echo "${TRUST_RELATIONSHIP}" > trust.json
运行上一步修改后的代码块,创建一个名为 . 的文件trust.json。
运行以下 AWS CLI 命令创建角色:
aws iam create-role --role-name eks-otomounter-role --assume-role-policy-document file://trust.json --description "Mount s3 bucket to EKS"
运行以下命令,将上一节中创建的 ARN 对应的 IAM 策略附加到您的角色:
aws iam attach-role-policy --role-name eks-otomounter-role --policy-arn=IAM_POLICY_ARN
4. 最后——安装 S3 挂载器!
- 将 Helm 仓库添加到您的仓库列表中:
helm repo add otomount https://otomato-gh.github.io/s3-mounter
- 检查其参数
values.yaml
helm show values otomount/s3-otomount
最后要设置的值是:
bucketName: my-bucket
iamRoleARN: my-role
mountPath: /var/s3
hostPath: /mnt/s3data
- 通过提供您自己的值来安装图表:
helm upgrade --install s3-mounter otomount/s3-otomount \
--namespace otomount --set bucketName=<your-bucket-name> \
--set iamRoleARN=<your-role-arn> --create-namespace
这将使用挂载的默认主机路径,即/mnt/s3data
5. 在部署中使用已挂载的 S3 存储桶。
以下是一个示例 Pod 定义,它为容器提供对已挂载存储桶的访问权限:
apiVersion: v1
kind: Pod
metadata:
name: sleeper
spec:
containers:
- command:
- sleep
- infinity
image: ubuntu
name: ubuntu
volumeMounts:
- mountPath: /mydata:shared
name: s3data
volumes:
- hostPath:
path: /mnt/s3data
name: s3data
注意:shared- 这是字段中的挂载传播mountPath修饰符,允许同一节点上的多个 pod/容器共享此卷。
好了!现在你可以访问你的存储桶了。如果你已经按照我们的示例创建了 Pod,你可以执行以下命令进行验证:
kubectl exec sleeper -- ls /mydata
注意:在集群上运行此程序会产生一些额外的费用,因为 goofys 会调用 S3 API 来维护挂载点。所以请务必监控您的云费用。不过,无论如何您都应该这样做,对吧?
送货愉快!
文章来源:https://dev.to/otomato_io/mount-s3-objects-to-kubernetes-pods-12f5