大约两年前也有类似的问题被问到,虽然那个问题是关于机密的,但我认为配置映射的情况也不会有什么不同,但至少我可以介绍一下使用案例以及现有的解决方法为何对我们来说不可行。
假设有一个简单的、精简的deployment.yaml
:
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: example
spec:
template:
spec:
containers:
- name: example
volumeMounts:
- name: vol
mountPath: /app/Configuration
volumes:
- name: vol
configMap:
name: configs
还有匹配的configmap.yaml
:
apiVersion: v1
kind: ConfigMap
metadata:
name: configs
labels:
k8s-app: example
data:
example1.json: |-
{
"key1": "value1"
}
example2.json: |-
{
"key2": "value2"
}
< p > 无论configmap.yaml
中的密钥是什么,它们都会被简单地创建为文件,而无需修改deployment.yaml
或具有任何特定要求,只需使用即可。
问题在于实际的结构具有子文件夹来处理特定区域的值以覆盖根目录:
Configuration \ example1.json
Configuration \ example2.json
Configuration \ us \ example1.json
Configuration \ us \ ca \ example2.json
这些配置的数量和性质显然会因为不同国家、地区和每个单独配置的模块而有所不同。我们的目标是为终端用户提供一个工具,使他们能够设置和管理这些配置。在幕后自动生成
configmap.yaml
并在kubernetes中更新它。然而,除非我还没有发现的技巧,否则这似乎超出了kubernetes的能力,有几个方面。
首先,没有语法允许指定作为目录的configmap键,也不能在键中包含子目录路径。
data:
# one possible approach (currently complains that it doesn't validate '[-._a-zA-Z0-9]+')
/us/example1.json: |-
{
"key1": "value1"
}
# another idea; this obviously results in 'invalid type for io.k8s.api.core.v1.ConfigMap.data: got "map", expected "string"'
us:
example2.json: |-
{
"key2": "value2"
}
那么我们有哪些选项来实现这个目标呢?
嗯,我们可以使用deployment.yaml
中volumes: -configMap:
节点中的items: -key: path:
方法将键映射到特定位置,
或者在deployment.yaml
的volumeMounts:
节点中生成多个节点,
使用subPath:
(基本上与在volumes: configMap:
中使用items: -key: -path:
相同),
或者为每个子目录单独生成配置映射,并将它们全部作为不同的volumes
挂载到deployment.yaml
中。
所有这些方法都需要对deployment.yaml
进行大量且非常冗长的更改,泄漏出它不应该知道的知识,使其变得可变并不断重新生成而不是静态的,使滚动设置更新到已部署的pod变得复杂等等等等。这样做并不好。而所有这些只是为了映射一个目录,仅仅因为它包含子目录...
肯定不是这个工作的方式吧?我错过了什么?我该怎么办?