How to prepare a .NET 5.0 webapi for Kubernetes based deployment

Thomas Scherer
8 min readMar 14, 2021

This tutorial deals with preparing a .NET based webapi for Kubernetes deployment.

It is part of a multi-series tutorial for full stack development using .NET 5.0 for API development, Gravitee for API management and React for frontend development:

Here, we will strip away all those code pieces , which we will handle in later articles by an API gateway or the Kubernetes cluster itself. We will add those parts, which allow us to build a docker image to wrap the API, and add elements to the code, which allow us to better integrate with and take leverage of a Kubernetes cluster.

So we will prepare a webapi with DB for CRUD operations. Notably, we will:

  • Disable https and CORS, since we offload this to an API gateway in the next article
  • Get logging onto console, such that Kubernetes is able to monitor the application health and to receive debug information in a Kubernetes deployment
  • Parametrize DB connection, such that this can be configured via Kubernetes yaml files at deployment time
  • Automatic initialisation of the DB scheme if not present
  • Build, run, debug and push the docker image
  • Deploy the API including DB onto a Kubernetes cluster

So let’s start.

Preparation and context

Here we assume you have a running .NET 5.0 based webapi interfacing a database. We will later deploy both onto Kubernetes.

For getting started with webapi and have a first API in place in Visual Studio Code, you may use the introductory tutorial here:

This tutorial scaffolds a webapi out of a single Model class to perform CRUD operations onto an in-memory database.

Alternatively you may pull the code of this tutorial from github here:

Now, if you wish to autocreate a DB system from exactly the same model to achieve persistency, then Entity Framework Core, can help, as we will also do in this tutorial and in a nutshell here:

Additionally you should have an up and running Kubernetes cluster, locally, or in a cloud. You are ready to go if you can deploy onto a cluster and know the basic concepts as described here:

You will need Docker, and the Docker extension within Visual Studio Code to wrap your code into a docker container:

You need Docker Hub or any user container image repository to upload your image and pull it from Kubernetes your cluster.

Finally, a local database system is required to test the API. I am using postgreSQL, and hence below code tweaks assume such but any other will work as well.

Preparing the API

Now you should have a .NET webapi project in Visual Sutdio Code, which we prepare, e.g. based on above tutorial, or a naked by issuing on CLI.

It is time to prepare the API for Kubernetes based hosting. As explained in the introduction, we try to achieve an as small as possible microservice, and offload most generic work to Kubernetes or an API gateway.

Disable https and redirection

The default template uses https. Here we will focus on deploying the api on a Kubernetes cluster. We will let the Kubernetes ingress gateway handle all ssl offloading. So we won’t need this as part of the microservice. In some cases, it may nonetheless be preferred to stick to https traffic within the Kubernetes cluster. To still achieve a most stripped code, I recommend offloading https to a service mesh for in-cluster security, traffic management and https offloading, such as ISTIO.

There’s not much to be done to disable https. First is to comment the required line in Startup.cs.

Second, change the applicationUrl parameter in launchsettings.json to exclude https.

Get http request logging to console

Kubernetes assumes console logging of hosted containers. Doing so will greatly help troubleshooting and will ensure that health status is properly displayed of the container in the Kubernetes cluster. Logging is configured in appsettings.json and/or appsettings. Development.json. I prefer heaving all logging on “Information”-level, so to see requests to the API later on (at least for development purposes). The default is “Warning”-only.

Disable CORS

Since we’ll be hiding the API behind a gateway, and we want to offload as much as possible off the code to the gateway, we disable CORS as well. All this is configured in Startup.cs

Adding DB connector and parametrize database configuration for later Kubernetes configuration

As part of introductory tutorials or whatever the case may be, you’ll be adding a DB connection. The introductory tutorial inserts a full connection string. Using Docker and/or Kubernetes, we are later able to add such parameters as environmental variables into the deployment configurations, such that we can configure everything in a “Infrastructure as a Script” mode.

Using .NET makes it pretty easy to achieve this. The appsettings.json file serves as interface between environmental variables configured by the Docker or Kubernetes deployment and the code. So, in this example we will configure the DB connector in such manner, that we are later able to connect each deployment where ever we deem useful. Here in this example, we configure all DB settings as follows in appsettings.json:

Later on, when we deploy the API using Docker or Kubernetes we may set those variables using two underscores between subitems “__”. For example the DBConnection can be altered — as we do later — in a Kubernetes yaml file as follows:

Now we can use those variables in .NET where ever we wish doing so. Here for establishing the DB connection. In my example, we need to add the required SQL and PostgreSQL modules via CLI.

Additionally, we need to establish the DB connection in Startup.cs.

Auto-deploy database (i.e. use existing DB or create a new DB at deployment time)

With the above code, a model class behind and it’s DB context (please check the tutorial from Microsoft for webapi and EF above or use the code summary below), you have all ingredients in place to auto-create a DB onto the database system, which is connected via the configuration as we did before. Microsoft Entity Framework uses the Model description to create a DB scheme and deploy it onto the database. The necessary code can be autogenerated via command line:

This will create a new folder called “Migrations” in your project with the necessary code to deploy a DB. Above tutorial deploys such DB via CLI. Since we here want to get rid of any manual task — and as usual today, we will let the code deploy the necessary DB onto the system if the db “mydb” is not existing. So later on, when we deploy this container. If the DB exists, then it will use the existing one. Otherwise it will deploy a fresh DB onto the configured DB system and one avoids any manual schema creation.

For this add MigrationManager.cs into the Migrations folder:

Finally you need to issue this code to run at launch time:

Create and test docker image

Now it’s time to actually build and wrap the code into a docker container. You may follow the steps of this tutorial

In short: open the command palette (⇧⌘P or shift-ctrl-p), click “Docker: Add Docker Files to Workspace…”. Follow instructions (I recommend linux container).

This will create the Dockerfile. Add the ENV ASPNETCORE_URLS variable to ensure proper port binding:

Environmental variables can be set within .vscode/tasks.json. There you will find sections for docker based debugging and releasing. The dockerRun part hosts the environmental variables, which you may want to add:

Probably you still have localhost as DB host setting. This won’t work for the docker container since it has it’s own IP. So, please adjust accordingly.

Now you may build the image as explained in the previous tutorial.

In short: open the command palette (⇧⌘P or shift-ctrl-p), click “Docker Images: Build Image…”.

You may launch the code within docker via the debug tab in visual studio code. Use “Docker .NET Core Launch”

For those, who are using PostgreSQL, please instruct your configuration to listen on the correct IP (via postgresql.conf) and allow sql from clientIP addresses (pg_hba.conf).

Under the docker tab you can configure access to your docker repository like Docker Hub. Right-click the image and click “Push…” to upload the image (your namespace is your user name on docker hub).

Deploy onto Kubernetes

Now, with a ready to use image, the entire installation can be deployed onto Kubernetes. We will deploy the Postgres database system as well as the api.

First we deploy postgres from the public image repository. Following file will cover the deployment of a persistant storage for the DB, the pod for running postgres plus the service to reach the DB:

This will create a fresh new PostgreSQL installation onto Kubernetes, which can now be used by the api, which we have created. So, next step is to deploy the API with the DB connection string and the service to reach out for the API:

Again, we can deploy via cli.

Now we have deployed our API and it’s Database to Kubernetes. To make the API externally reachable, one needs to add an ingress, as described here:

Also, this is covered in the next tutorial of this series:

Code Summary

All code can be found here:

Yaml files for the Kubernetes deployment are here:

Here, I will add all changed files to run a sample API on a default webapi project in visual studio. Such that all code is complete.

First create the project on cli including all dependencies:

Add below model code to the project as needed.

Create entity framework migrations via cli

Then add controllers below or scaffold them

Aside to model classes, I suggest copy basting from below as needed and described before.

Here comes the Model in folder Model

Now the API controllers

--

--