Secret
Secret 是一種物件,包含少量敏感資料,例如密碼、令牌或金鑰。這類資訊原本可能會放在 Pod 規約或 容器映象 中。使用 Secret 意味著你無需將機密資料包含在應用程式程式碼中。
由於 Secret 可以獨立於使用它們的 Pod 建立,因此在建立、檢視和編輯 Pod 的工作流程中,Secret(及其資料)被洩露的風險更低。Kubernetes 以及在你叢集中執行的應用程式還可以對 Secret 採取額外的預防措施,例如避免將敏感資料寫入非易失性儲存。
Secret 類似於 ConfigMaps,但專門用於存放機密資料。
注意
Kubernetes Secret 預設以未加密的形式儲存在 API 伺服器底層資料儲存 (etcd) 中。任何擁有 API 訪問許可權的人都可以檢索或修改 Secret,任何擁有 etcd 訪問許可權的人也可以。此外,任何被授權在某個名稱空間中建立 Pod 的人都可以利用該許可權讀取該名稱空間中的任何 Secret;這包括間接訪問,例如建立 Deployment 的能力。
為了安全地使用 Secret,請至少採取以下步驟:
- 為 Secret 啟用靜態加密。
- 啟用或配置 RBAC 規則,並對 Secret 採取最小許可權訪問。
- 將 Secret 訪問限制到特定的容器。
- 考慮使用外部 Secret 儲存提供程式。.
有關管理和改進 Secret 安全性的更多指南,請參閱 Kubernetes Secret 最佳實踐。
有關更多詳細資訊,請參閱 Secret 的資訊安全。
Secret 的用途
你可以將 Secret 用於以下目的:
Kubernetes 控制平面也使用 Secret;例如,引導令牌 Secret 是一種幫助自動化節點註冊的機制。
用例:Secret 卷中的點檔案
你可以透過定義以點開頭的鍵來“隱藏”你的資料。此鍵表示點檔案或“隱藏”檔案。例如,當以下 Secret 掛載到卷 `secret-volume` 時,該卷將包含一個名為 `.secret-file` 的檔案,並且 `dotfile-test-container` 將在該路徑 `/etc/secret-volume/.secret-file` 中擁有此檔案。
注意
以點字元開頭的檔案在 `ls -l` 的輸出中是隱藏的;在列出目錄內容時,你必須使用 `ls -la` 才能看到它們。apiVersion: v1
kind: Secret
metadata:
name: dotfile-secret
data:
.secret-file: dmFsdWUtMg0KDQo=
---
apiVersion: v1
kind: Pod
metadata:
name: secret-dotfiles-pod
spec:
volumes:
- name: secret-volume
secret:
secretName: dotfile-secret
containers:
- name: dotfile-test-container
image: registry.k8s.io/busybox
command:
- ls
- "-l"
- "/etc/secret-volume"
volumeMounts:
- name: secret-volume
readOnly: true
mountPath: "/etc/secret-volume"
用例:Pod 中一個容器可見的 Secret
考慮一個需要處理 HTTP 請求、執行一些複雜的業務邏輯,然後用 HMAC 簽名一些訊息的程式。由於它具有複雜的應用程式邏輯,伺服器中可能存在未被注意的遠端檔案讀取漏洞,這可能導致私鑰暴露給攻擊者。
這可以分為兩個容器中的兩個程序:一個前端容器,它處理使用者互動和業務邏輯,但無法看到私鑰;一個簽名器容器,它可以看到私鑰,並響應來自前端的簡單簽名請求(例如,透過 localhost 網路)。
透過這種分割槽方法,攻擊者現在必須誘騙應用程式伺服器執行一些任意操作,這可能比讓它讀取檔案更難。
Secret 的替代方案
除了使用 Secret 保護機密資料外,你還可以選擇其他替代方案。
以下是一些選項:
- 如果你的雲原生元件需要對你知道執行在同一個 Kubernetes 叢集中的另一個應用程式進行身份驗證,你可以使用 ServiceAccount 及其令牌來識別你的客戶端。
- 你可以執行第三方工具,無論是在叢集內部還是外部,來管理敏感資料。例如,一個 Pods 透過 HTTPS 訪問的服務,如果客戶端正確驗證(例如,使用 ServiceAccount 令牌),則會暴露 Secret。
- 對於身份驗證,你可以為 X.509 證書實現一個自定義簽名器,並使用 CertificateSigningRequests 允許該自定義簽名器向需要證書的 Pods 頒發證書。
- 你可以使用 裝置外掛 將節點本地加密硬體暴露給特定的 Pod。例如,你可以將受信任的 Pods 排程到提供 Trusted Platform Module 的節點上,並進行帶外配置。
你還可以結合使用這些選項中的兩個或更多個,包括使用 Secret 物件本身。
例如:實現(或部署)一個 operator,從外部服務獲取短期會話令牌,然後根據這些短期會話令牌建立 Secret。叢集中執行的 Pods 可以使用會話令牌,operator 確保它們是有效的。這種分離意味著你可以執行不知道頒發和重新整理這些會話令牌確切機制的 Pods。
Secret 的型別
建立 Secret 時,你可以使用 Secret 資源的 `type` 欄位,或某些等效的 `kubectl` 命令列標誌(如果可用)來指定其型別。Secret 型別用於方便對 Secret 資料進行程式設計處理。
Kubernetes 為一些常見的用法場景提供了幾個內建型別。這些型別在執行的驗證和 Kubernetes 對其施加的限制方面有所不同。
內建型別 | 用途 |
---|---|
Opaque | 任意使用者定義的資料 |
kubernetes.io/service-account-token | ServiceAccount 令牌 |
kubernetes.io/dockercfg | 序列化的 `~/.dockercfg` 檔案 |
kubernetes.io/dockerconfigjson | 序列化的 `~/.docker/config.json` 檔案 |
kubernetes.io/basic-auth | 基本認證的憑證 |
kubernetes.io/ssh-auth | SSH 認證的憑證 |
kubernetes.io/tls | TLS 客戶端或伺服器的資料 |
bootstrap.kubernetes.io/token | 引導令牌資料 |
你可以透過為 Secret 物件將 `type` 欄位設定為一個非空字串(空字串被視為 `Opaque` 型別)來定義和使用你自己的 Secret 型別。
Kubernetes 對型別名稱沒有任何限制。但是,如果你使用的是內建型別之一,則必須滿足該型別定義的所有要求。
如果你正在定義一種供公共使用的 Secret 型別,請遵循約定,將 Secret 型別結構為在名稱前加上你的域名,並用 `/` 分隔。例如:`cloud-hosting.example.net/cloud-api-credentials`。
不透明 Secret (Opaque Secrets)
如果你在 Secret 清單中沒有顯式指定型別,則 `Opaque` 是預設的 Secret 型別。當使用 `kubectl` 建立 Secret 時,你必須使用 `generic` 子命令來指示 `Opaque` Secret 型別。例如,以下命令建立一個空的 `Opaque` 型別的 Secret:
kubectl create secret generic empty-secret
kubectl get secret empty-secret
輸出如下:
NAME TYPE DATA AGE
empty-secret Opaque 0 2m6s
`DATA` 列顯示儲存在 Secret 中的資料項數量。在本例中,`0` 表示你建立了一個空的 Secret。
ServiceAccount 令牌 Secret
型別為 `kubernetes.io/service-account-token` 的 Secret 用於儲存識別 ServiceAccount 的令牌憑據。這是一種遺留機制,它為 Pods 提供長期有效的 ServiceAccount 憑據。
在 Kubernetes v1.22 及更高版本中,推薦的方法是使用 `TokenRequest` API 獲取短期、自動輪換的 ServiceAccount 令牌。你可以透過以下方法獲取這些短期令牌:
- 直接呼叫 `TokenRequest` API,或使用像 `kubectl` 這樣的 API 客戶端。例如,你可以使用 `kubectl create token` 命令。
- 在 Pod 清單中的投影卷中請求掛載令牌。Kubernetes 建立令牌並將其掛載到 Pod 中。當掛載該令牌的 Pod 被刪除時,令牌會自動失效。有關詳細資訊,請參閱使用 ServiceAccount 令牌投影啟動 Pod。
注意
只有當你無法使用 `TokenRequest` API 獲取令牌,並且在可讀的 API 物件中持久化永不過期的令牌憑據的安全暴露是可以接受的情況下,你才應該建立 ServiceAccount 令牌 Secret。有關說明,請參閱手動為 ServiceAccount 建立長期有效的 API 令牌。使用這種 Secret 型別時,你需要確保 `kubernetes.io/service-account.name` 註解被設定為一個現有的 ServiceAccount 名稱。如果你同時建立 ServiceAccount 和 Secret 物件,應該先建立 ServiceAccount 物件。
Secret 建立後,Kubernetes 控制器 會填寫其他一些欄位,例如 `kubernetes.io/service-account.uid` 註解,以及 `data` 欄位中的 `token` 鍵,其中填充了身份驗證令牌。
以下示例配置聲明瞭一個 ServiceAccount 令牌 Secret:
apiVersion: v1
kind: Secret
metadata:
name: secret-sa-sample
annotations:
kubernetes.io/service-account.name: "sa-name"
type: kubernetes.io/service-account-token
data:
extra: YmFyCg==
建立 Secret 後,等待 Kubernetes 填充 `data` 欄位中的 `token` 鍵。
有關 ServiceAccount 如何工作的更多資訊,請參閱 ServiceAccount 文件。你還可以檢視 `Pod` 的 `automountServiceAccountToken` 欄位和 `serviceAccountName` 欄位,以獲取從 Pod 內部引用 ServiceAccount 憑據的資訊。
Docker 配置 Secret
如果你要建立 Secret 以儲存用於訪問容器映象登錄檔的憑據,則該 Secret 必須使用以下 `type` 值之一:
- `kubernetes.io/dockercfg`:儲存序列化的 `~/.dockercfg`,這是配置 Docker 命令列的舊格式。Secret 的 `data` 欄位包含一個 `.dockercfg` 鍵,其值是經過 base64 編碼的 `~/.dockercfg` 檔案的內容。
- `kubernetes.io/dockerconfigjson`:儲存序列化的 JSON,它遵循與 `~/.docker/config.json` 檔案相同的格式規則,`~/.docker/config.json` 是 `~/.dockercfg` 的新格式。Secret 的 `data` 欄位必須包含一個 `.dockerconfigjson` 鍵,其值是經過 base64 編碼的 `~/.docker/config.json` 檔案的內容。
下面是 `kubernetes.io/dockercfg` 型別 Secret 的示例:
apiVersion: v1
kind: Secret
metadata:
name: secret-dockercfg
type: kubernetes.io/dockercfg
data:
.dockercfg: |
eyJhdXRocyI6eyJodHRwczovL2V4YW1wbGUvdjEvIjp7ImF1dGgiOiJvcGVuc2VzYW1lIn19fQo=
注意
如果你不想執行 base64 編碼,可以選擇改用 `stringData` 欄位。當你使用清單建立 Docker 配置 Secret 時,API 伺服器會檢查 `data` 欄位中是否存在預期鍵,並驗證所提供的值是否可以解析為有效的 JSON。API 伺服器不驗證 JSON 是否真的是 Docker 配置檔案。
你也可以使用 `kubectl` 建立 Secret 來訪問容器登錄檔,例如當你沒有 Docker 配置檔案時:
kubectl create secret docker-registry secret-tiger-docker \
--docker-email=tiger@acme.example \
--docker-username=tiger \
--docker-password=pass1234 \
--docker-server=my-registry.example:5000
此命令建立一個 `kubernetes.io/dockerconfigjson` 型別的 Secret。
從該新 Secret 中檢索 `.data.dockerconfigjson` 欄位並解碼資料:
kubectl get secret secret-tiger-docker -o jsonpath='{.data.*}' | base64 -d
輸出等同於以下 JSON 文件(這也是一個有效的 Docker 配置檔案):
{
"auths": {
"my-registry.example:5000": {
"username": "tiger",
"password": "pass1234",
"email": "tiger@acme.example",
"auth": "dGlnZXI6cGFzczEyMzQ="
}
}
}
注意
這裡的 `auth` 值是經過 base64 編碼的;它被遮蔽但並非秘密。任何可以讀取該 Secret 的人都可以知道登錄檔訪問的持有者令牌。
建議使用憑據提供者按需動態安全地提供拉取 Secret。
基本認證 Secret
`kubernetes.io/basic-auth` 型別用於儲存基本認證所需的憑據。使用此 Secret 型別時,Secret 的 `data` 欄位必須包含以下兩個鍵之一:
- `username`:用於認證的使用者名稱
- `password`:用於認證的密碼或令牌
上述兩個鍵的值都是經過 base64 編碼的字串。你也可以選擇使用 Secret 清單中的 `stringData` 欄位提供明文內容。
以下清單是基本認證 Secret 的示例:
apiVersion: v1
kind: Secret
metadata:
name: secret-basic-auth
type: kubernetes.io/basic-auth
stringData:
username: admin # required field for kubernetes.io/basic-auth
password: t0p-Secret # required field for kubernetes.io/basic-auth
注意
Secret 的 `stringData` 欄位與伺服器端應用不相容。基本認證 Secret 型別僅為方便起見而提供。你可以為基本認證使用的憑據建立 `Opaque` 型別。但是,使用已定義的公共 Secret 型別 (`kubernetes.io/basic-auth`) 有助於其他人理解你的 Secret 的目的,併為預期鍵名設定約定。
SSH 認證 Secret
內建型別 `kubernetes.io/ssh-auth` 用於儲存 SSH 認證中使用的資料。使用此 Secret 型別時,你需要在 `data`(或 `stringData`)欄位中指定 `ssh-privatekey` 鍵值對作為要使用的 SSH 憑據。
以下清單是用於 SSH 公鑰/私鑰認證的 Secret 示例:
apiVersion: v1
kind: Secret
metadata:
name: secret-ssh-auth
type: kubernetes.io/ssh-auth
data:
# the data is abbreviated in this example
ssh-privatekey: |
UG91cmluZzYlRW1vdGljb24lU2N1YmE=
SSH 認證 Secret 型別僅為方便起見而提供。你可以為用於 SSH 認證的憑據建立 `Opaque` 型別。但是,使用已定義和公共的 Secret 型別 (`kubernetes.io/ssh-auth`) 有助於其他人理解你的 Secret 的目的,併為預期鍵名設定約定。Kubernetes API 會驗證此型別的 Secret 是否設定了必需的鍵。
注意
SSH 私鑰本身無法在 SSH 客戶端和主機伺服器之間建立受信任的通訊。需要第二種建立信任的方法來緩解“中間人”攻擊,例如新增到 ConfigMap 中的 `known_hosts` 檔案。TLS Secret
`kubernetes.io/tls` Secret 型別用於儲存證書及其相關金鑰,通常用於 TLS。
TLS Secret 的一個常見用途是為 Ingress 配置傳輸中的加密,但你也可以將其與其他資源或直接在工作負載中使用。使用此型別的 Secret 時,必須在 Secret 配置的 `data`(或 `stringData`)欄位中提供 `tls.key` 和 `tls.crt` 鍵,儘管 API 伺服器實際上不驗證每個鍵的值。
作為使用 `stringData` 的替代方案,你可以使用 `data` 欄位提供 base64 編碼的證書和私鑰。有關詳細資訊,請參閱 Secret 名稱和資料限制。
以下 YAML 包含 TLS Secret 的示例配置:
apiVersion: v1
kind: Secret
metadata:
name: secret-tls
type: kubernetes.io/tls
data:
# values are base64 encoded, which obscures them but does NOT provide
# any useful level of confidentiality
# Replace the following values with your own base64-encoded certificate and key.
tls.crt: "REPLACE_WITH_BASE64_CERT"
tls.key: "REPLACE_WITH_BASE64_KEY"
TLS Secret 型別僅為方便起見而提供。你可以為用於 TLS 認證的憑據建立 `Opaque` 型別。但是,使用已定義和公共的 Secret 型別 (`kubernetes.io/tls`) 有助於確保專案中 Secret 格式的一致性。API 伺服器會驗證此型別的 Secret 是否設定了必需的鍵。
要使用 `kubectl` 建立 TLS Secret,請使用 `tls` 子命令:
kubectl create secret tls my-tls-secret \
--cert=path/to/cert/file \
--key=path/to/key/file
公鑰/私鑰對必須事先存在。`--cert` 的公鑰證書必須是 .PEM 編碼的,並且必須與 `--key` 給定的私鑰匹配。
引導令牌 Secret
`bootstrap.kubernetes.io/token` Secret 型別用於節點引導過程中使用的令牌。它儲存用於簽名眾所周知的 ConfigMaps 的令牌。
引導令牌 Secret 通常在 `kube-system` 名稱空間中建立,並以 `bootstrap-token-
作為 Kubernetes 清單,引導令牌 Secret 可能如下所示:
apiVersion: v1
kind: Secret
metadata:
name: bootstrap-token-5emitj
namespace: kube-system
type: bootstrap.kubernetes.io/token
data:
auth-extra-groups: c3lzdGVtOmJvb3RzdHJhcHBlcnM6a3ViZWFkbTpkZWZhdWx0LW5vZGUtdG9rZW4=
expiration: MjAyMC0wOS0xM1QwNDozOToxMFo=
token-id: NWVtaXRq
token-secret: a3E0Z2lodnN6emduMXAwcg==
usage-bootstrap-authentication: dHJ1ZQ==
usage-bootstrap-signing: dHJ1ZQ==
引導令牌 Secret 在 `data` 下指定了以下鍵:
- `token-id`:作為令牌識別符號的隨機 6 個字元的字串。必需。
- `token-secret`:作為實際令牌 Secret 的隨機 16 個字元的字串。必需。
- `description`:描述令牌用途的人類可讀字串。可選。
- `expiration`:使用 RFC3339 指定令牌何時過期的絕對 UTC 時間。可選。
- `usage-bootstrap-
`:一個布林標誌,指示引導令牌的其他用途。 - `auth-extra-groups`:一個逗號分隔的組名列表,除 `system:bootstrappers` 組外,還將作為這些組進行身份驗證。
你也可以在 Secret 的 `stringData` 欄位中提供這些值,而無需對其進行 base64 編碼:
apiVersion: v1
kind: Secret
metadata:
# Note how the Secret is named
name: bootstrap-token-5emitj
# A bootstrap token Secret usually resides in the kube-system namespace
namespace: kube-system
type: bootstrap.kubernetes.io/token
stringData:
auth-extra-groups: "system:bootstrappers:kubeadm:default-node-token"
expiration: "2020-09-13T04:39:10Z"
# This token ID is used in the name
token-id: "5emitj"
token-secret: "kq4gihvszzgn1p0r"
# This token can be used for authentication
usage-bootstrap-authentication: "true"
# and it can be used for signing
usage-bootstrap-signing: "true"
注意
Secret 的 `stringData` 欄位與伺服器端應用不相容。使用 Secret
建立 Secret
有幾種建立 Secret 的選項:
Secret 名稱和資料限制
Secret 物件的名稱必須是有效的 DNS 子域名。
在為 Secret 建立配置檔案時,你可以指定 `data` 和/或 `stringData` 欄位。`data` 和 `stringData` 欄位是可選的。`data` 欄位中所有鍵的值都必須是 base64 編碼的字串。如果不需要轉換為 base64 字串,你可以選擇指定 `stringData` 欄位,它接受任意字串作為值。
`data` 和 `stringData` 的鍵必須由字母數字字元、`-`、`_` 或 `.` 組成。`stringData` 欄位中的所有鍵值對都會在內部合併到 `data` 欄位中。如果一個鍵同時出現在 `data` 和 `stringData` 欄位中,則 `stringData` 欄位中指定的值優先。
大小限制
單個 Secret 的大小限制為 1MiB。這是為了阻止建立可能耗盡 API 伺服器和 kubelet 記憶體的超大 Secret。然而,建立許多較小的 Secret 也可能耗盡記憶體。你可以使用資源配額來限制名稱空間中 Secret(或其他資源)的數量。
編輯 Secret
你可以編輯現有的 Secret,除非它是不可變的。要編輯 Secret,請使用以下方法之一:
你也可以使用 Kustomize 工具編輯 Secret 中的資料。但是,此方法會建立一個帶有編輯資料的新 `Secret` 物件。
根據你建立 Secret 的方式以及 Secret 在 Pod 中使用的方式,對現有 `Secret` 物件的更新會自動傳播到使用這些資料的 Pod。有關更多資訊,請參閱從 Pod 以檔案形式使用 Secret 部分。
使用 Secret
Secret 可以作為資料卷掛載或作為環境變數暴露,供 Pod 中的容器使用。Secret 也可以被系統的其他部分使用,而無需直接暴露給 Pod。例如,Secret 可以儲存系統其他部分代表你與外部系統互動時應使用的憑據。
Secret 卷源經過驗證,以確保指定的物件引用確實指向 Secret 型別的物件。因此,Secret 需要在任何依賴它的 Pod 之前建立。
如果 Secret 無法獲取(可能是因為它不存在,或者由於暫時無法連線到 API 伺服器),kubelet 會定期重試執行該 Pod。kubelet 還會為該 Pod 報告一個事件,包括獲取 Secret 問題的詳細資訊。
可選的 Secret
當你在 Pod 中引用 Secret 時,你可以將 Secret 標記為 *可選*,如下例所示。如果可選 Secret 不存在,Kubernetes 將忽略它。
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret
optional: true
預設情況下,Secret 是必需的。除非所有非可選 Secret 都可用,否則 Pod 的容器都不會啟動。
如果 Pod 引用了非可選 Secret 中的特定鍵,並且該 Secret 確實存在,但缺少指定的鍵,則 Pod 在啟動期間會失敗。
從 Pod 中以檔案形式使用 Secret
如果你想在 Pod 中訪問 Secret 中的資料,一種方法是讓 Kubernetes 將 Secret 的值作為檔案提供給一個或多個 Pod 容器的檔案系統。
有關說明,請參閱建立透過 Volume 訪問 Secret 資料的 Pod。
當捲包含來自 Secret 的資料,並且該 Secret 被更新時,Kubernetes 會跟蹤此情況並使用最終一致性方法更新卷中的資料。
注意
使用 Secret 作為 subPath 卷掛載的容器不會收到 Secret 的自動更新。kubelet 會快取該節點上 Pod 卷中使用的 Secret 的當前鍵和值。你可以配置 kubelet 檢測快取值變化的方式。kubelet 配置中的 `configMapAndSecretChangeDetectionStrategy` 欄位控制 kubelet 使用的策略。預設策略是 `Watch`。
Secret 的更新可以透過 API watch 機制(預設)、基於具有定義生命週期的快取,或者在每個 kubelet 同步迴圈中從叢集 API 伺服器輪詢來傳播。
因此,從 Secret 更新到新鍵投影到 Pod 的總延遲可能與 kubelet 同步週期 + 快取傳播延遲一樣長,其中快取傳播延遲取決於所選的快取型別(按照上一段中列出的相同順序,它們是:watch 傳播延遲、配置的快取 TTL,或直接輪詢的零)。
使用 Secret 作為環境變數
要在 Pod 的環境變數中使用 Secret,請執行以下操作:
- 對於你的 Pod 規約中的每個容器,為你想要使用的每個 Secret 鍵新增一個環境變數到 `env[].valueFrom.secretKeyRef` 欄位。
- 修改你的映象和/或命令列,以便程式在指定的環境變數中查詢值。
有關說明,請參閱使用 Secret 資料定義容器環境變數。
值得注意的是,Pod 中環境變數名稱允許的字元範圍是受限的。如果任何鍵不符合規則,這些鍵將無法供你的容器使用,儘管 Pod 仍允許啟動。
容器映象拉取 Secret
如果你想從私有倉庫獲取容器映象,你需要一種方法讓每個節點上的 kubelet 向該倉庫進行身份驗證。你可以配置*映象拉取 Secret* 來實現這一點。這些 Secret 在 Pod 級別配置。
使用 imagePullSecrets
`imagePullSecrets` 欄位是同一名稱空間中 Secret 的引用列表。你可以使用 `imagePullSecrets` 將包含 Docker(或其他)映象登錄檔密碼的 Secret 傳遞給 kubelet。kubelet 使用此資訊代表你的 Pod 拉取私有映象。有關 `imagePullSecrets` 欄位的更多資訊,請參閱 PodSpec API。
手動指定 imagePullSecret
你可以從容器映象文件中瞭解如何指定 `imagePullSecrets`。
自動附加 imagePullSecrets
你可以手動建立 `imagePullSecrets`,並從 ServiceAccount 中引用它們。使用該 ServiceAccount 或預設使用該 ServiceAccount 建立的任何 Pods,其 `imagePullSecrets` 欄位都將設定為與該 ServiceAccount 相同。有關該過程的詳細說明,請參閱向 ServiceAccount 新增 ImagePullSecrets。
將 Secret 與靜態 Pod 一起使用
你不能將 ConfigMap 或 Secret 與靜態 Pod 一起使用。
不可變 Secret
Kubernetes v1.21 [stable]
Kubernetes 允許你將特定的 Secret(和 ConfigMaps)標記為 *不可變*。防止更改現有 Secret 的資料具有以下優點:
- 保護你免受可能導致應用程式中斷的意外(或不必要)更新。
- (對於大量使用 Secret 的叢集 - 至少數萬個唯一的 Secret 到 Pod 掛載),切換到不可變 Secret 可以顯著減少 kube-apiserver 上的負載,從而提高叢集效能。kubelet 無需對任何標記為不可變的 Secret 維護 [watch]。
將 Secret 標記為不可變
你可以透過將 `immutable` 欄位設定為 `true` 來建立不可變的 Secret。例如:
apiVersion: v1
kind: Secret
metadata: ...
data: ...
immutable: true
你還可以更新任何現有的可變 Secret 以使其不可變。
注意
一旦 Secret 或 ConfigMap 被標記為不可變,就 *無法* 撤銷此更改,也無法修改 `data` 欄位的內容。你只能刪除並重新建立 Secret。現有的 Pod 會保留對已刪除 Secret 的掛載點 - 建議重新建立這些 Pod。Secret 的資訊安全
儘管 ConfigMap 和 Secret 的工作方式相似,Kubernetes 對 Secret 物件應用了一些額外的保護。
Secret 通常包含各種重要程度的值,其中許多可能導致 Kubernetes 內部(例如服務帳戶令牌)和外部系統許可權升級。即使單個應用程式能夠推斷其預期互動的 Secret 的許可權,同一名稱空間中的其他應用程式也可能使這些假設失效。
Secret 僅在節點上的 Pod 需要時才傳送到該節點。為了將 Secret 掛載到 Pod 中,kubelet 將資料副本儲存到 `tmpfs` 中,以便機密資料不會寫入持久儲存。一旦依賴 Secret 的 Pod 被刪除,kubelet 就會從 Secret 中刪除其本地的機密資料副本。
一個 Pod 中可能包含多個容器。預設情況下,你定義的容器只能訪問預設的 ServiceAccount 及其相關的 Secret。你必須顯式定義環境變數或將卷對映到容器中,才能提供對任何其他 Secret 的訪問。
同一節點上可能有多個 Pod 的 Secret。但是,只有 Pod 請求的 Secret 才可能在其容器內可見。因此,一個 Pod 無法訪問另一個 Pod 的 Secret。
配置 Secret 的最小特權訪問
為了增強圍繞 Secret 的安全措施,請使用單獨的名稱空間來隔離對掛載 Secret 的訪問。
警告
任何在節點上以 `privileged: true` 執行的容器都可以訪問該節點上使用的所有 Secret。下一步
- 有關管理和改進 Secret 安全性的指南,請參閱 Kubernetes Secret 最佳實踐。
- 瞭解如何使用 `kubectl` 管理 Secret
- 瞭解如何使用配置檔案管理 Secret
- 瞭解如何使用 Kustomize 管理 Secret
- 閱讀 `Secret` 的 API 參考