How to deploy multiple services in a Kubernetes cluster and how to inject environment configuration settings on deployment time.
Introduction
The purpose of this article is to show how we can create a
companion application to support the API and for the most part how to use
mounted volume feature in Kubernetes to allow configuration information that
needs to be passed to an application deployed on Kubernetes cluster. This
article also services as the last part of the series of articles talking about
leveraging the Kubernetes, docker and ASP.NET core to create a truly cloud
native application.
Why
An obvious question is that why we care about mounted
volume. The reason we care about mounted volume is because this how we can pass
environment and configuration information to an application that is hosted by
Kubernetes cluster. When creating an ASP.NET core application or any application
that has configuration, we come across the question of configuration and how to
handle it. We live in a world where application does not need to know which
environment it is being hosted in. It just need to focus on what that
application is designed for (creating value). The configuration information
should be stay in the environment and the application when it is being
provisioned should pick those configuration information and run with it.
Mounted volume allows us to store environment specific information that the
applications can use.
Solution
So far we have been successful in creating a Kubernetes
cluster that is hosted an ASPNET Core Api. The next logical step is to add a
front end application that will use the Api. We can host that frontend application
anywhere but since we are using Kubernetes then why don’t we leverage
Kubernetes and use the same cluster that we had created before. So what this article will detail is how we go
from single service Api deployed on a Kubernetes cluster to multi service (Api
and Web App) deployed on Kubernetes cluster.
The following image shows the transition from initial state
to the final state.
Source code for the API app can be found at: https://github.com/mnabeel/mac-api
Source code for the Web app can be found at: https://github.com/mnabeel/mac-app
Once we deploy the API app and Web and we query the services
on the Kubernetes cluster by running “kubectl
get services” command, we get the following:
The API app and deploying it to Kubernetes is pretty
straight forward. It has self-contained database and now external dependencies.
The case is different for the Web App as it needs to know the reference
(endpoint url) to the API app. Since we are using Kubernetes to deploy the API
app and Web App, we run into the issue that the URL of the API app can change
whenever Kubernetes restarts the pod or we have to resurrect the Kubernetes cluster
or services.
One solution could be that every time we see a change in the
API endpoint, we update the source code for the Web App, recreate the docker
image, push the docker image to the docker hub and then recreate Kubernetes
deployment and expose the service.
The other solution is to use mount volume as secret to
supply the url of the API app whenever there is a change in the API endpoint. And
that is the purpose of this article. To
accomplish this will need to create a store in our web app that will carry the
base URL of the API app. This is done be creating a folder called “secrets” and
the creating a file called “appsettings.secrets.json” as shown below:
You can see that the ConnectionString element is pointing to
a “localhost”. When it is time to deploy
will create “appsettings.secrets.json” as a secret and use it when we are
creating a deployment for the Web app.
Let us take a look at the Deployment.yaml which is also part of the
github repo for the web app mentioned above.
As mentioned above in the highlighted red square we have
information about the volumeMounts and secrets. This is who we are declaring
where the secrets will be mounted on the deployed service by Kubernetes.
Important thing to note here is the secretName field. It is important to use
the same value for secretName field that we will use in the step to create a
secret in Kubernetes cluster. The value for secretName is :
“secret-appsettings”
In order for us to deploy the Web App service in Kubernetes,
we also need to create a Service.yaml file. Here is the screenshot:
We have the source code for the WebApp (github link provided
in previous sections), we have the Deployment.yaml that tells us how the
deployment will be created, and we also have the service.yaml that will tell
the Kubernetes how to create the service from the deployment. That completes
the prerequisites for deploying Web app to Kubernetes. We can now proceed to
deploy. Here are the steps.
1.
Create secret:
“kubectl create secret generic secret-appsettings --from-file=./appsettings.secrets.json”
“kubectl create secret generic secret-appsettings --from-file=./appsettings.secrets.json”
Running the above kubectl command will
create the secret. One thing to note here is that we are using the same name
for secret as we have in the Deployment.yaml which is “secret-appsettings”.
2.
Confirm that new secret has been created by
running the following command:
“kubectl get secrets”
“kubectl get secrets”
3. Create
Kubernetes deployment by running the following command:
“kubectl create –f deployment.yaml”
“kubectl create –f deployment.yaml”
4. Create
Kubernetes service by running the following command:
“kubectl create –f service.yaml
“kubectl create –f service.yaml
That will deploy the web app in your Kubernetes cluster.
How to change the secret
Follow the following steps:
1.
Update the appsettings.secrets.json file from
the runtime location of your command.
2.
Delete the old secret by running the following
command
5.
Recreate the new secret (which will carry the
new endpoint as it will reference the updated “appsettings.secrets.json” file)
by running the following command:
“kubectl create secret generic secret-appsettings --from-file=./appsettings.secrets.json”
“kubectl create secret generic secret-appsettings --from-file=./appsettings.secrets.json”
6. Update
the Web App deployment which will automatically push the change in the URL to
Web App. This can be done many ways. What I have found easy to follow is to
first delete the old deployment and then running the creating of deployment
again as shown in the following command that was mentioned in the previous
section:
“kubectl create –f deployment.yaml”
“kubectl create –f deployment.yaml”
Here is how the application looks like:
This is basically a simple front end that
displays the member information from the api and allows the user to enter a new
member. On the above screenshot, you
will notice that I am printing some information about the host, environment,
and the endpoint url to the API that the frontend app is using. This way I know
what endpoint app is hitting for data. Notice that URL value is not showing http://localhost:8000 but it is showing this
value as http://35.202.95.20 . This means our
secret injecting on deployment time using mounted volume worked.
Conclusion
In this article we have seen how we can
deploy two different applications in the same Kubernetes cluster and how we can
use mounted volume to inject configuration information to an application that
is deployed on a Kubernetes cluster. This article is the last part of the
series articles that talk about deploy ASP.NET Core app using containerization
technology and then leveraging Kubernetes as a container orchestration engine.
I like your article . Go to this site and read the interesting thing that you must need to know.Cloud Security
ReplyDeleteReally nice post, share more post. Cloud Services Provider | Cloud Managed Services Providers | Digital Marketing | Cloud System Integrators | Cloud Migration
ReplyDelete