Skip to content

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

本站内容由 褚成志 整理编写,仅供学习参考