joho / godotenv

A Go port of Ruby's dotenv library (Loads environment variables from .env files)
http://godoc.org/github.com/joho/godotenv
MIT License
8.34k stars 402 forks source link

Integrate with Kubernetes #51

Closed DazWilkin closed 6 years ago

DazWilkin commented 6 years ago

Very useful, thank you!

I discovered godotenv through a Go sample that uses it. I'm working on running that solution on Kubernetes. One way to solve this with Kubernetes would be to add the .env file to the container but this seems to defeat the principle of keeping config externalized.

I used ConfigMaps and am sharing it here for consideration:

There's a limitation (!) in ConfigMaps which prevents using them to map a source file containing environment variables or other properties directly into container environment variables.

The workaround is to surface the ConfigMap's contents as a volume in the container but this then requires moving the .env (or similarly named file) to a separate directory.

  1. Move .env. to its own directory and revise the Golang reference. NB for convenience I'm using a relative reference here without "./" and I use an absolute reference in the container spec (step 3)

    err := godotenv.Load("config/.env")
  2. Convert an existing .env to a ConfigMap

    kubectl create configmap env --from-file=./config/.env
  3. The container spec must then reference the ConfigMap (env) through a volume mount:

    spec:
    containers:
    - image: dazwilkin/configmaptest:rpi3
    imagePullPolicy: Always
    name: configmaptest
    ports:
    - name: http
      containerPort: 8080
      protocol: TCP
    volumeMounts:
    - name: config-volume
      mountPath: /config
    volumes:
    - name: config-volume
      configMap:
        name: configmaptest

    This results in a container that will run on Kubernetes deriving its env settings from the pod during deployment. The same image may be used in multiple pods each using a different configuration.

Thoughts?

joho commented 6 years ago

Hi Daz,

I'm not 100% sure what you're asking, but I think you're asking if I'd recommend your approach?

If so, I'd have to say probably not. dotenv isn't really designed to be a production config injection tool, but instead a development fallback to emulate ENV based configuration set up in the 12 factor app style popularised by heroku. In common usage the call to Load in production is meant to be a no-op.

I'm not very familiar with kubernetes so this advice is likely not very good, but I'd look to the example under section 3 in https://www.mirantis.com/blog/how-do-you-build-12-factor-apps-using-kubernetes/ to inject your configmap as environment variables. There are many valid critiques of using ENV variables for secrets and if those arguments apply to you, I'd recommend staying away from the dotenv family of tools.

DazWilkin commented 6 years ago

@joho Thanks!

Yes, I was asking for your recommendation and proposing one way to incorporate this into K8s.

Reading your response, I agree that godotenv is probably not suitable for Kubernetes deployments.

The solution I proposed is a reflection of how godotenv is used locally but applied to Kubernetes.

Config remains externalized and provided through Kubernetes recommended Pod config mechanisms (ConfigMaps). It supports providing environment variables through env properties on the pod spec and it will use env properties from a config file if provided by godotenv.

joho commented 6 years ago

Glad I could help you clarify your thinking - good luck with you k8s setup!

pixie79 commented 6 years ago

@DazWilkin I think you are looking for something like this https://github.com/UKHomeOffice/kd

alo-zi commented 2 years ago

@DazWilkin is that working with kube secret?