(2年前问过一个非常类似的问题,虽然它是关于秘密的,但我怀疑配置图的故事有什么不同......但至少,我可以介绍用例以及为什么现有的解决方法对我们来说是不可行的。)
给出一个简单的,简化的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"
}
configmap.yaml
中的密钥,无论它们是什么,都只是创建为文件,不需要修改deployment.yaml
或具有除mountPath之外的任何细节。
问题是实际结构有子文件夹来处理覆盖根域的特定于区域的值:
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"
}
那么 是 我们的选择是什么?
Wellll,我们可以使用deployment.yaml的items: -key: path:
节点中的volumes: -configMap:
方法将密钥映射到特定位置,
和/或在deployment.yaml的volumeMounts:
节点中生成多个节点,
使用subPath:
(与items: -key: -path:
中使用volumes: configMap:
基本相同),
或每个子目录的单独配置映射,并在deployment.yaml中将它们全部安装为不同的volumes
。
所有这些方法都需要对deployment.yaml进行大规模且令人难以置信的冗长更改,泄露出不应该有任何理由知道的知识,使其变得可变且不断重新生成而不是静态,使滚动复杂化对部署的pod等的设置更新等等。它只是不好。所有这些只是为了映射一个目录,只是因为它包含子目录......
当然,这可以成为它支持的工作方式吗?我错过了什么?我该怎么办?
答案 0 :(得分:0)
从“容器本地”的角度来看,拥有配置文件的大型文件系统树,应用程序在启动时处理它以达到其规范配置是一种反模式。最好有一个生成单个文件的工作流,可以存储在ConfigMap中,并以最终形式轻松检查。例如,参见nginx ingress。
但显然不是每个人都在重写他们的应用程序以更好地与kubernetes方法保持一致。在部署时将配置文件的完整目录树放入容器的最简单方法是使用initContainers和emptyDir挂载。
将配置文件树打包到容器(有时称为“仅数据”容器)中,并让容器启动脚本将配置树复制到emptyDir挂载中。然后,应用程序可以按预期使用树。
答案 1 :(得分:0)
根据配置树的规模,另一个可行的选择可能是模拟带有下划线而不是configmap内部文件“ paths”中的斜线的子树。这将使您失去一般文件系统的性能(如果您只需要读取配置,就不会有问题),并迫使您重写一些应用程序代码(访问配置时,使用文件模式遍历而不是目录遍历),但是应该以相当便宜的价格解决您的用例。
答案 2 :(得分:0)
一些解决方法:
FROM scratch
... # copy data here
然后将其添加为将卷安装在另一个容器上的边车...
从配置中创建一个 tar 球,将其转换为 configmap,安装在容器中并更改容器命令以在开始前解压配置...
使用一些特殊字符而不是 /
重命名文件,例如 us@example.json
并使用脚本将它们mv
像开头一样。
所有这些都非常hacky...最好的方案是重构它们以在平面文件夹中使用并使用类似kustomize的东西创建它们:
kustomize edit add configmap my-configmap --from-file='./*.json'