Running Azure Functions in Knative
Azure functions are one of the serverless offerings available to users. Perhaps little known is that Azure functions can be easily packaged as Docker containers and that a tool called
func is available to build and test functions locally. It has also been documented that Azure functions can easily run in Kubernetes since they can be packaged as containers.
This repository is a step by step tutorial to show you how to run functions that use the Azure function runtime in knative.
For local testing you need:
On OSX for example, once you get the .NET core SDK you can get the Azure function core tools via
brew tap azure/functions brew install azure-functions-core-tools
If you struggle to install .NET core and the Azure functions CLI, you can build it via Docker as shown in the next section.
Getting the Azure functions
func CLI via Docker
First build the Docker image using the provided Dockerfile in the
docker build -t azure-func func-in-docker/
You will then be able to run
func from an interactive container.
docker run --rm --name azurefunc -w /workspace -v $(pwd):/workspace -p 7071:7071 -p 8080:8080 -ti azure-func func@13a5ece9b783:/workspace$ which func /usr/bin/func
Local function testing
You are now ready to start developing your function whether directly on your local machine or from within a container.
The following commands shows you the step by step process to start a function from scratch:
mkdir /tmp/functions cd /tmp/functions func init --worker-runtime=node func new --name foobar --template "HTTP trigger" sed -i 's/"authLevel": "function"/"authLevel": "anonymous"/' foobar/function.json func start --port=8080 %%%%%% %%%%%% @ %%%%%% @ @@ %%%%%% @@ @@@ %%%%%%%%%%% @@@ @@ %%%%%%%%%% @@ @@ %%%% @@ @@ %%% @@ @@ %% @@ %% % Azure Functions Core Tools (2.1.725 Commit hash: 68f448fe6a60e1cade88c2004bf6491af7e5f1df) Function Runtime Version: 2.0.12134.0 [10/19/2018 12:40:27] Building host: startup suppressed:False, configuration suppressed: False [10/19/2018 12:40:27] Reading host configuration file '/tmp/functions/host.json' [10/19/2018 12:40:27] Host configuration file read: ...
On another terminal do:
curl -w '\n\' http://localhost:8080/api/foobar?name=alice Hello alice
If you reach this point you have successfully built a node.js function with the Azure Functions runtime. You can now move on to packaging that function as a container.
Preparing a Docker image
The simplest is to package your function within the
azure-func Docker image with a Dockerfile like this:
FROM gcr.io/triggermesh/azure-func RUN mkdir /tmp/funcroot COPY . /tmp/funcroot WORKDIR /tmp/funcroot CMD ["func", "start", "--port", "8080"]
Build the image and run the container
docker build -t myfunc . docker run -d -p 8080:8080 myfunc
You can now check the logs
docker logs -f myfunc
You are then ready to call the function.
curl -w '\n' http://localhost:8080/api/MyHttpTrigger?name=alice
Example: Create a Function with a Queue Trigger
First you need to create a queue on the Azure Queue Storage service and make note of your Storage connection string (aka your secret access key).
Let's assume you create a queue called
Now initialize the function in an empty directory:
func init --worker-runtime=node
And create a new Queue trigger
func new -t "Queue trigger" --name foobar
Specify your queue name in the file
./foobar/function.json which was just created.
Now build the function container with the following Dockerfile:
FROM gcr.io/triggermesh/azure-func USER root COPY . /home/func RUN chown -R func:func /home/func ENV ASPNETCORE_URLS=http://+:8080 USER func:func WORKDIR /home/func RUN func extensions install --package Microsoft.Azure.Storage.Queue --version 9.4.0 CMD ["func", "start", "--port", "8080"]
And run it, with taking care to pass your connection string as an environment variable:
docker run -it --env AzureWebJobsStorage="...put in your Azure storage connection string ..." myfunc
Publish a message to your queue and watch it being consumed by your function.
Deploying Azure Functions in Knative
Please see the TriggerMesh nodejs runtime for complete instructions and explanations.
Knative leverages Kubernetes and Istio to provide automatic scaling and container image build steps. Knative can therefore package your functions in container images and run then with autoscaling turned on.
To build the container images that contain your Azure functions you need to deploy the Build template from this repo:
kubectl apply -f knative-build-template.yaml
And then as an example, create a Configuration object that will reference this build template and create what are called Knative revisions.
To get traffic to flow to your functions (assuming it is an
HTTP Trigger type function you can create a Knative route object.
See the provided manifests:
kubectl apply -f build-r00001.yaml kubectl apply -f route-r00001.yaml
To call your function you can use the debugging command below which lets your reach the function from within the cluster using the proper Host header.
kubectl run -it curl --image=gcr.io/cloud-builders/curl --restart=Never --rm -- \ --connect-timeout 3 --retry 10 -vSL -w '\n' \ -H 'Host: azure-runtime-example-function.default.example.com' \ http://knative-ingressgateway.istio-system.svc.cluster.local/api/foobar?name=Hi%20Knative
Add a runtime
Any of Azure's worker runtimes is likely supported.
To add one,
update the build template with Dockerfile content from
func init --docker and the environment variable
ASPNETCORE_URLS to set the port to 8080.
We would love your feedback on this project so don't hesitate to let us know what is wrong and how we could improve it, just file an issue