A workaround solution for using Kubernetes Configmap to map a recursive directory.
First, about ConfigMap recursive directory issues, you can find from below topics
or
However, unfortunately, it isn’t possible to build a Kubernetes ConfigMap from a directory, recursively [1] currently.
For example,
conf/
└── integrator
└── conf
├── axis2
│ └── axis2.xml
├── carbon.xml
├── datasources
│ └── master-datasources.xml
├── registry.xml
└── user-mgt.xml
Therefore, we will use a work-around to solve this issue.
Prepare a Helm template
First, let prepare a Helm template for Kubernetes deployment with configmap.yaml for ConfigMap and deployment.yaml for Deployment
$ tree -L 2 helm_templates/your-template
helm_templates/your-template
├── Chart.yaml
├── templates
│ ├── NOTES.txt
│ ├── _helpers.tpl
│ ├── configmap.yaml <--- ConfigMap
│ ├── deployment.yaml <--- Deployment
└── values.yaml
For instance, Configmap yaml for you Helm template
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "your-template.fullname" . }}-config
data:
# mapping configMaps from values.yml to ConfigMap
{{- range $key, $value := .Values.configMaps }}
{{ $key }}: |-
{{ $value.content | indent 4 }}
{{- end }}
After that, a Deployment.yaml which mount all configMap data to volume using subPath. Please note that we using path properties for mount path setting.
spec:
volumes:
- name: {{ template "your-template.fullname" . }}-config
configMap: { name: {{ template "your-template.fullname" . }}-config }
containers:
- volumeMounts:
{{- range $key, $value := .Values.configMaps }}
- name: {{ template "your-template.fullname" $ }}-config
# note that we using path properties for mount path setting
mountPath: /config/{{ $value.path }}
subPath: {{ $key }}
{{- end }}
Generate your Helm values.yaml by Python code
After that, we will prepare a simple Python code to read recursive directory and pass file’s content to values.yaml. For loading recursive directory from config_dir.
def get_config_maps(config_dir) -> dict:
config_maps = {}
filenames = [y for x in os.walk(config_dir) for y in glob.glob(os.path.join(x[0], '*')) if os.path.isfile(y)]
for filename in filenames:
# remove parent dir path
relative_path = filename.replace(config_dir + os.path.sep, "")
# replace path separator by "__" to prevent Kubernetes syntax error
# currently file path doesn't validate '[-._a-zA-Z0-9]+'
key = relative_path.replace(os.path.sep, "__")
with open(filename, 'r') as file:
config_maps[key] = {
"path": relative_path, # a path that will be used for mount ConfigMap to Pod's volume
"content": file.read()
}
return config_maps
The next step is, saving file’s content to values.yaml
# load value template
confif_dir = 'path/to/your/conf'
with open('helm_templates/your-template/values.yaml', 'r') as file:
deploy_values = yaml.safe_load(file)
deploy_values['configMaps'] = get_config_maps(config_dir)
Deploy using your Helm template
helm install [your-helm-template-path] -f values.yaml
In conclusion, we can build a ConfigMap from a recursive directory by using a simple Python code with Helm template. Good luck & happy Kubernetes! :beer:
Additional, Other Kubernetes related topics is here. https://tuantranf.me/tag/kubernetes/
Original work is here https://gist.github.com/tuantranf/1faf61d0864353ed617af1f90f3ee453