Volume - Secret
什麼是 Secret?
在 Kubernetes 中,Secret 是一種資源物件,用於安全地存儲敏感數據,例如密碼、OAuth token、SSH key 等。與 ConfigMap 類似,Secret 能夠以鍵值對的形式存儲數據,但它的數據會被加密或編碼以提高安全性。
Secret 的主要特點包括:
- 敏感數據存儲:避免將敏感數據直接存放在 Pod 規範中。
- 靈活使用:可作為環境變量、Volume 或文件的形式掛載到 Pod 中。
- 安全性:通過 Base64 編碼存儲,並可以與 Kubernetes 中的 RBAC 一起使用來保護數據。
Secret 的類型
Kubernetes 提供了多種類型的 Secret,可以根據需求選擇合適的類型:
| Secret 類型 | 描述 |
|---|---|
| Opaque | 默認類型,用於存儲任意鍵值對數據。 |
| kubernetes.io/service-account-token | 用於存儲服務帳號的 token,自動創建並分配給 Pod。 |
| kubernetes.io/dockercfg | 用於存儲 Docker 鏡像拉取的 ~/.dockercfg 文件。 |
| kubernetes.io/dockerconfigjson | 用於存儲 Docker 鏡像拉取的 JSON 格式認證信息。 |
| kubernetes.io/tls | 用於存儲 TLS 私鑰和證書(PEM 格式)。 |
| bootstrap.kubernetes.io/token | 用於集群引導過程中的 token。 |
Secret 的生命週期
- 創建 Secret: Secret 可以通過 YAML 文件、Kubernetes CLI 或程序化的方式創建。
- 掛載到 Pod: Secret 可作為環境變量或 Volume 掛載到 Pod 中,供容器使用。
- 更新 Secret: Secret 可以被更新,更新後相關 Pod 將獲取新的數據。
- 刪除 Secret: 如果 Secret 被刪除,相關的 Pod 將無法訪問這些敏感數據。
Secret 的使用方式
1. 作為環境變量
Secret 可以作為 Pod 的環境變量,容器內應用程序可直接通過環境變量訪問。
2. 掛載為 Volume
Secret 可作為文件掛載到 Pod 的文件系統,應用程序可以從指定路徑讀取。
3. 使用於容器映像憑據
Secret 可以用來存儲 Docker 鏡像的認證信息,以便 Kubernetes 拉取私有鏡像。
注意事項
- Base64 編碼: Secret 資料是以 Base64 編碼的形式存儲,但這不是加密,因此不要將其視為完全安全的保護機制。
- 安全性:
- 使用 Kubernetes 的 RBAC 設定適當的存取權限。
- 確保 Kubernetes 集群的 etcd 數據存儲是加密的。
- 更新影響: Secret 更新後,會立即影響掛載該 Secret 的 Pod。
Secret 的創立
使用指令建立
- 直接使用指令建立 Secret
kubectl.exe create secret generic test-secret --from-literal='username=my-account' --from-literal='password=my-password'
---
secret/test-secret created
- 查看 Secret,我們會發現 data 只顯示大小,不顯示內容。
kubectl.exe describe secrets test-secret
---
Name: test-secret
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password: 11 bytes
username: 10 bytes
使用 yaml 建立
在建立 Secret 的值時,我們必需先使用 base64 編碼,而 kubernetes 在我們正確掛載後會自動幫我們解碼回原本的值。
- 首先假設我們有 my-account 和 my-password 這兩個字串要當成我們的 username 和 password,首先我們需要對他做 base64 加密。
Linux
echo -n "my-account" | base64
echo -n "my-password" | base64
---
bXktYWNjb3VudA==
bXktcGFzc3dvcmQ=
Windows
[Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("my-account"))
[Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("my-password"))
---
bXktYWNjb3VudA==
bXktcGFzc3dvcmQ=
- 建立一個 test-secret.yaml,裡面的 kind 設定為 Secret,並且在 data 儲存 key-value,並且 value 必須要是 base64 後的數值。
test-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: test-secret
data:
username: bXktYWNjb3VudA==
password: bXktcGFzc3dvcmQ=
- 透過 kubectl 來執行他。
kubectl.exe apply -f test-secret.yaml
---
secret/test-secret created
- 並且查看一下結果,我們可以發現他只會顯示加密過後的大小,不會顯示內容。
kubectl.exe describe secrets test-secret
---
Name: test-secret
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password: 11 bytes
username: 10 bytes
實作 Secret
使用 Secret 作為環境變量
- 在上面建立 test-secret 之後,我們撰寫一個 pod 來使用這些 secret,我們可以使用 secretKeyRef,指定 Secret 名稱和 Key,就會自動映射到對應的環境變數。
secret-test-pod-key-value.yaml
apiVersion: v1
kind: Pod
metadata:
name: secret-test-pod
spec:
containers:
- name: test-container
image: nginx
env:
- name: USERNAME
valueFrom:
secretKeyRef: # 從 Secret 中引用值來設定環境變數
name: test-secret # Secret 的名稱為 test-secret
key: username # 取 Secret 中的 key 為 username 的值
- name: PASSWORD
valueFrom:
secretKeyRef:
name: test-secret # Secret 的名稱為 test-secret
key: password # 取 Secret 中的 key 為 password 的值
- 透過指令來運行這個 Pod
kubectl.exe apply -f .\secret-test-pod-key-value.yaml
---
pod/secret-test-pod created
- 我們可以連進去 Pod 查看是否成功注入
kubectl.exe exec -it pods/secret-test-pod -- bash
---
root@secret-test-pod:/#