首页 > 解决方案 > 访问 kubernetes pod 中 configMapRef 设置的环境变量

问题描述

我在deploymentusingEnvFrom和中有一组环境变量configMapRef。这些 configMaps 中保存的环境变量是由 kustomize 最初从 json 文件设置的。

spec.template.spec.containers[0].

envFrom:
  - secretRef:
      name: eventstore-login
  - configMapRef:
      name: environment
  - configMapRef:
      name: eventstore-connection
  - configMapRef:
      name: graylog-connection
  - configMapRef:
      name: keycloak
  - configMapRef:
      name: database

问题是我无法直接访问特定的环境变量。

这是printenv在 pod 中运行的结果:

...
eventstore-login={
  "EVENT_STORE_LOGIN": "admin",
  "EVENT_STORE_PASS": "changeit"
}

evironment={
  "LOTUS_ENV":"dev",
  "DEV_ENV":"dev"
}

eventstore={
  "EVENT_STORE_HOST": "eventstore-cluster",
  "EVENT_STORE_PORT": "1113"
}

graylog={
  "GRAYLOG_HOST":"",
  "GRAYLOG_SERVICE_PORT_GELF_TCP":""
}
...

这意味着从我的 nodejs 应用程序我需要做这样的事情

> process.env.graylog
'{\n  "GRAYLOG_HOST":"",\n  "GRAYLOG_SERVICE_PORT_GELF_TCP":""\n}\n'

这仅返回与我的原始 json 文件对应的 json 字符串。但我希望能够做这样的事情:

process.env.GRAYLOG_HOST

检索我的环境变量。但我不想修改我的部署看起来像这样:

          env:
            - name: NODE_ENV
              value: dev
            - name: EVENT_STORE_HOST
              valueFrom:
                secretKeyRef:
                  name: eventstore-secret
                  key: EVENT_STORE_HOST
            - name: EVENT_STORE_PORT
              valueFrom:
                secretKeyRef:
                  name: eventstore-secret
                  key: EVENT_STORE_PORT
            - name: KEYCLOAK_REALM_PUBLIC_KEY
              valueFrom:
                configMapKeyRef:
                  name: keycloak-local
                  key: KEYCLOAK_REALM_PUBLIC_KEY

每个变量都被显式声明。我可以这样做,但维护起来更痛苦。

标签: node.jskuberneteskustomize

解决方案


简短的回答:

您将需要显式定义变量或更改配置映射以使它们具有1 environment variable = 1 value结构,这样您就可以使用envFrom. 例如:

"apiVersion": "v1",
"data": {
    "EVENT_STORE_LOGIN": "admin",
    "EVENT_STORE_PASS": "changeit"
},
"kind": "ConfigMap",

更多细节

Configmaps是键值对,这意味着对于一个键,只有一个值,configmaps可以string作为数据获取,但不能与map.

我尝试手动编辑configmap以确认上述内容并得到以下信息:

invalid type for io.k8s.api.core.v1.ConfigMap.data: got "map", expected "string"

这就是为什么 environment 作为一个字符串而不是结构出现的原因。

例如,这就是configmap.json外观:

$ kubectl describe cm test2

Name:         test2
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
test.json:
----
environment={
  "LOTUS_ENV":"dev",
  "DEV_ENV":"dev"
}

这就是它在 Kubernetes 中的存储方式:

$ kubectl get cm test2 -o json

{
    "apiVersion": "v1",
    "data": {
        "test.json": "evironment={\n  \"LOTUS_ENV\":\"dev\",\n  \"DEV_ENV\":\"dev\"\n}\n"
    },

换句话说,观察到的行为是预期的。

有用的链接:


推荐阅读