I am deploying my application in kubernetes using helm chart with 2 sub-charts app
and test
.
I have the pod of app
chart properly running.
But test
pod will be running only if it can properly authenticate to app
container.
That means, i have to generate an auth_token
using a curl request to app
service and then add that token as Environment variable AUTH_TOKEN
for test
container.
I tried different ways to achieve this:
Added an init-container generate-token
for test
pod, that will generate the token and will save it in a shared volume. And test
container will have access to that volume. But the problem here is, the test
container doesn't have a code to set env for the container by reading from the shared volume.
Added a sidecar-container sidecar-generate-token
instead of an init-container for the same setup as mentioned above. Here also problem is, the test
container doesn't have a code to set env for the container by reading from the shared volume. And also, the test pod got into a crashloopbackoff state. If you check the content of volume by getting into the container, there are multiple tokens in the volume file which are generated on each pod restart of crashloopbackoff.
Third plan was that an init-container generate-token
should create a kubernetes secret in the cluster, after generating the auth_token. Then the main container test
can set Environment variable from that secret. For that, the init container generate-token
should have a kubectl setup in it first.
If i am proceeding with the third plan, How can i setup and use kubectl from init-container to generate secret in the cluster?
Is there any other alternative plan to achieve this goal?
EDIT:
This is the yaml part for the first option:
initContainers:
- name: generate-service-token
image: app.mycr.io/alpine-network-troubleshooting:dev-latest
command:
- /bin/sh
- -c
- |
BEARER_TOKEN=$(curl -k -X POST -H "Content-Type:application/json" --data '{"user":"dynizer","password":"xxxx"}' "https://app:50051/api/v2/login" | jq -r '.jwt')
SERVICE_TOKEN=$(curl -k -X GET -H 'Accept: application/json' -H "Authorization: Bearer ${BEARER_TOKEN}" "https://app:50051/api/v2/servicetoken/issue" | jq -r '.token')
echo $SERVICE_TOKEN
mkdir -p /vol
touch /vol/token.txt
echo $SERVICE_TOKEN >> /vol/token.txt
volumeMounts:
- mountPath: /vol
name: token-vol
containers:
- name: nginx-container
image: nginx
volumeMounts:
- name: token-vol
mountPath: /vol
volumes:
- name: token-vol
emptyDir: {}
Trying to answer your question:
But still the same problem of container not having the code to set env by reading from the shared volume, will be there.
Let's try to read this env from other container. Here Is what I have come up with.
First you need to know what command your container is running. In case of nginx that is /docker-entrypoint.sh nginx -g "daemon off;"
(source code)
Then you use command
field where you read the token value from file and use env
to set it and run the actual applciation.
Example:
initContainers:
- name: generate-service-token
image: app.mycr.io/alpine-network-troubleshooting:dev-latest
command:
- /bin/sh
- -c
- |
BEARER_TOKEN=$(curl -k -X POST -H "Content-Type:application/json" --data '{"user":"dynizer","password":"xxxx"}' "https://app:50051/api/v2/login" | jq -r '.jwt')
SERVICE_TOKEN=$(curl -k -X GET -H 'Accept: application/json' -H "Authorization: Bearer ${BEARER_TOKEN}" "https://app:50051/api/v2/servicetoken/issue" | jq -r '.token')
echo $SERVICE_TOKEN
mkdir -p /vol
touch /vol/token.txt
echo $SERVICE_TOKEN >> /vol/token.txt
volumeMounts:
- mountPath: /vol
name: token-vol
containers:
- name: nginx-container
image: nginx
command:
- sh
- -c
- exec env SERVICE_TOKEN=$(cat /vol/token.txt) /docker-entrypoint.sh nginx -g "daemon off;"
volumeMounts:
- name: token-vol
mountPath: /vol
volumes:
- name: token-vol
emptyDir: {}
More general example:
command:
- sh
- -c
- exec env SERVICE_TOKEN=$(cat /vol/token.txt) <<any command>>
I am not sure if this is the best example, but I hope that at least it gives you an idea how you can approach this problem.