昨天介紹了 ConfigMap,因 ConfigMap 使用明文來儲存數據的特性,故不適合儲存資敏資訊,在 Kubernetes 中應該使用今天介紹的 Secret 來儲存。
簡單來說,Secret 的建立方式與使用方式非常相似,一樣提供以下方式讓 Pod 使用
kubectl
提供使用以下方式建立 Secret
kubectl create secret generic my-secret --from-file=secret-file.yaml
kubectl create secret generic my-secret --from-literal=username=myusername --from-literal=password=mypassword
kubectl apply -f my-secret.yaml
讓我們透過 kubectl
建立一個 demo-secret.yaml,並介紹其中的屬性
# create secret
kubectl create secret generic demo-secret --dry-run=client -o yaml --from-literal=APP.TOKEN="dummy token from secret" > demo-secret.yaml
參數中的
generic
代表通用類型,代表儲存的資料使用 key-value pair 儲存,也有 docker-registry, tls.. 等類型能提供訪問 dockerHub 或儲存 TLS 憑證, 更多類型請參考官方文檔
demo-secret.yaml 內容
apiVersion: v1
data:
APP.TOKEN: ZHVtbXkgdG9rZW4gZnJvbSBzZWNyZXQ=
kind: Secret
metadata:
creationTimestamp: null
name: demo-secret
Secret 的 yaml 格式也非常簡單,能看到資料存放於 data
欄位,並已 key-value 的方式定義,差別在 Value 的值是使用 Base64 編碼後的值,而非明文,依此例存放了一個變數
key | value | decode value |
---|---|---|
APP.TOKEN | ZHVtbXkgdG9rZW4= | dummy token |
注意! 經過 Base64 編碼的資料,能輕易被還原成原始值,需搭配後續 如何保護 Secret 章節才能保護了機敏資料
我們透過該 yaml 建立 Secret 資源,方便後面實作進行測試
# apply yaml
kubectl apply -f demo-secret.yaml
# 查詢建立的 Secret
kubectl get secret demo-secret
與 ConfigMap 的實作相同,我們使用一個簡單的 範例應用程序,這個應用程序提供一個 API
APP.TOKEN
之值,若該變數不存在時,返回 local token.
我們調整一下昨天建立的 deployment,將 secret 當作環境變數
搭配上面建立的 configMap 來建立一個 deployment,並使用該 configMap 當作配置檔
# 建立 deployment
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-deployment
spec:
replicas: 1
selector:
matchLabels:
app: demo-deployment
template:
metadata:
labels:
app: demo-deployment
spec:
containers:
- name: app
image: yihonggaotw/demo-image:v3
envFrom: # 將 ConfigMap 或 Secret 注入此容器
- configMapRef:
name: demo-config # 注入的 ConfigMap 名稱
- secretRef:
name: demo-secret # 注入的 Secret 名稱
EOF
# 將該 Pod 服務轉發至本地 8080 port 提供測試
kubectl port-forward deployments/demo-deployment 8080:8080
測試 localhost:8080/token,預期結果為 dummy token from secret
而不是預設得 local token.
儲存於 Secret 的資料,是透過 Base64 編碼後儲存的,而 Base64 不是加密演算法,任何人取得該值,都能反編碼並取得原始值,導致機敏資訊洩漏。
所以必須搭配其他措施才能 保護 Secret 中的資敏資料
Kubernetes 在設計時,區分了 ConfigMap 與 Secret 這兩個組件,分別應用於不同的使用案例,也讓管理者能透過 RBAC 來區隔權限,保護 Secret 數據的安全。
ConfigMap:
Secret:
補充知識:
GitOps 是實現 IaC(Infrastructure as Code)的方式,運用在 Kubernetes 生態時,能簡單理解為有一個 git repo,裡面存放了你部署在 Kubernetes 上所有資源的 yaml file。
但 Secret 的 yaml 中,數據欄位是 base64 編碼的,如果上傳至 git repo,能存取這個 repo 的使用者,都能還原並取得 Secret 中的資敏資訊,這造成更多洩漏的風險。
明天我們來介紹如何透過 sealed-secrets 來解決這個問題