ASP.NET Core is a cross-platform, open source framework that builds modern applications by using the C# programming language.

Kubernetes is an open source system for automating deployment, scaling, and management of containerized applications. Kubernetes is an open source project, which can run in many different environments: from laptops to high-availability multi-node clusters, from public clouds to on-premise deployments, from virtual machines to bare metal.

In this tutorial, you will learn to deploy a simple ASP.NET Core app to Kubernetes. The main purpose of this tutorial is for you to turn your code into a replicated application that’s running on Kubernetes. You can take any application that you developed on your machine, turn it into a Docker container image, and then run that image on the IBM Cloud Kubernetes Service (IKS).

Why is it advantageous to deploy an application in Kubernetes?

With modern web services, users expect applications to be available 24/7, and developers expect to deploy new versions of those applications several times a day. Containerization helps package software to serve these goals, enabling applications to be released and updated in an easy and fast way without downtime.

Kubernetes helps you make sure those containerized applications run where and when you want, and helps them find the resources and tools they need to work.

Deploying Kubernetes is definitely worth it in cases where you need to:

  • Provide the fastest possible and least costly horizontal scalability by distributing Docker containers over multiple hosts.
  • Reduce the need for new hardware resources when scaling.
  • Provide the comprehensive control and automation in the administration processes.
  • Introduce algorithms for replication, scaling, self-recovery, and resumption of system operability.
  • Provide increased fault tolerance and minimize downtime by launching containers on different machines.

The IBM Cloud Kubernetes Service provides a native Kubernetes experience that is secure and easy to use. The service removes the distractions that are related to managing your clusters and extends the power of your apps with IBM Watson™ and other cloud services by binding them with Kubernetes secrets. It applies pervasive security intelligence to your entire DevOps pipeline by automatically scanning images for vulnerabilities and malware.

The goal of this tutorial for you is to turn your code into a replicated application that runs on Kubernetes. You can take the code that you developed on your machine, turn it into a Docker container image, and then run that image on the IBM Cloud Kubernetes Service. The IBM Cloud: Getting started tutorial for ASP.NET Core App is used as an example application in this tutorial.

About the ASP.NET Core application

The IBM Cloud: Getting started tutorial for ASP.NET Core App uses this sample application to provide you with a sample workflow for working with any .NET Core app on IBM Cloud™ you set up a development environment, deploy an app locally and on IBM Cloud, and integrate an IBM Cloud database service in your app. The application uses a Cloudant® noSQL DB service from IBM Cloud to add information to a database and then return information from a database to the UI.

Gif of the sample app contains a title that says, Welcome, a prompt asking the user to enter their name, and a list of the database contents which are the names Joe, Jane, and Bob. The user enters the name, Mary and the screen refreshes to display, Hello, Mary, I've added you to the database. The database contents listed are now Mary, Joe, Jane, and Bob.

This gif contains a title that welcomes the user, prompts the user to enter a name, and then lists the database contents with the names Joe, Jane, and Bob. The user enters “Mary” and the screen refreshes to display, “Hello, Mary, I’ve added you to the database. The database contents listed are now Mary, Joe, Jane, and Bob.”

What you’ll learn in this tutorial

Upon completion of this tutorial, you will know how to:

  • Dockerize a simple ASP.NET Core app
  • Create your Kubernetes cluster on the IBM Cloud Kubernetes Service (IKS) environment
  • Create a Cloudant Database in your IKS Cluster
  • Deploy your ASP.NET Core app to an IKS Cluster

Before you begin

You’ll need following installed on your machine.

Steps

Clone/download the IBM Cloud ASP.NET Core Getting Started Application

git clone https://github.com/IBM-Cloud/get-started-aspnet-core

Run the ASP.NET Core app locally

This step is to verify whether your app is running successfully locally before deployment. You can start by verifying the version of dotnet as follows:

dotnet --version

Next, navigate to your App folder.

cd get-started-aspnet-core/src/GetStartedDotnet

Restore the app with the following command:

dotnet restore

This uses NuGet to restore dependencies and project-specific tools that are specified in the project file. By default, the restoration of dependencies and tools are executed in parallel. For more info visit Docs.

Now, run your application with the following command:

dotnet run

The application starts listening on port 5000. You will see the following message.

    ...
    Now listening on: http://localhost:5000
    Application started. Press Ctrl+C to shut down.

Publish the ASP.NET Core app

To pack the application and its dependencies, create a new folder named publish for deployment to a hosting system for execution. We have to use dotnet to publish. Then it’s ready to run anywhere.

Publish the app to get a self-contained DLL using the dotnet publish command.

  dotnet publish -c Release

Running publish displays some messages with a successfully published DLL at the end of the process. For our example, you can see the following message.

    ...
    GetStartedDotnet -> /home/get-started-aspnet-core/src/GetStartedDotnet/bin/Release/netcoreapp2.0/GetStartedDotnet.dll

Dockerize the ASP.NET Core app

Once the application is ready, we can make an image of it and put it inside a container. We need a file that contains step-by-step instructions to deploy the image inside the container to run our application anywhere. This Dockerfile is a basic file and you may only require a few lines to get started with your own image.

Go to the app folder (here GetStartedDotnet) and create a Dockerfile to define the Docker image.

cd get-started-aspnet-core/src/GetStartedDotnet

Add the contents of Dockerfile by using your favorite editor (vim, nano, etc.) and save the file.

vi Dockerfile
FROM microsoft/aspnetcore:2.0

WORKDIR /app1

COPY ./bin/Release/netcoreapp2.0/publish .

ENTRYPOINT ["dotnet", "GetStartedDotnet.dll"]

The first line we added FROM microsoft/aspnetcore:2.0 will download the aspnetcore image from the hub repository, so it actually contains the .NET Core and you don’t need to put it inside the image. You can find more repositories and versions in the Docker hub.

The Dockerfile line WORKDIR /app sets our working directory in the app folder, which is inside the container that we’re building.

Now we need to copy the contents of the publish folder into the app folder on the image COPY ./bin/Release/netcoreapp2.0/publish.

Note: You can find this path in the output when you run dotnet publish -c Release.

The last line in the Dockerfile is the ENTRYPOINT statement: ENTRYPOINT ["dotnet", "GetStartedDotnet.dll"]. This line tells Docker that it should run the dotnet command with GetStartedDotnet.dll as parameter.

Run the app on Docker (Optional)

You can test your dockerized app by following the steps below. This section is optional for this tutorial, though.

First, build an image.

docker build -t get-started-aspnet

Note: You can choose any name for your app.

Running the build command displays the following message in the end.

...
Successfully tagged get-started-aspnet:latest

The following command will run an app.

docker run -d -p 8080:80 --name app get-started-aspnet

Navigate to http://localhost:8080 to access your app in a web browser.

Clean up with the following commands.

docker stop /app
docker rm /app

These above commands stop and remove the Docker container of your app, respectively. You can use them to remove your container if you no longer need it.

Create a Kubernetes cluster on the IKS environment

We are now ready to create our Kubernetes cluster.

  1. Make sure you are logged into your IBM Cloud account by using:

    ibmcloud login
    

    or

    ibmcloud login --sso
    
  2. Create the IKS cluster for deployment.

    i. Create a Kubernetes cluster by choosing Cluster Type – Free. Give a unique name to the cluster and click Create Cluster.

    Note: For more details, see Creating a Kubernetes cluster in IBM Cloud.

    IKS Cluster creation

    ii. It will take some time. It is ready to use if you see the following:

    IKS Cluster ready

  3. It’s time to deploy your containerized application to the Kubernetes cluster. From now on, you’ll use the kubectl command line.

  4. Follow the instructions in the Access tab to set up your kubectl CLI and get access to your cluster.
  5. On running the kubectl get nodes command, you should see something like the following.

         NAME           STATUS    AGE       VERSION
         10.76.197.43   Ready     1d        v1.10.8+IKS
    

Create a Cloudant database in the IKS Cluster

  1. Our example application uses the Cloudant database to save the data that was entered. The goal here is to show how the database is created and can be deployed to the IKS cluster. You can use any database for this purpose and follow the same steps of deployment that are mentioned here (or avoid these steps if your application does not use database at all).

    To create an IBM Cloud Cloudant Database, create a new Cloudant database instance. Select Use both legacy credentials and IAM under Available authentication methods.

    cloudant in ibm cloud

  2. Create new credentials under Service Credentials and copy the value of the url field. (See image below).

    service credentials

  3. Create a Kubernetes secret with your Cloudant credentials. A secret is an object that contains a small amount of sensitive data, such as a password, a token, or a key. Such information might otherwise be put in a Pod specification or in an image; putting it in a Secret object allows for more control over how it is used, and reduces the risk of accidental exposure. For more info, visit Kubernetes Secret.

     kubectl create secret generic cloudant --from-literal=url=<URL>
    

    For example:

     kubectl create secret generic cloudant --from-literal=url=https://username:passw0rdf@username-bluemix.cloudant.com
    
  4. You will need this info in your deployment. You can see your secrets by using the following command.

     kubectl get secrets
    

    This will display all the secrets you created in their respective clusters.

Deploy ASP.NET Core app to an IKS cluster

The IBM Cloud Container Registry provides a multi-tenant private image registry that you can use to safely store and share your Docker images with users in your IBM Cloud account.

  1. Log in to the Container Registry Service to store the Docker image that we created with Docker.

     ibmcloud cr login
    
  2. Find your container registry namespace by running the following command.

     ibmcloud cr namespaces
    
  3. If you don’t have any, create one by using following command.

     ibmcloud cr namespace-add <name>
    

    For example:

     ibmcloud cr namespace-add aspnetapp-01
    
  4. Identify your Container Registry by running the following command.

     ibmcloud cr info
    

    For example: registry.ng.bluemix.net

  5. Build and tag (-t) the Docker image by running the command below, replacing REGISTRY and NAMESPACE with the appropriate values.

     docker build . -t <REGISTRY>/<NAMESPACE>/myapp:v1.0.0
    

    For example:

     docker build . -t registry.ng.bluemix.net/aspnetapp-01/myapp:v1.0.0
    

    It will display the following message in the end.

         ...
         Successfully tagged registry.ng.bluemix.net/aspnetapp-01/app:v1.0.0
    
  6. Push the Docker image to your Container Registry on IBM Cloud.

     docker push <REGISTRY>/<NAMESPACE>/myapp:v1.0.0
    
  7. Verify that the image was pushed successfully by running the following command.

     ibmcloud cr image-list
    

    Good work! You set up a namespace in the IBM Cloud Container Registry and pushed a Docker image to your namespace.

Deploy your containerized application

Once you have a running Kubernetes cluster, you can deploy your containerized application on top of it. To do so, you create a Kubernetes Deployment configuration. The Deployment instructs Kubernetes on how to create and update instances of your application. Once you create a Deployment, the Kubernetes master schedules the mentioned application instances onto individual Nodes in the cluster. A Kubernetes Deployment Controller continuously monitors those instances that were created. If the Node that’s hosting an instance goes down or is deleted, the Deployment controller replaces it. This provides a self-healing mechanism to address machine failure or maintenance.

  1. To create a deployment, you will create a folder called “kubernetes” and create a deployment.yaml file.

    mkdir kubernetes
    
    vi deployment.yaml
    
    # Update <REGISTRY> <NAMESPACE> values before use
    # Replace app name instead of get-started-aspnet if you wish to use different name for your app
    
    apiVersion: apps/v1
    kind: Deployment
    metadata:
     name: get-started-aspnet
     labels:
       app: get-started-aspnet
    spec:
     replicas: 2
     selector:
       matchLabels:
         app: get-started-aspnet
     template:
       metadata:
         labels:
           app: get-started-aspnet
       spec:
         containers:
         - name: get-started-aspnet
           image: <REGISTRY>/<NAMESPACE>/myapp:v1.0.0
           ports:
           - containerPort: 8080
           imagePullPolicy: Always
           env:
           - name: CLOUDANT_URL
             valueFrom:
               secretKeyRef:
                 name: cloudant
                 key: url
                 optional: true
    

    The deployment get-started-aspnet was created, indicated by the .metadata.name field. The Deployment creates two replicated Pods, indicated by the replicas field. These replicas are needed to handle the traffic in deployment. You can keep it to 1 as well. The selector field defines how the Deployment finds which Pods to manage. However, more sophisticated selection rules are possible, as long as the Pod template itself satisfies the rule. The Pods labeled app: get-started-aspnet are using the labels field. The Pod template’s specification, or .template.spec field, indicates that the Pods run one container, get-started-aspnet, which runs the <REGISTRY>/<NAMESPACE>/myapp:v1.0.0 Docker image. Open port 8080 so that the container can send and accept traffic. Set the imagePullPolicy of the container to Always. The Secret information has been updated in the env field, like the CLOUDANT_URL that we mentioned while creating our Secret for the Cloudant database.

  2. Create a deployment by using the following command.

    kubectl create -f kubernetes/deployment.yaml
    

    The output will display, similar to the following message.

    deployment "get-started-aspnet" created
    
  3. By default, the pod is only accessible by its internal IP within the cluster. Create a Kubernetes Service object that external clients can use to access an application running in a cluster. The Service provides load balancing for an application.

    Use the NodePort 8080 to expose the deployment.

    kubectl expose deployment get-started-aspnet --type NodePort --port 8080 --target-port 8080
    

    You will see the following message.

     service "get-started-aspnet" exposed
    

Access the application

To verify that your application is running successfully, you need to check the STATUS of your pod. It should be in a state of Running:

  kubectl get pods -l app=get-started-aspnet

It should look like the following:

    NAME                                  READY     STATUS    RESTARTS   AGE
    get-started-aspnet-68d6dc5c4-2trcl    1/1       Running   0          1m
    get-started-aspnet-68d6dc5c4-qdbkt    1/1       Running   0          1m

It should also show two instances as we have set two replicas in our deployment.

To access your ASP.Net Core application:

  1. Identify your Worker Public IP by using ibmcloud cs workers YOUR_CLUSTER_NAME.
  2. Identify the Node Port by using kubectl describe service get-started-aspnet.
  3. Access your application at http://<WORKER-PUBLIC-IP>:<NODE-PORT>/.

This is how you could deploy and access your application in the IKS environment.

Clean up

Use the following commands to clean up the sample application that we created for this tutorial:

kubectl delete deployment,service -l app=get-started-aspnet
kubectl delete secret cloudant

Conclusion

This concludes a simple, getting-started walkthrough of an ASP.NET Core app deployment in IKS. By following this tutorial, you can take any application that you have developed on your machine, turn it into a Docker container image, and then run that image on IBM Cloud Kubernetes Service. This tutorial also explained how you can put sensitive information into secrets. We have only touched the surface of this technology and I encourage you to explore further with your own pods, replication controllers, and services. You can also put your new skills to the test with the code pattern, Build an airline booking platform on a private cloud.