Kubernetes generating dynamic config files

12/15/2017

I would like to generate dynamic configuration files (redis, database) based on values (ex.redis_host) collected from env variables which will differ from service to service and put it on a specific location (config/redis.yml).

How will i be able to achieve it?

-- Daniel Sagayaraj
docker
kubernetes
kubernetes-helm

2 Answers

12/15/2017

Dynamic Config file generation can include creation of

  1. Config file structure:

    The config files for e.g redis.yaml might varry for development, staging, production environments. eg:

    staging

    ${ENVIRONMENT}:
        host: ${REDIS_HOST}
        namespace: ${REDIS_NAMESPACE}
        port: 6379

    production:

    ${ENVIRONMENT}:
        host: ${REDIS_HOST}
        namespace: ${REDIS_NAMESPACE}
        port: 6379
        connect_timeout: ${REDIS_CONNECT_TIMEOUT}
        timeout: {REDIS_TIMEOUT}
  2. Config file content:

    The content of the config files could again be populated dynamically.

we could generate config-templates or config-file-structure using helm and mount them in the required place (say config/redis.yaml ) inside the pod.Then these config-templates can be converted/rendered into proper file using utilities at container run time.

Dynamic creation of config files based on the environment/environment_variables could be achieved using following ways.

The Bash Way (using eval and cat):

  1. Create a file named inator with the following content

    #!/bin/bash
    eval "cat <<EOF 
    $(<$1)
    EOF
    " | tee $1 >/dev/null
  2. Make inator as executable and place it inside the docker image and execute it as a ENTRYPOINT script

  3. Considering the env varibles are avilable inside the pod/container

    eg: staging

    $ env
    ENVIRONMENT=staging
    REDIS_HOST=abc.com
    REDIS_NAMESPACE=inator
    
    $ cat config/redis.yaml
    ${ENVIRONMENT}:
       host: ${REDIS_HOST}
       namespace: ${REDIS_NAMESPACE}
       port: 6379
    
    $ ./inator config/redis.yaml
    $ cat config/redis.yaml
    staging:
      host: abc.com
      namespace: inator
      port: 6379

    production

    $ env
    ENVIRONMENT=production
    REDIS_HOST=redis.prod.com
    REDIS_NAMESPACE=prod
    REDIS_CONNECT_TIMEOUT=5
    TIMEOUT=10
    
    $ cat config/redis.yaml
    ${ENVIRONMENT}:
       host: ${REDIS_HOST}
       namespace: ${REDIS_NAMESPACE}
       port: 6379
       connect_timeout: ${REDIS_CONNECT_TIMEOUT}           
       timeout: {REDIS_TIMEOUT}
    
    $ ./inator config/redis.yaml
    $ cat config/redis.yaml
    production:
      host: redis.prod.com
      namespace: prod
      port: 6379
      connect_timeout: 5
      timeout: 10

Advantages: no additional package required.

The dockerize way:

dockerize is a utility to simplify running applications in docker containers. It internally uses go templates to populate config files from environment variabels.

Have a look at this blog post Environment Variable Templates for further information.

-- codenio
Source: StackOverflow

12/15/2017

Maybe helm can help you out here. Helm allows you to template your k8s yaml files and bundle them into one deployable k8s package. Your configuration files might be placed in ConfigMaps and can also be templated with helm. How this is done in detail can be seen in the chart template guide.

One way to fill these templates at deploy time then would be:

helm upgrade --install my-service /path/to/my/chart/package --set my.value=${MY_VALUE_ENV_VAR}
-- fishi0x01
Source: StackOverflow