在學習docker的時候,大家可能經常看到不少示例在docker run的時候指定環境變量(比如wordpress的docker示例就是通過環境變量傳入賬戶和密碼到容器內).這里之所以經常用到環境變量,主要基於以下兩點原因
-
容器內的操作往往都是自動化的,而不像在windows會有圖形界面提示輸入信息或者像在linux有交互式命令可以輸入程序需要的數據.也就是程序運行時需要的參數無法交互式指定,不同程序讀取配置的方式又各式各樣,這種情況下讀取環境變量是比較通用的做法
-
容器的隔離性,在k8s里,pod是最小的邏輯單元,關於容器運行時的很多信息(pod的ip,節點的ip,申請的cpu資源,內存資源)都存在pod里,但是有些時候pod內的容器想要知道這些信息,然而容器無法直接讀取到pod的所有信息,kubernetes本身提供了
download ap(下面交介紹)i
來把pod的信息傳遞給容器,其實就是通過環境變量把pod的信息傳遞給容器.
為容器定義環境變量
當創建pod的時候,可以在配置文件里使用env
字段來定義環境變量,示例如下
apiVersion: v1
kind: Pod
metadata:
name: envar-demo
labels:
purpose: demonstrate-envars
spec:
containers:
- name: envar-demo-container
image: tutum/hello-world
env:
- name: DEMO_GREETING
value: "Hello from the environment"
- name: DEMO_FAREWELL
value: "Such a sweet sorrow"
我們通過kubectl apply -f
創建它
通過執行命令kubectl exec -it envar-demo /bin/sh
進入交互式命令執行容器
輸入printenv
來查看環境變量是否正確傳入
/ # printenv DEMO_GREETING
Hello from the environment
/ # printenv DEMO_FAREWELL
Such a sweet sorrow
/ #
在配置文件中使用環境變量
以上我們通過交互式容器查看到了我們定義的環境變量,實際上我們在配置文件中定義的環境變量也可以在配置文件中其它位置被引用,比如做為容器初始化執行命令的參數,請看下面示例:
apiVersion: v1
kind: Pod
metadata:
name: print-greeting
spec:
containers:
- name: env-print-demo
image: tutum/hello-world
env:
- name: GREETING
value: "Warm greetings to"
- name: HONORIFIC
value: "The Most Honorable"
- name: NAME
value: "Kubernetes"
command: ["echo"]
args: ["$(GREETING) $(HONORIFIC) $(NAME)"]
與上面不同的是,上面僅僅定義了變量,這里我們引用了定義的變量.
我們通過以上配置創建容器,然后執行kubectl logs
查看輸出日志
λ kubectl logs print-greeting
Warm greetings to The Most Honorable Kubernetes
可以看到,被引用的環境變量內容輸出了.
downwardapi介紹及簡單使用
對於一些容器類型,特別是有狀態的,它運行的時候可能需要知道外部依附於pod的信息,比如pod的ip,集群ip,pod申請的內存和cpu數量等.這時候可以通過環境變量把這些依附於pod的字段信息傳入到容器內容.另一種方式是通過DownwardAPIVolumeFiles
把信息傳入到容器內容,這兩種方式合在一起被稱作downward api
使用pod的字段值作為環境變量
apiVersion: v1
kind: Pod
metadata:
name: dapi-envars-fieldref
spec:
containers:
- name: test-container
image: tutum/hello-world
command: [ "sh", "-c"]
args:
- while true; do
echo -en '\n';
printenv MY_NODE_NAME MY_POD_NAME MY_POD_NAMESPACE;
printenv MY_POD_IP MY_POD_SERVICE_ACCOUNT;
sleep 10;
done;
env:
- name: MY_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: MY_POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: MY_POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: MY_POD_SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
restartPolicy: Never
以上配置文件,我們引用了pod的若干屬性然后通過printenv打印出來查看.
我們使用kubectl logs pod名稱
來查看輸出信息
docker-for-desktop
dapi-envars-fieldref
default
10.1.0.75
需要注意的是,以上字段是pod的字段,而不是容器的字段.