X
  • September 5, 2018

Running .NET Core on the Oracle Container Engine for Kubernetes

Photo by Leone Venter on Unsplash

 

Recently, I got a note from an attendee I met at the Getting Function'l with Kubernetes event about running .NET core applications on Kubernetes. It got me thinking, "how far has the Windows and .NET world come regarding running cloud native apps in the last year?" I remembered when I filmed my LinkedIn Learning tutorial on Kubernetes; it wasn't that difficult to run Kubernetes with Minikube on Windows, but what about running .NET apps? 

I took some time to explore the ecosystem, and in this post, I'll show you how to run a sample .NET application on the Oracle Container Engine. If you're a developer and want to get straight to the code, you can check out my entire walkthrough on GitHub. I built all of these examples on my mac, but you should be able to do all of this on any platform you choose. If for some reason you get stuck, comment below, and I can try to replicate your issues!

It's been a good five years since I wrote my last .NET application, so I had to install all the things on my mac. I started with the simple .NET tutorial published on Microsoft to create a .NET Core Web API application. I thought about adding more endpoints and code to it, but in the end, kept it the same as the generated code to keep it simple. I didn't want to confuse the reader with .NET REST API magic, but instead, get the application running in the Kubernetes platform. As a side note, it is SUPER cool to have the dotnet command now. It makes development, building, and testing all very seamless and is innate to cloud native developers who run docker and kubectl commands all day long.

After installing the needful, I created a simple ASP.NET Core Web API application with the command: ~$ dotnet new webapi --auth None --no-https

For a full-fledged app, you will most likely want to set up authentication if you're working with sensitive data, and turn on https as well. Running the command will create a new webapp that creates a simple REST API. The output looks something like: 

  ~$ dotnet new webapi --auth None --no-https
The template "ASP.NET Core Web API" was created successfully.
Processing post-creation actions...
Running 'dotnet restore' on /Users/karthik/dev/src/github.com/karthequian/dotnet-example/dotnet-example.csproj...
  Restoring packages for /Users/karthik/dev/src/github.com/karthequian/dotnet-example/dotnet-example.csproj...
  Generating MSBuild file /Users/karthik/dev/src/github.com/karthequian/dotnet-example/obj/dotnet-example.csproj.nuget.g.props.
  Generating MSBuild file /Users/karthik/dev/src/github.com/karthequian/dotnet-example/obj/dotnet-example.csproj.nuget.g.targets.
  Restore completed in 1.42 sec for /Users/karthik/dev/src/github.com/karthequian/dotnet-example/dotnet-example.csproj.
Restore succeeded.

Great! Now, to run this newly created application, I can type dotnet run, and it should launch my API as shown below:

 ~$ dotnet run
Using launch settings from /Users/karthik/dev/src/github.com/karthequian/dotnet-example/Properties/launchSettings.json...
: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[0]
  User profile is available. Using '/Users/karthik/.aspnet/DataProtection-Keys' as key repository; keys will not be encrypted at rest.
Hosting environment: Development
Content root path: /Users/karthik/dev/src/github.com/karthequian/dotnet-example
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.

 

If I wanted to test, I could curl the /api/values/ endpoint as shown below. If I get a list of values back, I know that the application is working as expected.

 

~$ curl localhost:5000/api/values/

["value1","value2"]

 

Now that I have a .NET webapp running on my mac, I can do the fun stuff - dockerize and kubify!

To dockerize, I followed the guidelines to build a Docker image for a .NET application from the Docker documentation. I changed the name of the entrypoint to dotnet-example.dll because that was the name of my project. You can find my final Dockerfile here. After running and testing again with curl, I pushed the application to the Docker store as karthequian/dotnetexample, so that anyone can just run the example as a test.

Finally, to run this in Kubernetes, I created a deployment and service here: https://github.com/karthequian/dotnet-example/blob/master/Deployment.yaml. This yaml exposes the container as a deployment with a nodePort service running on port 32000 of the host. For ease of use, you can type

kubectl apply -f https://raw.githubusercontent.com/karthequian/dotnet-example/master/Deployment.yaml
to run the deployment and service on Kubernetes. I chose to run my application in the Oracle Container Engine as a proof of concept, but it should work in any Kubernetes distro out there. I've tested this on a Kubernetes 1.9.7 cluster, but it will be forward compatible with the latest version as well.

 

 Following is an example to run this:

 ~$ kubectl apply -f https://raw.githubusercontent.com/karthequian/dotnet-example/master/Deployment.yaml
deployment "dotnetworld" created
service "dotnetworld" created
 ~$ kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
dotnetworld 1 1 1 1 20s
 ~$ kubectl get services
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
dotnetworld 10.96.79.93 80:32080/TCP 26s
kubernetes 10.96.0.1 443/TCP 30d

Finally, to test this out, we can once again run a curl against the node IP and port as shown below:

 ~$ kubectl get services
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
dotnetworld 10.96.79.93 80:32080/TCP 26s
kubernetes 10.96.0.1 443/TCP 30d
 ~/dev/src/github.com/karthequian/dotnet-example$ kubectl get nodes
NAME STATUS AGE VERSION
129.146.123.174 Ready 30d v1.9.7
129.146.133.234 Ready 30d v1.9.7
129.146.162.102 Ready 30d v1.9.7
 ~$ curl 129.146.162.102:32080/api/values
["value1","value2"]

So there you have it - a .NET core web application, built on a mac, containerized with Docker and running in Kubernetes 1.9.7, managed by the Oracle Container Service for Kubernetes. It might sound time consuming, but I was able to get all of this running in about an hour, so it wasn't that much work at all. 

Let me know if you run into issues or have any questions by commenting below, finding me on twitter @iteration1 or in the GitHub repo itself. Good luck!!

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.Captcha
Oracle

Integrated Cloud Applications & Platform Services