首页 > 解决方案 > Spring Boot 应用程序不使用 k8 gke 服务帐户,而是使用默认服务帐户

问题描述

问题陈述:

我已经在 gke 中的命名空间下部署了一个 spring boot 应用程序,当应用程序启动时它使用默认的 gce sa 凭据进行身份验证。我所做的是创建一个 gke 服务帐户并使用 iam 策略绑定与 google 服务帐户绑定并添加工作负载身份用户角色,然后通过执行以下 2 个命令来注释 gke sa

问题仍然是我的 Spring Boot 使用默认的 gce sa 凭据可以有人请帮我解决这个问题。

我可以看到 serviceAccountName 更改为新的 gke k8 SA,并且秘密也正在创建和安装。但是部署的应用程序没有使用这个 Gke SA

注意:我使用 Helsm 图表进行部署

gcloud iam service-accounts add-iam-policy-binding \
  --member serviceAccount:{projectID}.svc.id.goog[default/{k8sServiceAccount}] \
  --role roles/iam.workloadIdentityUser \
  {googleServiceAccount}

kubectl annotate serviceaccount \
  --namespace default \
  {k8sServiceAccount} \
  iam.gke.io/gcp-service-account={googleServiceAccount}
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: helloworld
    appVersion: {{ .Values.appVersion }}
  name: helloworld
spec:
  replicas: 1
  selector:
    matchLabels:
      app: helloworld
  template:
    metadata:
      labels:
        app: helloworld
        environment: {{ .Values.environment }}
    spec:
      serviceAccountName: {{ .Values.serviceAccountName }}
      containers:
        - name: helloworld
          image: {{ .Values.imageSha }}
          imagePullPolicy: Always
          securityContext:
            allowPrivilegeEscalation: false
            runAsUser: 1000
          ports:
            - containerPort: 8080
          env:
          - name: SPRING_CONFIG_LOCATION
            value: "/app/deployments/config/"          
          volumeMounts:
            - name: application-config
              mountPath: "/app/deployments/config"
              readOnly: true
      volumes:
      - name: application-config
        configMap:
          name: {{ .Values.configMapName }}
          items:
          - key: application.properties
            path: application.properties

标签: spring-bootgoogle-cloud-platformgoogle-kubernetes-enginekubernetes-pod

解决方案


创建 Pod 时,如果不指定服务帐号,则会自动为其分配default同一命名空间中的服务帐号。如果您获得了您创建的 pod 的原始 json 或 yaml(例如,kubectl get pods/<podname> -o yaml),您可以看到该spec.serviceAccountName字段已被自动设置。

您可以使用自动挂载的服务帐户凭据从 pod 内部访问 API,如访问集群 [1] 中所述。服务帐户的 API 权限取决于使用的授权插件和策略 [2]。

在 1.6+ 版本中,您可以通过设置服务帐户来选择不为服务帐户自动挂载 API 凭据automountServiceAccountToken: false

apiVersion: v1
kind: ServiceAccount
metadata:
  name: build-robot
automountServiceAccountToken: false
...

在 1.6+ 版本中,您还可以选择不为特定 pod 自动挂载 API 凭证:

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  serviceAccountName: build-robot
  automountServiceAccountToken: false
  ...

automountServiceAccountToken如果两者都指定了值,则 pod 规范优先于服务帐户。


[1] https://kubernetes.io/docs/tasks/access-application-cluster/access-cluster/

[2] https://kubernetes.io/docs/reference/access-authn-authz/authorization/#authorization-modules


推荐阅读