对于容器来说,拥有关于自身的信息有时是很有用的。 Downward API 允许容器在不使用 Kubernetes 客户端或 API 服务器的情况下获得自己或集群的信息。例如,现有应用程序假设某特定的周知的环境变量是存在的,其中包含唯一标识符。 一种方法是对应用程序进行封装,但这很繁琐且容易出错,并且违背了低耦合的目标。 更好的选择是使用 Pod 名称作为标识符,并将 Pod 名称注入到周知的环境变量中。在 Kubernetes 中,有两种方法可以将 Pod 和容器字段暴露给运行中的容器:作为环境变量作为 downwardAPI 卷中的文件这两种暴露 Pod 和容器字段的方式统称为 Downward API。可用字段只有部分 Kubernetes API 字段可以通过 Downward API 使用。可以使用 fieldRef 传递来自可用的 Pod 级字段的信息。 可以使用 resourceFieldRef 传递来自可用的 Container 级字段的信息。可通过fieldRef获得的信息对于某些 Pod 级别的字段,你可以将它们作为环境变量或使用 downwardAPI 卷提供给容器,同时也是最常用的字段:metadata.name:Pod 的名称metadata.namespace:Pod 的命名空间metadata.uid:Pod 的唯一 IDmetadata.annotations['<KEY>']:Pod 的注解 <KEY> 的值(例如:metadata.annotations['myannotation'])metadata.labels['<KEY>']:Pod 的标签 <KEY> 的值(例如:metadata.labels['mylabel'])以下信息可以通过环境变量获得,但不能作为 downwardAPI 卷 fieldRef 获得spec.serviceAccountName:Pod 的服务账号名称spec.nodeName:Pod 运行时所处的节点名称status.hostIP:Pod 所在节点的主 IP 地址status.hostIPs:这组 IP 地址是 status.hostIP 的双协议栈版本,第一个 IP 始终与 status.hostIP 相同。 该字段在启用了 PodHostIPs 特性门控后可用。status.podIP:Pod 的主 IP 地址(通常是其 IPv4 地址)status.podIPs:这组 IP 地址是 status.podIP 的双协议栈版本, 第一个 IP 始终与 status.podIP 相同。以下信息可以通过 downwardAPI 卷 fieldRef 获得,但不能作为环境变量获得metadata.labels:Pod 的所有标签,格式为 标签键名="转义后的标签值",每行一个标签metadata.annotations:Pod 的全部注解,格式为 注解键名="转义后的注解值",每行一个注解为应用注入Pod环境变量示例:
apiVersion: v1kind: Podmetadata: name: dapi-envars-fieldrefspec: 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
可通过resourceFieldRef获得的信息resource: limits.cpu:容器的 CPU 限制值resource: requests.cpu:容器的 CPU 请求值resource: limits.memory:容器的内存限制值resource: requests.memory:容器的内存请求值resource: limits.hugepages-:容器的巨页限制值resource: requests.hugepages-:容器的巨页请求值resource: limits.ephemeral-storage:容器的临时存储的限制值resource: requests.ephemeral-storage:容器的临时存储的请求值如果没有为容器指定 CPU 和内存限制时尝试使用 Downward API 暴露该信息,那么 kubelet 默认会根据节点可分配资源计算并暴露 CPU 和内存的最大可分配值。为应用注入容器环境变量示例:
apiVersion: v1kind: Podmetadata: name: dapi-envars-resourcefieldrefspec: 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
典型容器内环境变量
APP_VERSION=10.1.1BITNAMI_APP_NAME=grafana……GRAFANA_SERVICE_HOST=10.105.105.161GRAFANA_SERVICE_PORT=3000……HOME=/HOSTNAME=grafana-66f79fcc97-jm9mbKUBERNETES_PORT_443_TCP_ADDR=10.96.0.1KUBERNETES_PORT_443_TCP_PORT=443KUBERNETES_PORT_443_TCP_PROTO=tcpKUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443KUBERNETES_PORT=tcp://10.96.0.1:443KUBERNETES_SERVICE_HOST=10.96.0.1KUBERNETES_SERVICE_PORT=443KUBERNETES_SERVICE_PORT_HTTPS=443OS_ARCH=amd64OS_FLAVOUR=debian-11OS_NAME=linux
总结在 Kubernetes 中,有两种方法可以将 Pod 和容器字段暴露给运行中的容器:作为环境变量,这个是最常用的作为 downwardAPI 卷中的文件这两种暴露 Pod 和容器字段的方式统称为 Downward API。通常使用现代的开发框架,如springboot,都可以自动识别很多Pod和容器信息,具体需要参考各个框架。应用最常用的是环境变量方案获取Podname或者IP,用于设置日志文件名称或者注册中心注册,这两个信息通常默认都有(HOSTNAME和XXX_SERVICE_HOST),不需要额外注入,其他信息需要根据需要选择注入。
0 评论