Home > OS >  Kubernetes: How to refer environment variable in config file
Kubernetes: How to refer environment variable in config file

Time:12-15

As per Kubernetes Doc , to reference a env variable in config use expr $(ENV_VAR).
But, this is not working for me. In Readiness and Liveliness Probe API, I am getting token value as $(KUBERNETES_AUTH_TOKEN) instead of abcdefg

containers:
    env:
      - name: KUBERNETES_AUTH_TOKEN
        value: "abcdefg"
    lifecycle:
      preStop:
        exec:
          command:
            - "sh"
            - "-c"
            - |
              curl -H "Authorization: $(KUBERNETES_AUTH_TOKEN)" -H "Content-Type: application/json" -X GET http://localhost:9443/pre-stop
    readinessProbe:
      failureThreshold: 3
      httpGet:
        path: /status
        port: 9853
        scheme: HTTP
        httpHeaders:
          - name: Authorization
            value: $(KUBERNETES_AUTH_TOKEN)

    livenessProbe:
      failureThreshold: 3
      httpGet:
        path: /status
        port: 9853
        scheme: HTTP
        httpHeaders:
          - name: Authorization
            value: $(KUBERNETES_AUTH_TOKEN)

CodePudding user response:

I don't think that's possible, and really your readiness and liveness endpoints shouldn't require authentication.

However, there is a hacky way around this. I don't know if its available to you, but it works for me. First, you'll need to have the KUBERNETES_AUTH_TOKEN variable set in the environment in which you're running kubectl, then you need to use the bash tool envsubst, like so:

  cat k8s.yaml | envsubst | kubectl apply -f -

If you use this approach, you'll have to remove the parenthesis around the env-var.

One final note, the header you're using requires a hint as to the nature of the token, so it should maybe be:

value: Bearer $KUBERNETES_AUTH_TOKEN

Or Basic, or whatever. Also, I believe the token itself must be base64 encoded.

CodePudding user response:

There is an issue opened about a very similar question here

Anyway, i want to share some yaml lines.
This is not intended for production env, obviously it's just to play around with the commands.

apiVersion: v1
kind: Pod
metadata:
  labels:
    run: ngtest
  name: ngtest
spec:
  volumes:
    - name: stackoverflow-volume
      hostPath:
        path: /k8s/stackoverflow-eliminare-vl
  initContainers:
  - name: initial-container
    volumeMounts:
      - mountPath: /status/
        name: stackoverflow-volume
    image: bash
    env:
      - name: KUBERNETES_AUTH_TOKEN
        value: "abcdefg"
    command:
      # this only writes a text file only to show the purpose of initContainers (here you could create a bash script)
      - "sh"
      - "-c"
      - "echo $(KUBERNETES_AUTH_TOKEN) > /status/$(KUBERNETES_AUTH_TOKEN).txt" # withi this line, substitution occurs with $() form
  containers:
  - image: nginx    
    name: ngtest
    ports:
      - containerPort: 80
    env:
      - name: KUBERNETES_AUTH_TOKEN
        value: "abcdefg"
    volumeMounts:
      - mountPath: /status/
        name: stackoverflow-volume    
    lifecycle:
      preStop:
        exec:
          command:
            - "sh"
            - "-c"
            - |
              echo $KUBERNETES_AUTH_TOKEN > /status/$KUBERNETES_AUTH_TOKEN.txt  &&
              echo 'echo $KUBERNETES_AUTH_TOKEN > /status/anotherFile2.txt' > /status/exec-$KUBERNETES_AUTH_TOKEN-2.sh  && . /status/exec-$KUBERNETES_AUTH_TOKEN-2.sh &&
              echo 'echo $(KUBERNETES_AUTH_TOKEN) > /status/anotherFile3.txt' > /status/exec-$(KUBERNETES_AUTH_TOKEN)-3.sh  && . /status/exec-$(KUBERNETES_AUTH_TOKEN)-3.sh &&
              echo 'curl -H "Authorization: $KUBERNETES_AUTH_TOKEN" -k https://www.google.com/search?q=$KUBERNETES_AUTH_TOKEN > /status/googleresult.txt && exit 0' > /status/exec-a-query-on-google.sh  && . /status/exec-a-query-on-google.sh 
            # first two lines are working
            # the third one with $(KUBERNETES_AUTH_TOKEN), do not
            # last one with a bash script creation works, and this could be a solution
    resources: {}

    # # so, instead of use http liveness
    # livenessProbe:
    #   failureThreshold: 3    
    #   httpGet:
    #     path: /status
    #     port: 80
    #     scheme: HTTP
    #     httpHeaders:
    #       - name: Authorization
    #         value: $(KUBERNETES_AUTH_TOKEN)

    # u can use the exec to call the endpoint from the bash script.
    # reads the file of the initContainer (optional) 
    # here i omitted the url call , but you can copy from the above examples
    livenessProbe:
      exec:
        command:
        - sh
        - -c
        - "cat /status/$KUBERNETES_AUTH_TOKEN.txt && echo -$KUBERNETES_AUTH_TOKEN- `date` top! >> /status/resultliveness.txt && 
          exit 0" 
      initialDelaySeconds: 15
      periodSeconds: 5  
  dnsPolicy: ClusterFirst
  restartPolicy: Always

This creates a pod with an hostPath volume (only to show you the output of the files) where will be create files based on the command of the yaml. More details on the yaml. If you go in you cluster machine, you can view the files produced.

Anyway, you should use ConfigMap, Secrets and/or https://helm.sh/docs/chart_template_guide/values_files/, which allow us to create your own charts an separate you config values from the yaml templates.

Hopefully, it helps.

Ps. This is my first answer on StackOverflow, please don't be too rude with me!

  • Related