The Azure Functions team has been doing some great work lately and as a part of that work the runtime for the runtime of the serverless function was ported to .NET Core 2.0 in late September.
This set the stage really for cross-platform development and running of Azure Functions and in November; Azure Functions on Linux was announced for Preview.
What does it all mean? There is a serverless framework for Azure that we can run in a container on Linux (and maybe a Raspberry PI??) and deploy to Kubernetes on the managed host in Azure...AKS (Azure Kubernetes Service).
Requirements
- Docker
- .NET Core 2.0
- The latest azure-functions-core-tools
npm install -g azure-functions-core-tools@core
The sample code for the app is available on github: https://github.com/spboyer/az-funky-linux
Create the app
Create the directory for the app and cd
into it, then use the functions cli to initialize the project with the base Docker file.
func init --docker
Add a new HttpTrigger function, called "echo", using JavaScript as the language.
func new -n echo -t HttpTrigger -l JavaScript
Replace the code in /echo/index.js with the following:
module.exports = function (context, req) {
context.log('JavaScript HTTP trigger function processed a request.');
const os = require("os");
context.res = {
// status: 200, /* Defaults to 200 */
body: "Hello from " + os.hostname() + " [" + os.platform() + ", " + os.arch() + "]"
}
context.done();
};
Open the function.json and update the authLevel
value to anonymous instead of function.
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req"
},
Run the application locally using the cli.
func start
Browse to http://localhost:7071/api/echo
Putting it in a container
The Dockerfile was added to the project initially and is very basic, using a base image microsoft/azure-functions-runtime:v2.0.0-beta1, establishing the home directory and copying the code there.
FROM microsoft/azure-functions-runtime:v2.0.0-beta1
ENV AzureWebJobsScriptRoot=/home/site/wwwroot
COPY . /home/site/wwwroot
Create the image for the project
docker build -t funkylinux .
Run the image and map port 80 to a local port.
docker run -p 3001:80 funkylinux
Browse to the same endpoints on the new url - http://localhost:3001/api/echo
Publishing our app
Having a container image gives you many options for deployments:
Azure Kubernetes Service (more)
# Create the cluster
az aks create -g aks-funky -n funkylinux --node-count 1 --generate-ssh-keys
# Get the credentials for kubectl
az aks get-credentials -g myResourceGroup -n funkylinux
# Run the application on the cluster
kubectl run funkylinux --image=spboyer/funkylinux --port=80
# Expose the deployment to the internet
kubectl expose deployment funkylinux --port=80 --type=LoadBalancer
# Watch the services to see the public IP allocate
kubectl get svc -w
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
funkylinux LoadBalancer 10.0.148.126 52.168.66.109 80:30448/TCP 4h
kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 4h
Scale the app manually
kubectl scale --replicas=5 deployment/funkylinux
or use the Kubernetes auto scaling
kubectl autoscale deployment funkylinux --cpu-percent=75 --min=1 --max=10
Azure App Service on Linux (more)
# Create a Web App
az webapp create --name funkylinux --plan AppServiceLinuxDockerPlan -g myResourceGroup
# Configure Web App with our image
az webapp config container set --docker-custom-image-name spboyer/az-funky --name funkylinux -g myResourceGroup
Azure Container Instances (more)
az container create --name mycontainer --image funkylinux -g myResourceGroup --ip-address public --ports 80
Summary
This is an opportunity to run the functions runtime where you want and still have the hooks into the Azure products like CosmosDB, Queues, TableStorage and external webhooks like Github is pretty awesome.
Let me know your thoughts.