If you are working on .net core application and doing the kubernetes deployment, there is an important consideration one must consider which will be explained below
Every .net core project consists of one config file(appsettings.json) which contains connection strings that includes sensitive information such as server ips, passwords etc that shouldn’t be exposed to anyone. They are different for different environments like development, staging, production. They are highly confidential and should only be given access to very few people like the ones who are working on deployment.
Dockerising the application is the first step before deployment. However, Dockerising the .net core including appsettings file is not the recommended way to do since anybody who pulls the docker image will be able to look into the contents of file.
In case, we remove the appsettings.json file in our project files and then build docker image and do deployment, Ofcourse it doesn’t work because we might have mentioned required information such as ip address and some other key values in the config file.
So, One simple solution to overcome this problem would be moving .net core appsettings.json to kubernetes secrets and loading that config file from container image.
Step 1: Creating the secrets
Command used to create the secret is
Kubectl create secret generic my-secret1 –from-file=”<path>\appsettings.json”
‘my-secret1’ is the name of the secret that we gave and ‘path’ is the path in which the appsettings file is present. Do not keep this file with other project files. Keep it in a different folder so that it wont be included when we do docker build.
To check if the secrets has been created properly, use the command
kubectl get secrets
This will return all the secrets created. In our case, it will be just one named ‘my-secret1’.
Now, we can build the docker image and proceed to step 2.
Step 2: Using the secrets in kubernetes deployment file
Adding the secrets is simple and can be done by adding few fields in the deployment file as follows.
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: secrets-demo
spec:
replicas: 2
template:
metadata:
labels:
app: secrets-demo
spec :
containers:
– name: secrets-demo
image: <image name>:latest
ports:
– containerPort: 80
volumeMounts:
– name: secrets
mountPath: /app/secrets
volumes:
– name: secrets
secret:
secretName: my-secret1
‘volumes’ field is added to tell the deployment to use the secret named my-secret1 that we created already in step1.
volumeMounts is used to mount that secret into the container.i.e at app/secrets.
Now our file is present in app/secrets/appsettings.json. But, the problem is our project code might be configured to look for appsettings.json in the root folder. As per what we did, it is somewhere inside sub directory i.e app/secrets/appsettings.json and not in the root directory i.e app/appsettings.json. So the file doesn’t get loaded and our project doesn’t work as expected.
However, if we change the mountPath to /app, there is a catch here. When we mount the path to /app. It will remove all the existing files in “app” directory and add the appsettings.json file. This is because of the nature of volumes in kubernetes. Now in app directory, instead of all project files, only appsettings.json file is present.
To solve this problem, we need to use one more field called as subPath. Basically, subPath is used to mount a file to existing directory.
Now modify the deployment file as follows:-
kind: Deployment
metadata:
name: secrets-demo
spec:
replicas: 2
template:
metadata:
labels:
app: secrets-demo
spec:
containers:
– name: secrets-demo
image: <image-name> :latest
ports:
– containerPort: 80
volumeMounts:
– name: secrets
mountPath: /app/appsettings.json
subPath: appsettings.json
volumes:
– name: secrets
secret:
secretName: my-secret1
Create the deployment using the following command,
kubectl apply -f <deployment file name.yaml>
Now, in a container, appsettings.json is stored in app directory along with existing project files. If there are multiple config files, multiple subpaths have to be added. As per the kubernetes documents, subPath configuration is not recommended for production use. We need to somehow change the code and pull the config file from .net core middleware.
In this way, we can exclude appsettings.json in our build. We store it in kubernetes secret and pull it from the container image modifying the kubernetes deployment file.
Thanks for reading! I hope you enjoyed the article.
Related links:
https://kubernetes.io/docs/concepts/configuration/secret