Opensourcetechブログ

OpensourcetechによるNGINX/Kubernetes/Zabbix/Neo4j/Linuxなどオープンソース技術に関するブログです。

Podに環境変数を渡す方法(kubernetes)

LinuCエヴァンジェリスト・Open Source Summit Japanボランティアリーダー鯨井貴博@opensourcetechです。


はじめに
KubernetesのPodへ環境変数を渡す方法に関するメモです。


その1
env/valueで定義する

root@rke2-1:~# kubectl explain pod.spec.containers.env
KIND:       Pod
VERSION:    v1

FIELD: env <[]EnvVar>

DESCRIPTION:
    List of environment variables to set in the container. Cannot be updated.
    EnvVar represents an environment variable present in a Container.
    
FIELDS:
  name  <string> -required-
    Name of the environment variable. Must be a C_IDENTIFIER.

  value <string>
    Variable references $(VAR_NAME) are expanded using the previously defined
    environment variables in the container and any service environment
    variables. If a variable cannot be resolved, the reference in the input
    string will be unchanged. Double $$ are reduced to a single $, which allows
    for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the
    string literal "$(VAR_NAME)". Escaped references will never be expanded,
    regardless of whether the variable exists or not. Defaults to "".

  valueFrom     <EnvVarSource>
    Source for the environment variable's value. Cannot be used if value is not
    empty.


実際にやってみます。

root@rke2-1:~# kubectl run envpod --image=nginx --dry-run=client -o yaml > pod11.yaml 

root@rke2-1:~# vi pod11.yaml 

root@rke2-1:~# cat pod11.yaml 
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: envpod
  name: envpod
spec:
  containers:
  - image: nginx
    name: envpod
    env:
    - name: DEMO1
      value: demo1
    - name: DEMO2
      value: demo2

root@rke2-1:~# kubectl apply -f pod11.yaml 
pod/envpod created

root@rke2-1:~# kubectl get pods envpod
NAME     READY   STATUS    RESTARTS   AGE
envpod   1/1     Running   0          9s


想定通りか確認。

root@rke2-1:~# kubectl describe pod envpod
Name:             envpod
Namespace:        default
Priority:         0
Service Account:  default
Node:             rke2-2/192.168.1.64
Start Time:       Wed, 24 Jan 2024 07:36:09 +0000
Labels:           run=envpod
Annotations:      cni.projectcalico.org/containerID: 50527aad0034b87e5d70670e3a131a234d17d915234de5b73443975cb1329bac
                  cni.projectcalico.org/podIP: 10.42.1.20/32
                  cni.projectcalico.org/podIPs: 10.42.1.20/32
Status:           Running
IP:               10.42.1.20
IPs:
  IP:  10.42.1.20
Containers:
  envpod:
    Container ID:   containerd://772384c6acc81dfa6e54bcd96a1cb17cb47e251175217b49ff59a170e519c52d
    Image:          nginx
    Image ID:       docker.io/library/nginx@sha256:4c0fdaa8b6341bfdeca5f18f7837462c80cff90527ee35ef185571e1c327beac
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Wed, 24 Jan 2024 07:36:12 +0000
    Ready:          True
    Restart Count:  0
    Environment:
      DEMO1:  demo1
      DEMO2:  demo2
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-jcv22 (ro)
Conditions:
  Type                        Status
  PodReadyToStartContainers   True 
  Initialized                 True 
  Ready                       True 
  ContainersReady             True 
  PodScheduled                True 
Volumes:
  kube-api-access-jcv22:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  18s   default-scheduler  Successfully assigned default/envpod to rke2-2
  Normal  Pulling    17s   kubelet            Pulling image "nginx"
  Normal  Pulled     15s   kubelet            Successfully pulled image "nginx" in 1.903s (1.903s including waiting)
  Normal  Created    15s   kubelet            Created container envpod
  Normal  Started    15s   kubelet            Started container envpod

root@rke2-1:~# kubectl exec -it envpod -- sh -c /bin/bash

root@envpod:/# echo $DEMO1
demo1

root@envpod:/# echo $DEMO2
demo2

root@envpod:/# env | grep DEMO
DEMO1=demo1
DEMO2=demo2

root@envpod:/# exit
exit



その2
ConfigMapで定義して、環境変数全体をenvFromで渡す

root@rke2-1:~# kubectl explain pod.spec.containers.envFrom
KIND:       Pod
VERSION:    v1

FIELD: envFrom <[]EnvFromSource>

DESCRIPTION:
    List of sources to populate environment variables in the container. The keys
    defined within a source must be a C_IDENTIFIER. All invalid keys will be
    reported as an event when the container is starting. When a key exists in
    multiple sources, the value associated with the last source will take
    precedence. Values defined by an Env with a duplicate key will take
    precedence. Cannot be updated.
    EnvFromSource represents the source of a set of ConfigMaps
    
FIELDS:
  configMapRef  <ConfigMapEnvSource>
    The ConfigMap to select from

  prefix        <string>
    An optional identifier to prepend to each key in the ConfigMap. Must be a
    C_IDENTIFIER.

  secretRef     <SecretEnvSource>
    The Secret to select from


root@rke2-1:~# kubectl explain pod.spec.containers.envFrom.configMapRef
KIND:       Pod
VERSION:    v1

FIELD: configMapRef <ConfigMapEnvSource>

DESCRIPTION:
    The ConfigMap to select from
    ConfigMapEnvSource selects a ConfigMap to populate the environment variables
    with.
    
    The contents of the target ConfigMap's Data field will represent the
    key-value pairs as environment variables.
    
FIELDS:
  name  <string>
    Name of the referent. More info:
    https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

  optional      <boolean>
    Specify whether the ConfigMap must be defined


ConfigMapの作成。

root@rke2-1:~# kubectl create configmap test-cm --from-literal=DEMO1=demo1 --from-literal=DEMO2=demo2
configmap/test-cm created

root@rke2-1:~# kubectl get cm
NAME               DATA   AGE
kube-root-ca.crt   1      2d1h
test-cm            2      5s

root@rke2-1:~# kubectl describe cm test-cm
Name:         test-cm
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
DEMO1:
----
demo1
DEMO2:
----
demo2

BinaryData
====

Events:  <none>


root@rke2-1:~# vi pod12.yaml 

root@rke2-1:~# cat pod12.yaml 
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: envpod2
  name: envpod2
spec:
  containers:
  - image: nginx
    name: envpod2
    envFrom:
    - configMapRef:
        name: test-cm

root@rke2-1:~# kubectl apply -f pod12.yaml 
pod/envpod2 created

root@rke2-1:~# kubectl get pod
NAME      READY   STATUS    RESTARTS      AGE
envpod2   1/1     Running   0             4s


確認。

root@rke2-1:~# kubectl describe pods envpod2
Name:             envpod2
Namespace:        default
Priority:         0
Service Account:  default
Node:             rke2-2/192.168.1.64
Start Time:       Wed, 24 Jan 2024 08:23:26 +0000
Labels:           run=envpod2
Annotations:      cni.projectcalico.org/containerID: eabe3c1829d59192d9b9604ea2273edc18758d303dba06d3f720ebb0e84e4f11
                  cni.projectcalico.org/podIP: 10.42.1.21/32
                  cni.projectcalico.org/podIPs: 10.42.1.21/32
Status:           Running
IP:               10.42.1.21
IPs:
  IP:  10.42.1.21
Containers:
  envpod2:
    Container ID:   containerd://1c80629d399d7a68559665648d520e22296d470bd83a4622b4fe4289db4b5d11
    Image:          nginx
    Image ID:       docker.io/library/nginx@sha256:4c0fdaa8b6341bfdeca5f18f7837462c80cff90527ee35ef185571e1c327beac
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Wed, 24 Jan 2024 08:23:29 +0000
    Ready:          True
    Restart Count:  0
    Environment Variables from:
      test-cm     ConfigMap  Optional: false
    Environment:  <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-6tvf2 (ro)
Conditions:
  Type                        Status
  PodReadyToStartContainers   True 
  Initialized                 True 
  Ready                       True 
  ContainersReady             True 
  PodScheduled                True 
Volumes:
  kube-api-access-6tvf2:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  5m57s  default-scheduler  Successfully assigned default/envpod2 to rke2-2
  Normal  Pulling    5m56s  kubelet            Pulling image "nginx"
  Normal  Pulled     5m55s  kubelet            Successfully pulled image "nginx" in 1.505s (1.505s including waiting)
  Normal  Created    5m54s  kubelet            Created container envpod2
  Normal  Started    5m54s  kubelet            Started container envpod2

root@rke2-1:~# kubectl exec -it envpod2 -- sh -c /bin/bash

root@envpod2:/# echo $DEMO1
demo1

root@envpod2:/# echo $DEMO2
demo2

root@envpod2:/# env | grep DEMO
DEMO1=demo1
DEMO2=demo2

root@envpod2:/# exit
exit



その3
ConfigMapで定義して、1部の環境変数だけをenv/valueFrom/configMapKeyRefで渡す

root@rke2-1:~# kubectl explain pod.spec.containers.env.valueFrom
KIND:       Pod
VERSION:    v1

FIELD: valueFrom <EnvVarSource>

DESCRIPTION:
    Source for the environment variable's value. Cannot be used if value is not
    empty.
    EnvVarSource represents a source for the value of an EnvVar.
    
FIELDS:
  configMapKeyRef       <ConfigMapKeySelector>
    Selects a key of a ConfigMap.

  fieldRef      <ObjectFieldSelector>
    Selects a field of the pod: supports metadata.name, metadata.namespace,
    `metadata.labels['<KEY>']`, `metadata.annotations['<KEY>']`, spec.nodeName,
    spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.

  resourceFieldRef      <ResourceFieldSelector>
    Selects a resource of the container: only resources limits and requests
    (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu,
    requests.memory and requests.ephemeral-storage) are currently supported.

  secretKeyRef  <SecretKeySelector>
    Selects a key of a secret in the pod's namespace


root@rke2-1:~# kubectl explain pod.spec.containers.env.valueFrom.configMapKeyRef
KIND:       Pod
VERSION:    v1

FIELD: configMapKeyRef <ConfigMapKeySelector>

DESCRIPTION:
    Selects a key of a ConfigMap.
    Selects a key from a ConfigMap.
    
FIELDS:
  key   <string> -required-
    The key to select.

  name  <string>
    Name of the referent. More info:
    https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

  optional      <boolean>
    Specify whether the ConfigMap or its key must be defined


root@rke2-1:~# vi pod13.yaml 

root@rke2-1:~# cat pod13.yaml 
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: envpod3
  name: envpod3
spec:
  containers:
  - image: nginx
    name: envpod3
    env:
      - name: DEMO1A
        valueFrom:
          configMapKeyRef:
            name: test-cm
            key: DEMO1

root@rke2-1:~# kubectl apply -f pod13.yaml 
pod/envpod3 created

root@rke2-1:~# kubectl get pods
NAME      READY   STATUS    RESTARTS      AGE
envpod3   1/1     Running   0             7s


確認。

root@rke2-1:~# kubectl descrobe pod envpod3
error: unknown command "descrobe" for "kubectl"

Did you mean this?
        describe
root@rke2-1:~# kubectl describe pod envpod3
Name:             envpod3
Namespace:        default
Priority:         0
Service Account:  default
Node:             rke2-2/192.168.1.64
Start Time:       Wed, 24 Jan 2024 08:38:29 +0000
Labels:           run=envpod3
Annotations:      cni.projectcalico.org/containerID: c56a636d10a767b68e57868b198b16db2683b93a8cafcd60aa604a4ecfc697a6
                  cni.projectcalico.org/podIP: 10.42.1.22/32
                  cni.projectcalico.org/podIPs: 10.42.1.22/32
Status:           Running
IP:               10.42.1.22
IPs:
  IP:  10.42.1.22
Containers:
  envpod3:
    Container ID:   containerd://ad88f1bc309e5ea19a0b5f42f241732636ffa7fbdfa79c57edb32f89849aa2dc
    Image:          nginx
    Image ID:       docker.io/library/nginx@sha256:4c0fdaa8b6341bfdeca5f18f7837462c80cff90527ee35ef185571e1c327beac
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Wed, 24 Jan 2024 08:38:31 +0000
    Ready:          True
    Restart Count:  0
    Environment:
      DEMO1A:  <set to the key 'DEMO1' of config map 'test-cm'>  Optional: false
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-7ddkr (ro)
Conditions:
  Type                        Status
  PodReadyToStartContainers   True 
  Initialized                 True 
  Ready                       True 
  ContainersReady             True 
  PodScheduled                True 
Volumes:
  kube-api-access-7ddkr:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  55s   default-scheduler  Successfully assigned default/envpod3 to rke2-2
  Normal  Pulling    54s   kubelet            Pulling image "nginx"
  Normal  Pulled     53s   kubelet            Successfully pulled image "nginx" in 1.404s (1.404s including waiting)
  Normal  Created    53s   kubelet            Created container envpod3
  Normal  Started    53s   kubelet            Started container envpod3
 
root@rke2-1:~# kubectl exec -it envpod3 -- sh -c /bin/bash

root@envpod3:/# echo $DEMO1A
demo1

root@envpod3:/# env | grep DEMO
DEMO1A=demo1

root@envpod3:/# exit
exit



その4
ConfigMapをVolumeとして定義し、1部の環境変数だけを指定ファイルに格納する

root@rke2-1:~# kubectl explain pod.spec.containers.volumeMounts
KIND:       Pod
VERSION:    v1

FIELD: volumeMounts <[]VolumeMount>

DESCRIPTION:
    Pod volumes to mount into the container's filesystem. Cannot be updated.
    VolumeMount describes a mounting of a Volume within a container.
    
FIELDS:
  mountPath     <string> -required-
    Path within the container at which the volume should be mounted.  Must not
    contain ':'.

  mountPropagation      <string>
    mountPropagation determines how mounts are propagated from the host to
    container and the other way around. When not set, MountPropagationNone is
    used. This field is beta in 1.10.
    
    Possible enum values:
     - `"Bidirectional"` means that the volume in a container will receive new
    mounts from the host or other containers, and its own mounts will be
    propagated from the container to the host or other containers. Note that
    this mode is recursively applied to all mounts in the volume ("rshared" in
    Linux terminology).
     - `"HostToContainer"` means that the volume in a container will receive new
    mounts from the host or other containers, but filesystems mounted inside the
    container won't be propagated to the host or other containers. Note that
    this mode is recursively applied to all mounts in the volume ("rslave" in
    Linux terminology).
     - `"None"` means that the volume in a container will not receive new mounts
    from the host or other containers, and filesystems mounted inside the
    container won't be propagated to the host or other containers. Note that
    this mode corresponds to "private" in Linux terminology.

  name  <string> -required-
    This must match the Name of a Volume.

  readOnly      <boolean>
    Mounted read-only if true, read-write otherwise (false or unspecified).
    Defaults to false.

  subPath       <string>
    Path within the volume from which the container's volume should be mounted.
    Defaults to "" (volume's root).

  subPathExpr   <string>
    Expanded path within the volume from which the container's volume should be
    mounted. Behaves similarly to SubPath but environment variable references
    $(VAR_NAME) are expanded using the container's environment. Defaults to ""
    (volume's root). SubPathExpr and SubPath are mutually exclusive.

root@rke2-1:~# kubectl explain pod.spec.volumes
KIND:       Pod
VERSION:    v1

FIELD: volumes <[]Volume>

DESCRIPTION:
    List of volumes that can be mounted by containers belonging to the pod. More
    info: https://kubernetes.io/docs/concepts/storage/volumes
    Volume represents a named volume in a pod that may be accessed by any
    container in the pod.
    
FIELDS:
  awsElasticBlockStore  <AWSElasticBlockStoreVolumeSource>
    awsElasticBlockStore represents an AWS Disk resource that is attached to a
    kubelet's host machine and then exposed to the pod. More info:
    https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore

  azureDisk     <AzureDiskVolumeSource>
    azureDisk represents an Azure Data Disk mount on the host and bind mount to
    the pod.

  azureFile     <AzureFileVolumeSource>
    azureFile represents an Azure File Service mount on the host and bind mount
    to the pod.

  cephfs        <CephFSVolumeSource>
    cephFS represents a Ceph FS mount on the host that shares a pod's lifetime

  cinder        <CinderVolumeSource>
    cinder represents a cinder volume attached and mounted on kubelets host
    machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md

  configMap     <ConfigMapVolumeSource>
    configMap represents a configMap that should populate this volume

  csi   <CSIVolumeSource>
    csi (Container Storage Interface) represents ephemeral storage that is
    handled by certain external CSI drivers (Beta feature).

  downwardAPI   <DownwardAPIVolumeSource>
    downwardAPI represents downward API about the pod that should populate this
    volume

  emptyDir      <EmptyDirVolumeSource>
    emptyDir represents a temporary directory that shares a pod's lifetime. More
    info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir

  ephemeral     <EphemeralVolumeSource>
    ephemeral represents a volume that is handled by a cluster storage driver.
    The volume's lifecycle is tied to the pod that defines it - it will be
    created before the pod starts, and deleted when the pod is removed.
    
    Use this if: a) the volume is only needed while the pod runs, b) features of
    normal volumes like restoring from snapshot or capacity
       tracking are needed,
    c) the storage driver is specified through a storage class, and d) the
    storage driver supports dynamic volume provisioning through
       a PersistentVolumeClaim (see EphemeralVolumeSource for more
       information on the connection between this volume type
       and PersistentVolumeClaim).
    
    Use PersistentVolumeClaim or one of the vendor-specific APIs for volumes
    that persist for longer than the lifecycle of an individual pod.
    
    Use CSI for light-weight local ephemeral volumes if the CSI driver is meant
    to be used that way - see the documentation of the driver for more
    information.
    
    A pod can use both types of ephemeral volumes and persistent volumes at the
    same time.

  fc    <FCVolumeSource>
    fc represents a Fibre Channel resource that is attached to a kubelet's host
    machine and then exposed to the pod.

  flexVolume    <FlexVolumeSource>
    flexVolume represents a generic volume resource that is provisioned/attached
    using an exec based plugin.

  flocker       <FlockerVolumeSource>
    flocker represents a Flocker volume attached to a kubelet's host machine.
    This depends on the Flocker control service being running

  gcePersistentDisk     <GCEPersistentDiskVolumeSource>
    gcePersistentDisk represents a GCE Disk resource that is attached to a
    kubelet's host machine and then exposed to the pod. More info:
    https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk

  gitRepo       <GitRepoVolumeSource>
    gitRepo represents a git repository at a particular revision. DEPRECATED:
    GitRepo is deprecated. To provision a container with a git repo, mount an
    EmptyDir into an InitContainer that clones the repo using git, then mount
    the EmptyDir into the Pod's container.

  glusterfs     <GlusterfsVolumeSource>
    glusterfs represents a Glusterfs mount on the host that shares a pod's
    lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md

  hostPath      <HostPathVolumeSource>
    hostPath represents a pre-existing file or directory on the host machine
    that is directly exposed to the container. This is generally used for system
    agents or other privileged things that are allowed to see the host machine.
    Most containers will NOT need this. More info:
    https://kubernetes.io/docs/concepts/storage/volumes#hostpath

  iscsi <ISCSIVolumeSource>
    iscsi represents an ISCSI Disk resource that is attached to a kubelet's host
    machine and then exposed to the pod. More info:
    https://examples.k8s.io/volumes/iscsi/README.md

  name  <string> -required-
    name of the volume. Must be a DNS_LABEL and unique within the pod. More
    info:
    https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

  nfs   <NFSVolumeSource>
    nfs represents an NFS mount on the host that shares a pod's lifetime More
    info: https://kubernetes.io/docs/concepts/storage/volumes#nfs

  persistentVolumeClaim <PersistentVolumeClaimVolumeSource>
    persistentVolumeClaimVolumeSource represents a reference to a
    PersistentVolumeClaim in the same namespace. More info:
    https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims

  photonPersistentDisk  <PhotonPersistentDiskVolumeSource>
    photonPersistentDisk represents a PhotonController persistent disk attached
    and mounted on kubelets host machine

  portworxVolume        <PortworxVolumeSource>
    portworxVolume represents a portworx volume attached and mounted on kubelets
    host machine

  projected     <ProjectedVolumeSource>
    projected items for all in one resources secrets, configmaps, and downward
    API

  quobyte       <QuobyteVolumeSource>
    quobyte represents a Quobyte mount on the host that shares a pod's lifetime

  rbd   <RBDVolumeSource>
    rbd represents a Rados Block Device mount on the host that shares a pod's
    lifetime. More info: https://examples.k8s.io/volumes/rbd/README.md

  scaleIO       <ScaleIOVolumeSource>
    scaleIO represents a ScaleIO persistent volume attached and mounted on
    Kubernetes nodes.

  secret        <SecretVolumeSource>
    secret represents a secret that should populate this volume. More info:
    https://kubernetes.io/docs/concepts/storage/volumes#secret

  storageos     <StorageOSVolumeSource>
    storageOS represents a StorageOS volume attached and mounted on Kubernetes
    nodes.

  vsphereVolume <VsphereVirtualDiskVolumeSource>
    vsphereVolume represents a vSphere volume attached and mounted on kubelets
    host machine

root@rke2-1:~# kubectl explain pod.spec.volumes.configMap
KIND:       Pod
VERSION:    v1

FIELD: configMap <ConfigMapVolumeSource>

DESCRIPTION:
    configMap represents a configMap that should populate this volume
    Adapts a ConfigMap into a volume.
    
    The contents of the target ConfigMap's Data field will be presented in a
    volume as files using the keys in the Data field as the file names, unless
    the items element is populated with specific mappings of keys to paths.
    ConfigMap volumes support ownership management and SELinux relabeling.
    
FIELDS:
  defaultMode   <integer>
    defaultMode is optional: mode bits used to set permissions on created files
    by default. Must be an octal value between 0000 and 0777 or a decimal value
    between 0 and 511. YAML accepts both octal and decimal values, JSON requires
    decimal values for mode bits. Defaults to 0644. Directories within the path
    are not affected by this setting. This might be in conflict with other
    options that affect the file mode, like fsGroup, and the result can be other
    mode bits set.

  items <[]KeyToPath>
    items if unspecified, each key-value pair in the Data field of the
    referenced ConfigMap will be projected into the volume as a file whose name
    is the key and content is the value. If specified, the listed keys will be
    projected into the specified paths, and unlisted keys will not be present.
    If a key is specified which is not present in the ConfigMap, the volume
    setup will error unless it is marked optional. Paths must be relative and
    may not contain the '..' path or start with '..'.

  name  <string>
    Name of the referent. More info:
    https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

  optional      <boolean>
    optional specify whether the ConfigMap or its keys must be defined

root@rke2-1:~# kubectl explain pod.spec.volumes.configMap.items
KIND:       Pod
VERSION:    v1

FIELD: items <[]KeyToPath>

DESCRIPTION:
    items if unspecified, each key-value pair in the Data field of the
    referenced ConfigMap will be projected into the volume as a file whose name
    is the key and content is the value. If specified, the listed keys will be
    projected into the specified paths, and unlisted keys will not be present.
    If a key is specified which is not present in the ConfigMap, the volume
    setup will error unless it is marked optional. Paths must be relative and
    may not contain the '..' path or start with '..'.
    Maps a string key to a path within a volume.
    
FIELDS:
  key   <string> -required-
    key is the key to project.

  mode  <integer>
    mode is Optional: mode bits used to set permissions on this file. Must be an
    octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML
    accepts both octal and decimal values, JSON requires decimal values for mode
    bits. If not specified, the volume defaultMode will be used. This might be
    in conflict with other options that affect the file mode, like fsGroup, and
    the result can be other mode bits set.

  path  <string> -required-
    path is the relative path of the file to map the key to. May not be an
    absolute path. May not contain the path element '..'. May not start with the
    string '..'.


root@rke2-1:~# vi pod14.yaml 

root@rke2-1:~# cat pod14.yaml 
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: envpod4
  name: envpod4
spec:
  containers:
  - image: nginx
    name: envpod4
    volumeMounts:
      - name: config-volume
        mountPath: /tmp/cm
  volumes:
    - name: config-volume
      configMap:
        name: test-cm
        items:
        - key: DEMO1
          path: demo1

root@rke2-1:~# kubectl apply -f pod14.yaml 
pod/envpod4 created

root@rke2-1:~# kubectl get pods
NAME      READY   STATUS    RESTARTS       AGE
envpod4   1/1     Running   0              4s

確認。

root@rke2-1:~# kubectl describe pods envpod4
Name:             envpod4
Namespace:        default
Priority:         0
Service Account:  default
Node:             rke2-2/192.168.1.64
Start Time:       Wed, 24 Jan 2024 08:55:14 +0000
Labels:           run=envpod4
Annotations:      cni.projectcalico.org/containerID: c9e471ed5e6ad7b8e29e397fda07a0dc46861b4e4b3f936d49caace1ed81ebff
                  cni.projectcalico.org/podIP: 10.42.1.23/32
                  cni.projectcalico.org/podIPs: 10.42.1.23/32
Status:           Running
IP:               10.42.1.23
IPs:
  IP:  10.42.1.23
Containers:
  envpod4:
    Container ID:   containerd://750b336e798b66122807f127f755fb280273a07780d0211ef3e9368f55ddb232
    Image:          nginx
    Image ID:       docker.io/library/nginx@sha256:4c0fdaa8b6341bfdeca5f18f7837462c80cff90527ee35ef185571e1c327beac
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Wed, 24 Jan 2024 08:55:17 +0000
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /tmp/cm from config-volume (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-jk29d (ro)
Conditions:
  Type                        Status
  PodReadyToStartContainers   True 
  Initialized                 True 
  Ready                       True 
  ContainersReady             True 
  PodScheduled                True 
Volumes:
  config-volume:
    Type:      ConfigMap (a volume populated by a ConfigMap)
    Name:      test-cm
    Optional:  false
  kube-api-access-jk29d:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  41s   default-scheduler  Successfully assigned default/envpod4 to rke2-2
  Normal  Pulling    40s   kubelet            Pulling image "nginx"
  Normal  Pulled     38s   kubelet            Successfully pulled image "nginx" in 1.391s (1.391s including waiting)
  Normal  Created    38s   kubelet            Created container envpod4
  Normal  Started    38s   kubelet            Started container envpod4

root@rke2-1:~# kubectl exec -it envpod4 -- sh -c /bin/bash

root@envpod4:/# ls /tmp/cm/
demo1

root@envpod4:/# cat /tmp/cm/demo1 
demo1

root@envpod4:/# exit
exit



おわりに
今回、"Podに環境変数を渡す"が複数あることが分かりました。
使い分けとしては、 おそらく以下のようになるのかなと感じました。

  • 単体のPodを起動するだけ:その1(env/valueで定義する)
  • 同じ環境変数を複数のPodで利用する:その2~4



参照サイト
Define Environment Variables for a Container
Configure a Pod to Use a ConfigMap

Opensourcetech by Takahiro Kujirai