Kubernetes环境变量

2024-02-20 69

Kubernetes中,环境变量是一种常见的配置方式,用于将配置信息传递给运行在容器内的应用程序。本教程主要介绍如何为 Kubernetes Pod 中的容器定义相互依赖的环境变量和为容器设置环境变量,并通过环境变量将 Pod 信息呈现给容器。

必须拥有一个 Kubernetes 的集群,同时必须配置 kubectl 命令行工具与集群通信。 建议在至少有两个不作为控制平面主机的节点的集群上运行本教程。

一、定义环境变量

当创建一个 Pod 时,可以为运行在 Pod 中的容器设置相互依赖的环境变量。 若要设置相互依赖的环境变量,可以在配置清单文件的 env 的 value 中使用 $(VAR_NAME)。

在本练习中,会创建一个单容器的 Pod。 此 Pod 的配置文件定义了一个已定义常用用法的相互依赖的环境变量。 下面是此 Pod 的配置清单:

apiVersion: v1
kind: Pod
metadata:
name: dependent-envars-demo
spec:
containers:
- name: dependent-envars-demo
args:
- while true; do echo -en '\n'; printf UNCHANGED_REFERENCE=$UNCHANGED_REFERENCE'\n'; printf SERVICE_ADDRESS=$SERVICE_ADDRESS'\n';printf ESCAPED_REFERENCE=$ESCAPED_REFERENCE'\n'; sleep 30; done;
command:
- sh
- -c
image: busybox:1.28
env:
- name: SERVICE_PORT
value: "80"
- name: SERVICE_IP
value: "172.17.0.1"
- name: UNCHANGED_REFERENCE
value: "$(PROTOCOL)://$(SERVICE_IP):$(SERVICE_PORT)"
- name: PROTOCOL
value: "https"
- name: SERVICE_ADDRESS
value: "$(PROTOCOL)://$(SERVICE_IP):$(SERVICE_PORT)"
- name: ESCAPED_REFERENCE
value: "$$(PROTOCOL)://$(SERVICE_IP):$(SERVICE_PORT)"

1、依据清单创建 Pod:

kubectl apply -f https://k8s.io/examples/pods/inject/dependent-envars.yaml
pod/dependent-envars-demo created

2、列出运行的 Pod:

kubectl get pods dependent-envars-demo
NAME READY STATUS RESTARTS AGE
dependent-envars-demo 1/1 Running 0 9s

3、检查 Pod 中运行容器的日志:

kubectl logs pod/dependent-envars-demo
UNCHANGED_REFERENCE=$(PROTOCOL)://172.17.0.1:80
SERVICE_ADDRESS=https://172.17.0.1:80
ESCAPED_REFERENCE=$(PROTOCOL)://172.17.0.1:80

如上所示,已经定义了 SERVICE_ADDRESS 的正确依赖引用, UNCHANGED_REFERENCE 的错误依赖引用, 并跳过了 ESCAPED_REFERENCE 的依赖引用。如果环境变量被引用时已事先定义,则引用可以正确解析, 比如 SERVICE_ADDRESS 的例子。

请注意,env 列表中的顺序很重要。如果某环境变量定义出现在列表的尾部, 则在解析列表前部环境变量时不会视其为“已被定义”。 这就是为什么 UNCHANGED_REFERENCE 在上面的示例中解析 $(PROTOCOL) 失败的原因。

当环境变量未定义或仅包含部分变量时,未定义的变量会被当做普通字符串对待, 比如 UNCHANGED_REFERENCE 的例子。 注意,解析不正确的环境变量通常不会阻止容器启动。

$(VAR_NAME) 这样的语法可以用两个 $ 转义,即:$$(VAR_NAME)。 无论引用的变量是否定义,转义的引用永远不会展开。 这一点可以从上面 ESCAPED_REFERENCE 的例子得到印证。

二、设置环境变量

创建 Pod 时,可以为其下的容器设置环境变量。通过配置文件的 env 或者 envFrom 字段来设置环境变量。

  • env 和 envFrom 字段具有不同的效果;
  • env :可以为容器设置环境变量,直接为所给的每个变量指定一个值;
  • envFrom :可以通过引用 ConfigMap 或 Secret 来设置容器的环境变量。 使用 envFrom 时,引用的 ConfigMap 或 Secret 中的所有键值对都被设置为容器的环境变量。 也可以指定一个通用的前缀字符串。

本示例中,将创建一个只包含单个容器的 Pod。此 Pod 的配置文件中设置环境变量的名称为 DEMO_GREETING, 其值为 “Hello from the environment”。下面是此 Pod 的配置清单:

apiVersion: v1
kind: Pod
metadata:
name: envar-demo
labels:
purpose: demonstrate-envars
spec:
containers:
- name: envar-demo-container
image: gcr.io/google-samples/node-hello:1.0
env:
- name: DEMO_GREETING
value: "Hello from the environment"
- name: DEMO_FAREWELL
value: "Such a sweet sorrow"

1、基于配置清单创建一个 Pod:

kubectl apply -f https://k8s.io/examples/pods/inject/envars.yaml

2、获取正在运行的 Pod 信息:

kubectl get pods -l purpose=demonstrate-envars

查询结果应为:

NAME READY STATUS RESTARTS AGE
envar-demo 1/1 Running 0 9s

3、列出 Pod 容器的环境变量:

kubectl exec envar-demo -- printenv

打印结果应为:

NODE_VERSION=4.4.2
EXAMPLE_SERVICE_PORT_8080_TCP_ADDR=10.3.245.237
HOSTNAME=envar-demo
...
DEMO_GREETING=Hello from the environment
DEMO_FAREWELL=Such a sweet sorrow

注意:

  • 通过 env 或 envFrom 字段设置的环境变量将覆盖容器镜像中指定的所有环境变量;
  • 环境变量可以互相引用,但是顺序很重要。 使用在相同上下文中定义的其他变量的变量必须在列表的后面。 同样,请避免使用循环引用。

在 Pod 的配置中定义的、位于 .spec.containers[*].env[*] 下的环境变量 可以在配置的其他地方使用,例如可用在为 Pod 的容器设置的命令和参数中。 在下面的示例配置中,环境变量 GREETING、HONORIFIC 和 NAME 分别设置为 Warm greetings to、 The Most Honorable 和 Kubernetes。 环境变量 MESSAGE 将所有这些环境变量的集合组合起来, 然后再传递给容器 env-print-demo 的 CLI 参数中使用。

apiVersion: v1
kind: Pod
metadata:
name: print-greeting
spec:
containers:
- name: env-print-demo
image: bash
env:
- name: GREETING
value: "Warm greetings to"
- name: HONORIFIC
value: "The Most Honorable"
- name: NAME
value: "Kubernetes"
command: ["echo"]
args: ["$(GREETING) $(HONORIFIC) $(NAME)"]

创建后,命令 echo Warm greetings to The Most Honorable Kubernetes 将在容器中运行。

三、呈现Pod信息

在 Kubernetes 中有两种方式可以将 Pod 和容器字段呈现给运行中的容器:

  • 如本任务所述的环境变量;
  • 卷文件。

这两种呈现 Pod 和容器字段的方式统称为 downward API。

Service 是 Kubernetes 管理的容器化应用之间的主要通信模式,因此在运行时能发现这些 Service 是很有帮助的。

在这部分练习中,将创建一个包含一个容器的 Pod。并将 Pod 级别的字段作为环境变量投射到正在运行的容器中:

apiVersion: v1
kind: Pod
metadata:
name: dapi-envars-fieldref
spec:
containers:
- name: test-container
image: registry.k8s.io/busybox
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

这个清单中,可以看到五个环境变量。env 字段定义了一组环境变量。 数组中第一个元素指定 MY_NODE_NAME 这个环境变量从 Pod 的 spec.nodeName 字段获取变量值。 同样,其它环境变量也是从 Pod 的字段获取它们的变量值。

创建 Pod:

kubectl apply -f https://k8s.io/examples/pods/inject/dapi-envars-pod.yaml

验证 Pod 中的容器运行正常:

# 如果新创建的 Pod 还是处于不健康状态,请重新运行此命令几次。
kubectl get pods

查看容器日志:

kubectl logs dapi-envars-fieldref

输出信息显示了所选择的环境变量的值:

minikube
dapi-envars-fieldref
default
172.17.0.4
default

要了解为什么这些值出现在日志中,请查看配置文件中的 command 和 args 字段。 当容器启动时,它将五个环境变量的值写入标准输出。每十秒重复执行一次。

接下来,进入 Pod 中运行的容器,打开一个 Shell:

kubectl exec -it dapi-envars-fieldref -- sh

在 Shell 中,查看环境变量:

# 在容器内的 `shell` 中运行
printenv

输出信息显示环境变量已经设置为 Pod 字段的值。

MY_POD_SERVICE_ACCOUNT=default
...
MY_POD_NAMESPACE=default
MY_POD_IP=172.17.0.4
...
MY_NODE_NAME=minikube
...
MY_POD_NAME=dapi-envars-fieldref

前面的练习中,将 Pod 级别的字段作为环境变量的值。 接下来这个练习中,将传递属于 Pod 定义的字段,但这些字段取自特定容器而不是整个 Pod。

这里是只包含一个容器的 Pod 的清单:

apiVersion: v1
kind: Pod
metadata:
name: dapi-envars-resourcefieldref
spec:
containers:
- name: test-container
image: registry.k8s.io/busybox:1.24
command: [ "sh", "-c"]
args:
- while true; do
echo -en '\n';
printenv MY_CPU_REQUEST MY_CPU_LIMIT;
printenv MY_MEM_REQUEST MY_MEM_LIMIT;
sleep 10;
done;
resources:
requests:
memory: "32Mi"
cpu: "125m"
limits:
memory: "64Mi"
cpu: "250m"
env:
- name: MY_CPU_REQUEST
valueFrom:
resourceFieldRef:
containerName: test-container
resource: requests.cpu
- name: MY_CPU_LIMIT
valueFrom:
resourceFieldRef:
containerName: test-container
resource: limits.cpu
- name: MY_MEM_REQUEST
valueFrom:
resourceFieldRef:
containerName: test-container
resource: requests.memory
- name: MY_MEM_LIMIT
valueFrom:
resourceFieldRef:
containerName: test-container
resource: limits.memory
restartPolicy: Never

这个清单中,可以看到四个环境变量。env 字段定义了一组环境变量。 数组中第一个元素指定 MY_CPU_REQUEST 这个环境变量从容器的 requests.cpu 字段获取变量值。同样,其它的环境变量也是从特定于这个容器的字段中获取它们的变量值。

创建 Pod:

kubectl apply -f https://k8s.io/examples/pods/inject/dapi-envars-container.yaml

验证 Pod 中的容器运行正常:

# 如果新创建的 Pod 还是处于不健康状态,请重新运行此命令几次。
kubectl get pods

查看容器日志:

kubectl logs dapi-envars-resourcefieldref

输出信息显示了所选择的环境变量的值:

1
1
33554432
67108864
  • 广告合作

  • QQ群号:707632017

温馨提示:
1、本网站发布的内容(图片、视频和文字)以原创、转载和分享网络内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。邮箱:2942802716#qq.com(#改为@)。 2、本站原创内容未经允许不得转裁,转载请注明出处“站长百科”和原文地址。