Is it possible to pass different args to pods based on their ordinal index in StatefulSets? Didn\'t find the answer on the StatefulSets documentation. Thanks!
I don't know of a non-hacky way to do it, but I know a hack that works. First, each pod in a StatefulSet gets a unique predictable name. It can discover that name via the downward API or just by calling hostname
. So I have shell script as then entrypoint to my container and that script gets it's pod/hostname. From there it calls the "real" executable using command line args appropriate for the specific host.
For example, one of my scripts expects the pod name to be mapped into the environment as POD_NAME
via downward api. It then does something like:
#!/bin/bash
pet_number=${POD_NAME##*-}
if [ pet_number == 0 ]
then
# stuff here
fi
# etc.
You can avoid using the Downward API by using HOSTNAME
:
command:
- bash
- c
- |
ordinal=${HOSTNAME##*-}
if [[ "$ordinal" = "0" ]]; then
...
else
...
fi
I found one less hacky
way to pass in ordinal index into container using the lifecycle hooks
containers:
- name: cp-kafka
imagePullPolicy: Always
image: confluentinc/cp-kafka:4.0.0
resources:
requests:
memory: "2Gi"
cpu: 0.5
ports:
- containerPort: 9093
name: server
protocol: TCP
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "export KAFKA_BROKER_ID=${HOSTNAME##*-}"]
env:
- name: KAFKA_ZOOKEEPER_CONNECT
value: zk-cs.default.svc.cluster.local:2181
- name: KAFKA_ADVERTISED_LISTENERS
value: PLAINTEXT://localhost:9093
In case you want to track the progress of this, the ticket in question for this feature is here: https://github.com/kubernetes/kubernetes/issues/30427
The proposal involves putting the ordinal as a label on the pod and then using the downward api to pull that out into an environment variable or something.
Recommended way, see https://kubernetes.io/docs/tasks/run-application/run-replicated-stateful-application/#statefulset
# Generate server-id from pod ordinal index.
[[ `hostname` =~ -([0-9]+)$ ]] || exit 1
ordinal=${BASH_REMATCH[1]}
# ${ordinal} now holds the replica number
server-id=$((100 + $ordinal))
# Copy appropriate conf.d files from config-map to emptyDir.
if [[ $ordinal -eq 0 ]]; then
# do something
else
# do something else
fi