1、ConfigMap
- ConfigMap 功能在 Kubernetes1.2 版本中引入,許多應用程式會從配置檔案、命令列引數或環境變數中讀取配置資訊。ConfigMap API 給我們提供了向容器中注入配置資訊的機制,ConfigMap 可以被用來儲存單個屬性,也可以用來儲存整個配置檔案或者 JSON 二進位制大物件
- 相當於一個配置檔案的註冊中心,將資料儲存在etcd中,讓Pod以變數和volume掛載
- 應用場景
- 比如好幾個Pod共用一個配置檔案
1.1、目錄建立
-
—from-file 指定在目錄下的所有檔案都會被用在 ConfigMap 裡面建立一個鍵值對,鍵的名字就是檔名,值就是檔案的內容 (—from-file 指定目錄)
-
# 建立game.properties 和 ui.properties 檔案 [root@k8smaster configmap]# cat properties/game.properties enemies=aliens lives=3 enemies.cheat=true enemies.cheat.level=noGoodRotten secret.code.passphrase=UUDDLRLRBABAS secret.code.allowed=true secret.code.lives=30 [root@k8smaster configmap]# cat properties/ui.properties color.good=purple color.bad=yellow allow.textmode=true how.nice.to.look=fairlyNice # 使用命令建立 並且檢視 DATA 表示鍵的數量 [root@k8smaster configmap]# kubectl create configmap game-config --from-file=/root/configmap/properties configmap/game-config created [root@k8smaster configmap]# kubectl get configmap NAME DATA AGE game-config 2 11s # 檢視詳細資訊 [root@k8smaster configmap]# kubectl get configmap game-config -o yaml apiVersion: v1 data: game.properties: | enemies=aliens lives=3 enemies.cheat=true enemies.cheat.level=noGoodRotten secret.code.passphrase=UUDDLRLRBABAS secret.code.allowed=true secret.code.lives=30 ui.properties: | color.good=purple color.bad=yellow allow.textmode=true how.nice.to.look=fairlyNice kind: ConfigMap metadata: creationTimestamp: "2020-12-17T03:31:25Z" managedFields: - apiVersion: v1 fieldsType: FieldsV1 fieldsV1: f:data: .: {} f:game.properties: {} f:ui.properties: {} manager: kubectl operation: Update time: "2020-12-17T03:31:25Z" name: game-config namespace: default resourceVersion: "1357422" selfLink: /api/v1/namespaces/default/configmaps/game-config uid: 2085e855-4bf9-4cdb-9ee8-30f1385ae2c5
1.2、檔案建立
-
只要指定為一個檔案就可以從單個檔案中建立 ConfigMap
-
—from-file 這個引數可以使用多次,你可以使用兩次分別指定上個例項中的那兩個配置檔案,效果就跟指定整個目錄是一樣的 (—from-file 指定檔案)
-
# 建立configmap 並檢視 [root@k8smaster configmap]# kubectl create configmap game-config1 --from-file=/root/configmap/properties/ui.properties configmap/game-config1 created [root@k8smaster configmap]# kubectl get configmap game-config1 NAME DATA AGE game-config1 1 22s # 檢視詳細資訊 和目錄建立效果一樣 [root@k8smaster configmap]# kubectl get configmap game-config1 -o yaml apiVersion: v1 data: ui.properties: | color.good=purple color.bad=yellow allow.textmode=true how.nice.to.look=fairlyNice kind: ConfigMap metadata: creationTimestamp: "2020-12-17T03:37:30Z" managedFields: - apiVersion: v1 fieldsType: FieldsV1 fieldsV1: f:data: .: {} f:ui.properties: {} manager: kubectl operation: Update time: "2020-12-17T03:37:30Z" name: game-config1 namespace: default resourceVersion: "1358296" selfLink: /api/v1/namespaces/default/configmaps/game-config1 uid: 46e88eb8-1377-4710-abf6-a1d92273d5bf [root@k8smaster configmap]# kubectl describe configmap game-config1 Name: game-config1 Namespace: default Labels: <none> Annotations: <none> Data ==== ui.properties: ---- color.good=purple color.bad=yellow allow.textmode=true how.nice.to.look=fairlyNice
1.3、字面值建立
-
使用文字值建立,利用 —from-literal 引數傳遞配置資訊,該引數可以使用多次
-
# 建立configmap並檢視 [root@k8smaster configmap]# kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm configmap/special-config created [root@k8smaster configmap]# kubectl describe configmap special-config Name: special-config Namespace: default Labels: <none> Annotations: <none> Data ==== special.how: ---- very special.type: ---- charm Events: <none> # 檢視詳細資訊 用cm也可以 [root@k8smaster configmap]# kubectl get cm special-config -o yaml apiVersion: v1 data: special.how: very special.type: charm kind: ConfigMap metadata: creationTimestamp: "2020-12-17T03:43:34Z" managedFields: - apiVersion: v1 fieldsType: FieldsV1 fieldsV1: f:data: .: {} f:special.how: {} f:special.type: {} manager: kubectl operation: Update time: "2020-12-17T03:43:34Z" name: special-config namespace: default resourceVersion: "1359169" selfLink: /api/v1/namespaces/default/configmaps/special-config uid: 96b10ac7-964d-4c49-8dec-9dfd1697be72
1.4、Pod中使用
-
使用 ConfigMap 來替代環境變數
-
資源清單示例
-
如果建立ConfigMap是對應的name已經存在,則會更新其中的鍵值對,不會刪除或建立失敗
-
如果使用不存在的configmap 會出現失敗等錯誤
-
apiVersion: v1 kind: ConfigMap metadata: name: special-config namespace: default # ConfigMap 中的鍵值對 data: special.how: very special.type: charm
-
apiVersion: v1 kind: ConfigMap metadata: name: log-config namespace: default # ConfigMap 中的鍵值對 data: log_level: INFO
-
apiVersion: v1 kind: Pod metadata: name: env-test-pod spec: containers: - name: test-container image: nginx # 打出環境變數 command: [ "/bin/sh", "-c", "env" ] # 設定容器的環境變數 多個 env: # 環境變數名稱為 SPECIAL_LEVEL_KEY - name: SPECIAL_LEVEL_KEY # 對應的值從configmap中取 configmap的名稱為special-config 取得是key為special.how的值 做為 環境變數的值 valueFrom: configMapKeyRef: name: special-config key: special.how - name: SPECIAL_TYPE_KEY valueFrom: configMapKeyRef: name: special-config key: special.type - name: UI_PROPERTIES valueFrom: configMapKeyRef: name: game-config key: ui.properties # 將configmap所有的鍵值對作為 環境變數 key為名稱 value為值 envFrom: - configMapRef: name: log-config restartPolicy: Never
-
# 建立Pod 並檢視日誌 [root@k8smaster configmap]# kubectl apply -f env-test-pod.yaml pod/env-test-pod created [root@k8smaster configmap]# kubectl get pod NAME READY STATUS RESTARTS AGE env-test-pod 0/1 Completed 0 54s # 檢視日誌後發現輸出了我們設定的環境變數 [root@k8smaster configmap]# kubectl logs env-test-pod SPECIAL_TYPE_KEY=charm UI_PROPERTIES=color.good=purple color.bad=yellow allow.textmode=true how.nice.to.look=fairlyNice SPECIAL_LEVEL_KEY=very log_level=INFO
-
-
-
用 ConfigMap 設定命令列引數
-
資源清單示例
-
apiVersion: v1 kind: Pod metadata: name: linecommand-test-pod spec: containers: - name: test-container image: nginx # 在命令引數中 使用環境變數 用$(環境變數名) command: [ "/bin/sh", "-c", "echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ] env: - name: SPECIAL_LEVEL_KEY valueFrom: configMapKeyRef: name: special-config key: special.how - name: SPECIAL_TYPE_KEY valueFrom: configMapKeyRef: name: special-config key: special.type restartPolicy: Never
-
# 建立 Pod 並檢視 [root@k8smaster configmap]# kubectl apply -f linecommand-test-pod.yaml pod/linecommand-test-pod created [root@k8smaster configmap]# vim linecommand-test-pod.yaml [root@k8smaster configmap]# kubectl get pod NAME READY STATUS RESTARTS AGE linecommand-test-pod 0/1 Completed 0 65s # 建立日誌 發現輸出了 環境變數 [root@k8smaster configmap]# kubectl logs linecommand-test-pod very charm
-
-
-
通過資料卷外掛使用ConfigMap
-
在資料卷裡面使用這個 ConfigMap,有不同的選項。最基本的就是將檔案填入資料卷,在這個檔案中,鍵就是檔名,鍵值就是檔案內容
-
資源清單示例
-
apiVersion: v1 kind: Pod metadata: name: volume-test-pod spec: containers: - name: test-container image: nginx command: [ "/bin/sh", "-c", "cat /etc/config/special.how" ] # 容器掛載的資料卷 volumeMounts: # 資料卷的名稱 在Pod宣告的資料卷中選擇 - name: config-volume # 掛載到容器內部的路徑 mountPath: /etc/config # Pod的資料卷 volumes: # 資料卷的名稱 - name: config-volume # 資料卷掛載的地方 此處是來源configMap 名稱是special-config # 也就是說哪個容器使用的資料卷 會在容器掛載的路徑下生成多個檔案(取決於configmap中key的數量) key為檔名,value為檔案內容 configMap: name: special-config restartPolicy: Never
-
# 建立Pod並檢視 [root@k8smaster configmap]# kubectl apply -f volume-test-pod.yaml pod/vloume-test-pod created [root@k8smaster configmap]# kubectl get pod volume-test-pod 0/1 Completed 0 24s # 檢視日誌 輸出了檔案內容 [root@k8smaster configmap]# kubectl logs vloume-test-pod very
-
-
1.5、ConfigMap熱更新
-
更新 ConfigMap 後
-
使用該 ConfigMap 掛載的 Env 不會同步更新
-
使用該 ConfigMap 掛載的 Volume 中的資料需要一段時間(實測大概10秒)才能同步更新 (這樣就可以實時修改配置檔案,比如nginx的)
-
雖然配置檔案可以熱更新,但是能不能起作用還要看具體情況,比如nginx,啟動之後,就不會再去看配置檔案了,我們需要手動重啟nginx,來達到重新讀取配置檔案的目的,如果有的服務可以一直監測配置檔案,我們則不用手動處理(這種情況很少)
-
更新 ConfigMap 目前並不會觸發相關 Pod 的滾動更新,可以通過修改 pod annotations 的方式強制觸發滾動更新
-
$ kubectl patch deployment hot-update-test --patch '{"spec": {"template": {"metadata": {"annotations":{"version/config": "20201010" }}}}}'
-
這個例子裡我們在 .spec.template.metadata.annotations 中新增 version/config ,每次通過修改version/config 來觸發滾動更新
-
-
-
資源清單示例
-
apiVersion: apps/v1 kind: Deployment metadata: name: hot-update-test spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: my-nginx image: nginx ports: - containerPort: 80 # 容器使用Pod的容器卷 並掛載在自己內部 volumeMounts: - name: config-volume mountPath: /etc/config # 宣告Pod的容器卷 volumes: - name: config-volume configMap: name: log-config
-
# 建立Pod 並檢視掛載目錄下的檔案 和檔案內容 [root@k8smaster configmap]# kubectl apply -f hot-update-test.yaml deployment.apps/hot-update-test created [root@k8smaster configmap]# kubectl get pod NAME READY STATUS RESTARTS AGE hot-update-test-6fd96995b6-jfw2w 1/1 Running 0 100s # 檢視掛載目錄下的檔案 和檔案內容 [root@k8smaster configmap]# kubectl exec -it hot-update-test-6fd96995b6-jfw2w -- ls /etc/config log_level [root@k8smaster configmap]# kubectl exec -it hot-update-test-6fd96995b6-jfw2w -- cat /etc/config/log_level INFO
-
修改 ConfigMap(log-config)中的內容 (將INFO改成DEBUD)
-
[root@k8smaster configmap]# kubectl edit configmap log-config configmap/log-config edited [root@k8smaster configmap]# kubectl describe configmap log-config Name: log-config Namespace: default Labels: <none> Annotations: Data ==== log_level: ---- DEBUG Events: <none>
-
# 檢視log_level 檔案內容發生了改變 [root@k8smaster configmap]# kubectl exec -it hot-update-test-6fd96995b6-jfw2w -- cat /etc/config/log_level DEBUG
-
-
2、Secret
- ConfigMap將資料以明文的方式存放,不太安全,Secret可以用Base64編碼存放,比較安全
- Secret 解決了密碼、token、金鑰等敏感資料的配置問題,而不需要把這些敏感資料暴露到映象或者 Pod Spec中。Secret 可以以 Volume 或者環境變數的方式使用
- Secret 有三種型別
- Service Account :用來訪問Kubernetes API,由Kubernetes自動建立,並且會自動掛載到Pod的/run/secrets/kubernetes.io/serviceaccount目錄中,比如coredns、kube-proxy可以訪問(不是什麼都可以訪問Kubernetes API)
- Opaque :base64編碼格式的Secret,用來儲存密碼、金鑰等
- kubernetes.io/dockerconfigjson :用來儲存私有 docker registry 的認證資訊
2.1、Service Account
-
# 查詢系統的Pod [root@k8smaster secret]# kubectl get pod -n kube-system NAME READY STATUS RESTARTS AGE coredns-7ff77c879f-494fb 1/1 Running 2 46h coredns-7ff77c879f-tvgrz 1/1 Running 2 46h etcd-k8smaster 1/1 Running 3 6d19h kube-apiserver-k8smaster 1/1 Running 3 6d19h kube-controller-manager-k8smaster 1/1 Running 16 6d19h kube-flannel-ds-amd64-hflj8 1/1 Running 4 6d6h kube-flannel-ds-amd64-s9xhk 1/1 Running 3 6d6h kube-flannel-ds-amd64-wp7mp 1/1 Running 4 6d6h kube-proxy-5l8kb 1/1 Running 2 47h kube-proxy-6n8vp 1/1 Running 2 47h kube-proxy-lgcxp 1/1 Running 2 47h kube-scheduler-k8smaster 1/1 Running 17 6d19h # 檢視 kube-proxy/run/secrets/kubernetes.io/serviceaccount 下的檔案 # ca.crt 是https的證書資訊 namespace 是名稱空間 token 是訪問時攜帶的token [root@k8smaster secret]# kubectl exec -it -n kube-system kube-proxy-5l8kb -- ls /run/secrets/kubernetes.io/serviceaccount ca.crt namespace token
2.2、Opaque
-
Opaque 型別的資料是一個 map 型別,要求 value 是 base64 編碼格式
-
[root@k8smaster secret]# echo admin | base64 YWRtaW4K [root@k8smaster secret]# echo 123456 | base64 MTIzNDU2Cg== # 解碼 [root@k8smaster secret]# echo YWRtaW4K | base64 -d admin
-
-
資源清單示例
-
apiVersion: v1 kind: Secret metadata: name: mysecret type: Opaque data: username: YWRtaW4= password: MTIzNDU2Cg==
-
# 建立 secret 並檢視 [root@k8smaster secret]# kubectl apply -f secret-test.yaml secret/mysecret created [root@k8smaster secret]# kubectl get secret NAME TYPE DATA AGE default-token-99w8n kubernetes.io/service-account-token 3 6d19h mysecret Opaque 2 8s
-
-
將 Secret 掛載到 Volume 中
-
Secret中的鍵值對會以檔案的方式存在在容器掛載的目錄下 key為檔名 value為檔案值(自動解碼)
-
資源清單示例
-
apiVersion: v1 kind: Pod metadata: name: opaque-test labels: name: opaque-test spec: volumes: - name: secrets # 使用secret secret的名稱是mysecret secret: secretName: mysecret containers: - image: nginx name: opaque-nginx volumeMounts: - name: secrets mountPath: /etc/opaque # 只讀 readOnly: true
-
# 建立Pod [root@k8smaster secret]# kubectl apply -f opaque-test.yaml pod/opaque-test created [root@k8smaster secret]# kubectl get pod NAME READY STATUS RESTARTS AGE hot-update-test-6fd96995b6-jfw2w 1/1 Running 0 60m opaque-test 1/1 Running 0 51s # 檢視掛載目錄下的檔案 [root@k8smaster secret]# kubectl exec -it opaque-test -- ls /etc/opaque password username # 檢視掛載目錄下的檔案內容 自動解碼 [root@k8smaster secret]# kubectl exec -it opaque-test -- cat /etc/opaque/username admin
-
-
-
將 Secret 匯出到環境變數中
-
資源清單示例
-
apiVersion: apps/v1 kind: Deployment metadata: name: opaque-env spec: replicas: 2 # 這個版本的Deployment不能省去selector selector: matchLabels: app: opaque-deployment template: metadata: labels: app: opaque-deployment spec: containers: - name: pod-1 image: nginx ports: - containerPort: 80 # 設定環境變數 env: # 環境變數名稱 - name: TEST_USER # 環境變數值得來源為secret secret的名稱是mysecret 用的是key為username的value valueFrom: secretKeyRef: name: mysecret key: username - name: TEST_PASSWORD valueFrom: secretKeyRef: name: mysecret key: password
-
# 建立deployment 並檢視Pod [root@k8smaster secret]# kubectl apply -f opaque-env.yaml deployment.apps/opaque-env created [root@k8smaster secret]# kubectl get pod NAME READY STATUS RESTARTS AGE opaque-env-54d4fd67f4-9xrrs 1/1 Running 0 11s opaque-env-54d4fd67f4-h7689 1/1 Running 0 11s # 檢視兩個Pod中的環境變數 均已解碼 [root@k8smaster secret]# kubectl exec -it opaque-env-54d4fd67f4-9xrrs -- env TEST_USER=admin TEST_PASSWORD=123456 [root@k8smaster secret]# kubectl exec -it opaque-env-54d4fd67f4-h7689 -- env TEST_USER=admin TEST_PASSWORD=123456
-
-
2.3、kubernetes.io/dockerconfigjson
-
用來儲存私有 docker registry 的認證資訊
-
使用命令建立(docker資訊換成自己的)
-
kubectl create secret docker-registry myregistrykey --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
-
# 檢視 myregistrykey 檢視具體資訊也是編碼過的 [root@k8smaster secret]# kubectl get secret NAME TYPE DATA AGE default-token-99w8n kubernetes.io/service-account-token 3 6d20h myregistrykey kubernetes.io/dockerconfigjson 1 10s mysecret Opaque 2 50m
-
-
使用docker的登入檔案建立
-
cat ~/.docker/config.json 這個docker的登入檔案登入docker的倉庫後自動生成
-
# 將登入檔案的內容進行base64編碼 cat ~/.docker/config.json | base64 # 將編碼後的結果寫入資源清單中 cat > myregistrykey.yaml <<EOF apiVersion: v1 kind: Secret metadata: name: myregistrykey data: .dockerconfigjson: docker的登入檔案內容的base64編碼 type: kubernetes.io/dockerconfigjson EOF # 建立serret kubectl create -f myregistrykey.yaml
-
資源清單示例
-
apiVersion: v1 kind: Secret metadata: name: myregistrykey data: .dockerconfigjson: docker的登入檔案內容的base64編碼 type: kubernetes.io/dockerconfigjson
-
-
-
資源清單示例
-
apiVersion: v1 kind: Pod metadata: name: docker-pod spec: containers: - name: foo # 這個映象需要在自己的倉庫中 需要身份認證 image: registry.cn-hangzhou.aliyuncs.com/******/mytomcat:8.1.0 # 使用映象拉取的secret 包含映象倉庫的地址 使用者名稱 密碼等 imagePullSecrets: - name: myregistrykey
-
# 檢視pod 已經執行 [root@k8smaster secret]# kubectl get pod NAME READY STATUS RESTARTS AGE docker-pod 1/1 Running 0 6m22s
-