其实我们用 kubeadm 安装的集群,master 节点上面的几个重要组件都是用静态 Pod 的方式运行的,我们登录到 master 节点上查看/etc/kubernetes/manifests目录:
?~ ls /etc/kubernetes/manifests/etcd.yamlkube-apiserver.yamlkube-controller-manager.yamlkube-scheduler.yaml
现在明白了吧,这种方式也为我们将集群的一些组件容器化提供了可能,因为这些 Pod 都不会受到 apiserver 的控制,不然我们这里kube-apiserver怎么自己去控制自己呢?万一不小心把这个 Pod 删掉了呢?所以只能有kubelet自己来进行控制,这就是我们所说的静态 Pod 。
Downward API¶前面我们从 Pod 的原理到生命周期介绍了 Pod 的一些使用,作为 Kubernetes 中最核心的资源对象、最基本的调度单元,我们可以发现 Pod 中的属性还是非常繁多的,前面我们使用过一个 volumes 的属性,表示声明一个数据卷,我们可以通过命令kubectl explain pod.spec.volumes去查看该对象下面的属性非常多,前面我们只是简单使用了 hostPath 和 emptyDir{} 这两种模式,其中还有一种模式叫做downwardAPI,这个模式和其他模式不一样的地方在于它不是为了存放容器的数据也不是用来进行容器和宿主机的数据交换的,而是让 Pod 里的容器能够直接获取到这个 Pod 对象本身的一些信息 。
目前 Downward API 提供了两种方式用于将 Pod 的信息注入到容器内部:
- 环境变量:用于单个变量,可以将 Pod 信息和容器信息直接注入容器内部
- Volume 挂载:将 Pod 信息生成为文件,直接挂载到容器内部中去
# env-pod.yamlapiVersion: v1kind: Podmetadata:name: env-podnamespace: kube-systemspec:containers:- name: env-podimage: busyboxcommand: ["/bin/sh", "-c", "env"]env:- name: POD_NAMEvalueFrom:fieldRef:fieldPath: metadata.name- name: POD_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespace- name: POD_IPvalueFrom:fieldRef:fieldPath: status.podIP
我们可以看到上面我们使用了一种新的方式来设置 env 的值:valueFrom,由于 Pod 的 name 和 namespace 属于元数据,是在 Pod 创建之前就已经定下来了的,所以我们可以使用 metata 就可以获取到了,但是对于 Pod 的 IP 则不一样,因为我们知道 Pod IP 是不固定的,Pod 重建了就变了,它属于状态数据,所以我们使用 status 这个属性去获取 。另外除了使用 fieldRef获取 Pod 的基本信息外,还可以通过 resourceFieldRef 去获取容器的资源请求和资源限制信息 。我们直接创建上面的 Pod:
?~ kubectl apply -f env-pod.yamlpod "env-pod" created
Pod 创建成功后,我们可以查看日志:?~ kubectl logs env-pod -n kube-system |grep PODkubectl logs -f env-pod -n kube-systemPOD_IP=10.244.1.121KUBERNETES_SERVICE_PORT=443KUBERNETES_PORT=tcp://10.96.0.1:443KUBE_DNS_SERVICE_PORT_DNS_TCP=53HOSTNAME=env-podSHLVL=1HOME=/rootKUBE_DNS_SERVICE_HOST=10.96.0.10KUBE_DNS_PORT_9153_TCP_ADDR=10.96.0.10KUBE_DNS_PORT_9153_TCP_PORT=9153KUBE_DNS_PORT_9153_TCP_PROTO=tcpKUBE_DNS_SERVICE_PORT=53KUBE_DNS_PORT=udp://10.96.0.10:53POD_NAME=env-podKUBERNETES_PORT_443_TCP_ADDR=10.96.0.1PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binKUBE_DNS_PORT_53_TCP_ADDR=10.96.0.10KUBERNETES_PORT_443_TCP_PORT=443KUBE_DNS_SERVICE_PORT_METRICS=9153KUBERNETES_PORT_443_TCP_PROTO=tcpKUBE_DNS_PORT_9153_TCP=tcp://10.96.0.10:9153KUBE_DNS_PORT_53_UDP_ADDR=10.96.0.10KUBE_DNS_PORT_53_TCP_PORT=53KUBE_DNS_PORT_53_TCP_PROTO=tcpKUBE_DNS_PORT_53_UDP_PORT=53KUBE_DNS_SERVICE_PORT_DNS=53KUBE_DNS_PORT_53_UDP_PROTO=udpKUBERNETES_SERVICE_PORT_HTTPS=443KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443POD_NAMESPACE=kube-systemKUBERNETES_SERVICE_HOST=10.96.0.1PWD=/KUBE_DNS_PORT_53_TCP=tcp://10.96.0.10:53KUBE_DNS_PORT_53_UDP=udp://10.96.0.10:53
我们可以看到 Pod 的 IP、NAME、NAMESPACE 都通过环境变量打印出来了 。环境变量
上面打印 Pod 的环境变量可以看到有很多内置的变量,其中大部分是系统自动为我们添加的,Kubernetes 会把当前命名空间下面的 Service 信息通过环境变量的形式注入到 Pod 中去:
$ kubectl get svc -n kube-systemNAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)AGEkube-dnsClusterIP10.96.0.10<none>53/UDP,53/TCP,9153/TCP4d21h
Volume 挂载¶Downward API除了提供环境变量的方式外,还提供了通过 Volume 挂载的方式去获取 Pod 的基本信息 。接下来我们通过Downward API将 Pod 的 Label、Annotation 等信息通过 Volume 挂载到容器的某个文件中去,然后在容器中打印出该文件的值来验证,对应的资源清单文件如下所示:
推荐阅读
- 平原游击队|演员潘德民在长春病逝享年97岁,演农民角色深入人心
- 粉色|好像理解宛瑜要的自由了!演员本人戏里戏外都漂亮自在,女星榜样
- 邓家佳|《全民目击》:邓家佳出演悬疑片受好评,影片内涵值得深入思考
- 天珠|关于天珠,你是怎么理解的?
- |成年人的放下:一半是理解,一半是算了
- 爱情的理解|一次比一次更心痛,《爱情的理解》第2集:看见安秀荣被拥抱
- 爱情的理解|《爱情的理解》柳演锡文佳煐上演成年人爱情,拉扯的办公室四角恋
- 爱情的理解|表白是件危险的事:文佳瑛的新剧《爱情的理解》第1集结尾很意外
- 惠英红|惠英红大不同,16岁就工作的她不能理解甜妹的世界
- 净资产的通俗理解."净资产"是什么意思,为什么在帐户结构中"净资产的减少"表示属于借方?