0

我一直在按照教程使用 helm 在 minikube 上设置 vault 和 kubernetes。

在我看来,保险库服务帐户正在使用默认服务帐户 JWT 令牌来访问 API 进行身份验证。Vault 服务帐户是否应该使用自己的令牌,而不是默认令牌?

以下是相关的配置步骤:

# Configure the auth.
vault write auth/kubernetes/config \
      token_reviewer_jwt="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
      kubernetes_host="https://$KUBERNETES_PORT_443_TCP_ADDR:443" \
      kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt \
      disable_iss_validation=true

# Configure the policy.
vault policy write webapp - <<EOF
path "secret/data/webapp/config" {
  capabilities = ["read"]
}
EOF

# Create the role.
vault write auth/kubernetes/role/webapp \
      bound_service_account_names=vault \
      bound_service_account_namespaces=default \
      policies=webapp \
      ttl=24h

webapp pod 上的客户端(expressjs)读取挂载的令牌进行身份验证:

...
await axiosInst.post("/auth/kubernetes/login",
  {jwt: fs.readFileSync(process.env.JWT_PATH, {encoding: "utf-8"}),
  role: "webapp"});
...

但是,/var/run/secrets/kubernetes.io/serviceaccount/tokenwebapp pod 上的令牌是默认服务帐户令牌,而不是保管库服务帐户令牌,对吗?

我在这里做错了吗?

网络部署.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web-pod
  template:
    metadata:
      labels:
        app: web-pod
    spec:
      serviceAccountName: vault
      containers:
      - name: web
        image: kahunacohen/hello-k8s
        imagePullPolicy: IfNotPresent
        env:
          - name: VAULT_ADDR
            value: 'http://vault:8200'
          - name: JWT_PATH
            value: '/var/run/secrets/kubernetes.io/serviceaccount/token'
          - name: SERVICE_PORT
            value: '8080'
        envFrom:
          - configMapRef:
              name: web-configmap
        ports:
        - containerPort: 3000
          protocol: TCP

我描述了保险库sa:

$ kubectl describe  serviceaccounts vault
Name:                vault
Namespace:           default
Labels:              app.kubernetes.io/instance=vault
                     app.kubernetes.io/managed-by=Helm
                     app.kubernetes.io/name=vault
                     helm.sh/chart=vault-0.14.0
Annotations:         meta.helm.sh/release-name: vault
                     meta.helm.sh/release-namespace: default
Image pull secrets:  <none>
Mountable secrets:   vault-token-jhp5q
Tokens:              vault-token-jhp5q
Events:              <none>

我描述了与这个 sa 相关的秘密:

$ kubectl describe secret vault-token-jhp5q
Name:         vault-token-jhp5q
Namespace:    default
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: vault
              kubernetes.io/service-account.uid: 9a091a35-9292-4d77-abac-a7d62f312d27

Type:  kubernetes.io/service-account-token

Data
====
ca.crt:     1111 bytes
namespace:  7 bytes
token:      eyJhb...

但是当我将令牌放在我的 pod 上时,它与上面的不匹配:

$ kubectl exec web-deployment-66968775cb-8td6c -- cat  /var/run/secrets/kubernetes.io/serviceaccount/token
...

豆荚yaml:

$ kubectl get pods web-deployment-66968775cb-8td6c -o yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: "2021-08-14T19:32:54Z"
  generateName: web-deployment-66968775cb-
  labels:
    app: web-pod
    app.kubernetes.io/managed-by: skaffold
    pod-template-hash: 66968775cb
    skaffold.dev/run-id: f58f771b-258a-4304-baf6-1cc4d9bc3029
  name: web-deployment-66968775cb-8td6c
  namespace: default
  ownerReferences:
  - apiVersion: apps/v1
    blockOwnerDeletion: true
    controller: true
    kind: ReplicaSet
    name: web-deployment-66968775cb
    uid: 6e62ba08-8b56-402a-ae10-e5d95f93dc39
  resourceVersion: "1444983"
  uid: 991199f5-0e53-45b9-a4d7-ab1d3cc44079
spec:
  containers:
  - env:
    - name: VAULT_ADDR
      value: http://vault:8200
    - name: JWT_PATH
      value: /var/run/secrets/kubernetes.io/serviceaccount/token
    - name: SERVICE_PORT
      value: "8080"
    envFrom:
    - configMapRef:
        name: web-configmap
    image: kahunacohen/hello-k8s:fb961e142e46220f11853eba6f50eaf94510a95dc08046ad8a1517d92fcb2d85
    imagePullPolicy: IfNotPresent
    name: web
    ports:
    - containerPort: 3000
      protocol: TCP
    resources: {}
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
    volumeMounts:
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: kube-api-access-zjkvp
      readOnly: true
  dnsPolicy: ClusterFirst
  enableServiceLinks: true
  nodeName: minikube
  preemptionPolicy: PreemptLowerPriority
  priority: 0
  restartPolicy: Always
  schedulerName: default-scheduler
  securityContext: {}
  serviceAccount: vault
  serviceAccountName: vault
  terminationGracePeriodSeconds: 30
  tolerations:
  - effect: NoExecute
    key: node.kubernetes.io/not-ready
    operator: Exists
    tolerationSeconds: 300
  - effect: NoExecute
    key: node.kubernetes.io/unreachable
    operator: Exists
    tolerationSeconds: 300
  volumes:
  - name: kube-api-access-zjkvp
    projected:
      defaultMode: 420
      sources:
      - serviceAccountToken:
          expirationSeconds: 3607
          path: token
      - configMap:
          items:
          - key: ca.crt
            path: ca.crt
          name: kube-root-ca.crt
      - downwardAPI:
          items:
          - fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace
            path: namespace
status:
  conditions:
  - lastProbeTime: null
    lastTransitionTime: "2021-08-14T19:32:54Z"
    status: "True"
    type: Initialized
  - lastProbeTime: null
    lastTransitionTime: "2021-08-15T15:01:02Z"
    status: "True"
    type: Ready
  - lastProbeTime: null
    lastTransitionTime: "2021-08-15T15:01:02Z"
    status: "True"
    type: ContainersReady
  - lastProbeTime: null
    lastTransitionTime: "2021-08-14T19:32:54Z"
    status: "True"
    type: PodScheduled
  containerStatuses:
  - containerID: docker://4759183417a8ef0bbee8f28bf345aed373371f7ca462b9a5f5a966eba33117d2
    image: kahunacohen/hello-k8s:b65b899-dirty
    imageID: docker://sha256:fb961e142e46220f11853eba6f50eaf94510a95dc08046ad8a1517d92fcb2d85
    lastState:
      terminated:
        containerID: docker://87636058668d022160149f176cd3c565bf17c239e97c55d873e42c9c074215d6
        exitCode: 255
        finishedAt: "2021-08-15T15:00:01Z"
        reason: Error
        startedAt: "2021-08-14T19:32:55Z"
    name: web
    ready: true
    restartCount: 1
    started: true
    state:
      running:
        startedAt: "2021-08-15T15:01:01Z"
  hostIP: 192.168.49.2
  phase: Running
  podIP: 172.17.0.10
  podIPs:
  - ip: 172.17.0.10
  qosClass: BestEffort
  startTime: "2021-08-14T19:32:54Z"
4

1 回答 1

0

webapp pod 上的“/var/run/secrets/kubernetes.io/serviceaccount/token”是默认的服务帐户令牌,对吧?

不,这取决于 Pod YAML。

  1. 案例 1:如果您没有为您的 pod 设置服务帐户,它使用default服务帐户。
  2. 案例 2:如果您为您的 pod 设置服务帐户,它将使用该服务帐户的 jwt 令牌。在你的情况下,它是vault.
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  serviceAccountName: vault
... ... ...

Kubernetes 身份验证和保险库:

  • 您需要一个admin用于配置(即token_reviewer_jwt=...)Vault k8s 身份验证的服务帐户(例如)。它将具有system-authdelegator分配给它的 RBAC 角色。现在它有权验证其他服务帐户 JWT 令牌。
  • 您有一个使用另一个服务帐户(例如client)运行的应用程序,保管库管理员已使用它创建了一个 k8s auth 角色(即。bound_service_account_names=client)。
  • 您的应用程序会将客户端的 JWT 发送到 Vault--> Vault 会将其发送到 kube-api,其中包含管理员的 JWT(介绍他是管理员的 kube-api)和客户端的 JWT(管理员想要验证的人)。
于 2021-08-16T09:02:56.427 回答