Secrets PropertySource

Kubernetes 引入了 Secrets 概念,用於儲存密碼、OAuth 令牌等敏感資料。本專案提供了與 Secrets 的整合,使 Spring Boot 應用能夠訪問 Secrets。你可以透過設定 spring.cloud.kubernetes.secrets.enabled 屬性來顯式啟用或停用此功能。

啟用後,Fabric8SecretsPropertySource 會從以下來源在 Kubernetes 中查詢 Secrets

  1. 遞迴讀取 Secrets 掛載

  2. 以應用名稱命名(由 spring.application.name 定義)

  3. 匹配特定標籤

注意

預設情況下,出於安全原因,透過 API 使用 Secrets(上述第 2 和第 3 點)未啟用。對 secrets 擁有 'list' 許可權允許客戶端檢查指定名稱空間中的 secrets 值。此外,我們建議容器透過掛載卷的方式共享 secrets。

如果你透過 API 啟用 Secrets 使用,我們建議你使用授權策略(如 RBAC)限制對 Secrets 的訪問。有關透過 API 使用 Secrets 的風險和最佳實踐的更多資訊,請參閱此文件

如果找到 secrets,其資料將可供應用使用。

假設我們有一個名為 demo 的 Spring Boot 應用,它使用屬性讀取資料庫配置。我們可以使用以下命令建立一個 Kubernetes secret

kubectl create secret generic db-secret --from-literal=username=user --from-literal=password=p455w0rd

上述命令將建立以下 secret(你可以使用 kubectl get secrets db-secret -o yaml 命令檢視)

apiVersion: v1
data:
  password: cDQ1NXcwcmQ=
  username: dXNlcg==
kind: Secret
metadata:
  creationTimestamp: 2017-07-04T09:15:57Z
  name: db-secret
  namespace: default
  resourceVersion: "357496"
  selfLink: /api/v1/namespaces/default/secrets/db-secret
  uid: 63c89263-6099-11e7-b3da-76d6186905a8
type: Opaque

請注意,資料包含由 create 命令提供的字面值的 Base64 編碼版本。

你的應用隨後可以使用此 secret — 例如,將其值匯出為環境變數

apiVersion: v1
kind: Deployment
metadata:
  name: ${project.artifactId}
spec:
   template:
     spec:
       containers:
         - env:
            - name: DB_USERNAME
              valueFrom:
                 secretKeyRef:
                   name: db-secret
                   key: username
            - name: DB_PASSWORD
              valueFrom:
                 secretKeyRef:
                   name: db-secret
                   key: password

你可以透過多種方式選擇要使用的 Secrets

  1. 透過列出 secrets 對映的目錄

    -Dspring.cloud.kubernetes.secrets.paths=/etc/secrets/db-secret,etc/secrets/postgresql

    如果你的所有 secrets 都對映到一個公共根目錄,你可以像這樣設定它們

    -Dspring.cloud.kubernetes.secrets.paths=/etc/secrets
  2. 透過設定命名 secret

    -Dspring.cloud.kubernetes.secrets.name=db-secret
  3. 透過定義標籤列表

    -Dspring.cloud.kubernetes.secrets.labels.broker=activemq
    -Dspring.cloud.kubernetes.secrets.labels.db=postgresql

ConfigMap 一樣,也可以進行更高階的配置,你可以使用多個 Secret 例項。spring.cloud.kubernetes.secrets.sources 列表使得這成為可能。例如,你可以定義以下 Secret 例項

spring:
  application:
    name: cloud-k8s-app
  cloud:
    kubernetes:
      secrets:
        name: default-name
        namespace: default-namespace
        sources:
         # Spring Cloud Kubernetes looks up a Secret named s1 in namespace default-namespace
         - name: s1
         # Spring Cloud Kubernetes looks up a Secret named default-name in namespace n2
         - namespace: n2
         # Spring Cloud Kubernetes looks up a Secret named s3 in namespace n3
         - namespace: n3
           name: s3

在前面的示例中,如果未設定 spring.cloud.kubernetes.secrets.namespace,則名為 s1Secret 將在應用執行的名稱空間中查詢。請參閱Namespace 解析以更好地理解應用名稱空間的解析方式。

類似於 ConfigMaps;如果你希望應用在無法載入 Secrets property sources 時啟動失敗,可以設定 spring.cloud.kubernetes.secrets.fail-fast=true

也可以為 Secret property sources 啟用重試,類似於 ConfigMaps。與 ConfigMap property sources 一樣,首先需要設定 spring.cloud.kubernetes.secrets.fail-fast=true。然後需要將 spring-retryspring-boot-starter-aop 新增到類路徑中。可以透過設定 spring.cloud.kubernetes.secrets.retry.* 屬性來配置 Secret property sources 的重試行為。

如果由於某種原因你的類路徑中已經有 spring-retryspring-boot-starter-aop,並且想要啟用 fail-fast 但不想啟用重試;你可以透過設定 spring.cloud.kubernetes.secrets.retry.enabled=false 來停用 Secrets PropertySources 的重試。

由於來自 Secrets 的資料通常被視為敏感資料,因此可以對 actuator 的 /env/configprops 端點進行資料清理,使其不以純文字形式顯示。為此,你需要設定

spring.cloud.kubernetes.sanitize.secrets=true

此設定從 3.0.6 版本及更高版本開始支援。

表 1. 屬性
名稱 型別 預設值 描述

spring.cloud.kubernetes.secrets.enabled

Boolean

true

啟用 Secrets PropertySource

spring.cloud.kubernetes.secrets.name

String

${spring.application.name}

設定要查詢的 secret 名稱

spring.cloud.kubernetes.secrets.namespace

String

客戶端名稱空間

設定要查詢的 Kubernetes 名稱空間

spring.cloud.kubernetes.secrets.labels

Map

null

設定用於查詢 secrets 的標籤

spring.cloud.kubernetes.secrets.paths

List

null

設定 secrets 掛載的路徑(示例 1)

spring.cloud.kubernetes.secrets.enableApi

Boolean

false

啟用或停用透過 API 使用 secrets(示例 2 和 3)

spring.cloud.kubernetes.secrets.fail-fast

Boolean

false

當載入 Secret 時發生錯誤時,啟用或停用應用啟動失敗

spring.cloud.kubernetes.secrets.retry.enabled

Boolean

true

啟用或停用 secrets 重試。

spring.cloud.kubernetes.secrets.retry.initial-interval

Long

1000

初始重試間隔(毫秒)。

spring.cloud.kubernetes.secrets.retry.max-attempts

Integer

6

最大嘗試次數。

spring.cloud.kubernetes.secrets.retry.max-interval

Long

2000

最大退避間隔。

spring.cloud.kubernetes.secrets.retry.multiplier

Double

1.1

下一次間隔的乘數。

註釋

  • spring.cloud.kubernetes.secrets.labels 屬性的行為遵循Map-based binding的定義。

  • spring.cloud.kubernetes.secrets.paths 屬性的行為遵循Collection-based binding的定義。

  • 出於安全原因,透過 API 訪問 secrets 可能會受到限制。推薦的方式是將 secrets 掛載到 Pod 中。

你可以在spring-boot-camel-config找到一個使用 secrets 的應用示例(儘管它尚未更新以使用新的 spring-cloud-kubernetes 專案)