【问题标题】:Why Aren't My Environment Variables Set in Kubernetes Pods From ConfigMap?为什么我的环境变量没有通过 ConfigMap 在 Kubernetes Pod 中设置?
【发布时间】:2021-09-21 11:30:36
【问题描述】:

我有以下 configmap 规范:

apiVersion: v1
data:
  MY_NON_SECRET: foo
  MY_OTHER_NON_SECRET: bar
kind: ConfigMap
metadata:
  name: web-configmap
  namespace: default
$ kubectl describe configmap web-configmap
Name:         web-configmap
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
MY_NON_SECRET:
----
foo
MY_OTHER_NON_SECRET:
----
bar
Events:  <none>

以及以下 pod 规格:

apiVersion: v1
kind: Pod
metadata:
  name: web-pod
spec:
  containers:
    - name: web
      image: kahunacohen/hello-kube:latest
      envFrom:
        - configMapRef:
            name: web-configmap
      ports:
      - containerPort: 3000
$ kubectl describe pod web-deployment-5bb9d846b6-8k2s9
Name:         web-deployment-5bb9d846b6-8k2s9
Namespace:    default
Priority:     0
Node:         minikube/192.168.49.2
Start Time:   Mon, 12 Jul 2021 12:22:24 +0300
Labels:       app=web-pod
              pod-template-hash=5bb9d846b6
              service=web-service
Annotations:  <none>
Status:       Running
IP:           172.17.0.5
IPs:
  IP:           172.17.0.5
Controlled By:  ReplicaSet/web-deployment-5bb9d846b6
Containers:
  web:
    Container ID:   docker://8de5472c9605e5764276c345865ec52f9ec032e01ed58bc9a02de525af788acf
    Image:          kahunacohen/hello-kube:latest
    Image ID:       docker-pullable://kahunacohen/hello-kube@sha256:930dc2ca802bff72ee39604533342ef55e24a34b4a42b9074e885f18789ea736
    Port:           3000/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Mon, 12 Jul 2021 12:22:27 +0300
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-tcqwz (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  kube-api-access-tcqwz:
    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  19m   default-scheduler  Successfully assigned default/web-deployment-5bb9d846b6-8k2s9 to minikube
  Normal  Pulling    19m   kubelet            Pulling image "kahunacohen/hello-kube:latest"
  Normal  Pulled     19m   kubelet            Successfully pulled image "kahunacohen/hello-kube:latest" in 2.3212119s
  Normal  Created    19m   kubelet            Created container web
  Normal  Started    19m   kubelet            Started container web

该 pod 具有正在运行 expressjs 的容器,该代码正在尝试打印出配置映射中设置的环境变量:

const process = require("process");
const express = require("express");
const app = express();


app.get("/", (req, res) => {
  res.send(`<h1>Kubernetes Expressjs Example 0.3</h2>
  <h2>Non-Secret Configuration Example</h2>
  <p>This uses ConfigMaps as env vars.</p>
  <ul>
    <li>MY_NON_SECRET: "${process.env.MY_NON_SECRET}"</li>
    <li>MY_OTHER_NON_SECRET: "${process.env.MY_OTHER_NON_SECRET}"</li>
  </ul>
  `);
});


app.listen(3000, () => {
  console.log("Listening on http://localhost:3000");
})

当我部署这些 pod 时,环境变量是 undefined

当我做$ kubectl exec {POD_NAME} -- env

我没有看到我的环境变量。

我做错了什么?我已经尝试杀死 pod,等到它们重新启动然后再次检查无济于事。

【问题讨论】:

  • pod 是否也在默认命名空间中?
  • 是的,当我描述它时,我看到: 名称:web-deployment-5bb9d846b6-ng2n8 命名空间:默认当 pod 的名称指定为“web”时,它被列为 web-deployment 是否正常-pod”在 yaml 规范中?

标签: express kubernetes kubectl configmap


【解决方案1】:

您的 pod 似乎由 web-deployment 部署管理。您不能直接修补此类 pod。

如果您运行kubectl get pod &lt;pod-name&gt; -n &lt;namespace&gt; -oyaml,您将在metadata 部分下看到一个名为ownerReferences 的块。这会告诉您谁是该 pod 的所有者/管理员。

在部署的情况下,所有权层次结构如下:

部署 -> ReplicaSet -> Pod

即部署创建副本集,副本集依次创建 pod。

因此,如果您想更改 pod Spec 中的任何内容,您应该在 deployment 中进行更改,而不是直接在副本集或 pod 中进行更改,因为它们会被覆盖。

通过在此处运行和编辑环境字段来修补您的部署:

kubectl edit deployment.apps <deployment-name> -n <namespace>

或使用您的更改更新部署 yaml 并运行

kubectl apply -f <deployment-yaml-file>

【讨论】:

  • 所以您是说envFrom 块属于deployment.yaml 清单?作为一个 kubernetes 新手,我还注意到在我的情况下,spec.containers 块基本上在 pod yaml 和部署 yaml 之间重复。那么我可以摆脱 pod yaml 中的那个块,只让部署 yaml 定义它们,因为它是“父级”吗?如果是这样,则 pod yaml 中所剩无几。我什至需要它吗?我无法理解 pod 规范中的内容以及部署规范中的内容。是否需要 pod 规范但不需要部署规范?
  • 部署中的spec.containers 详细信息会沿层次结构向下传递。因此,这不是重复,而是将配置传递到最低级别。 Pod 是 kubernetes(k8s) 中的原子计算对象,就像虚拟机对于管理程序一样。您可以独立创建它,但您将对它的生命周期负责。当 pod 死亡或被驱逐时,K8s 不会采取任何行动。但是,对于 deploymentstatefulSetreplicaSet 等结构,您可以提供与 pod 生命周期相关的某种程度的自动化。因此,与其创建简单的 pod,不如创建 deployment
  • 如果我从不打算在没有容器的情况下使用 pod,那么在部署中定义容器而不是 pod 就可以了吗?
  • 使用deployment 比仅使用pod 在生产中部署容器更好,因为使用deployment,您可以获得比简单的独立pod 更多的功能。关于为什么需要将容器部署为 deployment 而不仅仅是 pod 的一部分的简要说明:stackoverflow.com/a/47729498/777617
  • 是的。 @raghwendra-singh,这行得通。如果我执行kb exec web-deployment-db786f754-jv9gl -- env,我现在可以看到环境变量,但是。我的快递应用程序仍然无法读取它。它打印为未定义。就配置而言,我还需要什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-19
  • 2019-06-22
  • 1970-01-01
  • 2019-09-07
  • 1970-01-01
相关资源
最近更新 更多