Search code examples
pythondockerkubernetesenvironment-variableskubernetes-secrets

How to get secret environment variables implemented by kubernetes into python?


For my project I need a config file to connect my program to a database. Instead of writing the config data(for example username and password) hard coded in a document I want to save it as secure environment variables in kubernetes.

I programmed my application with python. The python application runs successfully in a docker container. I then created the secret variables via kubernetes. I wrote a .yaml file and specified the required container and image data. That's the Kubernetes tutorial: Link to Kubernetes tutorial

Now I want to access the secret environment variables I created in kubernetes. But how?

How can I read a secret environment variable with python? Do I have to initialize the environment variables in the docker file?

PS: I already tried things like this:

import os
print(os.environ['USERNAME'])

Solution

  • Th following works and should prove this to you:

    1. Base64 encode e.g. username|password:

    U=$(echo -n "freddie" | base64)
    P=$(echo -n "fridays" | base64)
    

    NB The host's environment variables are U and P

    Assuming

    POD="p"             # Or...
    SECRET="s"          # Or...
    NAMESPACE="default" # Or...
    

    2. Create the secret:

    echo "
    apiVersion: v1
    kind: Secret
    metadata:
      name: ${SECRET}
    data:
      u: ${U}
      p: ${P}
    " | kubectl apply --filename=- --namespace=${NAMESPACE}
    

    NB The Secret's data contains values u and p (corresponding to U and P)

    yields:

    secret/x created
    

    And:

    kubectl describe secret/${SECRET} --namespace=${NAMESPACE}
    

    yields:

    Name:         ${SECRET}
    Namespace:    ${NAMESPACE}
    Labels:       <none>
    Annotations:  
    Type:         Opaque
    
    Data
    ====
    p:  7 bytes
    u:  7 bytes
    

    3. Attach the secret's values to a Pod:

    echo "
    apiVersion: v1
    kind: Pod
    metadata:
      name: ${POD}
    spec:
      containers:
      - name: test
        image: python
        command:
        - python3
        - -c
        - \"import os;print(os.environ['USERNAME']);print(os.environ['PASSWORD'])\"
        env:
        - name: USERNAME
          valueFrom:
            secretKeyRef:
              name: ${SECRET}
              key: u
        - name: PASSWORD
          valueFrom:
            secretKeyRef:
              name: ${SECRET}
              key: p
    " | kubectl apply --filename=- --namespace=${NAMESPACE}
    

    NB The Pod's environment maps the Secret's u-->USERNAME, p-->PASSWORD

    NB These variable name changes are to demonstrate the point; they may be the same

    4. Review the Pod's logs

    kubectl logs pod/${POD} --namespace=${NAMESPACE}
    

    yields (in my case):

    freddie
    fridays