kubernetes容器编排之定义环境变量以及通过downwardapi把pod信息作为环境变量传入容器内

时间:2022-06-15 23:05:26

系列目录

在学习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的字段,而不是容器的字段.