與常規應用程式一樣,容器化應用程式可以使用命令列參數、環境變數、檔案進行配置。
您了解到當容器啟動時執行的命令通常在容器image中定義。此命令是設定在容器的Dockerfile中使用ENTRYPOINT指令指定,而參數通常使用CMD指令指定。 環境變數也可以在Dockerfile中的ENV指令指定。如果應用程式是使用設定檔來設定的,則可以在Dockerfile中使用COPY指令將設定檔加入到容器image中。
接著讓我們的kiada應用程式變成可以使用命令列參數和環境變數進行設定。此應用程式的早期版本都監聽port 8080。
現在可以利用--listen-port
命令列參數進行設定。此外,應用程式將從INITIAL_STATUS_MESSAGE 環境變數中讀取初始狀態訊息。
應用程式現在不僅返回hostname,還會返回pod名稱和pod IP,以及運行它的叢集節點的名稱。應用程式利用環境變數獲得此資訊。
更新後的 Dockerfile 如下。
FROM node:12
COPY app.js /app.js
COPY html/ /html
ENV INITIAL_STATUS_MESSAGE="This is the default status message"
ENTRYPOINT ["node", "app.js"]
CMD ["--listen-port", "8080"]
將設定寫死到容器image中就跟寫死到應用程式的原始碼一樣。這並不理想,因為每次更改設定時都必須重建image。 此外,您永遠不應該在容器image中包含機敏設定資料,例如:安全憑據或加密鑰匙,因為任何有權限存取它的人都可以輕鬆提取它們。
相反,將這些檔案儲存在您掛載到容器中的volume中要安全得多。 一種方法是將檔案儲存在PV中。另一種方法是使用emptyDir volume並且使用init容器從安全儲存中獲得檔案並將檔案寫入volume。 但有更好的方法。在本章中,您將學習如何在不使用init容器的情況下使用特殊的volume類型來得到相同的結果。 但首先,讓我們學習如何在不重新建立容器image的情況下修改命令、參數和環境變數。
建立容器image時,命令及參數都是在Dockerfile中的使用ENTRYPOINT跟CMD指令指定的。 由於這兩個ENTRYPOINT跟CMD都接受陣列數值,因此您可以使用一個ENTRYPOINT或CMD來指定命令及參數,或者將命令及參數拆分為兩者。 當容器被執行時,兩個陣列被連接起來產生完整的命令。
k8s提供了兩個字段類似於Docker的ENTRYPOINT跟CMD。這兩個字段分別為command和args。 您可以在pod yaml的容器定義中指定這些字段。與Docker一樣,這兩個字段接受陣列數值,並且在容器中命令的執行結果是透過連接兩個陣列得出的。
圖 9.1 覆蓋pod yaml中的命令和參數
通常,您使用ENTRYPOINT來指定命令,並使用CMD來指定參數。這允許您覆蓋pod yaml中的參數,而無需再次指定命令。 如果您想覆蓋此命令,您仍然可以這樣做。你可以在不覆蓋參數的情況下做到這一點。
下表顯示了Dockerfile指令跟pod yaml字段的同等對照表
Dockerfile | Pod manifest | 描述 |
---|---|---|
ENTRYPOINT | command | 在容器中運行的可執行檔。這可能包含除了執行檔之外的參數。 |
CMD | args | 傳遞附加參數給使用ENTRYPOINT或command字段所指定的命令。 |
假設您想在啟用CPU 和heap profiling的情況下運行 Kiada 應用程式。 使用Node.JS情況下,您可以利用--cpu-prof和--heap-prof參數傳遞給node命令來啟用profiling。 您可以修改pod yaml來完成此操作,而不是修改Dockerfile和重建image,如下。
kind: Pod
spec:
containers:
- name: kiada
image: luksa/kiada:0.4
command: ["node", "--cpu-prof", "--heap-prof", "app.js"]
當使用以上yaml部署pod時,將運行node --cpu-prof --heap-prof app.js
命令來取代Dockerfile中指定的預設的node app.js
命令。
正如您在yaml中看到的,這個command字段,就像它的 Dockerfile 對應一樣,接受陣列字串來代表要執行的命令。 yaml中使用的陣列表示法在陣列僅包含少數元素時非常有用,但隨著元素數量的增加變得難以閱讀。在這種情況下,最好使用以下符號:
command:
- node
- --cpu-prof
- --heap-prof
- app.js
<aside> 💡 字串必須要用引號包起來,以避免YAML解析器可能將字串以外的值解析成其他東西。 這包含像是 1234 的數字數值,和像是 true/false 的布林值。 一些特別的字串也必須用引號包起來,否則它們會解析成布林值或其他類型。這些包含true、false、yes、no、on、off、y、n、t、f、null等數值。
</aside>