全部產品
Search
文件中心

Container Service for Kubernetes:使用ServiceAccount Token卷投影

更新時間:Aug 28, 2024

ServiceAccount Token作為身分識別驗證的憑證,使Pod中啟動並執行應用程式可以安全地與Kubernetes API進行通訊。為解決傳統的ServiceAccount Token以Secret的形式自動掛載到Pod中可能帶來的安全風險,您可以通過ACK服務賬戶令牌卷投影功能,使Pod以卷投影的形式將ServiceAccount Token或其他相關認證掛載到容器中,減少Secret的暴漏風險。

功能介紹

ServiceAccount是Pod和叢集API Server通訊的訪問憑證。傳統方式下,在Pod中使用ServiceAccount可能會面臨以下挑戰:

  • ServiceAccount中的JSON Web Token (JWT) 沒有綁定audience身份,因此所有ServiceAccount的使用者都可以彼此扮演,存在偽裝攻擊的可能。

  • 傳統方式下,每個ServiceAccount都需要儲存在一個對應的Secret中,並且會以檔案形式儲存在對應的應用節點上,而叢集的系統組件在運行過程中也會使用到一些許可權很高的ServiceAccount,其增大了叢集控制面的攻擊面,攻擊者可以通過擷取這些管控組件使用的ServiceAccount非法提權。

  • ServiceAccount中的JWT Token沒有設定到期時間,當上述ServiceAccount泄露情況發生時,您只能通過輪轉ServiceAccount的簽發私密金鑰來進行防範,而client-go中還不支援這樣的自動化流程,需要一個繁瑣的手動營運流程。

  • 每一個ServiceAccount都需要建立一個與之對應的Secret,在大規模的應用部署下存在彈性和容量風險。

ServiceAccount Token卷投影特性用於增強ServiceAccount的安全性,以更安全、更靈活的方式向Pod提供ServiceAccount相關的認證資訊。ServiceAccount Token卷投影可使Pod以卷投影的形式將ServiceAccount掛載到容器中,從而避免了對Secret的依賴。

前提條件

  • 已建立ACK託管叢集ACK專有叢集ACK Serverless叢集,且叢集版本為1.20及以上。具體操作,請參見建立ACK託管叢集建立ACK專有叢集建立叢集

  • 已在建立叢集的過程中啟用ServiceAccount Token卷投影功能。

    1.22及以上版本的叢集預設啟用ServiceAccount Token卷投影功能,無需手動操作。如需升級叢集,請參見手動升級叢集1.png

    叢集的系統組件API Server和Controller Manager會自動開啟綁定ServiceAccount Token卷投影的特性門控,同時在API Server的啟動參數中增加以下配置。

    參數

    說明

    預設值

    控制台配置

    service-account-issuer

    ServiceAccount Token中的簽發身份,即Token payload中的iss欄位。

    https://kubernetes.default.svc

    支援。

    api-audiences

    合法的請求Token身份,用於API Server服務端認證請求Token是否合法。

    https://kubernetes.default.svc

    支援。可以配置多個audience,通過英文半形逗號,分割。

    service-account-signing-key-file

    Token簽名私密金鑰檔案路徑。

    /etc/kubernetes/pki/sa.key

    不支援。預設使用/etc/kubernetes/pki/sa.key,無需配置。

步驟一:建立一個ServiceAccount對象

每個命名空間會存在一個預設的default ServiceAccount,您可以通過kubectl get serviceaccounts命令來查看。如果您需要為Pod中啟動並執行進程提供其他身份標識,您可以參見以下代碼建立一個新的ServiceAccount。

kubectl apply -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
  name: build-robot
EOF

ServiceAccount建立完成後,您可以執行kubectl get serviceaccounts/build-robot -o yaml命令查看該ServiceAccount的完整資訊。

步驟二:部署使用ServiceAccount Token投影的Pod應用

您可以將該ServiceAccount以卷的形式投射到Pod中,Pod中的容器便可以使用該Token訪問叢集API Server,並使用該ServiceAccount來進行身分識別驗證。例如,您可以指定Token的audience、有效期間限(expirationSeconds)等屬性,將其投射到一個Pod應用中。

  1. 使用以下範例程式碼,建立nginx.yaml檔案,其中Pod聲明了需要使用audiencevault且有效期間限為2個小時的ServiceAccount。

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx
    spec:
      containers:
      - image: nginx
        name: nginx
        volumeMounts:
        - mountPath: /var/run/secrets/tokens
          name: vault-token
      serviceAccountName: build-robot
      volumes:
      - name: vault-token
        projected:
          sources:
          - serviceAccountToken:
              path: vault-token
              expirationSeconds: 7200
              audience: vault
  2. 執行以下命令,部署使用卷投影的Pod應用。

    kubectl apply -f nginx.yaml
  3. 驗證該Pod中掛載的Token的有效期間。

    1. 執行以下命令,確認Pod已正常運行。

      kubectl get pod nginx

      預期輸出:

      NAME    READY   STATUS    RESTARTS   AGE
      nginx   1/1     Running   0          3m15s
    2. 下載Pod容器中掛載的Token。

      kubectl exec -t nginx -- cat /var/run/secrets/tokens/vault-token > vault-token
    3. 執行以下命令,擷取Token到期時間。

      cat vault-token |awk -F '.' '{print $2}' |base64 -d 2>/dev/null |jq  '.exp' | xargs -I {} date -d @{}

      樣本輸出:

      一  8 26 15:45:59 CST 2024
重要
  • 請您確保Pod中能夠即時擷取到輪轉後最新的Token,也就是確保Pod邏輯中能夠定期重新載入目標Token(建議為5分鐘)。官方Kubernetes在client-go 10.0.0版本後已經支援自動擷取最新的Token。

  • 容器中ServiceAccount對應的Token檔案屬性不再是644,在使用綁定ServiceAccount Token卷投影時,對應的Token檔案屬性已經改為600(使用fsGroup特性時為640)。