在 k8s 中使用設定主要可以有以下幾種方式來實現:
1. 向容器傳遞命令列引數
2. 為每個容器指定自定義的環境變數
3. 通過特殊型別的卷將組態檔掛載到容器中
在 k8s 中覆蓋命令列引數
和 docker 內一樣,可以定義容器啟動中的執行程式和引數,並且映象的 ENTRYPOINT 和 CMD 會被 k8s 中的 command 和 args 覆蓋。
Docker | K8s | 描述 |
ENTRYPOINT | command | 容器中執行可執行檔案 |
CMD | args | 傳給可執行檔案的引數 |
在pod定義中可以這樣子宣告 command 和 args
kind: Pod spec: containers: - image: some/image command: ["/bin/command"] args: ["args1", "args2", "args3"]
在容器中指定環境變數
在 k8s 中宣告環境變數,在容器中可以通過環境變數來進行設定,但是需要注意的是,在每個容器中,k8s 會自動暴露相同名稱空間下每個 service 對應的環境變數。雖然環境變數是被設定在 pod 的容器定義中,但是並非是 pod 級別的,比如說運維需要在容器中宣告一些運維中特殊宣告的環境變數。比如叢集中的dns域名解析,當前宿主ip,當前pod的ip等等。
kind: Pod spec: containers: - image: xxx/image env: - name: INTERVAL value: "30" name: env-config-name ...
在環境變數中參照另一個環境變數
env: - name: OTHER_VAR value: "foo" - name: THIS_VAR value: "$(OTHER_VAR)_change"
利用 config 設定
上面的兩種設定方式更適合運維和 k8s 工程師在設定叢集的時候進行寫死的設定,對於服務開發來說,這兩種設定方式不太合適。
使用指令 kubectl 建立 ConfigMap
$ kubectl create configmap set-config --from-literal=keyname=config-key-value --from-literal=one=two $ kubectl describe configmap set-config Name: set-config Namespace: default Labels: <none> Annotations: <none> Data ==== keyname: ---- config-key-value one: ---- two Events: <none>
configmap可以混合使用不同的自選選項:完整資料夾、單獨檔案、自定義鍵名條目下的檔案以及字面量等等。
$ kubectl create configmap my-config --from-file=foo.json ## 單獨檔案 --from-file=var=foobar.conf ## 自定義鍵名條目下的檔案 --from-file=config-opts/ ## 完整的資料夾 --from-literral=some=thing ## 字面量
在實際應用中,我們一般這樣子使用 configmap,利用 configmap 設定不同環境下的組態檔,然後利用 volume 來掛載到 pod 容器資料夾內。
例如,先宣告兩個configmap,一個代表正式環境,一個代表測試環境
$ vim config-learn-test.xml <conf> <env>test</env> <service> <servicename></servicname> <host></host> <port></port> </service> <conf> $ vim config-learn-prod.xml <conf> <env>prod</env> <service> <servicename></servicname> <host></host> <port></port> </service> <conf>
生成 configmap
$ kubectl create configmap config-learn-prod --from-file=config-learn.xml=/path/configmap-learn/config-learn-prod.xml $ kubectl create configmap config-learn-test --from-file=config-learn.xml=/path/configmap-learn/config-learn-test.xml
注意這裡兩個都使用的設定名稱為 config-learn.xml,這樣方便統一設定名
建立 pod,並且宣告需要的設定,如果環境是測試則選擇 config-learn-test,如果環境為正式則選擇 config-learn-prod
$ vim ./configmap-learn.yaml apiVersion: v1 kind: Pod metadata: name: configmap-learn spec: containers: - image: luksa/kubia name: kubia ports: - containerPort: 8080 protocol: TCP volumeMounts: - name: configname mountPath: /data/service/conf readOnly: true volumes: - name: configname configMap: name: config-learn-test
在生成的 pod 中去檢驗對應目錄下的組態檔如下:
$ kubectl exec configmap-learn cat /data/service/conf/config-learn.xml
<conf>
<env>test</env>
<service>
<servicename></servicname>
<host></host>
<port></port>
</service>
<conf>
可以看到確實是採取的測試環境設定,而且如果此目錄下有相同名字的組態檔,此檔案會被覆蓋。
編輯修改configmap
$ kubectl edit configmap config-learn-prod
# Please edit the object below. Lines beginning with a '#' will be ignored, # and an empty file will abort the edit. If an error occurs while saving this file will be # reopened with the relevant failures. # apiVersion: v1 data: config-learn.xml: | <conf> <env>prod</env> <service> <servicename></servicname> <host></host> <port></port> </service> <conf> kind: ConfigMap metadata: creationTimestamp: "2022-09-11T10:59:28Z" managedFields: - apiVersion: v1 fieldsType: FieldsV1 fieldsV1: f:data: .: {} f:config-learn.xml: {} manager: kubectl operation: Update time: "2022-09-11T10:59:28Z" name: config-learn-prod namespace: default resourceVersion: "23045374" selfLink: /api/v1/namespaces/default/configmaps/config-learn-prod uid: 79663144-2b5e-4e29-8c94-0469d5906e19
儲存檔案後關閉編輯器,configmap 會在不久後更新對應的檔案,檔案更新過程需要一些時間,最後會看到組態檔的變化。但是一般容器程序並不會監控檔案的變化在載入之後,所以一般都是重啟容器並載入設定的。