Configuration
Last updated
Last updated
The configuration of the application in a container is often communicated through environment variables (abbreviated env).
Kubernetes provides us with a way to pass a list of envs inside each Pod container. For example, we have an image 080196/hello-env with the following code:
In this image we have the PORT configuration of the application that will be passed inside the container through env PORT. Create a file named pod-hello-env.yaml with the following configuration:
In this config file, we have specified an attribute named env, this is a Pod attribute that helps us pass env inside the container, with the name of env being PORT and its value will be 3000, note that the value env value is always a string , if you leave it as a number it will give an error. Now we create the Pod and check the log.
Here, our application runs correctly according to the PORT we passed into the container through env. You can check more closely by accessing the container and printing out its env as follows:
Note that this env list will not be able to update inside the container when that container is already running. To update, we must delete the Pod to get it running again.
Using env to pass configuration inside the container is very easy, but as our application gets larger and needs more and more env, we will realize that specifying env directly in the Pod like this has many limitations. Firstly, our config file will be extremely long, secondly, if there are some envs we will use over and over again, we will copy and paste them in many places. For example:
In this config file we have 2 Pods, one Pod runs the application and one Pod runs the database. We will see that the configuration related to database information will be repeated twice. When our application grows, it will need a lot more envs. At this point, we just want to declare the general configuration in one place, and use that configuration to reuse many times. Then kubernetes provides us with a resource to do that, ConfigMap.
Note that information about the user and password of the database is sensitive data. Usually with sensitive information we will not use ConfigMap but will use Secret (will be discussed below), here for example. so we will ConfigMap.
This is a resource that helps us separate configuration. The value will be defined as key/value pairs in the data attribute, as follows:
And this value will be passed inside the container as an env. And because ConfigMap is an individual resource, we can reuse it for many different containers. Using ConfigMap is a way to avoid having to write the env configuration inside the Pod container config.
Now we will create a ConfigMap. Create a cm-db.yaml file with the following configuration:
Here we will create a ConfigMap named postgres-config with 3 keys: DB, USER, PASSWORD.
Or we can also create ConfigMap through the cli command without writing a config file, as follows:
Pass ConfigMap inside the container. We will reuse the example above, create a file named pod-with-cm.yaml using image 080196/hello-cm , the image code is as follows:
Config of pod-with-cm.yaml file:
Here we will use the envFrom attribute instead of env to specify the use of ConfigMap, the prefix field will be concatenated in front of all our envs with the value POSTGRES_. As you can see, instead of having to rewrite env in both Pods, we just need to create a configmap and use it many times. Let's create and test:
Here we check that the Pod db is running, then let's create a hello-cm pod and test it:
If we log in and print out the line connect db successfully , then we have successfully passed the configuration to the container through ConfigMap. At this point, we know how to pass configuration through env to the container using ConfigMap. But what if our application's configuration is a config file? We can also use ConfigMap.
With ConfigMap we can use a key whose value is the content of an entire config file, as follows:
For example, we will create a config file for nginx that compresses its responses before returning it to the client, creating a file called nginx-config-cm.yaml with the following config:
Here we create a ConfigMap with the name nginx-config, with the key my-nginx-config.conf which will be the name of the file when we pass it into the container. Create a file named pod-nginx.yaml with the following configuration:
Here, our ConfigMap will be used as a volume, with content being the content in the ConfigMap. At this time, our volume will contain a file named my-nginx-config.conf, then this file will be mounted to the web-server container in the /etc/nginx/conf.d folder, we will have /etc/nginx/ conf.d/my-nginx-config.conf
Let's create a Pod and check if our config is correct:
Open another terminal:
We can check more closely by accessing the Pod:
Here it is, this is the file that we mounted into the container via ConfigMap. Let's print its content and see:
This is the value of the my-nginx-config.conf key that we defined in ConfigMap. We can also change the name of the file by writing config in the volume as follows:
Here we rename the file from my-nginx-config.conf to gzip.conf using the path attribute. We can also just mount the content of the file:
Here, we copy the content from the file my-nginx-config.conf to gzip.conf. If you want to specify file permissions, use the defaultMode property.
When we use ConfigMap in the form of volume config. If we change the value of ConfigMap, it will automatically referencing and updating inside the Pod's volume, and we need the application to detect changes in our config file to reload the new config and re-run. If we use ConfigMap in env form, it will not update automatically, we need to re-create the Pod.
We use ConfigMap when we want to use config in many different Pods and the data is not sensitive data. For sensitive data, kubernetes provides us with another resource called Secret .
Secret is similar to ConfigMap, data is stored as key/value pairs, the way we use Secret is similar to ConfigMap. Secret is different from ConfigMap in that it is used to contain sensitive data. For ConfigMap, developers who can access our kubernetes cluster can read it, but for Secret, this data is not readable by everyone, right? Only with permissions granted by the administrator can we read.
In addition, kubernetes will increase security a bit by only sending secrets to worker nodes that have a Pod that needs to use it, and the Secret data will be stored in memory and never in physical storage, this will help when workers If the node dies, the Secret in memory will be deleted. And at the master node, the Secret will be saved under etcd in encrypted form.
To create a Secret, we should use CLI rather than creating a config file. Back to the DB example above, instead of using ConfigMap, we will use Secret.
When we look at the secret information, we will see that it is saved in base64 encoded format.
Use Secret in Pod.
Here we will use the secretRef attribute instead of configMapRef. When we pass the Secret to the Pod it will be decoded from base64 form back to the same.
Remember:
Use ConfigMap for non-sensitive, plain configuration information.
Use Secret for sensitive information, use CLI, not config file.