概念解析
ConfigMap和Secret是Kubernetes中用於管理配置數據和敏感信息的核心資源。它們允許將配置信息與容器鏡像分離,提高應用程序的可移植性和安全性。
ConfigMap概念
ConfigMap是一種API對象,用於存儲非機密性的鍵值對配置數據。它可以被Pod使用,作為環境變量、命令行參數或存儲卷文件的形式注入到容器中。
Secret概念
Secret是用於存儲敏感信息(如密碼、OAuth令牌和SSH密鑰)的Kubernetes對象。與ConfigMap類似,Secret也可以以環境變量或存儲卷的形式注入到Pod中,但提供了額外的安全保護措施。
核心區別
- 數據敏感性:ConfigMap用於非敏感配置,Secret用於敏感信息
- 存儲方式:Secret數據會被Base64編碼(但不是加密)
- 訪問控制:Secret有更嚴格的訪問控制機制
- 使用場景:ConfigMap用於一般配置,Secret用於密碼、令牌等
核心特性
ConfigMap特性
- 多種數據格式:支持鍵值對、文件內容等多種數據格式
- 靈活注入:可通過環境變量、存儲卷等方式注入Pod
- 動態更新:支持運行時更新配置(需要應用支持)
- 命名空間隔離:在命名空間內隔離配置數據
Secret特性
- 數據加密:數據在etcd中以Base64編碼存儲
- 訪問控制:支持RBAC權限控制
- 多種類型:支持generic、tls、docker-registry等類型
- 自動掛載:ServiceAccount自動掛載相關Secret
實踐教程
創建ConfigMap
# 從字面值創建
kubectl create configmap app-config --from-literal=database.host=localhost --from-literal=database.port=5432
# 從文件創建
echo -n "localhost" > db-host.txt
echo -n "5432" > db-port.txt
kubectl create configmap app-config --from-file=db-host.txt --from-file=db-port.txt
# 從配置文件創建
cat <<EOF > app.properties
database.host=localhost
database.port=5432
log.level=INFO
EOF
kubectl create configmap app-config --from-file=app.properties
創建Secret
# 從字面值創建
kubectl create secret generic db-secret --from-literal=username=admin --from-literal=password=secretpassword
# 從文件創建
echo -n "admin" > username.txt
echo -n "secretpassword" > password.txt
kubectl create secret generic db-secret --from-file=username.txt --from-file=password.txt
# 從TLS證書創建
kubectl create secret tls tls-secret --cert=path/to/cert.crt --key=path/to/key.key
在Pod中使用ConfigMap
apiVersion: v1
kind: Pod
metadata:
name: configmap-pod
spec:
containers:
- name: app
image: busybox
command: ["/bin/sh", "-c", "echo Database Host: $DB_HOST; sleep 3600"]
env:
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: app-config
key: database.host
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: app-config
在Pod中使用Secret
apiVersion: v1
kind: Pod
metadata:
name: secret-pod
spec:
containers:
- name: app
image: busybox
command: ["/bin/sh", "-c", "echo Username: $DB_USER; sleep 3600"]
env:
- name: DB_USER
valueFrom:
secretKeyRef:
name: db-secret
key: username
volumeMounts:
- name: secret-volume
mountPath: /etc/secret
readOnly: true
volumes:
- name: secret-volume
secret:
secretName: db-secret
真實案例
案例:微服務配置管理平台
某公司在Kubernetes集羣中運行多個微服務,每個服務都有不同的配置需求。通過ConfigMap和Secret實現統一的配置管理:
# 數據庫配置ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: database-config
data:
host: postgresql.db.svc.cluster.local
port: "5432"
name: myapp_db
sslmode: require
---
# 應用配置ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
log.level: INFO
cache.size: "1000"
api.timeout: "30s"
feature.flags: "enable-cache=true,enable-metrics=false"
---
# 數據庫憑證Secret
apiVersion: v1
kind: Secret
metadata:
name: database-secret
type: Opaque
data:
username: YWRtaW4= # admin (base64)
password: cGFzc3dvcmQxMjM= # password123 (base64)
---
# API密鑰Secret
apiVersion: v1
kind: Secret
metadata:
name: api-keys
type: Opaque
data:
payment-api-key: cG9ydGFsX2tleV9zZWNyZXQ= # portal_key_secret (base64)
notification-token: bm90aWZpY2F0aW9uX3Rva2VuX3NlY3JldA== # notification_token_secret (base64)
---
# 應用Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 3
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: app
image: mycompany/web-app:1.0
env:
# 從ConfigMap注入數據庫配置
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: database-config
key: host
- name: DB_PORT
valueFrom:
configMapKeyRef:
name: database-config
key: port
# 從Secret注入數據庫憑證
- name: DB_USER
valueFrom:
secretKeyRef:
name: database-secret
key: username
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: database-secret
key: password
# 從ConfigMap注入應用配置
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: app-config
key: log.level
volumeMounts:
# 掛載配置文件
- name: config-volume
mountPath: /etc/app/config
readOnly: true
# 掛載密鑰文件
- name: secret-volume
mountPath: /etc/app/secrets
readOnly: true
volumes:
- name: config-volume
configMap:
name: app-config
- name: secret-volume
secret:
secretName: api-keys
這種配置管理方式的優勢:
- 配置與代碼分離,提高安全性
- 統一管理所有服務的配置
- 支持不同環境的不同配置
- 動態更新配置而無需重建鏡像
配置詳解
複雜ConfigMap配置
apiVersion: v1
kind: ConfigMap
metadata:
name: complex-config
data:
# 簡單鍵值對
database.url: "postgresql://localhost:5432/mydb"
# 多行配置
application.yml: |
server:
port: 8080
spring:
datasource:
url: ${DATABASE_URL}
username: ${DATABASE_USER}
# JSON配置
app-settings.json: |
{
"cache": {
"enabled": true,
"ttl": 3600
},
"features": {
"logging": true,
"metrics": false
}
}
# 環境變量文件
env.properties: |
LOG_LEVEL=DEBUG
MAX_CONNECTIONS=100
ENABLE_SSL=true
不同類型的Secret
# 通用Secret
apiVersion: v1
kind: Secret
metadata:
name: generic-secret
type: Opaque
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm
# TLS Secret
apiVersion: v1
kind: Secret
metadata:
name: tls-secret
type: kubernetes.io/tls
data:
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNVakNDQWZHZ0F3SUJBZ0lKQU5hTmx...
tls.key: LS0tLS1CRUdJTiBSU0EgUFJJV
# Docker Registry Secret
apiVersion: v1
kind: Secret
metadata:
name: registry-secret
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: eyJhdXRocyI6eyJodHRwczovL2luZGV4LmRvY2tlci5pby92MS8iOnsidXNlcm5hbWUiOiJkb2NrZXJ1c2VyIiwicGFzc3dvcmQiOiJkb2NrZXJwYXNzd29yZCIsImF1dGgiOiJkb2NrZXJhdXRoIn19fQ==
Immutable ConfigMap和Secret
apiVersion: v1
kind: ConfigMap
metadata:
name: immutable-config
immutable: true
data:
key: value
故障排除
常見問題及解決方案
-
ConfigMap/Secret未注入到Pod
# 檢查ConfigMap/Secret是否存在 kubectl get configmap <configmap-name> kubectl get secret <secret-name> # 檢查Pod配置 kubectl describe pod <pod-name> # 檢查Pod日誌 kubectl logs <pod-name> -
Base64編碼錯誤
# 正確的Base64編碼方式 echo -n "mypassword" | base64 # 解碼驗證 echo "bXlwYXNzd29yZA==" | base64 --decode -
權限問題
# 檢查RBAC權限 kubectl auth can-i get secrets --namespace <namespace> # 檢查ServiceAccount kubectl describe serviceaccount <sa-name> -
數據更新不生效
# 檢查是否使用了Immutable配置 kubectl get configmap <name> -o yaml # 檢查應用是否支持熱更新 # 有些應用需要重啓才能讀取新配置
最佳實踐
-
命名規範:
- 使用有意義的名稱
- 遵循命名空間隔離原則
- 為不同環境使用不同的ConfigMap/Secret
-
數據管理:
- 敏感數據使用Secret,非敏感數據使用ConfigMap
- 避免在配置中硬編碼敏感信息
- 定期輪換密鑰和密碼
-
版本控制:
- 將ConfigMap/Secret定義保存在版本控制系統中
- 使用標籤或註解記錄版本信息
- 建立配置變更審批流程
-
安全考慮:
- 限制對Secret的訪問權限
- 使用加密存儲敏感數據
- 定期審計配置訪問日誌
-
監控和告警:
- 監控ConfigMap/Secret的變更
- 設置配置異常告警
- 建立配置備份機制
安全考慮
加密存儲敏感數據
apiVersion: v1
kind: Secret
metadata:
name: encrypted-secret
type: Opaque
data:
# 敏感數據應進行Base64編碼
api-key: c2VjcmV0LWFwaS1rZXk= # secret-api-key (base64)
使用RBAC控制訪問
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: config-reader
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-configs
namespace: default
subjects:
- kind: User
name: developer
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: config-reader
apiGroup: rbac.authorization.k8s.io
啓用靜態加密
在kube-apiserver配置中啓用靜態加密:
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- aesgcm:
keys:
- name: key1
secret: c2VjcmV0IGtleSBtdXN0IGJlIDMyIGJ5dGVzIGxvbmc=
- identity: {}
命令速查
| 命令 | 描述 |
|---|---|
kubectl create configmap <name> --from-literal=<key>=<value> |
從字面值創建ConfigMap |
kubectl create secret generic <name> --from-literal=<key>=<value> |
從字面值創建Secret |
kubectl get configmaps |
查看ConfigMap列表 |
kubectl get secrets |
查看Secret列表 |
kubectl describe configmap <name> |
查看ConfigMap詳細信息 |
kubectl describe secret <name> |
查看Secret詳細信息 |
kubectl get configmap <name> -o yaml |
以YAML格式查看ConfigMap |
kubectl get secret <name> -o yaml |
以YAML格式查看Secret |
kubectl delete configmap <name> |
刪除ConfigMap |
kubectl delete secret <name> |
刪除Secret |
總結
ConfigMap和Secret是Kubernetes中管理配置和敏感信息的核心組件。通過本文檔的學習,你應該能夠:
- 理解ConfigMap和Secret的概念和區別
- 創建和管理ConfigMap和Secret
- 在Pod中正確使用ConfigMap和Secret
- 遵循配置管理的最佳實踐和安全考慮
- 排查常見的配置管理問題
在下一文檔中,我們將學習PersistentVolume持久化存儲,它是管理有狀態應用數據的重要組件。