【发布时间】:2018-09-15 18:02:15
【问题描述】:
我是 Kubernetes 和 Helm 的新手。我来自一个普通的 Docker/docker-compose 世界。
我有一些运行多个 Docker 容器的复杂服务,这些服务需要大量的配置参数和逻辑。 docker 化的服务在启动时需要很多不同的配置文件、键和命令行参数。我还需要一些只能在容器内部执行的运行时配置逻辑(必须生成一些配置元素)。
我最终做的是编写一个 shell 脚本(用作 CMD),它需要环境变量、定义默认值、将这些环境变量转换为命令参数和配置文件。
这是一个关于我如何构建它的非工作示例,没有考虑 Kubernetes 和 Helm。
Dockerfile
...
CMD [ "./bootstrap.sh" ]
bootstrap.sh(打包在镜像中)
# Define default values, if no environment variables provided on
# on "docker run"
export CONFIG_VALUE_A=${CONFIG_VALUE_A:="a"}
export CONFIG_VALUE_B=${CONFIG_VALUE_B:="b"}
export CONFIG_VALUE_C=${CONFIG_VALUE_C:="c"}
# write CONFIG_VALUE_A to file
echo ${CONFIG_VALUE_A} > ./some-config-file-a.cfg
ARGS="--config-file-a ./some-config-file-a.cfg --config-value-b ${CONFIG_VALUE_B} --config-value-c ${CONFIG_VALUE_C}"
exec ./my-app ${ARGS}
这样做的好处是使用环境变量,我有一个标准的配置接口,不需要处理配置文件的卷。
现在,我正在 Helm 中加入 Kubernetes。 Helm 有自己的参数概念,使用 values.yaml。要将其与上面已有的内容结合起来,我只需将 values.yaml 中的值与这些环境变量进行映射。
deployment.yaml
...
spec:
...
template:
...
spec:
containers:
- name: my-app
...
env:
- name: "CONFIG_VALUE_A"
value: {{ .Values.config.value_a }}
- name: "CONFIG_VALUE_B"
value: {{ .Values.config.value_b }}
- name: "CONFIG_VALUE_C"
value: {{ .Values.config.value_c }}
values.yaml
config:
value_a: a
value_b: b
value_c: c
但是,我在三个配置层中来回映射值(helm 模板 => 容器环境变量 => 配置文件/CLI 参数)违反了 DRY 原则,并增加了很多潜在的拼写错误/错误以后再找。
理想情况下,
- 我只需在
deployment.yaml中定义我的配置结构,在 Helm 的default.yaml中定义一次默认值 - 我会将这些值直接传递给容器,让某种配置脚本构建命令行参数和配置文件,而不使用环境变量作为中间层
- 使用某种类型安全的配置格式
- 尽量减少总行数
- 保持配置文件的可读性,不要混淆不同的语言(即在 YAML 文件中定义的 JSON)
您如何使用 Kubernetes、Helm 和 Docker 解决复杂的配置管理问题?
【问题讨论】:
标签: docker kubernetes configuration-management kubernetes-helm