configuration - 如何在 Kubernetes ConfigMap 中使用唯一值

标签 configuration kubernetes

问题

我有一个监控应用程序,我想将其部署在 DaemonSet 内。在应用程序的配置中,指定了唯一的用户代理来将该节点与其他节点分开。我为应用程序创建了一个 ConfigMap,但这仅适用于同步环境中的其他设置。

理想的解决方案?

我想指定一个唯一值,例如节点的主机名或另一个本地推断的值,以用作用户代理字符串。有没有办法可以从系统调用此信息,并且 Kubernetes 将使用值(如主机名)填充所需的键?

这有意义吗,或者有更好的方法吗?我正在查看文档,但在任何地方都找不到这个特定问题的答案。

作为示例,这是我现在拥有的应用程序配置中的字符串与我想要使用的字符串。

user_agent = "app-k8s-test"

但我更愿意......

user_agent = $HOSTNAME

这样的事情可能吗?

最佳答案

您可以使用 init 容器从配置映射中预处理配置模板。预处理步骤可以将局部变量注入(inject)到配置文件中。扩展的配置被写入初始化容器和主应用程序容器之间共享的emptyDir。以下是如何执行此操作的示例。

首先,为您想要扩展的任何字段创建一个带有占位符的配置映射。我使用 sed 和临时名称来替换。您也可以使用 jinja2 或任何您喜欢的东西。只需将您想要的任何预处理器放入 init 容器镜像中即可。您可以使用任何您想要的配置文件的文件格式。我只是在这里使用 TOML 来表明它不一定是 YAML。我将其称为“.tpl”,因为它尚未准备好使用:它有一个字符串 _HOSTNAME_,需要扩展。

$ cat config.toml.tpl 
[blah]
blah=_HOSTNAME_
otherkey=othervalue
$ kubectl create configmap cm --from-file=config.toml.tpl
configmap "cm" created

现在编写一个带有 init 容器的 pod,该容器将配置映射安装在卷中,并将其扩展并写入与主容器共享的另一个卷:

$ cat personalized-pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod-5
  labels:
    app: myapp
  annotations:
spec:
  containers:
  - name: myapp-container
    image: busybox
    command: ['sh', '-c', 'echo The app is running and my config-map is && cat /etc/config/config.toml && sleep 3600']
    volumeMounts:
      - name: config-volume
        mountPath: /etc/config
  initContainers:
  - name: expander
    image: busybox
    command: ['sh', '-c', 'cat /etc/config-templates/config.toml.tpl | sed "s/_HOSTNAME_/$MY_NODE_NAME/" > /etc/config/config.toml']
    volumeMounts:
      - name: config-tpl-volume
        mountPath: /etc/config-templates
      - name: config-volume
        mountPath: /etc/config
    env:
      - name: MY_NODE_NAME
        valueFrom:
          fieldRef:
            fieldPath: spec.nodeName
  volumes:
    - name: config-tpl-volume
      configMap:
        name: cm
    - name: config-volume
      emptyDir:
$ kubctl create -f personalized-pod.yaml
$ sleep 10
$ kubectl logs myapp-pod
The app is running and my config-map is
[blah]
blah=gke-k0-default-pool-93916cec-p1p6
otherkey=othervalue

我将其作为一个裸容器作为示例。您可以将这种类型的 Pod 嵌入到 DaemonSet 的 Pod 模板中。

这里,Downward API is used to set the MY_NODE_NAME Environment Variable ,因为节点名称无法从容器内轻松获得。

请注意,由于某种原因,您无法将 spec.nodeName 放入文件中,而只是将环境变量放入文件中。

如果您只需要环境变量中的主机名,那么您可以跳过 init 容器。

由于 Init Container 仅运行一次,因此您不应更新 configMap 并期望它重新扩展。如果您需要更新,可以执行以下两种操作之一:

  • 运行一个 sidecar 来监视配置映射卷并在其更改时重新扩展(或者只是定期执行),而不是 init 容器。这要求主容器也知道如何监视配置文件更新。

  • 您可以在每次配置模板更改时创建一个新的配置映射,然后编辑 daemonSet 以更改一行以指向新的配置映射。 然后进行滚动更新以使用新配置。

关于configuration - 如何在 Kubernetes ConfigMap 中使用唯一值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45150362/

相关文章:

java - 如何获取当前的屏幕方向?

java - 在 kubernetes 平台上的 spring-cloud-dataflow 中创建调度程序时出现 NullPointerException

asp.net - IIS 7.5 – 应用 Windows Server 2008 R2 SP1 后无扩展 URI 处理的重大变化?

WCF 错误 - 找不到与方案匹配的基地址

redirect - 如何告诉nginx将网站的所有页面重定向到root?

amazon-web-services - 在AWS EKS中,如何安装和访问etcd,kube-apiserver等?

kubernetes:部署仪表板(ui)时出错

PHP - MySQL PDO 最大查询大小

docker - kind 集群 - 如何查看已加载的 docker-images?

kubernetes - 使用 Redis 处理程序在 Istio 中进行速率限制