问题
我有一个监控应用程序,我想将其部署在 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/