美文网首页
Kubernetes in Action 笔记 —— 使用 Co

Kubernetes in Action 笔记 —— 使用 Co

作者: rollingstarky | 来源:发表于2022-01-15 19:41 被阅读0次

    设置命令、参数和环境变量

    同普通的应用一样,容器化应用也可以通过命令行参数、环境变量、文件等完成配置。
    比如容器启动时执行的命令可以由 Dockerfile 中的 ENTRYPOINT 选项指定;命令参数通常由 CMD 选项指定;环境变量则可以使用 ENV 选项指定;假如应用通过文件进行配置,则这些配置文件可以借助 COPY 选项复制到容器镜像中。

    下面是一个名为 kiada 的示例应用。
    Dockerfile 配置文件:

    FROM node:12
    COPY app.js /app.js
    COPY html /html
    
    ENV INITIAL_STATUS_MESSAGE="This is the default status message"
    
    ENTRYPOINT ["node", "app.js"]
    CMD ["--listen-port", "8080"]
    

    其他文件如 htmlapp.js 可以从作者的 Github 处获取。同时构建好的镜像也被作者放到了 Dockerhub 的 luksa/kiada:0.4 位置。

    借助上述 Dockerfile,应用的监听端口可以通过 --listen-port 命令参数配置;同时应用会读取环境变量 INITIAL_STATUS_MESSAGE 来获取初始状态信息。

    将配置硬编码进容器的镜像,事实上和将配置硬编码到应用的源代码中一样,都不是理想的情况。因为每当应用需要修改配置,都必须再重新 build 一遍镜像。此外,还必须避免在镜像中包含敏感的配置信息,比如认证数据或密钥等。
    将上述配置文件放置在 Volume 中并挂载到容器上,相对而言更安全一点。

    配置命令和参数

    在创建镜像时,容器启动时执行的命令和参数分别由 Dockerfile 中的 ENTRYPOINTCMD 选项指定。
    Kubernetes 提供了两个同样功能的字段:commandsargs。假如在 Pod 的清单文件中指定了 commandsargs,或者其中任何一个字段,则 Dockerfile 中对应的 ENTRYPOINTCMD 配置会被覆盖。

    设置命令
    假如需要在运行 Kiada 应用时启用 CPU 和 heap 优化,对于 Node.js 而言,可以在执行时传入 --cpu-prof--heap-prof 参数。
    相对于修改 Dockerfile 重新 build 镜像,其实可以直接修改 Pod 的清单文件。

    apiVersion: v1
    kind: Pod
    spec:
      containers:
      - name: kiada
        image: luksa/kiada:0.4
        command:
        - node
        - --cpu-prof
        - --heap-prof
        - app.js
        ports:
        - name: http
          containerPort: 8080
    

    设置命令参数
    比如需要将 Dockerfile 中的命令参数 --listen-port 8080 改为 --listen-port 9090,可以使用如下配置的 Pod 清单文件:

    apiVersion: v1
    kind: Pod
    metadata:
      name: kiada
    spec:
      containers:
      - name: kiada
        image: luksa/kiada
        args:
        - --listen-port
        - "9090"
        ports:
        - containerPort: 9090
          name: http
    

    容器在创建时会自动组合 Dockerfile 中的 ENTRYPOINT 和 Pod 清单文件中的 args

    设置环境变量

    为环境变量设置字面量值
    Kiada 应用在运行时会显示 Pod 的名字,该名称由应用源代码从环境变量 POD_NAME 读取。此外还可以通过修改环境变量 INITIAL_STATUS_MESSAGE 来更改状态信息。

    为了修改上述环境变量,可以向 Dockerfile 中添加 ENV 选项并重新构建镜像,但更快速的方式时向 Pod 的清单文件中添加 env 选项。
    示例清单文件如下:

    apiVersion: v1
    kind: Pod
    metadata:
      name: kiada
    spec:
      containers:
        - name: kiada
          image: luksa/kiada:0.4
          env:
          - name: POD_NAME
            value: kiada
          - name: INITIAL_STATUS_MESSAGE
            value: This status message is set in the pod spec.
          ports:
          - name: http
            containerPort: 8080
    

    应用上述 Pod 清单文件并查看效果:

    $ kubectl apply -f kiada-env.yml
    pod/kiada unchanged
    $ kubectl exec kiada -- env
    PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    HOSTNAME=kiada
    POD_NAME=kiada
    INITIAL_STATUS_MESSAGE=This status message is set in the pod spec.
    KUBERNETES_SERVICE_PORT=443
    KUBERNETES_SERVICE_PORT_HTTPS=443
    KUBERNETES_PORT=tcp://10.96.0.1:443
    KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
    KUBERNETES_PORT_443_TCP_PROTO=tcp
    KUBERNETES_PORT_443_TCP_PORT=443
    KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
    KUBERNETES_SERVICE_HOST=10.96.0.1
    NODE_VERSION=16.11.1
    YARN_VERSION=1.22.15
    HOME=/root
    

    使用变量引用
    除了给环境变量设置一个固定值外,还可以采用 $(VAR_NAME) 格式引用其他变量。如:

    apiVersion: v1
    kind: Pod
    metadata:
      name: kiada
    spec:
      containers:
      - name: kiada
        image: luksa/kiada:0.4
        env:
        - name: POD_NAME
          value: kiada
        - name: INITIAL_STATUS_MESSAGE
          value: My name is $(POD_NAME). I run NodeJS version $(NODE_VERSION).
        ports:
        - name: http
          containerPort: 8080
    

    引用的变量中,POD_NAME 是在同一个 Pod 清单文件中定义的,NODE_VERSION 是在容器镜像中定义的。
    最终的状态信息会显示为 My name is kiada. I run NodeJS version $(NODE_VERSION).,因为此方式只支持引用同一个 Pod 清单文件中定义的变量,且该变量必须在引用位置之前定义。

    在命令和参数中使用变量引用
    还可以在命令和参数中引用清单文件中定义的变量。

    apiVersion: v1
    kind: Pod
    metadata:
      name: kiada
    spec:
      containers:
      - name: kiada
        image: luksa/kiada:0.4
        args:
        - --listen-port
        - $(LISTEN_PORT)
        env:
        - name: LISTEN_PORT
          value: "9090"
        ports:
        - name: http
          containerPort: 9090
    

    使用 config map 将配置与 Pod 解耦

    在前面的章节中,可以将应用的配置硬编码进 Pod 的 yaml 清单文件中。这种方式比将配置硬编码到容器镜像中要好很多,即不需要每次修改配置后都必须重新构建镜像。
    但这种方式也有一定的缺陷,它意味着比如针对不同环境的部署(development、staging、production 等),可能需要多个不同版本的清单文件。
    为了在多个环境下重复利用同一个清单文件,最好是将配置与 Pod 的清单文件解耦。

    ConfigMaps 介绍

    ConfigMap 是一种包含一系列键值对的 Kubernetes API 对象。其中的值可以是短字符串,也可以是一大段结构化的文本。Pod 可以引用一个或多个 ConfigMap 中的值。
    一个 Pod 可以引用多个 ConfigMaps,多个 Pods 可以使用同一个 ConfigMap。

    如下图所示,ConfigMap 中的键值对通常作为环境变量传递给 Pod,或者通过 ConfigMap Volume 作为文件挂载到容器的文件系统中。


    Pods use config maps through environment variables and configMap volumes

    将配置保存在一个独立的 ConfigMap 对象中,而不是直接保存在 Pod 里。这使得在不同的环境中能够部署同一个 Pod 清单文件,与此同时应用不同的配置(引用不同的 ConfigMap 对象)。


    Deploying the same pod manifest and different config map manifests in different environments
    创建 ConfigMap 对象

    从 YAML 文件创建 ConfigMap
    cm.kiada-config.yml

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: kiada-config
    data:
      status-message: This status message is set in the kiada-config config map
    

    运行 kubectl apply -f cm.kiada-config.yml 命令创建清单文件中定义的 ConfigMap 对象。

    查看 ConfigMap
    可以使用 kubectl get cm 命令列出 ConfigMap 对象:

    $ kubectl get cm
    NAME               DATA   AGE
    kiada-config       1      6s
    kube-root-ca.crt   1      55d
    

    可以使用如下命令查看 ConfigMap 的详细信息:

    $ kubectl get cm kiada-config -o yaml
    apiVersion: v1
    data:
      status-message: This status message is set in the kiada-config config map
    kind: ConfigMap
    metadata:
      annotations:
        kubectl.kubernetes.io/last-applied-configuration: |
          {"apiVersion":"v1","data":{"status-message":"This status message is set in the kiada-config config map"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"kiada-config","namespace":"default"}}
      creationTimestamp: "2022-01-10T05:11:35Z"
      name: kiada-config
      namespace: default
      resourceVersion: "99447"
      uid: e39e2676-2183-4582-9922-eac963b81093
    

    若只想精确地查找 ConfigMap 中的配置项,可以使用如下命令:

    $ kubectl get cm kiada-config -o json | jq .data
    {
      "status-message": "This status message is set in the kiada-config config map"
    }
    $ kubectl get cm kiada-config -o json | jq '.data["status-message"]'
    "This status message is set in the kiada-config config map"
    
    将 ConfigMap 中的值注入到环境变量

    pod.kiada.env-valueFrom.yml

    apiVersion: v1
    kind: Pod
    metadata:
      name: kiada
    spec:
      containers:
        - name: kiada
          image: luksa/kiada:0.4
          env:
          - name: INITIAL_STATUS_MESSAGE
            valueFrom:
              configMapKeyRef:
                name: kiada-config
                key: status-message
                optional: true
          ports:
            - containerPort: 8080
              name: http
    

    创建 Pod 并查看环境变量:

    $ kubectl apply -f pod.kiada.env-valueFrom.yml
    pod/kiada created
    $ kubectl exec kiada -- env
    PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    HOSTNAME=kiada
    INITIAL_STATUS_MESSAGE=This status message is set in the kiada-config config map
    ...
    

    注入整个 ConfigMap
    容器定义中的 env 字段接收的是由值组成的列表,因此可以同时设置多个环境变量。实际上可以使用 envFrom 注入整个 ConfigMap 中定义的多个值,而无需像 valueFrom 那样分别指定每一个键。
    唯一需要注意的是,ConfigMap 中的键必须与实际的环境变量名称保持一致。即之前使用的键 status-message 必须改成 INITIAL_STATUS_MESSAGE

    cm.kiada-config.yml

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: kiada-config
    data:
      INITIAL_STATUS_MESSAGE: This status message is set in the kiada-config config map
    

    使用 kubectl replace 命令更新 ConfigMap:

    $ kubectl replace -f cm.kiada-config.yml
    configmap/kiada-config replaced
    

    创建 Pod 清单文件 pod.kiada.envFrom.yml

    apiVersion: v1
    kind: Pod
    metadata:
      name: kiada
    spec:
      containers:
      - name: kiada
        image: luksa/kiada:0.4
        envFrom:
        - configMapRef:
            name: kiada-config
            optional: true
        ports:
        - name: http
          containerPort: 8080
    

    应用 Pod 清单文件并查看效果:

    kubectl delete -f pod.kiada.env-valueFrom.yml
    pod "kiada" deleted
    $ kubectl apply -f pod.kiada.envFrom.yml
    pod/kiada created
    $ kubectl exec kiada -- env
    PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    HOSTNAME=kiada
    INITIAL_STATUS_MESSAGE=This status message is set in the kiada-config config map
    ...
    
    将 ConfigMap 中的配置项作为文件嵌入到容器

    环境变量通常用于向应用传递较小的单行的值,而多行的数据通常作为文件传递。
    ConfigMap 中的配置项可以包含大块的数据,通过特殊的 ConfigMap volume 类型将这些数据以文件的形式注入到容器中。

    从文件创建 ConfigMaps
    除了直接在集群中创建 ConfigMap 对象之外,还可以先创建一个用于描述 ConfigMap 的 YAML 清单文件,从而可以将其保存到版本控制系统中。

    $ kubectl create configmap kiada-envoy-config \
    --from-file=envoy.yaml \
    --from-file=dummy.bin \
    --dry-run=client -o yaml > cm.kiada-envoy-config.yml
    

    其中 dummy.bin 和 envoy.yaml 两个文件可以从作者的 Github 下载。
    上述命令会创建一个名为 kiada-envoy-config 的 ConfigMap 的 YAML 描述文件。当命令中使用了 --dry-run 选项时,该命令并不会在 API server 创建新对象,而是只生成对象的定义。后续可继续运行 kubectl apply -f xxx.yml 命令创建对象。

    生成的 cm.kiada-envoy-config.yml 文件的具体内容如下:

    apiVersion: v1
    binaryData:
      dummy.bin: n2VW39IEkyQ6Jxo+rdo5J06Vi7cz5XxZzkPOtN7MOGyXxVzWv07vUz8bxY5h4njJfZixwhPwoGepLnGZdRGw1qgpFB9HpyLsqVZ6jAwjjHD0afxxwEjb6+wofmgGmS1E3U9BZScMPZGWJK7RGzZmQOeJeDPIt/1tBvQYwzMc8wu6owky4Ri3rOY9PlFnp5VOTzvBZadW8scbqtntJeWCtJFoS0AH2y4ZFyJPJ0l0V3JpY1qunnz60CyAMO9v1DgB2PUQUG/1HH89bpzf2OyMvHUJmOTIDZOh3D7aAEuYQ/6hU0uQsQ/K7Xx/nM9TA0RzEzuh8RBoXdkAvQPP5jk7yM2DqxG/CiHVp+7CDRFWgEN2GFd76RfO+pIoOFbD1Xm4yE/JBljOA9ztwm865m3A4l2ToT2p7ZWHKmdZe8pXz4ZwIGBYDUHHNVQW5UUnf0Jbd9UR8GJ//gmbxLfVxjC/lMSWGUqCpYO4YdBPjXQGM1xdxE+YP3Pzso6Z4rw27RJu5KEc2yPMxFY9dpFyVufP81kS19glNiQq+LM4B9EFPrNW1hqi+1Tb8ni+aFkriH1YuvHepIH0Px/ifFLgn+yDgwDs4UfMru2j4t5zAftUa0i6m3sH5adKcx4aCXYN9ijvEvjRmkcB/VJU6Zbd65UZVgD1Nwt2ZCrkoEdqO3Oe1/o=
    data:
      envoy.yaml: |
        admin:
          access_log_path: /tmp/envoy.admin.log
          address:
            socket_address:
              protocol: TCP
              address: 0.0.0.0
              port_value: 9901
    ...
    kind: ConfigMap
    metadata:
      creationTimestamp: null
      name: kiada-envoy-config
    

    在 Pod 中使用 ConfigMap
    为了令 ConfigMap 能够作为文件呈现在容器的文件系统中,需要在 Pod 中定义一个 ConfigMap Volume 并将其挂载到容器里。
    参考下面的 pod.kiada-ssl.configmap-volume.yml

    apiVersion: v1
    kind: Pod
    metadata:
      name: kiada-ssl
    spec:
      volumes:
      - name: envoy-config
        configMap:
          name: kiada-envoy-config
      containers:
      - name: kiada
        image: luksa/kiada:0.4
        ports:
        - name: http
          containerPort: 8080
      - name: envoy
        image: luksa/kiada-ssl-proxy:0.1
        volumeMounts:
        - name: envoy-config
          mountPath: /etc/envoy
          readOnly: true
        ports:
        - name: https
          containerPort: 8443
        - name: admin
          containerPort: 9901
    

    创建 kiada-envoy-config ConfigMap:

    $ kubectl apply -f cm.kiada-envoy-config.yml
    configmap/kiada-envoy-config created
    $ kubectl get cm
    NAME                 DATA   AGE
    kiada-config         1      46h
    kiada-envoy-config   2      13s
    kube-root-ca.crt     1      57d
    

    创建 Pod 并查看文件挂载情况:

    $ kubectl apply -f pod.kiada-ssl.configmap-volume.yml
    pod/kiada-ssl created
    $ kubectl exec kiada-ssl -c envoy -- ls /etc/envoy
    dummy.bin
    envoy.yaml
    
    理解 ConfigMap Volume 是如何工作的

    挂载 Volume 会隐藏文件系统中本来就存在的文件
    当挂载任意 volume 到容器的文件系统中时,挂载的路径下原本存在的文件就无法被访问。比如把某个 ConfigMap volume 挂载到容器的 /etc 路径下,则本来位于 /etc 下面的配置文件都会被隐藏掉。
    如果你还是想将 ConfigMap volume 挂载到 /etc 目录,又不影响原来存在的文件,可以结合使用 mountPathsubPath

    spec:
      containers:
      - name: my-container
        volumeMounts:
        - name: my-volume
          subPath: my-app.conf
          mountPath: /etc/my-app.conf
    
    Using subPath to mount a single file from the volume

    ConfigMap volumes 使用符号链接来实现原子化更新
    有些应用会监控其配置文件的变化来决定是否重新加载配置。但是,假如应用的配置文件很大或者涉及到很多文件,应用可能会在所有更新全部完成之前检查到变化并加载更新。若应用最终读取了未全部更新的文件,可能导致出现不正常的行为。
    为了防止上述情况发生,Kubernetes 会确保 ConfigMap volume 中所有文件的更新操作是原子的,即所有更新都会立即完成。
    上述机制是通过文件的符号链接实现的。

    $ kubectl exec kiada-ssl -c envoy -- ls -lA /etc/envoy
    total 4
    drwxr-xr-x 2 root root 4096 Jan 12 03:33 ..2022_01_12_03_33_58.815959464
    lrwxrwxrwx 1 root root   31 Jan 12 03:33 ..data -> ..2022_01_12_03_33_58.815959464
    lrwxrwxrwx 1 root root   16 Jan 12 03:33 dummy.bin -> ..data/dummy.bin
    lrwxrwxrwx 1 root root   17 Jan 12 03:33 envoy.yaml -> ..data/envoy.yaml
    

    每次用户修改 ConfigMap,Kubernetes 都会新建一个以当前时间戳命名的目录,将新的配置文件放到该目录中。再修改符号链接的指向,立即同时替换所有文件。

    更新和删除 ConfigMaps

    和大多数 Kubernetes API 对象一样,ConfigMaps 也支持手动修改其清单文件,再使用 kubectl apply 命令将最新版本重新应用到集群环境。
    此外还可以使用下面这种更快捷的方式。

    使用 kubectl edit 就地修改 API 对象
    kubectl edit cm kiada-config

    kubectl edit

    上面的命令会使用系统默认的编辑器(比如 Vim)打开 ConfigMap kiada-config 的清单文件,允许用户直接修改该 ConfigMap 对象。当关闭编辑器时,最新的改动会自动应用到 Kubernetes API server。

    修改 ConfigMap 的影响
    当更新某个 ConfigMap 后,若 ConfigMap 是以存储卷的形式作为配置文件挂载到容器中,则其中的文件会自动进行更新。
    但是不同于文件,环境变量在容器运行时不会自动进行更新。然而当容器因为某些特殊原因重启后,Kubernetes 会使用最新版本的 ConfigMap 值来初始化新容器的环境变量。

    容器最重要的属性之一就是其不变性,即用户可以肯定同一个容器的多个实例一定是相同的。
    假如应用通过 ConfigMap 以环境变量的方式注入配置,当 ConfigMap 修改后,实际上并不会影响正在运行的应用实例。但是当应用的某一部分实例因为故障重新启动,或者需要添加新的实例副本,就会导致只有这一部分实例在使用最新的配置。
    类似的场景甚至发生在应用自动重新加载其配置文件的时候。Kubernetes 对于 ConfigMap volumes 采用异步的更新方式,这导致某些实例可能会比其他实例更早地看到配置的变化。上述更新操作有可能会持续几十秒的时间,则在这部分时间内,各应用实例上的配置文件之间实际上是不同步的。
    从而也会导致应用的各个容器实例之间正使用着不同的配置。

    阻止 ConfigMap 被修改

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: my-immutable-configmap
    data:
      mykey: myvalue
      another-key: another-value
    immutable: true
    

    不可变 ConfigMap 可以阻止用户意外地修改应用配置,同时也会提高 Kubernetes 集群的性能。因为工作节点上的 Kubelets 无需再接收 ConfigMap 对象变化的通知。
    假如需要添加一系列使用不同配置的 Pods,就创建一个新的 ConfigMap。

    删除 ConfigMap
    ConfigMap 对象可以使用 kubectl delete 命令删除。删除某个 ConfigMap 后,引用它的正在运行的应用不会受到任何影响,直到容器重新启动。
    若 ConfigMap 没有被标记成可选的,则容器会在重启时失败。

    使用 Secrets 向容器嵌入敏感信息

    Secrets 介绍

    Secrets 和 ConfigMaps 非常相似。它们也是包含一系列键值对且能够作为环境变量或文件注入到容器中。
    事实上 Secrets 比 ConfigMap 更早出现。但是 Secrets 在存储普通的明文文本时友好性较差,因而引入了 ConfigMaps。
    对于 Secrets 对象,Kubernetes 在处理它们时会特别注意安全性。比如 Kubernetes 会确保 Secret 中的数据在分发时只传给有需要的节点;工作节点上的 Secrets 只保存在内存中,从来不会写入到物理存储。
    因此,必须将敏感数据保存到 Secrets 而不是 ConfigMaps 中。

    创建 Secret

    创建一个 TLS secret

    $ kubectl create secret tls kiada-tls --cert example-com.crt --key example-com.key
    secret/kiada-tls created
    

    其中 crt 文件和 key 文件可以从作者的 Github 下载。
    上述命令会创建一个名为 kiada-tls 的 Secret。

    从 YAML 清单文件创建 Secrets
    显而易见,从 YAML 文件创建 Secrets 并不是一个好主意。
    假如你只是需要在本地创建一个 YAML 清单文件而不是直接通过 API server 创建 Secret 对象,可以使用 kubectl create 加上 --dry-run=client -o yaml 选项。

    $ kubectl create secret generic my-credentials \
    --from-literal user=my-username \
    --from-literal pass=my-password \
    --dry-run=client -o yaml
    apiVersion: v1
    data:
      pass: bXktcGFzc3dvcmQ=
      user: bXktdXNlcm5hbWU=
    kind: Secret
    metadata:
      creationTimestamp: null
      name: my-credentials
    

    使用 stringData 字段
    因为并不是所有敏感数据都是二进制形式,Kubernetes 允许用户通过 stringData 字段指定 Secret 中的文本数据。

    apiVersion: v1
    kind: Secret
    stringData:
      user: my-username
      pass: my-password
    metadata:
      creationTimestamp: null
      name: my-credentials
    
    在容器中使用 Secrets

    借助 Secret Volume 注入 Secret 配置
    Secret volume 和前面提到的 ConfigMap volume 用法基本相同。参考如下 YAML 配置文件 pod.kiada-ssl.secret-volume.yml

    apiVersion: v1
    kind: Pod
    metadata:
      name: kiada-ssl
    spec:
      volumes:
      - name: cert-and-key
        secret:
          secretName: kiada-tls
          items:
          - key: tls.crt
            path: example-com.crt
          - key: tls.key
            path: example-com.key
            mode: 0600
      - name: envoy-config
        configMap:
          name: kiada-envoy-config
          items:
          - key: envoy.yaml
            path: envoy.yaml
      containers:
      - name: kiada
        image: luksa/kiada:0.4
        ports:
        - name: http
          containerPort: 8080
      - name: envoy
        image: envoyproxy/envoy:v1.14.1
        volumeMounts:
        - name: cert-and-key
          mountPath: /etc/certs
          readOnly: true
        - name: envoy-config
          mountPath: /etc/envoy
          readOnly: true
        ports:
        - name: https
          containerPort: 8443
        - name: admin
          containerPort: 9901
    
    Secret Volume

    通过 Downward API 向应用传递 Pod 的元数据

    前面介绍了如何向容器中的应用传递配置信息。但数据并不总是静态的,假如某些数据只有在 Pod 创建之后才能被知晓,比如 Pod 的 IP 地址、工作节点的名称、容器分配到的 CPU 和内存等。
    这些需求可以通过 Downward API 实现。

    Downward API 介绍

    Downward API 并不是一个需要应用去访问的 REST 端点,它实际上是一种将 Pod 的 metadata、spec 和 status 字段注入到容器中的方式。


    The Downward API exposes pod metadata through environment variables or files
    Downward API 支持哪些元数据

    用户并不能通过 Downward API 注入 Pod 对象中的所有字段。实际上只有一部分数据被支持,其列表如下。

    通过 fieldRef 字段注入的数据

    Field Description Allowed in env Allowed in volume
    metadata.name Pod 的名称 Yes Yes
    metadata.namespace Pod 的命名空间 Yes Yes
    metadata.uid Pod 的 UID Yes Yes
    metadata.labels Pod 的所有标签 No Yes
    metadata.labels['key'] 某个标签的值 Yes Yes
    metadata.annotations Pod 的所有注释 No Yes
    metadata.annotations['key'] 某个注释的值 Yes Yes
    spec.nodeName Pod 运行的工作节点的名称 Yes No
    spec.serviceAccountName Pod 的服务账户 Yes No
    status.podIP Pod 的 IP 地址 Yes No
    status.hostIP 工作节点的 IP 地址 Yes No

    通过 resourceFieldRef 字段注入的数据

    Resource Field Description Allowed in env Allowed in volume
    requests.cpu 容器的 CPU 请求 Yes Yes
    requests.memory 容器的内存请求 Yes Yes
    requests.ephemeral-storage 容器的临时存储请求 Yes Yes
    limits.cpu 容器的 CPU 限制 Yes Yes
    limits.memory 容器的内存限制 Yes Yes
    limits.ephemeral-storage 容器的临时存储限制 Yes Yes
    将 Pod 的元数据注入到环境变量中

    注入 Pod 对象中的字段
    kiada.yml

    apiVersion: v1
    kind: Pod
    metadata:
      name: kiada
    spec:
      containers:
      - name: kiada
        image: luksa/kiada:0.4
        env:
          - name: POD_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: POD_IP
            valueFrom:
              fieldRef:
                fieldPath: status.podIP
          - name: NODE_NAME
            valueFrom:
              fieldRef:
                fieldPath: spec.nodeName
          - name: NODE_IP
            valueFrom:
              fieldRef:
                fieldPath: status.hostIP
        ports:
        - name: http
          containerPort: 8080
    

    应用 kiada.yml 清单文件并查看其日志输出:

    $ kubectl apply -f kiada.yml
    pod/kiada created
    $ kubectl logs -f kiada
    Kiada - Kubernetes in Action Demo Application
    ---------------------------------------------
    Kiada 0.4 starting...
    Pod name is kiada
    Local hostname is kiada
    Local IP is 172.17.0.6
    Running on node minikube
    Node IP is 192.168.49.2
    Status message is This is the default status message
    Listening on port 8080
    

    注入容器的资源数据
    示例配置如下:

    env:
      - name: MAX_CPU_CORES
        valueFrom:
          resourceFieldRef:
            resource: limits.cpu
      - name: MAX_MEMORY_KB
        valueFrom:
          resourceFieldRef:
            resource: limits.memory
            divisor: 1k
    

    参考资料

    Kubernetes in Action, Second Edition

    相关文章

      网友评论

          本文标题:Kubernetes in Action 笔记 —— 使用 Co

          本文链接:https://www.haomeiwen.com/subject/tdrjcrtx.html