ServiceAccount 深度解析
ServiceAccount 概述
ServiceAccount 为 Pod 提供身份标识,用于访问 K8s API 和其他服务。
默认行为
bash
# 每个命名空间都有 default ServiceAccount
kubectl get serviceaccount -n default
# Pod 默认使用 default SA,自动挂载 Token
# 挂载路径:/var/run/secrets/kubernetes.io/serviceaccount/
# - token:JWT Token
# - ca.crt:API Server CA 证书
# - namespace:当前命名空间创建和使用
yaml
# 创建 ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-app-sa
namespace: production
automountServiceAccountToken: false # 默认不挂载 Token
---
# Pod 使用 ServiceAccount
spec:
serviceAccountName: my-app-sa
automountServiceAccountToken: true # 需要时才挂载Projected Token(推荐)
yaml
# 使用 Projected Volume 挂载短期 Token(更安全)
spec:
serviceAccountName: my-app-sa
volumes:
- name: token
projected:
sources:
- serviceAccountToken:
path: token
expirationSeconds: 3600 # 1 小时过期
audience: my-api-server # 限定受众
containers:
- name: app
volumeMounts:
- name: token
mountPath: /var/run/secrets/tokens
readOnly: true云厂商集成
AWS IRSA(IAM Roles for Service Accounts)
yaml
# ServiceAccount 关联 IAM Role
apiVersion: v1
kind: ServiceAccount
metadata:
name: s3-access-sa
namespace: production
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/S3AccessRole
---
# IAM Role 信任策略
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::123456789012:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/XXXXX"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.us-east-1.amazonaws.com/id/XXXXX:sub": "system:serviceaccount:production:s3-access-sa"
}
}
}]
}GKE Workload Identity
bash
# 绑定 K8s SA 和 GCP SA
gcloud iam service-accounts add-iam-policy-binding \
gcp-sa@project.iam.gserviceaccount.com \
--role roles/iam.workloadIdentityUser \
--member "serviceAccount:project.svc.id.goog[production/my-app-sa]"
kubectl annotate serviceaccount my-app-sa \
--namespace production \
iam.gke.io/gcp-service-account=gcp-sa@project.iam.gserviceaccount.com最佳实践
yaml
# 每个应用使用独立的 ServiceAccount
# 最小权限原则
# 不使用 default ServiceAccount
# 禁用不需要的 Token 自动挂载
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-app-sa
namespace: production
automountServiceAccountToken: false # 默认禁用
---
# 只在需要时启用
spec:
serviceAccountName: my-app-sa
automountServiceAccountToken: true