Docker 与 K8S学习笔记(二十)—— 使用Downward API向容器注入Pod信息

简介: Kubernetes在创建Pod时,会为Pod和容器设置一些额外的信息,比如Pod名称、Pod IP、Node IP、Label、Annotation、资源限制等,我们经常会在应用程序中使用到这些数据,比如利用Pod名称作为应用日志的字段,方便分析日志。为了能在容器内获取这些信息,我们可以使用Dow

Docker 与 K8S学习笔记(二十)—— 使用Downward API向容器注入Pod信息


Kubernetes在创建Pod时,会为Pod和容器设置一些额外的信息,比如Pod名称、Pod IP、Node IP、Label、Annotation、资源限制等,我们经常会在应用程序中使用到这些数据,比如利用Pod名称作为应用日志的字段,方便分析日志。为了能在容器内获取这些信息,我们可以使用Downward API机制来实现。


Downward API可以通过环境变量Volume挂载这两种方式将Pod信息注入容器,我们分别来看一下:

 

一、环境变量方式


我们还是以Busybox为例进行演示,我们将Pod信息和Container信息以环境变量方式注入容器,在容器启动后通过env命令打印出来,我们Yaml文件内容如下:


apiVersion: v1
kind: Pod
metadata:
  name: busybox-pod
spec:
  containers:
  - name: busybox
    image: busybox
    command: ["/bin/sh", "-c", "env | grep VAR_"]
    resources:
      requests:
        memory: "16Mi"
        cpu: "125m"
      limits:
        memory: "32Mi"
        cpu: "250m"
    env:
    - name: VAR_NODE_NAME
      valueFrom:
        fieldRef:
          fieldPath: spec.nodeName
    - name: VAR_POD_NAME
      valueFrom:
        fieldRef:
          fieldPath: metadata.name
    - name: VAR_POD_NAMESPACE
      valueFrom:
        fieldRef:
          fieldPath: metadata.namespace
    - name: VAR_POD_IP
      valueFrom:
        fieldRef:
          fieldPath: status.podIP
    - name: VAR_SERVICE_ACCOUNT
      valueFrom:
        fieldRef:
          fieldPath: spec.serviceAccountName
    - name: VAR_CPU_REQUEST
      valueFrom:
        resourceFieldRef:
          containerName: busybox
          resource: requests.cpu
    - name: VAR_CPU_LIMIT
      valueFrom:
        resourceFieldRef:
          containerName: busybox
          resource: limits.cpu
    - name: VAR_MEM_REQUEST
      valueFrom:
        resourceFieldRef:
          containerName: busybox
          resource: requests.memory
    - name: VAR_MEM_LIMIT
      valueFrom:
        resourceFieldRef:
          containerName: busybox
          resource: limits.memory
  restartPolicy: Never


我们创建Pod并使用kubtctl logs命令打印下输出:


$ sudo kubectl apply -f busy_pod.yaml
pod/busybox-pod created
$ sudo kubectl logs busybox-pod
VAR_MEM_REQUEST=16777216      # 容器内存请求值
VAR_NODE_NAME=ayato           # 节点名称
VAR_SERVICE_ACCOUNT=default   # Pod使用的ServiceAccount名称
VAR_CPU_REQUEST=1             # 容器cpu请求值
VAR_POD_NAME=busybox-pod      # pod名称
VAR_MEM_LIMIT=33554432        # 容器内存限制值
VAR_POD_NAMESPACE=default     # Pod所在命名空间
VAR_POD_IP=172.17.0.6         # Pod ip地址
VAR_CPU_LIMIT=1               # 容器cpu请求值


二、Volume挂载方式


我们接下来尝试使用Volume挂载方式,将Pod信息注入容器。还是以Busybox为例,由于Pod信息都是以文件方式注入容器,所以我们修改容器启动后执行命令:我们使用cat不断打印注入的文件,修改后的Yaml文件如下:


apiVersion: v1
kind: Pod
metadata:
  name: busybox-pod
  labels:
    cluster: demo-cluster
    type: tool-pod
  annotations:
    builder: alalazy
spec:
  containers:
  - name: busybox
    image: busybox
    command: ["/bin/sh", "-c"]
    args:
    - while true; do
        if [[ -e /etc/podinfo/labels ]]; then
          echo -en '\n\n'; cat /etc/podinfo/labels; fi;
        if [[ -e /etc/podinfo/annotations ]]; then
          echo -en '\n\n'; cat /etc/podinfo/annotations; fi;
        if [[ -e /etc/podinfo/cpu_limit ]]; then
          echo -en '\n\n'; cat /etc/podinfo/cpu_limit; fi;
        if [[ -e /etc/podinfo/cpu_request ]]; then
          echo -en '\n\n'; cat /etc/podinfo/cpu_request; fi;
        if [[ -e /etc/podinfo/mem_limit ]]; then
          echo -en '\n\n'; cat /etc/podinfo/mem_limit; fi;
        if [[ -e /etc/podinfo/mem_request ]]; then
          echo -en '\n\n'; cat /etc/podinfo/mem_request; fi;
        sleep 5;
      done;
    volumeMounts:
      - name: podinfo
        mountPath: /etc/podinfo
    resources:
      requests:
        memory: "16Mi"
        cpu: "125m"
      limits:
        memory: "32Mi"
        cpu: "250m"
  volumes:
    - name: podinfo
      downwardAPI:
        items:
          - path: "labels"
            fieldRef:
              fieldPath: metadata.labels
          - path: "annotations"
            fieldRef:
              fieldPath: metadata.annotations
          - path: "cpu_limit"
            resourceFieldRef:
              containerName: busybox
              resource: limits.cpu
              divisor: 1m
          - path: "cpu_request"
            resourceFieldRef:
              containerName: busybox
              resource: requests.cpu
              divisor: 1m
          - path: "mem_limit"
            resourceFieldRef:
              containerName: busybox
              resource: limits.memory
              divisor: 1Mi
          - path: "mem_request"
            resourceFieldRef:
              containerName: busybox
              resource: requests.memory
              divisor: 1Mi


我们创建此Pod,并通过kubectl logs查看输出:


$ sudo kubectl apply -f busy_pod.yaml
pod/busybox-pod created
$ sudo kubectl logs busybox-pod
cluster="demo-cluster"
type="tool-pod"
builder="alalazy"
kubectl.kubernetes.io/last-applied-configuration="{\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"annotations\":{\"builder\":\"alalazy\"},\"labels\":{\"cluster\":\"demo-cluster\",\"type\":\"tool-pod\"},\"name\":\"busybox-pod\",\"namespace\":\"default\"},\"spec\":{\"containers\":[{\"args\":[\"while true; do if [[ -e /etc/podinfo/labels ]]; then echo -en '\\\\n\\\\n'; cat /etc/podinfo/labels; fi; if [[ -e /etc/podinfo/annotations ]]; then echo -en '\\\\n\\\\n'; cat /etc/podinfo/annotations; fi; if [[ -e /etc/podinfo/cpu_limit ]]; then echo -en '\\\\n\\\\n'; cat /etc/podinfo/cpu_limit; fi; if [[ -e /etc/podinfo/cpu_request ]]; then echo -en '\\\\n\\\\n'; cat /etc/podinfo/cpu_request; fi; if [[ -e /etc/podinfo/mem_limit ]]; then echo -en '\\\\n\\\\n'; cat /etc/podinfo/mem_limit; fi; if [[ -e /etc/podinfo/mem_request ]]; then echo -en '\\\\n\\\\n'; cat /etc/podinfo/mem_request; fi; sleep 5; done;\"],\"command\":[\"/bin/sh\",\"-c\"],\"image\":\"busybox\",\"name\":\"busybox\",\"resources\":{\"limits\":{\"cpu\":\"250m\",\"memory\":\"32Mi\"},\"requests\":{\"cpu\":\"125m\",\"memory\":\"16Mi\"}},\"volumeMounts\":[{\"mountPath\":\"/etc/podinfo\",\"name\":\"podinfo\"}]}],\"volumes\":[{\"downwardAPI\":{\"items\":[{\"fieldRef\":{\"fieldPath\":\"metadata.labels\"},\"path\":\"labels\"},{\"fieldRef\":{\"fieldPath\":\"metadata.annotations\"},\"path\":\"annotations\"},{\"path\":\"cpu_limit\",\"resourceFieldRef\":{\"containerName\":\"busybox\",\"divisor\":\"1m\",\"resource\":\"limits.cpu\"}},{\"path\":\"cpu_request\",\"resourceFieldRef\":{\"containerName\":\"busybox\",\"divisor\":\"1m\",\"resource\":\"requests.cpu\"}},{\"path\":\"mem_limit\",\"resourceFieldRef\":{\"containerName\":\"busybox\",\"divisor\":\"1Mi\",\"resource\":\"limits.memory\"}},{\"path\":\"mem_request\",\"resourceFieldRef\":{\"containerName\":\"busybox\",\"divisor\":\"1Mi\",\"resource\":\"requests.memory\"}}]},\"name\":\"podinfo\"}]}}\n"
kubernetes.io/config.seen="2022-01-15T05:33:53.379386410Z"
kubernetes.io/config.source="api"
250
125
32
16


我们进入容器查看下挂载的文件:


$  sudo kubectl exec -it busybox-pod -- sh
/ # cd /etc/podinfo/
/etc/podinfo # ls
annotations  cpu_limit    cpu_request  labels       mem_limit    mem_request

 

三、Downward API的能力


我们可以通过Downward API向容器注入如下信息:


1)可通过fieldRef获得的信息:


  • metadata.name:Pod 名称


  • metadata.namespace:Pod 名字空间


  • metadata.uid:Pod 的 UID


  • metadata.labels['<KEY>']:Pod标签 <KEY> 的值 (例如, metadata.labels['mylabel'])


  • metadata.annotations['<KEY>']:Pod 的注解 <KEY> 的值(例如, metadata.annotations['myannotation'])


  • metadata.labels:获取所有标签


  • metadata.annotations:获取所有注解


  • status.podIP:节点 IP


  • spec.serviceAccountName:Pod 服务帐号名称, 版本要求v1.4.0-alpha.3


  • spec.nodeName:节点名称, 版本要求 v1.4.0-alpha.3


  • status.hostIP:节点 IP, 版本要求 v1.7.0-alpha.1


2)可通过 resourceFieldRef 获得的信息:


  • 容器的 CPU 约束值


  • 容器的 CPU 请求值


  • 容器的内存约束值


  • 容器的内存请求值


  • 容器的巨页限制值(前提是启用了DownwardAPIHugePages 特性门控


  • 容器的巨页请求值(前提是启用了DownwardAPIHugePages 特性门控


  • 容器的临时存储约束值


  • 容器的临时存储请求值


分类: 容器技术

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
10月前
|
Kubernetes Docker Python
Docker 与 Kubernetes 容器化部署核心技术及企业级应用实践全方案解析
本文详解Docker与Kubernetes容器化技术,涵盖概念原理、环境搭建、镜像构建、应用部署及监控扩展,助你掌握企业级容器化方案,提升应用开发与运维效率。
1288 108
|
9月前
|
Kubernetes Devops Docker
Kubernetes 和 Docker Swarm:现代 DevOps 的理想容器编排工具
本指南深入解析 Kubernetes 与 Docker Swarm 两大主流容器编排工具,涵盖安装、架构、网络、监控等核心维度,助您根据团队能力与业务需求精准选型,把握云原生时代的技术主动权。
783 115
|
9月前
|
缓存 前端开发 Docker
Docker Layer Caching:加速你的容器构建
Docker Layer Caching:加速你的容器构建
|
10月前
|
运维 持续交付 开发者
Docker:重塑现代应用开发的容器革命
Docker:重塑现代应用开发的容器革命
|
8月前
|
监控 Kubernetes 安全
还没搞懂Docker? Docker容器技术实战指南 ! 从入门到企业级应用 !
蒋星熠Jaxonic,技术探索者,以代码为笔,在二进制星河中书写极客诗篇。专注Docker与容器化实践,分享从入门到企业级应用的深度经验,助力开发者乘风破浪,驶向云原生新世界。
792 51
还没搞懂Docker? Docker容器技术实战指南 ! 从入门到企业级应用 !

相关产品

  • 容器服务Kubernetes版