ASP.NET Core Series 04: Building Serverless API Backend on Kubernetes

Nowadays with the increasing use of cloud-based systems, serverless architecture is a great concept that has been talking a lot about itself over the last a year. In today’s age while technology evolving and changing rapidly, sometimes all we need is just a function, especially when the “time to market” term is important. So, in this article, we will take a look at serverless(Function-as-a-Service) concept, and then develop a sample serverless API backend on Kubernetes with Fission serverless framework.

Introduction to Serverless Architecture

It is actually an architecture based on the ability to run a single function or applications without any server configurations or management things and even error management especially when the scalability is important. In short, we can say everything can be used as a service. So, in other words, the paradigm of serverless computing is based on the ability of the temporary short-running computation units which are opened on demand(event-driven) to complete a request and then to shut down oneself unlike of long-running virtual machines.

For example, the feature that users can add products to their favourite list is one of the essential features of e-commerce websites. This feature usually has an add, remove and list function. We can think of these three functions as a separate function which will be triggered by an event.

As a developer, it is great to be able to run a code, that we have developed, on-demand with a serverless architecture without having to maintain a backend server, sounds good, isn’t it? However, if you are a public cloud user, the best part is that you are being charged as much as you actually use it.

Of course, a well-built structure is necessary.

To use serverless architecture, Azure FunctionsAmazon Lambda and Google Cloud Functions provide the necessary infrastructure to us. In this article, I will focus on how we can use serverless architecture on kubernetes with fission serverless framework rather than these three major providers. Also, we will look at how we can develop a serverless backend API with ASPNET Core.

First I want to mention a few points that we should pay attention to in serverless architecture.

What Do We Have To Pay Attention To?

  • It should be noted that the functions should be “idempotent“. I mean, the provider can try to execute the corresponding function more than one time with an event that occurs. I will not mention too much detail on this. There is a good article about it here.
  • Long-running operations are another point to consider. For example, Amazon Lambda provides just 5 min for execution.
  • If the response time is important, latency problems due warm-up situations could be faced. Obviously, I faced. (There are a few plugins against warm-up situations but I have not experienced yet.)
  • Another important topic that should be considered is the provider dependency. If we did not apply a right abstraction, I think it will hard to change provider with another one. So, all of these will be reflected us as an “extra effort”.

Open-Source Serverless Frameworks

We mentioned the concept of serverless a bit. I have not mentioned much more details on this topic because there are many wonderful articles on the internet.

Well, we have mentioned that providers like Azure, Amazon and Google provide the necessary infrastructure for using serverless architecture to us. Also in this article, we mentioned that we will develop a backend API with fission serverless framework on kubernetes.

Now I would like to mention a bit about open-source serverless frameworks that are alternatives to Azure Functions, Amazon Lambda ve Google Cloud Functions.

In the open-source world, there are wonderful alternative frameworks such as Fission, OpenWhisk and Kubeless. I guess the best part of these frameworks is that they are cloud provider agnostic. For example, fission and kubeless can work wherever that kubernetes can work. Public cloud, private cloud or your own laptop, it doesn’t matter, you can run it everywhere you want. Open-source serverless frameworks provide us a wider third-party integration area and freedom according to commercial providers.

In the open-source world, there are wonderful alternative frameworks such as Fission, OpenWhisk and Kubeless. I guess the best part of these frameworks is that they are cloud provider agnostic. For example, fission and kubeless can work everywhere where kubernetes can work. Public cloud, private cloud or your own laptop, it doesn’t matter, you can run it everywhere you want. Open-source serverless frameworks provide us a wider third-party integration area and freedom according to commercial providers.

An open-source or a commercial option is entirely up to you. Since serverless architecture provides an effortless way to achieve the solution without extra effort and expensive infrastructure, it’s a tradeoff for companies those attracted by it.

Fission – Serverless Framework

Fission is an open-source serverless framework that provides a high-level abstraction layer for kubernetes. As I mentioned in the above section, the best part of fission is that it can work everywhere where kubernetes can work. Fission has a wide environment such as “Python”, “Go”, “.NET”, “.NET 2.0”, “NodeJS”, “Perl” and “Ruby”.

Fission has a built-in pre-warm up mechanism to speed up the startup time of functions. To provide this, it maintains “warm” containers which contain small dynamic loaders. At the time of cold-start, it selects one of the “warm” containers and loads the corresponding function. Thus, cold-start latencies are about “100msec“. You can reach detailed information from here.

Let’s take a look at a general concept of fission before we start using it.

  • Environment: It is a container that contains web server, dynamic loader and runtime specific parts of a function. First, we should create an environment before creating a function.
  • Function: Our code that will be executed.
  • Trigger: An event that invokes the functions. There are three triggers types: “HTTP“, “Time” and “MQ“. We will use the “HTTP” trigger in our example.

Let’s have a look at some code examples now.

Using Fission

First, we need a kubernetes cluster to use fission. We can have a kubernetes cluster in a quick way using Minikube or edge channel of Docker. You can get a detailed information from here.

After the kubernetes cluster installation, we need to install also “Kubernetes CLI“, “Helm” and “Fission” sequentially. You can follow the installation steps from here.

NOTE: When completed the installation steps, make sure that the example in the “Run an example” section is working.

Now let’s take a look at the part of how we can create and deploy a function with fission in the simplest way. Well, first create a .NET Core 2.0 environment on the fission called “dotnetcore-env” with the following command line.

fission env create --name dotnetcore-env --image fission/dotnet20-env

NOTE: It is possible to specify CPU and memory resource limits while creating an environment. E.g: “–mincpu 40 –maxcpu 80 –minmemory 64 –maxmemory 128

.NET Core 2.0 environment of fission includes Kestrel and Nancy to perform host operations, it also includes Roslyn to compile functions which will be uploaded.

Now we can create a basic function that applies addition operation using the environment that we have created. To do that, we will use function template of .NET Core 2.0 environment that fission has provided us with as built-in.

Let’s open VS Code and then create a class called “FissionFunction” as like below.

using System;
using Fission.DotNetCore.Api;

public class FissionFunction
{
    public string Execute(FissionContext context)
    {
        int x = Convert.ToInt32(context.Arguments["x"]);
        int y = Convert.ToInt32(context.Arguments["y"]);

        return (x + y).ToString();
    }
}

The built-in .NET Core 2.0 environment can work with a convention like above. I mean we need to create a class called “FissionFunction” as like above, where the “Execute” method takes place.

If we look at the “FissionFunction” class that we have created, we are accessing values from query-string via “context.Arguments” object. It is also possible to access values that coming from the Body via “context.Request.Body” stream.

Now we need to define the “FissionFunction” class which we have created, as a function on fussion as follows.

fission fn create --name addition --env dotnetcore-env --code [Your_Work_Dir]/FissionFunction.cs

With the above command line, we have defined a function called “addition” that uses the “dotnetcore-env” environment and will execute the “FissionFunction” class.

Now we have to create a trigger to execute the “addition” function. To do this, we need to run the following command line.

fission ht create --method GET --url /addition --function addition

We created an HTTP trigger to run the “addition” function when the URLhttp://localhost/addition” is triggered.

That’s all.

Let’s test it! Test URL: “http://localhost/addition?x=10&y=5


The result is above. The HTTP trigger triggered the “addition” function and then executed the “Execute” method in the “FissionFunction” class.

In our example, we have created a basic function using built-in .NET Core 2.0 environment that fission provided us. Well I guess, I can hear the question about how we can create a function when we will be faced different needs. I mean, maybe we might want to use a few different NuGet packages in a function.

Unfortunately, the disadvantage of fission is that it does not support multiple file feature for “compiled languages“. In such situations, instead of environments that are provided as built-in, we can create our environment (docker image) in an easy way using this project.

Once we have created our environment, all we need to do is to use it as follows.

fission env create --name your-dotnetcore-env --image your/dotnet20-env

Conclusion

FaaS is one of the rare topics that excited me in recent times. I think, to create short-lived functions and write small code pieces, to reduce the wasted time and extra effort for infrastructure operations are especially important in today’s age, while technology evolving and changing rapidly. Open-source serverless frameworks like fission are more attractive for me because they are provider agnostic. I have not seen much usage of FaaS in places where I am involved, but It is good to see that cloud providers are investing in this topic. I guess I will be seeing more usage of FaaS in future. I hope. 🙂

Some References

https://docs.fission.io/0.6.0/concepts/
https://medium.com/@PaulDJohnston/when-not-to-use-serverless-jeff-6d054d0e7098
http://www.datacenterknowledge.com/archives/2017/01/18/open-source-serverless-computing-frameworks-matter

Gökhan Gökalp

Recent Posts

Overcoming Event Size Limits with the Conditional Claim-Check Pattern in Event-Driven Architectures

{:en}In today’s technological age, we typically build our application solutions on event-driven architecture in order…

2 months ago

Securing the Supply Chain of Containerized Applications to Reduce Security Risks (Policy Enforcement-Automated Governance with OPA Gatekeeper and Ratify) – Part 2

{:tr} Makalenin ilk bölümünde, Software Supply Chain güvenliğinin öneminden ve containerized uygulamaların güvenlik risklerini azaltabilmek…

7 months ago

Securing the Supply Chain of Containerized Applications to Reduce Security Risks (Security Scanning, SBOMs, Signing&Verifying Artifacts) – Part 1

{:tr}Bildiğimiz gibi modern yazılım geliştirme ortamında containerization'ın benimsenmesi, uygulamaların oluşturulma ve dağıtılma şekillerini oldukça değiştirdi.…

9 months ago

Delegating Identity & Access Management to Azure AD B2C and Integrating with .NET

{:tr}Bildiğimiz gibi bir ürün geliştirirken olabildiğince farklı cloud çözümlerinden faydalanmak, harcanacak zaman ve karmaşıklığın yanı…

1 year ago

How to Order Events in Microservices by Using Azure Service Bus (FIFO Consumers)

{:tr}Bazen bazı senaryolar vardır karmaşıklığını veya eksi yanlarını bildiğimiz halde implemente etmekten kaçamadığımız veya implemente…

2 years ago

Providing Atomicity for Eventual Consistency with Outbox Pattern in .NET Microservices

{:tr}Bildiğimiz gibi microservice architecture'ına adapte olmanın bir çok artı noktası olduğu gibi, maalesef getirdiği bazı…

2 years ago