ConfigMap可以將應用程式所需的設定資料與Pod的配置分開管理,讓多個Pod可以共用設定,也能讓相同的應用程式在不同環境中使用不同的設定,而不需要把這些設定直接寫在Pod或Deployment中。
apiVersion: v1
kind: Pod
metadata:
name: config-demo
spec:
containers:
- name: config-demo
image: busybox
command: ["sh", "-c", "echo $APP_MODE && echo $LOG_LEVEL && sleep 3600"]
env:
- name: APP_MODE
valueFrom:
configMapKeyRef:
name: app-config
key: APP_MODE
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: app-config
key: LOG_LEVEL
---
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
APP_MODE: "production"
LOG_LEVEL: "info"
套用後我們來看一下印出的資訊
因為ConfigMap是透過環境變數提供給Pod,修改ConfigMap後,已經啟動的Pod不會自動更新環境變數。因此這裡改用Deployment進行示範,之後可以透過重新建立Pod來取得更新後的ConfigMap。
apiVersion: apps/v1
kind: Deployment
metadata:
name: config-demo
spec:
replicas: 1
selector:
matchLabels:
app: config-demo
template:
metadata:
labels:
app: config-demo
spec:
containers:
- name: config-demo
image: busybox
command: ["sh", "-c", "echo $APP_MODE && echo $LOG_LEVEL && sleep 3600"]
env:
- name: APP_MODE
valueFrom:
configMapKeyRef:
name: app-config
key: APP_MODE
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: app-config
key: LOG_LEVEL
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
APP_MODE: "test"
LOG_LEVEL: "debug"
將上面兩個yaml檔套用上Kubernetes。
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
APP_MODE: "production"
LOG_LEVEL: "debug"
將ConfigMap的yaml檔案更換成上方的內容。
由於ConfigMap不會觸發Deployment的自動更新,所以要輸入以下指令來觸發
kubectl rollout restart deployment config-demo
再查看一下
執行後 Deployment 會重新建立 Pod,而新的 Pod 在啟動時會重新讀取 ConfigMap,因此就能取得更新後的環境變數。
前面介紹的ConfigMap適合用來儲存一般的設定資料,但如果今天需要儲存的是密碼、Token等敏感資料,就不適合直接存放在ConfigMap中。
這時候可以使用Kubernetes提供的Secret來存放這些敏感資料。
Secret的使用方式和ConfigMap相似,可以將資料透過環境變數或Volume提供給Pod使用。
apiVersion: apps/v1
kind: Deployment
metadata:
name: secret-demo
spec:
replicas: 1
selector:
matchLabels:
app: secret-demo
template:
metadata:
labels:
app: secret-demo
spec:
containers:
- name: secret-demo
image: busybox
command: ["sh", "-c", "echo $DB_USER && echo $DB_PASSWORD && sleep 3600"]
env:
- name: DB_USER
valueFrom:
secretKeyRef:
name: db-secret
key: DB_USER
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: DB_PASSWORD
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
stringData:
DB_USER: "admin"
DB_PASSWORD: "123456"
將上方的兩個yaml檔案套入後,會印出示範用的使用者和密碼
**注意:**這裡為了方便觀察才直接將密碼印出,實際使用時應避免將密碼等敏感資料輸出到Log中。
除了stringData之外,Secret也可以使用data來儲存資料。兩者的差別在於,使用data時,需要先將資料轉換成Base64編碼,而stringData則可以直接寫入一般字串。data使用Base64編碼主要是為了讓二進位資料能以文字格式表示,並不是為了加密資料。
data範例:
data:
DB_PASSWORD: MTIzNDU2
註: 需要注意的是,Base64並不是加密。Secret的意義是讓Kubernetes將這些資料以Secret資源進行管理,實際安全性還需要搭配權限控管、etcd靜態資料加密等措施。