Monday, September 14, 2020

Running Azure Functions in a Docker Container: A Beginner’s Guide

 


A Brief Introduction to the Technologies

Image for post

Image for post

Fine but.. why using them together?

Image for post

Installation

npm install -g azure-functions-core-tools

Creating our first app

First of all, you will need to create a folder (or use an existing one). This folder is where we will create our Function App.

func init --docker
Image for post
Image 1.1
Image for post
Image 1.2
func new
Image for post
Image 1.3
Image for post
Image 1.4
Image for post
Image 1.5
docker build -t <imageName> .
Image for post
Image 2.1
docker images
Image for post
Image 2.2
docker run  -p <port> <imageName>
Image for post
Image 2.3
Image for post
Image 3.1
http://localhost:8080/api/httptriggerexample?name=Derek
Image for post
Image 3.2


Use these 8 tools to deploy microservices on Azure

For Microsoft Azure users, there are several native services and implementation frameworks that help reduce complexity and make it easier to manage distributed resources. IT technicians can access a range of tools through Azure Service Fabric, Microsoft's cloud-based hub for deploying container technology, invoking functions as a service (FaaS) or creating API protocols to expose a microservice.

In this article, we look at how Microsoft Azure supports microservices, including how it works with containers and serverless technologies. We focus on the eight key Azure tools available for building distributed systems and best practices to consider for microservices deployment.

Tools to deploy microservices on Azure

In general, IT teams can build and deploy software faster, and more flexibly, with microservices. Applications are broken into smaller service-based components, which makes them easier to autonomously scale and adjust. However, admins and developers must be prepared to adapt to the complexities that accompany these interconnected services.

monolithic vs. microservices
Compare monolithic and microservices architecture

The following Azure tools and services are designed for microservice deployment:

Azure Service Fabric

Azure Service Fabric is an application platform for microservices that run on premises or in Azure. DevOps teams can use its declarative model to deploy an application, and its dependencies, without the need to set up and manage the infrastructure. It runs globally, which reduces bottlenecks and delivers the high availability required by modern applications.

The framework provides application lifecycle management from the initial deployment to daily maintenance to decommissioning. Administrators can use it to detect and restart failed systems, discover service locations, monitor application health and manage state. Similar to Kubernetes, Azure Service Fabric simplifies configuration and deployment of applications comprised of container-hosted microservices as well as Azure's own platform services.

Azure Service Fabric Mesh

With Azure Service Fabric Mesh, IT teams indicate the resources needed, service availability requirements, and any resource limits, and it handles all the nuances of the underlying tools and infrastructure. The platform provides a serverless host for .NET Core microservices and enables developers to use any language supported by a Docker container. Service Fabric Mesh automatically handles upgrades and offers the ability to swap out containers when a new application version is deployed. In addition to being highly scalable for cloud-native workloads, the platform is both modular and adaptive.

Azure Functions

In general, FaaS ensures that code runs on demand when triggered by certain service events. With Azure Functions, you install parts of an app and the functions are only loaded when needed. They can also be executed in parallel on demand. As a result, administrators can eliminate the need to provision and build an application infrastructure, opting to only pay for the time spent running explicit pieces of code.

Azure Event Grid

Developers and administrators use event-based architectures to receive alerts on application state changes. Azure Event Grid provides alerts so developers and administrators can immediately respond to those changes. The tool essentially acts as the glue for building event-driven microservice applications.

Azure Kubernetes Service

Azure Kubernetes Service facilitates deployment and eases the ongoing testing and management of container instances. DevOps teams can quickly build and launch containerized applications using the Azure Cloud Shell or a remote Azure command-line interface (CLI).

Azure Container Instances (ACI)

Containers include all the elements that microservices need to run, including code, runtime, toolsets, system libraries and settings. Since ACI is essentially containers as a service, end users are shielded from the orchestrator and CLI. The only requirement is an accurate image of the container to be created. ACI also handles cluster initiations, updates and patching.

Azure API Management

Azure API Management ensures a single point of ingress for service functions. Through API management integration, DevOps teams can access multiple tools and services without changing application code. This includes importing service definitions, defining complex routing rules, logging events as they occur and caching responses.

Service Fabric Reliable Volume

As a temporary container disc, Service Fabric Reliable Volume helps microservice applications maintain a persistent state while removing some of the latency issues typically associated with accessing storage with containerized apps. However, while Service Fabric Reliable Volume does provide general-purpose file storage and enables read/write capabilities, admins can also access Azure File Storage to ensure data reliability.

Best practices to consider

Developers and admins need unified monitoring tools and practices in place to successfully deploy microservices on Azure. For example, use Azure Monitor's data metrics and a Log Analytics agent in conjunction for performance and cost analyses. DevOps teams can analyze different data streams to quantify write transactions or correlate service partitions to help monitor costs.

And rather than using traditional approaches to error handling, such as relying on return codes, use Azure Service Fabric health policies instead. The platform offers a detailed, flexible and extensible model for evaluation and reporting. By actively monitoring service deployment health, IT teams can prevent problems from cascading and causing massive outages.

Moreover, by collecting service-based reports based on local views, DevOps teams can capture cluster-level views and diagnose potential issues in advance. In fact, it's an approach that can be applied more broadly in Azure. The resulting improvements to your workload responsiveness will enable your IT team to focus more on app development and less on infrastructure management

Deploying Apps to Heterogenous Infra : AKS and Azure Functions

The need for scaling applications based on demand and usage has given rise to infrastructure services like kubernetes(K8s) and serverless paragidm (includes serverless functions). Intially, the applications were built with a single infrastructure in focus. Either it was instances only with auto-scaling or kubernetes environment or pure serverless applications. But as the application architectures’ have evolved, the services are being deployed across a combination of environments like kubernetes plus serverless functions or instances plus kubernetes.

In this blog, I will focus on configuring and deploying a microservices application across Azure Kubernetes Service and Azure function.

In this blog, I will review:

1. Introduction to Azure Functions
2. Configuring and Writing Azure Functions
3. (Re)Architecting for Serverless functions
4. Integrating with application services running on K8s

Introduction to Azure Functions

Azure functions is an event driven compute platform similar to AWS lambda. While AWS Lambda has just one hosting plan (deployment model) which is fully managed and deployed on AWS propreitary backend. Azure functions takes a slightly different approach to this. It provides with various Hosting Plan options.

a. Consumption Plan - This is similar to the AWS Lambda model. It is fully managed and has no fixed-cost or management overhead with it. The downside of this is that there might be some delay in start up of the function if it has been idle for a while.
b. Premium Plan - It provides pre-warmed workers with no delay even if the functions were idle. It achieves this by reserving capacity for your functions. With this plan you can also deploy the functions within your Virtual Network (VNET) for private access and unlimited execution duration. This plan also allows you to run these functions as docker container on kubernetes. The downside is higher cost.
c. Azure App Service Plan - This plan provides predictable pricing for those organization who are very price sensitive. The downside is that it has limited auto scaling behavior.

In AWS Lambda, the functions receives a JSON object as an input and can return a JSON as output. With Azure functions, you can add triggers and bindings. A trigger is the event that the function will listen to. Once the data is processed by the function, it can push the data to an output source which is output binding. All triggers and bindings have a direction. For triggers the direction is always in. For input and output bindings you can use in and out.

Now, let’s look at how to configure and write Azure functions.

Configuring and Writing Azure Functions

In this example, I will be using the Acme Fit Demo app. This app has 6 sevices - Front End, Users/Auth, Catalog, Cart, Order and Payment. I will modify the cart service (Python) from containerized application to Azure Functions (With Consumption plan). The rest of the services will be deployed on Azure Kubernetes Service(AKS) cluster.

Architecting for Serverless functions

There is an ongoing debate in the serverless community on how to structure your serverless application. But there are 2 main schools of thought:

1. Bundle as many functionalities as possible within a single function.
2. Every API route should be it’s own function.

While there are pros and cons to each method, I will use method 2. This primarily because when the functions would need less time to warm up and start (less code and libraries) and also makes it easier to handle request and not overburden only 1 single function.

I have decomposed the CART service, API routes into multiple functions, namely:

  • addCartItem
  • clearCart
  • getCartItems
  • getCartTotal
  • modifyCartItem

Each of the above functions corresponds to one of the CRUD operations on Cart items.

You can find the Azure Functions code here.

Configure Azure Functions

To configure the function, you can either use the Azure Portal or the Azure CLI. I will use a combination of the 2 to explain the setup process better.

1. Navigate to Azure portal [LINK HERE] and then select Compute > Function App.
Then click on Create.

You will also notice other hosting options, but for the purposes of this blog, I will be using the consumption plan. You can also enable Application Insights under Monitoring tab. Click on Review and Create.

create_function_app

After this verify the summary again and click on create.

review_and_create

2. I have selected python as the language for writing the Azure Functions. Most of the functionalities for creating and managing python based azure functions have to be done from the CLI, as of Jan 2020.

To get started with this, these are the following pre-reqs:

  • Python 3.7.4 - 64 bit. (Python 3.7.4 is verified with Azure Functions; Python 3.8 and later versions are not yet supported.)
  • Virtual Env (Recommended not mandatory)
  • The Azure Functions Core Tools version 2.7.1846 or a later.
  • The Azure CLI version 2.0.76 or later.

3. Activate the virtual environment and initialize the function with the same name used in the Azure portal.

python -m venv .venv

source .venv/bin/activate

func init <Azure FUNC NAME> --python

4. Create a new function with a reference template. In our case, we will leverage the HTTP trigger template.

func new --name addCartItem --template "HTTP trigger"

This will create a new directory with the function name, init.py file and a function.json file.

The directory structure should look something like this after ALL the functions have been created.

├── LICENSE
├── README.md
├── addCartItem
│   ├── __init__.py
│   └── function.json
├── clearCart
│   ├── __init__.py
│   └── function.json
├── getCartItems
│   ├── __init__.py
│   └── function.json
├── getCartTotal
│   ├── __init__.py
│   └── function.json
├── host.json
├── local.settings.json
├── modifyCartItem
│   ├── __init__.py
│   └── function.json
└── requirements.txt

The init.py contains the main() function for python. This file is triggered based on the description in the function.json file as shown below. The function.json is a config file that defines triggers, input and output bindings (Discussed in previous sections)

{
  "scriptFile": "__init__.py",
  "bindings": [
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "route":"cart/item/add/{userid}",
      "methods": [
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "$return"
    }
  ]
}

The config file above instucts the Azure function to be triggered on a HTTP call with POST method to the route, “cart/item/add/{userid}”. It also defines which file needs to be triggered upon invocation. In our case it is init.py. You can modify the trigger to a webhook by updating function.json to the following:

{
  "bindings": [
    {
      "type": "httpTrigger",
      "direction": "in",
      "webHookType": "github"
    },
    {
      "type": "http",
      "direction": "out"
    }
  ]
}

5. Once this is done, add your code under the main() function in init.py file. Check this repo for sample code. You can copy and paste one of the functions to see it in action.

Also, update the host.json under the root folder for the project, if needed. The Azure functions will by default append /api to your function URL. In my host.json configuration below, I have removed the route prefix.

{
  "version": "2.0",
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[1.*, 2.0.0)"
  },
  "extensions": {
    "http": {
      "routePrefix": ""
    }
  }
}

6. Next step is to test the function locally. Just run,

func start

Copy the URL displayed and test it using POSTMAN or curl.

func_start_local

7. In some scenarios, your app might be interacting with other services like Databases. In case of the cart service, I am also using Azure Cache for Redis.

For the functions of cart service to work, they would need access to the REDIS_HOST, REDIS_PORT and REDIS_PASSWORD environment variable.

You can set these variable in the Azure portal. To do so, Navigate to the FUNCTION > Configuration and under Application Settings you may add these variable names and their values.

add_env

For local testing, you can set the env variable on you local system or use the local.settings.json

NOTE: If you are adding any kind of secrets to the local.settings.json file, remember to add it to .gitignore file.

8. Once the app is tested locally, you can push it to Azure.

func azure functionapp publish <FUNCTION APP NAME>

publish_func_1

Function URLs after publishing to Azure.

publish_func_2

Integrating with application services running on K8s

Use the URL generated in previous section within your app. Notice that all of these functions have an additional parameter named "code=<SOME CODE>". This is the default code that is generated for your function. You can add or update this code within Azure portal under FUNCTION_NAME > Manage > Function Keys.

This keeps the function URL safe from unwanted API calls and acts as additional authorization.

The front-end service in ACME Fit Demo app, routes the traffic to other services like user, cart, catalog and others. When deployed on AKS the front-end can route traffic based on app labels and dns of the service except for the Cart service. As our cart service is deployed as function, we need to explicitly provide the endpoint for the Cart service. Additionally, the function key (the code=) param for every function must be passed to it.

Conclusion

Serverless paradigm is gaining a lot of traction because of it’s ease of use and low cost of maintenance along with scale. When using heterogenous infrastructure, one has to ensure reachability and availabilty of these services at all times. Complexities usually arise because of permissions issue as well as network connectivity. With Azure functions, there are various hosting plans available to handle each of these scenarios.

Choosing Between Azure Container Service, Azure Service Fabric, and Azure Functions

 

Azure Container Service (ACS) provides a way to simplify the creation, configuration, and management of a cluster of virtual machines that are preconfigured to run containerized applications. Using an optimized configuration of popular open-source scheduling and orchestration tools including DC/OS, Docker Swarm, and Kubernetes, ACS enables you to use your existing skills or draw upon a large and growing body of community expertise to deploy and manage container-based applications on Microsoft Azure.

The Azure Container service allows you to take advantage of the enterprise-grade features of Azure while maintaining application portability at the orchestration layer. ACS is primarily focused on distributed applications built using microservices; however, you can start using ACS by containerizing a monolithic application. The application can then be gradually broken down into a more modern, microservices-based implementation. The process of breaking down the monolith into microservices is entirely under the control of application architect/developers; ACS provides that flexibility to the development team.

From a high level, ACS is primarily focused on Azure infrastructure provisioning and orchestration.

Azure Service Fabric, on the other hand, is a distributed systems platform that makes it easy to package, deploy, and manage scalable and reliable microservices and containers. It can run on-premise as well as on any cloud (such as both AWS and Azure). This is a great option for teams who are looking to build an application using a microservice-based architecture on-premise. The flexibility of the Azure Service Fabric platform makes it extremely easy to port an application from on-premise infrastructure to the cloud. Unlike ACS, Service Fabric provides prescriptive guidance on how the application should be written; it actually provides a full-blown programming model. Some of the benefits of using this programming model include:

  • The resulting application can either be stateful or stateless.
  • ASF applications are more fault-tolerant and easy to scale.
  • Multiple ASF-based services can easily form a microservices-based application.
  • It gives more control (and ownership!) of the underlying infrastructure to developers.
Azure Containers and Microservices
Image source: Microsoft

Regardless of whether Azure Container Services or Azure Service Fabric is selected, as an application architecture evolves and as these microservices are decomposed further and further, they are reduced essentially to an atomic function. This is where Azure Functions comes into the picture.

Azure Functions is a solution for easily running small pieces of code, or “functions,” in the cloud. You can write just the code you need for the problem at hand without worrying about a whole application or the infrastructure to run it. Functions can make development time even more productive, and you can use your development languages of choice, such as C#, F#, Node.js, Java, or PHP. In addition, you pay only for the actual compute time used when your code runs, and Azure will implicitly handle scaling as needed. Azure Functions lets you develop serverless applications on Microsoft Azure.

What are some of the right scenarios for each of these tools?

Azure Container Service: If you are comfortable with a container orchestrator such as Docker Swarm, Kubernetes or DC/OS, you will want to use ACS. If you have a monolithic application, it can be continuously decomposed into smaller services gradually; this approach provides an immediate benefit of portability of such an application. In addition, each of the available container implementations is open sourced, and there is excellent community support around containers.

Azure Service Fabric: If an application must leverage stateful services, then use Azure Service Fabric. Typically, the workloads that can run well and can benefit from Azure Service Fabric orchestration are Web Applications, Real-time data streaming applications, IoT Solutions, etc. The biggest benefit of using ASF is that Service Fabric applications can run on-premise or in any of the available cloud platforms.

Azure Functions: Azure Functions is a solution for easily running small pieces of code, or “functions,” in the cloud. This allows you to focus all development effort on code you need for the problem at hand, without worrying about a whole application or the infrastructure to run it. Azure Functions is a great solution for processing data, integrating systems, working with the internet-of-things (IoT), and building simple APIs and microservices. Consider Functions for tasks like image or order processing, file maintenance, or for any tasks that you want to run on a schedule. Additionally, Azure Functions supports triggers, which are ways to start the execution of your code, and bindings, which are ways to simplify coding for input and output data.

If you have questions on how you can best leverage our experience, would like further examples and/or need help with your Cloud-based environment, check out our blog post on 5 Common Gotchas with Serverless Development in the Enterprise please engage with us via comments on this blog post, or reach out to us at https://www.xtivia.com/contact/ or info@xtivia.com.

Additional Resources

You can also continue to explore our Cloud Expertise by checking out the following posts.
Creating a Web Application with Azure App Service
Serverless and PaaS, FaaS, SaaS: Same, Similar or Not Even Close?Troubleshoot HTTP 502.5 Process Failure Error in Azure API App
Azure Cosmos DB Features and Benefits