在 ConfigMap和 Secret章节中可知,可以通过ConfigMap和Secret向应用中传递Pod创建前可预先知道的数据,但不能传递Pod创建后未知的一些元数据,比如pod的名字,pod的ip,因为这些信息都是pod创建后才会知道,在创建pod时不可以通过ConfigMap和Secret传递数据,可以通过下列方式传递pod的一些元数据信息:环境变量和Downward API。
Pod中可传递的元数据包括如下数据:
- pod的名称
- pod的IP
- pod所在的命名空间
- pod运行节点的名称
- pod运行所归属的服务账户的名称
- 每个容器请求的CPU和内存的使用量
- 每个容器可以使用的CPU和内存的限制
- pod的标签
- pod的注解
一、通过环境变量形式传递元数据
可以通过环境变量方式把pod和容器的一些元数据信息传递到pod中的容器,在下面资源清单中通过环境变量形式向容器中传递元数据。
apiVersion: v1
kind: Pod
metadata:
name: pod-env
spec:
containers:
- name: busybox
image: busybox
imagePullPolicy: IfNotPresent
command: ["sh", "-c", "sleep 3600"]
resources:
requests:
cpu: 30m
memory: 1Mi
limits:
cpu: 100m
memory: 5Mi
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
- name: REQUEST_CPU
valueFrom:
resourceFieldRef:
resource: requests.cpu
divisor: 1m
- name: REQUEST_MEMORY
valueFrom:
resourceFieldRef:
resource: requests.memory
divisor: 1Mi
- name: CPUT_LIMIT
valueFrom:
resourceFieldRef:
resource: limits.cpu
divisor: 1m
- name: MEMORY_LIMIT
valueFrom:
resourceFieldRef:
resource: limits.memory
divisor: 1Mi
其中,1m表示1 millicore,即千分之一内核,30m表示千分之30内核;1Mi表示1兆
requests:
cpu: 30m
memory: 1Mi
通过上面创建pod后,进入pod中容器可以查看传入的元数据信息,如下所示
[root@k8s-master01 downward]# kubectl exec pod-env env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=pod-env
MEMORY_LIMIT=5
POD_IP=10.244.2.189
NODE_NAME=k8s-node02
REQUEST_MEMORY=1
REQUEST_CPU=30
CPUT_LIMIT=100
POD_NAME=pod-env
POD_NAMESPACE=default
SERVICE_ACCOUNT=default
MYSERVICE_PORT_8080_TCP_PORT=8080
KUBERNETES_SERVICE_HOST=10.96.0.1
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT_443_TCP_PORT=443
MYSERVICE_SERVICE_HOST=10.106.129.199
MYSERVICE_SERVICE_PORT=8080
MYSERVICE_PORT_8080_TCP=tcp://10.106.129.199:8080
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
KUBERNETES_PORT_443_TCP_PROTO=tcp
MYSERVICE_SERVICE_PORT_HTTP=8080
MYSERVICE_PORT_8080_TCP_PROTO=tcp
KUBERNETES_SERVICE_PORT_HTTPS=443
MYSERVICE_PORT=tcp://10.106.129.199:8080
MYSERVICE_PORT_8080_TCP_ADDR=10.106.129.199
HOME=/root
二、通过Downward API传递元数据
上述方式是通过环境变量形式把元数据传递到容器中,也可以通过文件卷的方式把元数据传递到容器中,即本节讲的Down可以ward API方式,把Downward API卷挂载到容器中。Downward API可以给Pod中运行的容器暴露pod的元数据,如下所示
apiVersion: v1
kind: Pod
metadata:
name: mydownward
labels:
prod: dev
annotations:
description: this is description for downward
date: 2020-10-18
spec:
containers:
- name: busybox
image: busybox
imagePullPolicy: IfNotPresent
command: ["sh", "-c", "sleep 3600"]
resources:
requests:
cpu: 30m
memory: 1Mi
limits:
cpu: 100m
memory: 5Mi
volumeMounts:
- name: downward
mountPath: /etc/downward
volumes:
- name: downward
downwardAPI:
items:
- path: podName
fieldRef:
fieldPath: metadata.name
- path: podNamespace
fieldRef:
fieldPath: metadata.namespace
- path: labels
fieldRef:
fieldPath: metadata.labels
- path: annotations
fieldRef:
fieldPath: metadata.annotations
- path: requst-cpu
resourceFieldRef:
containerName: busybox
resource: requests.cpu
divisor: 1m
- path: limits-memory
resourceFieldRef:
containerName: busybox
resource: limits.memory
divisor: 1Mi
通过上述资源清单创建pod后,可以进入容器内部查看downward API挂在卷,发现annotations、labels等对象已经挂载到了容器中。
[root@k8s-master01 downward]# kubectl exec mydownward -it -- /bin/sh
/ # cd /etc/
/etc # ls
downward group hostname hosts localtime mtab network passwd resolv.conf shadow
/etc # cd downward
/etc/downward # ls
annotations labels limits-memory podName podNamespace requst-cpu
三、Downward API比环境变量优势
1、环境变量方式不可以暴露labels和annotations两种元数据,而Downward API可以;
2、运行的pod修改标签和注解后,Downward API可以更新挂载卷中内容,获取最新修改的元数据,而环境变量的方式,标签和注解修改后,无法把新修改的值暴露到容器内部,所以环境变量方式不能传递标签和注解两种元数据。
- 参考《kubenetes in action》