avatarAnto Semeraro

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

6697

Abstract

lled ‘my-app’.</li><li>Run 3 replicas of your application, meaning that there will always be three copies of your application running.</li><li>Use the ‘my-app:latest’ image, which is the image you built with Docker.</li><li>Listen on port 80 inside the container.</li></ol><h2 id="fa31">Applying the Kubernetes Configuration</h2><p id="e00d">To apply this configuration to your Kubernetes cluster, you would save it to a file (for example, ‘deployment.yaml’), then run:</p><div id="e0e0"><pre>kubectl apply -f deployment.yaml</pre></div><p id="f288">This command tells Kubernetes to create the resources described in the ‘deployment.yaml’ file, and in this case, that’s a deployment with three running instances of your application.</p><h1 id="ab15">Creating a .NET Microservice Locally Using Docker and Kubernetes: A Case Study</h1><figure id="71c2"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*IOZTPlXz0yoX2OAFMPZD7g.jpeg"><figcaption><a href="https://unsplash.com/photos/yW-Qgw_IJXg?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Maya Maceka</a></figcaption></figure><p id="e8ba">In this section, we will create a simple but attractive .NET microservice — a basic web API, and then package this service in a docker container and deploy it locally using K8s.</p><h2 id="0a12">Building a Simple .NET Web API</h2><p id="7fff">Let’s create a new .NET Web API project by running the following command in your preferred terminal:</p><div id="3e54"><pre>dotnet new webapi -n NetDeploymentMicroservice</pre></div><p id="2559">This will create a new .NET Web API project named “NetDeploymentMicroservice”; in this project, you’ll find the usual <code>WeatherForecastController</code> that returns a list of weather forecasts, and it's simple, but it's enough to demonstrate deploying a .NET microservice.</p><figure id="6670"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*MkJRuk17c7gExJZ2zXWnoA.png"><figcaption>Building a Simple .NET Web API console output | Author</figcaption></figure><h2 id="ac4b">Dockerizing the .NET Web API</h2><p id="203b">Next, we will create a Dockerfile in the root of the project, which is used to build a Docker image of our application; here’s a basic Dockerfile for a .NET application:</p><div id="f571"><pre>FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build-env WORKDIR /app

<span class="hljs-comment"># Copy everything and build</span> COPY . ./ RUN dotnet publish -c Release -o out

<span class="hljs-comment"># Build runtime image</span> FROM mcr.microsoft.com/dotnet/aspnet:7.0 WORKDIR /app COPY --from=build-env /app/out . ENTRYPOINT [<span class="hljs-string">"dotnet"</span>, <span class="hljs-string">"NetDeploymentMicroservice.dll"</span>]</pre></div><p id="cd3b">To build this docker image, navigate to the directory containing the Dockerfile and execute the following command:</p><div id="6fd0"><pre>docker build -t netdeploymentmicroservice:v1 .</pre></div><p id="8d67">This command creates a docker image named <code>netdeploymentmicroservice</code> with a <code>v1</code> tag.</p><figure id="41b6"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*Ze4vskYeftF5cJTFxUUxdA.png"><figcaption>This is the expected output, pulling resource and building the image | Author</figcaption></figure><figure id="0be5"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*p3-45evX9eDj4sYbm8HcDg.png"><figcaption>The end of the output | Author</figcaption></figure><p id="d899">To check if your image is built, you can list the docker images on your machine using <code>docker images</code>.</p><h2 id="e750">Creating a Kubernetes Deployment</h2><p id="cd88">With the docker image created, we can now move onto deploying this image using K8s, so we need a deployment configuration:</p><div id="37ff"><pre><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">apps/v1</span> <span class="hljs-attr">kind:</span> <span class="hljs-string">Deployment</span> <span class="hljs-attr">metadata:</span> <span class="hljs-attr">name:</span> <span class="hljs-string">netdeploymentmicroservice-deployment</span> <span class="hljs-attr">spec:</span> <span class="hljs-attr">replicas:</span> <span class="hljs-number">2</span> <span class="hljs-attr">selector:</span> <span class="hljs-attr">matchLabels:</span> <span class="hljs-attr">app:</span> <span class="hljs-string">netdeploymentmicroservice</span> <span class="hljs-attr">template:</span> <span class="hljs-attr">metadata:</span> <span class="hljs-attr">labels:</span> <span class="hljs-attr">app:</span> <span class="hljs-string">netdeploymentmicroservice</span> <span class="hljs-attr">spec:</span> <span class="hljs-attr">containers:</span> <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">netdeploymentmicroservice</span> <span class="hljs-attr">image:</span> <span class="hljs-string">netdeploymentmicroservice:v1</span> <span class="hljs-attr">ports:</span> <span class="hljs-bullet">-</span> <span class="hljs-attr">containerPort:</span> <span class="hljs-number">80</span></pre></div><p id="302f">This configuration will instruct K8s to pull the <code>netdeploymentmicroservice:v1</code> image we created, run 2 replicas (instances) of it, and expose port 80 on each container.</p><p id="0324">To apply this configuration, save it to a file called <code>k8s-deployment.yaml</code> and use the following command:</p><div id="feb0"><pre>kubectl apply -f k8s-deployment.yaml</pre></div><figure id="af9a"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*oimsmHsvU_hocNVX-yObag.png"><figcaption>Our service has deployment configuration applied now | Author</figcaption></figure><h2 id="62e3">Creating a Kubernetes Service</h2><p id="b4b4">The deployment is up, but it’s not accessible yet, so to access it, we need a Kubernetes service; here’s a simple configuration:</p><div id="2ab5"><pre><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">v1</span> <span class="hljs-attr">kind:</span> <span class="hljs-string">Service</span> <span class="hljs-attr">metadata:</span> <span class="hljs-attr">name:</span> <span class="hljs-string">netdeploymentmicroservice-service</span> <span class="hljs-attr">spec:</span> <span class="hljs-attr">selector:</span> <span class="hljs-attr">app:</span> <span class="hljs-string">netdeploymentmicroservice</span> <span class="hljs-attr">ports:</span> <span class="hljs-bullet">-</span> <span class="hljs-attr">protocol:</span> <span class="hljs-string">TCP</span> <span class="hljs-attr">port:

Options

</span> <span class="hljs-number">80</span> <span class="hljs-attr">targetPort:</span> <span class="hljs-number">80</span> <span class="hljs-attr">type:</span> <span class="hljs-string">LoadBalancer</span></pre></div><figure id="499a"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*Tv4w-qwTvj8SdxiHwxQnyg.png"><figcaption>If you did right all previous steps, you’re solution should look like this | Author</figcaption></figure><p id="5586">This configuration creates a service that exposes our deployment to external traffic, and to make it work, save this to a file called <code>k8s-service.yaml</code> and apply it with:</p><div id="3fd4"><pre>kubectl apply -f k8s-service.yaml</pre></div><figure id="efc8"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*tvpwNRRppBkxynATwyVzxA.png"><figcaption>Service created successful output | Author</figcaption></figure><h2 id="3b43">Testing the Deployment</h2><p id="a0b4">To test if everything is working, we can use <code>kubectl</code> to get our services:</p><div id="6e34"><pre>kubectl get services</pre></div><p id="3f1f">You should see your <code>netdeploymentmicroservice-service</code> in the list; there's a column named "EXTERNAL-IP" which you can use to access your service from a web browser.</p><figure id="edc6"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*wYsx1bwMBKP6BBV6cfNiOA.png"><figcaption>Here’s my output and how it should look like | Author</figcaption></figure><p id="8368">So, that’s it! We’ve created and deployed this .NET microservice example locally using Docker and Kubernetes.</p><h1 id="0f66">Final Thoughts</h1><figure id="8ff1"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*EwJnAEToUJBuXFc49bXwgQ.jpeg"><figcaption><a href="https://www.pexels.com/photo/photo-of-person-standing-on-rock-near-lake-2531455/">Simon Berger</a></figcaption></figure><p id="0438">So, we’ve explored the world of docker and kubernetes for deploying .NET microservices, demystifying these powerful tools, and with this step-by-step guide and hands-on case study, you’ve seen how to bring a .NET microservice to life, from creation, through dockerizing it, to deploying.</p><p id="6bbb">Take your learning to the next level with our other article titled “<a href="https://readmedium.com/net-7-docker-crafting-high-performance-microservices-architecture-1300e39939c2"><b>.NET 7 & Docker: Crafting High-Performance Microservices Architecture</b></a>”, where I dig deeper into how to revolutionize your software development with cutting-edge, containerized microservices powered by .NET 7 and Docker.</p><p id="9d1f">I’ve included a detailed case study of a video streaming platform, so you can see these concepts in action in a real-world scenario, so it’s a must-read if you want to supercharge your .NET microservices deployments with the latest techniques and tools.</p><p id="b1dc">Keep learning, keep exploring, and keep deploying those impressive .NET microservices!</p><figure id="d064"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*NLdUe7cNs7AjgKfammK-mg.png"><figcaption>Reading Advice | <a href="https://amzn.to/445cgUW"><b>Kubernetes and Docker — An Enterprise Guide: Effectively containerize applications, integrate enterprise systems, and scale applications in your enterprise</b></a>, by Scott Surovich and Marc Boorshtein, 2020, Packt Publishing</figcaption></figure><blockquote id="d020"><p><i>📕</i> Gentle nudge: Deciding to purchase this book equates to backing my endeavors, all without any extra cost to you. Your support is deeply acknowledged! <i>🏆</i></p></blockquote><h2 id="3190">Further Reading:</h2><div id="2f1b" class="link-block"> <a href="https://gethelios.dev/blog/cut-engineering-costs-save-time-helios?utm_source=medium&amp;utm_medium=referral&amp;utm_campaign=cloud+native+daily"> <div> <div> <h2>Microservices Monitoring: Cutting Engineering Costs and Saving Time</h2> <div><h3>A few ways fort leveraging Helios to save on engineering costs and dev time for a more resource-efficient organization…</h3></div> <div><p>gethelios.dev</p></div> </div> <div> <div style="background-image: url(https://miro.readmedium.com/v2/resize:fit:320/0*cpM8NUdfMtkgVkpU)"></div> </div> </div> </a> </div><div id="8646" class="link-block"> <a href="https://gethelios.dev/blog/testing-microservices-with-helios/?utm_source=medium&amp;utm_medium=referral&amp;utm_campaign=cloud+native+daily"> <div> <div> <h2>Testing Microservices - Trace Based Integration Testing Example</h2> <div><h3>Microservices architectures require a new type of testing. Here's why traditional testing fail and the new automated…</h3></div> <div><p>gethelios.dev</p></div> </div> <div> <div style="background-image: url(https://miro.readmedium.com/v2/resize:fit:320/0*njfrxTDPtOGC_3b5)"></div> </div> </div> </a> </div><div id="cb96" class="link-block"> <a href="https://gethelios.dev/blog/kubernetes-monitoring-opentelemetry/?utm_source=medium&amp;utm_medium=referral&amp;utm_campaign=cloud+native+daily"> <div> <div> <h2>Kubernetes Monitoring with OpenTelemetry</h2> <div><h3>Learn how to monitor Kubernetes using OpenTelemetry with real-time visibility and granular error data - Reduce MTTR by…</h3></div> <div><p>gethelios.dev</p></div> </div> <div> <div style="background-image: url(https://miro.readmedium.com/v2/resize:fit:320/0*UWOgvyfWtYW7nIRH)"></div> </div> </div> </a> </div><div id="f87f" class="link-block"> <a href="https://gethelios.dev/blog/serverless-observability/?utm_source=medium&amp;utm_medium=cloud+native+daily"> <div> <div> <h2>Serverless observability, monitoring, and debugging explained</h2> <div><h3>Serverless troubleshooting requires E2E observability, through collecting trace data on top of logs and metrics- Here's…</h3></div> <div><p>gethelios.dev</p></div> </div> <div> <div style="background-image: url(https://miro.readmedium.com/v2/resize:fit:320/0*2kr1vg8kVWLOo9O1)"></div> </div> </div> </a> </div></article></body>

Picture by Author ©

Back-End Development

Understanding Docker and Kubernetes Configurations for .NET Microservices Deployment

From understanding Docker and Kubernetes to deploying .NET microservices with a hands-on case study, discover the key to efficient, scalable, and manageable applications in today’s digital world.

Introduction

cottonbro studio

Hello there, curious learner! If you’re looking to understand Docker, Kubernetes, and how they work with .NET microservices, you’re in the right place, because in this article, I’ll explain what they are in a comprehensive way, and why they’re important when working with .NET microservices, and then I’ll show you how to set up and use Docker and Kubernetes step by step.

At last, we’ll build a simple .NET microservice together, package it with Docker, and then use Kubernetes to deploy it, so you can see exactly how all things work, and how they can help with your .NET microservices. Let’s get started!

Docker and Kubernetes

Joshua Reddekopp

Docker and Kubernetes (K8s) are essential tools for deploying microservices, where docker is a tool that lets you create, deploy, and run applications in containers, and K8s is a container orchestration platform, meaning it helps manage how and where those containers run.

A container is like a small, self-contained machine that runs your application and everything it needs, like certain versions of libraries and the operating system, and they help to make your application run the same way no matter where it’s running: on your laptop, on a coworker’s machine, or on a cloud server.

Docker in .NET Microservices Deployments

Matheus Bertelli

Creating a Docker Image for .NET Microservice

To use docker with a .NET application, you will need a Dockerfile. This file tells docker how to build an image of your application; here’s an example of what a Dockerfile for a .NET application might look like:

# Use Microsoft's official build .NET image.
FROM mcr.microsoft.com/dotnet/sdk:5.0 as build
WORKDIR /source

# Copy project files, restore dependencies and publish the application
COPY . .
RUN dotnet restore
RUN dotnet publish -c release -o /app --no-restore

# Final stage, create runtime image
FROM mcr.microsoft.com/dotnet/aspnet:5.0
WORKDIR /app
COPY --from=build /app ./
ENTRYPOINT ["dotnet", "YourApp.dll"]

This Dockerfile does several things:

  1. Uses the .NET SDK image to build your application: this is a ready-to-use Docker image provided by Microsoft that contains the .NET SDK.
  2. Sets a working directory and copies your application files into it.
  3. Restores any dependencies your application needs and publishes your application; the published files are placed into a directory named ‘/app’.
  4. Uses the .NET Runtime image to run your application, and again, this is a ready-to-use image provided by Microsoft; it doesn’t have the SDK (which is needed to build applications, but not run them), so it’s smaller.
  5. Copies the published files from the build image to the runtime image.
  6. Sets the command to run your application when the container starts up.

Running the Docker Image

Once you have your Dockerfile, you can create an image by running:

docker build -t my-app .

And then run it with:

docker run -p 8000:80 my-app

The -p 8000:80 part tells docker to forward any traffic going to port 8000 on your machine to port 80 inside the container.

Kubernetes in .NET Microservices Deployments

K8s takes docker’s concept of containers and allows you to run and manage many containers across many machines, and it uses a file (usually in YAML format) to describe how the application should run.

A K8s deployment configuration might look like this:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app
        image: my-app:latest
        ports:
        - containerPort: 80

This configuration file tells Kubernetes to:

  1. Create a deployment called ‘my-app’.
  2. Run 3 replicas of your application, meaning that there will always be three copies of your application running.
  3. Use the ‘my-app:latest’ image, which is the image you built with Docker.
  4. Listen on port 80 inside the container.

Applying the Kubernetes Configuration

To apply this configuration to your Kubernetes cluster, you would save it to a file (for example, ‘deployment.yaml’), then run:

kubectl apply -f deployment.yaml

This command tells Kubernetes to create the resources described in the ‘deployment.yaml’ file, and in this case, that’s a deployment with three running instances of your application.

Creating a .NET Microservice Locally Using Docker and Kubernetes: A Case Study

Maya Maceka

In this section, we will create a simple but attractive .NET microservice — a basic web API, and then package this service in a docker container and deploy it locally using K8s.

Building a Simple .NET Web API

Let’s create a new .NET Web API project by running the following command in your preferred terminal:

dotnet new webapi -n NetDeploymentMicroservice

This will create a new .NET Web API project named “NetDeploymentMicroservice”; in this project, you’ll find the usual WeatherForecastController that returns a list of weather forecasts, and it's simple, but it's enough to demonstrate deploying a .NET microservice.

Building a Simple .NET Web API console output | Author

Dockerizing the .NET Web API

Next, we will create a Dockerfile in the root of the project, which is used to build a Docker image of our application; here’s a basic Dockerfile for a .NET application:

FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build-env
WORKDIR /app

# Copy everything and build
COPY . ./
RUN dotnet publish -c Release -o out

# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:7.0
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "NetDeploymentMicroservice.dll"]

To build this docker image, navigate to the directory containing the Dockerfile and execute the following command:

docker build -t netdeploymentmicroservice:v1 .

This command creates a docker image named netdeploymentmicroservice with a v1 tag.

This is the expected output, pulling resource and building the image | Author
The end of the output | Author

To check if your image is built, you can list the docker images on your machine using docker images.

Creating a Kubernetes Deployment

With the docker image created, we can now move onto deploying this image using K8s, so we need a deployment configuration:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: netdeploymentmicroservice-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: netdeploymentmicroservice
  template:
    metadata:
      labels:
        app: netdeploymentmicroservice
    spec:
      containers:
      - name: netdeploymentmicroservice
        image: netdeploymentmicroservice:v1
        ports:
        - containerPort: 80

This configuration will instruct K8s to pull the netdeploymentmicroservice:v1 image we created, run 2 replicas (instances) of it, and expose port 80 on each container.

To apply this configuration, save it to a file called k8s-deployment.yaml and use the following command:

kubectl apply -f k8s-deployment.yaml
Our service has deployment configuration applied now | Author

Creating a Kubernetes Service

The deployment is up, but it’s not accessible yet, so to access it, we need a Kubernetes service; here’s a simple configuration:

apiVersion: v1
kind: Service
metadata:
  name: netdeploymentmicroservice-service
spec:
  selector:
    app: netdeploymentmicroservice
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: LoadBalancer
If you did right all previous steps, you’re solution should look like this | Author

This configuration creates a service that exposes our deployment to external traffic, and to make it work, save this to a file called k8s-service.yaml and apply it with:

kubectl apply -f k8s-service.yaml
Service created successful output | Author

Testing the Deployment

To test if everything is working, we can use kubectl to get our services:

kubectl get services

You should see your netdeploymentmicroservice-service in the list; there's a column named "EXTERNAL-IP" which you can use to access your service from a web browser.

Here’s my output and how it should look like | Author

So, that’s it! We’ve created and deployed this .NET microservice example locally using Docker and Kubernetes.

Final Thoughts

Simon Berger

So, we’ve explored the world of docker and kubernetes for deploying .NET microservices, demystifying these powerful tools, and with this step-by-step guide and hands-on case study, you’ve seen how to bring a .NET microservice to life, from creation, through dockerizing it, to deploying.

Take your learning to the next level with our other article titled “.NET 7 & Docker: Crafting High-Performance Microservices Architecture”, where I dig deeper into how to revolutionize your software development with cutting-edge, containerized microservices powered by .NET 7 and Docker.

I’ve included a detailed case study of a video streaming platform, so you can see these concepts in action in a real-world scenario, so it’s a must-read if you want to supercharge your .NET microservices deployments with the latest techniques and tools.

Keep learning, keep exploring, and keep deploying those impressive .NET microservices!

Reading Advice | Kubernetes and Docker — An Enterprise Guide: Effectively containerize applications, integrate enterprise systems, and scale applications in your enterprise, by Scott Surovich and Marc Boorshtein, 2020, Packt Publishing

📕 Gentle nudge: Deciding to purchase this book equates to backing my endeavors, all without any extra cost to you. Your support is deeply acknowledged! 🏆

Further Reading:

Dotnet
Docker
Kubernetes
DevOps
Backend
Recommended from ReadMedium