Kubernetes ConfigMap 使用指南
什麼是 ConfigMap?
Kubernetes ConfigMap 是一個 API 物件,用於存儲非敏感的配置資料,以鍵值對的形式存在。ConfigMap 允許您將配置從容器映像中分離出來,使應用程式更具可移植性和靈活性。
ConfigMap 的主要功能:
- 配置分離:將應用程式配置與程式碼分離
- 環境管理:支援不同環境的配置管理
- 動態更新:支援運行時配置更新
- 多種掛載方式:可作為環境變數、檔案或目錄掛載
為什麼使用 ConfigMap?
相較於將配置硬編碼在應用程式中,ConfigMap 提供了更好的配置管理方式:
- 靈活性:無需重新構建映像就能改變配置
- 可重用性:同一個 ConfigMap 可被多個 Pod 使用
- 版本控制:配置變更可以被追蹤和管理
- 環境一致性:確保不同環境使用正確的配置
ConfigMap 基本配置
基本 ConfigMap 範例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| apiVersion: v1 kind: ConfigMap metadata: name: dockertest-config namespace: dockertest-namespace labels: app: dockertest data: CUSTOM_VALUE: "configmap_version" LOG_LEVEL: "INFO" MAX_CONNECTIONS: "100" FEATURE_ENABLED: "true" DB_HOST: "database.example.com" DB_PORT: "5432" DB_NAME: "myapp" REDIS_HOST: "redis.example.com" REDIS_PORT: "6379"
|
包含檔案內容的 ConfigMap
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| apiVersion: v1 kind: ConfigMap metadata: name: app-config-files namespace: dockertest-namespace data: application.properties: | app.name=MyApplication app.version=1.0.0 server.port=8080 logging.level.root=INFO nginx.conf: | server { listen 80; server_name localhost; location / { root /usr/share/nginx/html; index index.html; } } config.json: | { "database": { "host": "localhost", "port": 5432, "name": "myapp" }, "features": { "enableLogging": true, "maxRetries": 3 } }
|
在 Pod 中使用 ConfigMap
方法一:作為環境變數
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| apiVersion: apps/v1 kind: Deployment metadata: name: dockertest-deployment namespace: dockertest-namespace spec: replicas: 1 selector: matchLabels: app: dockertest template: metadata: labels: app: dockertest spec: containers: - name: dockertest image: docker.io/pcion123/tinydocker:0.0.10 env: - name: CUSTOM_VALUE valueFrom: configMapKeyRef: name: dockertest-config key: CUSTOM_VALUE - name: LOG_LEVEL valueFrom: configMapKeyRef: name: dockertest-config key: LOG_LEVEL envFrom: - configMapRef: name: dockertest-config
|
方法二:作為檔案掛載
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| apiVersion: apps/v1 kind: Deployment metadata: name: dockertest-deployment namespace: dockertest-namespace spec: replicas: 1 selector: matchLabels: app: dockertest template: metadata: labels: app: dockertest spec: containers: - name: dockertest image: docker.io/pcion123/tinydocker:0.0.10 volumeMounts: - name: config-volume mountPath: /etc/config - name: nginx-config mountPath: /etc/nginx/nginx.conf subPath: nginx.conf volumes: - name: config-volume configMap: name: dockertest-config - name: nginx-config configMap: name: dockertest-config items: - key: nginx.conf path: nginx.conf
|
方法三:混合使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| apiVersion: apps/v1 kind: Deployment metadata: name: dockertest-deployment namespace: dockertest-namespace spec: replicas: 1 selector: matchLabels: app: dockertest template: metadata: labels: app: dockertest spec: containers: - name: dockertest image: docker.io/pcion123/tinydocker:0.0.10 env: - name: CUSTOM_VALUE valueFrom: configMapKeyRef: name: dockertest-config key: CUSTOM_VALUE - name: LOG_LEVEL valueFrom: configMapKeyRef: name: dockertest-config key: LOG_LEVEL envFrom: - configMapRef: name: dockertest-config volumeMounts: - name: config-volume mountPath: /etc/config - name: nginx-config mountPath: /etc/nginx/nginx.conf subPath: nginx.conf volumes: - name: config-volume configMap: name: dockertest-config - name: nginx-config configMap: name: dockertest-config items: - key: nginx.conf path: nginx.conf
|
建立和管理 ConfigMap
使用 kubectl 指令建立
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| kubectl create configmap my-config \ --from-literal=key1=value1 \ --from-literal=key2=value2 \ -n dockertest-namespace
kubectl create configmap file-config \ --from-file=application.properties \ --from-file=config.json \ -n dockertest-namespace
kubectl create configmap dir-config \ --from-file=./config-directory/ \ -n dockertest-namespace
kubectl create configmap env-config \ --from-env-file=.env \ -n dockertest-namespace
|
管理指令
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| kubectl get configmaps -n dockertest-namespace
kubectl describe configmap dockertest-config -n dockertest-namespace
kubectl get configmap dockertest-config -n dockertest-namespace -o yaml
kubectl edit configmap dockertest-config -n dockertest-namespace
kubectl delete configmap dockertest-config -n dockertest-namespace
|
更新 ConfigMap
1 2 3 4 5 6 7 8 9
| kubectl apply -f configmap.yaml
kubectl patch configmap dockertest-config -n dockertest-namespace \ --type merge -p '{"data":{"NEW_KEY":"new_value"}}'
kubectl replace -f updated-configmap.yaml
|
實際應用範例
範例一:Spring Boot 應用程式配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| apiVersion: v1 kind: ConfigMap metadata: name: spring-app-config namespace: dockertest-namespace data: SPRING_PROFILES_ACTIVE: "production" SERVER_PORT: "8080" LOGGING_LEVEL_ROOT: "INFO" LOGGING_LEVEL_COM_EXAMPLE: "DEBUG" SPRING_DATASOURCE_URL: "jdbc:postgresql://db:5432/myapp" SPRING_DATASOURCE_USERNAME: "appuser" SPRING_DATASOURCE_DRIVERCLASSNAME: "org.postgresql.Driver" JAVA_OPTS: "-Xmx512m -Xms256m -Djava.awt.headless=true" --- apiVersion: apps/v1 kind: Deployment metadata: name: spring-app namespace: dockertest-namespace spec: replicas: 2 selector: matchLabels: app: spring-app template: metadata: labels: app: spring-app spec: containers: - name: spring-app image: docker.io/pcion123/tinydocker:0.0.10 envFrom: - configMapRef: name: spring-app-config ports: - containerPort: 8080
|
範例二:多環境配置管理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| apiVersion: v1 kind: ConfigMap metadata: name: app-config-dev namespace: development data: ENVIRONMENT: "development" LOG_LEVEL: "DEBUG" DB_HOST: "dev-database" CACHE_ENABLED: "false" ---
apiVersion: v1 kind: ConfigMap metadata: name: app-config-prod namespace: production data: ENVIRONMENT: "production" LOG_LEVEL: "WARN" DB_HOST: "prod-database" CACHE_ENABLED: "true"
|
最佳實務建議
配置管理
- 命名規範:使用清晰、一致的 ConfigMap 命名
- 環境分離:為不同環境建立獨立的 ConfigMap
- 版本控制:將 ConfigMap 定義納入版本控制系統
- 文檔記錄:詳細記錄每個配置項的用途和格式
安全性考量
- 敏感資料:將密碼等敏感資料存儲在 Secret 中,而非 ConfigMap
- 存取控制:使用 RBAC 控制 ConfigMap 的存取權限
- 最小權限:只授予應用程式所需的最小配置存取權限
- 定期審核:定期檢查和清理不再使用的 ConfigMap
效能和可靠性
- 大小限制:單個 ConfigMap 不應超過 1MB
- 變更影響:了解 ConfigMap 變更對運行中 Pod 的影響
- 自動重啟:考慮使用工具自動重啟使用更新配置的 Pod
- 配置驗證:在應用配置前驗證配置的正確性
監控和維護
- 配置追蹤:追蹤配置變更的歷史和影響
- 健康檢查:確保應用程式能正確讀取和使用配置
- 備份策略:定期備份重要的 ConfigMap
- 清理策略:定期清理不再使用的 ConfigMap
疑難排解
常見問題
1. Pod 無法讀取 ConfigMap
1 2 3 4 5 6 7 8
| kubectl get configmap dockertest-config -n dockertest-namespace
kubectl describe pod <pod-name> -n dockertest-namespace
kubectl logs <pod-name> -n dockertest-namespace
|
2. 配置更新後 Pod 未重啟
1 2 3 4 5
| kubectl rollout restart deployment dockertest-deployment -n dockertest-namespace
kubectl rollout status deployment dockertest-deployment -n dockertest-namespace
|
3. 環境變數未正確載入
1 2 3 4 5
| kubectl exec -it <pod-name> -n dockertest-namespace -- env | grep CUSTOM_VALUE
kubectl get configmap dockertest-config -n dockertest-namespace -o yaml
|
透過正確使用 ConfigMap,您可以實現靈活的配置管理,讓應用程式更容易在不同環境間移植和部署,同時保持配置的一致性和可維護性。