Kubernetes Secrets 是管理敏感資訊的核心機制,用於儲存密碼、API 金鑰、憑證等,避免直接暴露在設定檔中。Secrets 的型別包括 Opaque、Service Account Token、Docker Config 和 Basic Authentication,各有不同的應用場景。Opaque Secrets 適用於儲存任意格式的敏感資料,可透過指令或檔案建立。Service Account Token 則用於 Pod 與 Kubernetes API 的互動驗證,早期版本為長期有效,現在則需手動建立。將 Service Account Token 掛載到 Pod 的檔案系統,讓 Pod 能夠直接使用 Token 進行驗證。Docker Config 則允許從私有或其他容器 registry 提取映像檔,需要將 Docker 設定檔轉換為 Base64 編碼後儲存為 Secret。Basic Authentication 則提供基本的使用者名稱和密碼驗證機制,適用於需要簡易驗證的服務。理解不同 Secret 型別的特性和使用方法,才能有效保護 Kubernetes 環境中的敏感資訊。
Kubernetes Secrets 管理概念探討
Kubernetes 中的 Secret 是用來管理和儲存敏感資訊,如密碼、API 金鑰、識別證書等。這些資訊通常需要在不同的 Pod 之間分享,但又不能直接暴露在 YAML 檔案中。Kubernetes 提供了多種方式來管理 Secret,以下是一些常見的 Secret 型別及其應用場景。
Opaque Secrets
Opaque Secrets 是最常見的 Secret 型別,可以儲存任何形式的敏感資料。它們可以透過多種方式建立,例如直接從文字建立、從檔案中讀取等。
以下是使用文字建立 Opaque Secret 的範例:
$ kubectl create secret generic opaque-example-from-literals --from-literal=literal1=text-for-literal-1
這個命令會建立一個名為 opaque-example-from-literals 的 Secret,並將 text-for-literal-1 作為 literal1 的值儲存。
也可以從檔案中建立 Opaque Secret:
$ kubectl create secret generic secretfile --from-file=secret-file.txt=./secret.file.txt
這個命令會將 ./secret.file.txt 的內容作為 secret-file.txt 的值儲存在 Secret 中。
內容解密:
這段程式碼展示瞭如何使用 kubectl 命令建立 Opaque Secrets。第一個命令使用 --from-literal 選項直接從文字建立 Secret,而第二個命令則使用 --from-file 選項從檔案中讀取內容建立 Secret。這樣可以方便地管理和儲存不同形式的敏感資料。
Kubernetes Service Account Token
在 Kubernetes 中,Pod 需要與 Kubernetes API 互動時,必須具有身份識別。Service Account 是這樣一種身份識別,可以直接或間接地繫結到 Pod 上。當 Pod 組態了 Service Account 後,會在啟動時附上一個 Service Account Token。
長期存活的 Access Token
在 Kubernetes v1.27 之前,Service Account Token 是作為一個由 Kubernetes 管理的長期存活的秘密存在。雖然在最新版本中這種方式已經不再是預設行為,但仍然可以手動建立長期存活的 Access Token。
以下是如何建立長期存活的 Access Token 的範例:
apiVersion: v1
kind: Secret
metadata:
name: service-account-secret
annotations:
kubernetes.io/service-account.name: example-service-account
type: kubernetes.io/service-account-token
這段 YAML 檔案會建立一個名為 service-account-secret 的 Secret,並將其與 example-service-account Service Account 關聯。
$ kubectl create sa example-service-account
$ kubectl apply -f service-account-secret.yaml
執行這些命令後,Kubernetes 會生成一個 Token,並將其儲存在 service-account-secret 中。
內容解密:
這段程式碼展示瞭如何手動建立長期存活的 Access Token。首先透過 kubectl create sa 命令建立一個 Service Account,然後使用 YAML 檔案應用組態來生成並關聯一個長期存活的 Access Token。
Service Account Token Mounted on Pod
當 Pod 組態了 Service Account 時,Service Account Token 會被掛載到 Pod 的檔案系統中。以下是如何將 Service Account Token 掛載到 Pod 上的範例:
apiVersion: v1
kind: ServiceAccount
metadata:
name: example-service-account
---
apiVersion: v1
kind: Pod
spec:
serviceAccountName: example-service-account
這段 YAML 檔案會建立一個名為 example-service-account 的 Service Account,並將其掛載到一個 Pod 上。
執行以下命令可以檢視掛載到 Pod 上的 Service Account Token:
$ kubectl exec -it busybox -- cat /var/run/secrets/kubernetes.io/serviceaccount/token
內容解密:
這段程式碼展示瞭如何將 Service Account Token 掛載到 Pod 上。首先透過 YAML 檔案建立一個 Service Account,然後將其掛載到 Pod 上。最後使用 kubectl exec 命令檢視掛載到 Pod 上的 Token。
Docker Config
當我們需要從替代容器登入檔提取影像時,可以透過掛載 Docker 組態來實作。以下是如何使用本地 Docker 組態來掛載 Kubernetes Secret 的範例:
apiVersion: v1
kind: Secret
metadata:
name: registry-docker-config
type: kubernetes.io/dockercfg
data:
.dockercfg: |
REPLACE_WITH_BASE64
這段 YAML 檔案會建立一個名為 registry-docker-config 的 Secret,並將 Docker 組態掛載到其中。
首先使用以下命令登入 Docker Hub:
$ docker --config ./ login --username=dockerhub-username --password=dockerhub-password
然後將組態檔案轉換為 Base64 編碼格式:
$ DOCKER_CONFIG=$(cat ./config.json|base64)
$ cat docker-credentials-template.yaml|sed "s/REPLACE_WITH_BASE64/$DOCKER_CONFIG/" > docker-credentials.yaml
最後應用組態檔案來上傳憑證:
$ kubectl apply -f docker-credentials.yaml
內容解密:
這段程式碼展示瞭如何將 Docker 組態掛載到 Kubernetes Secret 中。首先透過 docker login 命令登入 Docker Hub,然後將組態檔案轉換為 Base64 編碼格式並應用組態檔案來上傳憑證。最後透過 kubectl apply 命令應用組態檔案來上傳憑證。
Basic Authentication
基本認證由使用者名稱和密碼組成的金鑰和秘密組合構成。以下是如何建立基本認證秘密的範例:
apiVersion: v1
kind: Secret
metadata:
name: basic-auth-secret
type: kubernetes.io/basic-auth
stringData:
username: a-user
password: a-password
內容解密:
這段程式碼展示瞭如何使用基本認證秘密。YAML 檔案中包含了 username 和 password 的值,並指定了 secret 的型別為 basic-auth。
說明:
此圖示說明瞭不同型別的 Kubernetes Secrets 與其應用場景。 包括 Pod 與 Service Account 的關係、Docker Config 用於提取影像以及 Basic Auth 用於應用認證等。
## Kubernetes Secret 資源管理
在 Kubernetes 中,Secrets 是用來儲存敏感資訊的重要資源,例如密碼、SSL/TLS 金鑰以及 API 令牌等。透過 Secrets,可以避免將這些敏感資訊直接寫入組態檔案或程式碼中,從而提高系統的安全性。接下來,玄貓將詳細探討 Kubernetes Secrets 的各種管理概念及操作方式。
### Kubernetes Secrets 的基本概念
Kubernetes Secrets 主要有以下幾種型別:
- **Opaque**:這是最常見的 Secret 型別,用於儲存任意形式的資料。
- **kubernetes.io/service-account-token**:這類別 Secret 用於服務帳戶的 API 存取令牌。
- **kubernetes.io/dockercfg**:這類別 Secret 用於 Docker 的認證資訊。
- **kubernetes.io/tls**:這類別 Secret 用於儲存 TLS 認證書和金鑰。
每種 Secret 都有其特定的用途和格式。以 TLS Secret 為例,它通常用於儲存 SSL/TLS 認證書和金鑰,並且可以直接應用於 Ingress 資源中。
### 使用 TLS Secrets 加密 Ingress
TLS Secrets 主要用於儲存 SSL/TLS 認證書和金鑰,使得 Ingress 資源能夠處理 HTTPS 流量。以下是建立一個 TLS Secret 的範例:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: ingress-tls
type: kubernetes.io/tls
data:
tls.crt: <base64-encoded-cert>
tls.key: <base64-encoded-key>
這裡的 tls.crt 和 tls.key 分別是經過 base64 編碼的 SSL/TLS 認證書和金鑰。建立好 TLS Secret 後,可以在 Ingress 資源中使用它來加密流量:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
spec:
tls:
- secretName: ingress-tls
hosts:
- webpage.your.hostname
rules:
- host: webpage.your.hostname
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: example-service
port:
number: 80
內容解密:
以上程式碼片段中,我們建立了一個名為 ingress-tls 的 TLS Secret,並將其應用於一個名為 example-ingress 的 Ingress 資源中。這樣,當 HTTP 流量進入 Ingress 構件時,將會被自動轉換為 HTTPS 流量。
在實際操作中,我們可以使用一個 shell 指令碼來生成 SSL/TLS 認證書和金鑰,並自動建立對應的 TLS Secret。例如:
#!/bin/bash
# 生成 SSL/TLS 認證書和金鑰
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout tls.key -out tls.crt -subj "/CN=webpage.your.hostname"
# 建立 Kubernetes TLS Secret
kubectl create secret tls ingress-tls --cert=tls.crt --key=tls.key
這段指令碼會生成一個有效期為一年的 SSL/TLS 認證書和金鑰,並將其轉換為 Kubernetes TLS Secret。
minikube 中測試 Ingress
如果你使用 minikube 作為本地開發環境,可以按照以下步驟啟用 Ingress 構件並進行測試:
- 啟用 minikube 的 Ingress 構件:
$ minikube addons enable ingress
- 檢查 Ingress 資源的狀態:
$ kubectl get ing
- 啟動 minikube tunnel 將流量轉發到 Ingress 構件:
$ minikube tunnel
這樣,你就可以透過 https://localhost/ 測試你的 HTTPS 流量。
Token Secrets
除了 TLS Secrets 外,Kubernetes 還支援 Token Secrets。這類別 Secret 主要用於 Kubernetes 叢集的啟動過程中,提供一種安全的方式來允許新節點加入叢集。Token Secrets 的格式如下:
apiVersion: v1
kind: Secret
metadata:
name: bootstrap-token-secret
type: bootstrap.kubernetes.io/token
stringData:
token-id: "abcdef"
token-secret: "xxxxxx"
內容解密:
以上程式碼片段中,我們建立了一個名為 bootstrap-token-secret 的 Token Secret。這個 Secret 包含了 token-id 和 token-secret 兩個欄位,分別表示令牌 ID 和令牌秘密。當我們初始化一個 Kubernetes 叢集時,這些令牌將會被使用來允許新節點加入叢集。
其他操作:更新與刪除 Secrets
除了建立之外,我們還需要了解如何更新和刪除 Kubernetes Secrets。以下是一些常見操作:
編輯 Secrets
編輯一個現有的 Secret 可以透過 kubectl 的 edit 命令來完成:
$ kubectl edit secret plain-text --record=true
此命令會開啟預設編輯器(如 Vim),讓你可以修改 Secret 的內容。修改後儲存離開即可完成更新操作。
基本命令記錄
在編輯秘密時,如果你想記錄編輯操作命令(例如版本控制),可以新增 --record=true 引數:
$ kubectl edit secret plain-text --record=true
$ kubectl get secret plain-text -o yaml | grep 'change-cause'