如何在Kubernetes ConfigMap中使用唯一值

时间:2017-07-17 17:35:12

标签: configuration kubernetes

问题

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

理想的解决方案?

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

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

举个例子,这里是我现在拥有的应用配置中的字符串,而不是我想要使用的字符串。

user_agent = "app-k8s-test"

但我更喜欢......

user_agent = $HOSTNAME

这样的事情可能吗?

1 个答案:

答案 0 :(得分:3)

您可以使用init容器从配置映射中预处理配置模板。预处理步骤可以将局部变量注入配置文件。扩展的配置将写入init容器和主应用程序容器之间共享的emptyDir。这是一个如何做的例子。

首先,为要扩展的字段创建一个包含占位符的配置图。我使用了sed和ad-hoc名称来替换。你也可以使用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

我以裸露的吊舱为例。您可以在DaemonSet的pod模板中嵌入此类型的pod。

此处为Downward API is used to set the MY_NODE_NAME Environment Variable,因为节点名称在容器内不可随时提供。

请注意,出于某种原因,您无法将spec.nodeName放入文件中,只能获取env var。

如果您只需要Env Var中的主机名,那么您可以跳过init容器。

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

  • 运行一个监视配置映射卷的边车而不是初始容器,并在它发生变化时重新扩展(或者只是定期进行)。这要求主容器也知道如何监视配置文件更新。

  • 您可以在每次配置模板更改时创建新的配置映射,并编辑守护程序集以将一行更改为指向新的配置映射。 然后进行滚动更新以使用新配置。