For my AKS container setup, I would like to pass the requested number of replicas of a given statefulset to each pod through environment variables.
I was trying to do this without repeating myself (once in the "replicas" setting and once in the setting of the environment variables).
The only real solution I could find of how to do this was using anchors and aliases as such (based on Kubernetes StatefulSet - obtain spec.replicas metadata and reference elsewhere in configuration):
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: solr
spec:
selector:
matchLabels:
app: solr
serviceName: solr-hs
replicas: &numReplicas 3
updateStrategy:
type: RollingUpdate
# Make sure pods get created sequentially
podManagementPolicy: OrderedReady
template:
metadata:
labels:
app: solr
spec:
containers:
- name: kubernetes-solr
imagePullPolicy: Always
image: "..."
resources:
requests:
memory: "8Gi"
cpu: "0.5"
ports:
- containerPort: 8983
env:
- name: N_O_REPLICAS
value: *numReplicas
Unfortunately, it seems like the "env" value has to be a string, and the integer value of "replicas" does not get cast or transformed. The following error gets thrown instead:
v1.EnvVar.v1.EnvVar.Value: ReadString: expects " or n, but found 3, error found in #10 byte of ...|,"value":3},{"name":|..., bigger context ...|:"solr-config"}}},{"name":"N_O_REPLICAS","value":3},
I tried casting to a string manually by writing:
value: !!str *numReplicas
But this also doesn't work and throws the following error:
error converting YAML to JSON: yaml: line 52: did not find expected key
Is there any way to create a Kubernetes YAML file that allows the reusing of integer values as strings? Or is there another solution for this particular situation?
Helm is what you need.
Actually, Helm
is something more, than what you need, but it has a template engine (just like in Ansible), which could help with your case. Moreover, today using Helm
it's almost mandatory with the Kubernetes, just because it has got a huge library of charts, which could help you to deploy different software very fast, e.g Elastic stack or Redis via one command...(almost). So, try this out, it could improve your work with the Kubernetes
Although your approach is interesting, !!str
is not a casting operator and the YAML specification clearly indicates that what you tried is not going to work:
When a node has more than one occurrence (using aliases), tag resolution must depend only on the path to the first (anchored) occurrence of the node.
So within YAML this is not possible, unless the parser/loader is non-conform.
The best solution for your problem, IMO, would be that kubernetes explicitly casts all parameters that will be environment variables to a string before adding them to the environment. That way you could use booleans, dates, etc. as well.
You can also use any templating system that you like to generate the YAML input for kubernetes as long as such a system allows you to "stringify" your integer parameter.