Specifying the Compute Architecture on Which to Run Functions
Find out about specifying the processor architecture on which to run a function with OCI Functions.
When deploying a function to OCI Functions, you can specify the processor architecture of the compute instances on which you want to run the function. You can limit the function to running on a single architecture (such as Arm), or you can enable the function to run on multiple architectures (such as both Arm and x86).
There are three steps to specifying the processor architecture on which to run a function:
- Create an application and select a shape for the application that supports the architecture on which you want to run the function. See Selecting a Single Architecture or Multi-Architecture Application Shape on which to run a Function.
- Build an image that contains the necessary dependencies (child images) for the architecture on which you want to run the function. See Building Multi-Architecture (Multi-Arch) Images and Building Single Architecture Images.
- Create the function based on the image you've built, in the application with the appropriate shape. See Creating Functions.
Depending on how you choose to create functions using OCI Functions, you can complete and combine these steps in several different ways. For example:
- You can use the Console to create an application with the appropriate shape first, and then use the Fn Project CLI
fn deploy
command to create and deploy the function (which automatically builds a suitable image containing the necessary dependencies). - You can use a Docker command to build an image containing the necessary dependencies first, use the OCI CLI to create an application with the appropriate shape, and then use the Console to create a function in the application based on the image.
Selecting a Single Architecture or Multi-Architecture Application Shape on which to run a Function
Find out how selecting an application's shape influences the processor architecture of the compute instances on which functions run with OCI Functions.
When you define an application in OCI Functions, you select the processor architecture of the compute instances on which to deploy and run functions in the application. All the functions in the application are deployed and run on compute instances with the same architecture.
You specify the compute instance architecture on which you want to run functions in an application by selecting a shape for the application as follows:
- If you always want functions in the application to run on compute instances with an Arm-based architecture, select the Generic_ARM shape. If you select this single architecture shape for the application, every function's image must contain the necessary dependencies for the Arm architecture (in either a single architecture image, or a multi-architecture image).
- If you always want functions in the application to run on compute instances with an x86-based architecture, select the Generic_X86 shape. If you select this single architecture shape for the application, every function's image must contain the necessary dependencies for the x86 architecture (in either a single architecture image, or a multi-architecture image).
- If you want functions to run on compute instances with whichever architecture has sufficient capacity, select the Generic_X86_ARM shape. In this case, OCI Functions selects the architecture on which to run functions based on available capacity. If you select this multi-architecture shape for the application, every function's image must contain the necessary dependencies for both the Arm architecture and the x86 architecture (in a multi-architecture image).
When you create a function in an application, the image on which the function is based must include the necessary dependencies for the application's shape:
- If you select a single architecture shape for the application, the function's image must contain the necessary dependencies for the corresponding architecture (in either a single architecture image, or a multi-architecture image).
- If you select a multi-architecture shape for the application, the function's image must contain the necessary dependencies for both architectures (in a multi-architecture image).
To use the same image to deploy and run a function on multiple different architectures, you use a multi-architecture image (also known as a manifest list, or as a 'multi-arch image'). You build multi-architecture images from a single source tree, with one image tag that includes images for both x86 and Arm architectures.
If you use the Fn Project CLI command fn -v deploy --app <app-name>
to build a function and its dependencies as a Docker image, the image is built with the necessary dependencies for the application's shape. If the application has a multi-architecture shape, the function's image is built as a multi-architecture image. You can also build multi-architecture images using Docker Buildx and Podman. If you use a tool other than the Fn Project CLI to build a multi-architecture image, it is your responsibility to verify the image is compatible with the application's shape.
When you select a multi-architecture shape for an application, OCI Functions assesses available capacity and determines the architecture in which to deploy and run functions accordingly. Since a function might be deployed in different architectures, the function must be based on a multi-architecture image. It is your responsibility to verify that a function based on a multi-architecture image can be successfully invoked in both x86 and Arm architectures. To enable you to do so, we recommend that as well as creating such a function in an application with a multi-architecture shape, you also create functions based on a multi-architecture image in applications with single architecture shapes. To aid with debugging, Oracle also recommends that a function's logs include details of the architecture of the compute instance on which the function is running.
Having created an application, note that you cannot subsequently change the application's shape. If you want a particular function to run on a different architecture, create the function in a different application (create a new application if necessary) and provide the appropriate single architecture or multi-architecture image. For example:
- If you select a single architecture shape (Arm or x86) for an application but you want a particular function to run on a different architecture, create the function in a different application that has the appropriate architecture shape.
- If you select a multi-architecture shape for an application, but you want a particular function to always run on a specific architecture, create the function in a different application that has the appropriate single architecture shape.
- If you select a single architecture shape (Arm or x86) for the application but you want a particular function to run on any compute instance regardless of architecture, create the function in a different application that has a multi-architecture shape.
Building Multi-Architecture (Multi-Arch) Images
Find out how to build multi-architecture images for functions in applications that have multi-architecture shapes.
You can build multi-architecture images in different ways, including:
- using the Fn Project CLI (for more information, seee Using the Fn Project CLI to build a multi-architecture image (recommended))
- using Docker Buildx (for more information, see Using the Docker buildx plugin to build a multi-architecture image)
- using Podman
You can create functions based on a multi-architecture image both in applications that have a multi-architecture shape and in applications that have a single architecture shape, provided the multi-architecture image includes the necessary dependencies (child images) for the application's shape.
Using the Fn Project CLI to build a multi-architecture image (recommended)
You can use the Fn Project CLI to build a multi-architecture image when deploying a function in an application with a multi-architecture shape:
- Log in to your development environment as a functions developer.
- If a suitable application with a multi-architecture shape in which to create the function does not exist already, create such an application now. See Creating Applications.
- If you haven't already initialized the function, follow the instructions in Using Fn Project CLI Commands to initialize the function now.
- In the function's directory, enter the following Fn Project command to build the function and its dependencies as a Docker multi-architecture image, push the image to the specified Docker registry, and deploy the function to OCI Functions:
fn -v deploy --app <app-name>
where
<app-name>
is the name of the application with the multi-architecture shape, in which you want to create the function.The multi-architecture image is created, and includes the necessary dependencies for the architectures specified by the application's multi-architecture shape.
Using the Docker buildx plugin to build a multi-architecture image
Prerequisite: Before you can use the Docker buildx plugin, you have to download and install the plugin. For download and installation instructions, see the Docker buildx documentation on github.
Having downloaded and installed the Docker buildx plugin, you can use the plugin to build a multi-architecture image on which to base a function to deploy to an application with a single or multi-architecture shape. For more information about using the Docker buildx plugin, see the Docker buildx documentation on github.
For example, you might build a multi-architecture image for a Python hello-world image as follows:
- Log in to your development environment as a functions developer.
- In a terminal window, create a directory in which to store functions. For example:
mkdir helloworld-python-dir
- Change directory to the newly created directory. For example:
cd helloworld-python-dir
- Create a helloworld Python function by entering:
fn init --runtime python helloworld-func
A directory called
helloworld-func
is created, containing:func.yaml
: The function definition file, containing the minimum amount of information required to build and run the function. See the Fn Project documentation to find out about the additional parameters you can include in a func.yaml file.requirements.txt
: A list of required Python libraries.func.py
: The actual function file.
- Create a new file named
Dockerfile
in the same directory.Note that you must name the file
Dockerfile
. - Open the file named
Dockerfile
in an editor of your choice and add the following lines:FROM fnproject/python:3.6-dev as build-stage WORKDIR /function ADD requirements.txt /function/ RUN pip3 install --target /python/ --no-cache --no-cache-dir -r requirements.txt &&\ rm -fr ~/.cache/pip /tmp* requirements.txt func.yaml Dockerfile .venv &&\ chmod -R o+r /python ADD . /function/ RUN rm -fr /function/.pip_cache FROM fnproject/python:3.6 WORKDIR /function COPY --from=build-stage /python /python COPY --from=build-stage /function /function RUN chmod -R o+r /function ENV PYTHONPATH=/function:/python ENTRYPOINT ["/python/bin/fdk", "/function/func.py", "handler"]
- Save the file named
Dockerfile
. You can now use theDockerfile
file as a custom Dockerfile. - In the func.yaml file, change the value of the
runtime:
parameter toruntime: docker
.For example, change:
schema_version: 20180708 name: helloworld-func version: 0.0.1 runtime: python build_image: fnproject/python:3.9-dev run_image: fnproject/python:3.9 entrypoint: /python/bin/fdk /function/func.py handler memory: 256
to:
schema_version: 20180708 name: helloworld-func version: 0.0.1 runtime: docker build_image: fnproject/python:3.9-dev run_image: fnproject/python:3.9 entrypoint: /python/bin/fdk /function/func.py handler memory: 256
- Use the
docker buildx
command to build x86 and Arm-based images and generate a multi-architecture image from them, by entering:docker buildx build --push --platform <platform1,platform2,..> --tag <manifest_name> <dockerfile_path>
For example:
docker buildx build --push --platform linux/arm64/v8,linux/amd64 --tag my-manifest-name:1.0.0-SNAPSHOT-X86-ARM .
- Push the multi-architecture image to Oracle Cloud Infrastructure Registry. For example, by entering:
docker manifest push my-manifest-name:1.0.0-SNAPSHOT-X86-ARM
You can now base a function on the multi-architecture image.
- (Optional) Create a new function and set the function's Image property to the name of the multi-architecture image. For example:
- When using the Console, specify
my-manifest-name:1.0.0-SNAPSHOT-X86-ARM
in the Image field. - When using the Fn Project CLI, specify
my-manifest-name:1.0.0-SNAPSHOT-X86-ARM
as the value of the image argument. For example:fn create function acmeapp acme-func phx.ocir.io/ansh81vru1zp/acme-repo/my-manifest-name:1.0.0-SNAPSHOT-X86-ARM
- When using the Console, specify
Building Single Architecture Images
Find out how to build single architecture images for functions in applications that have single architecture shapes.
You can build single architecture images in different ways, including:
- Using the Fn Project CLI. See Using the Fn Project CLI to build a single architecture image.
- Using the Docker build command. See Using the Docker build command to build a single architecture image.
When you create a function based on a single architecture image, you must create the function in an application that has a compatible single architecture shape.
Using the Fn Project CLI to build a single architecture image
You can use the Fn Project CLI to build a single architecture image when deploying a function in an application with a single architecture shape:
- Log in to your development environment as a functions developer.
- If a suitable application with a single architecture shape in which to create the function does not exist already, create such an application now. See Creating Applications.
- If you haven't already initialized the function, follow the instructions in Using Fn Project CLI Commands to initialize the function now.
- In the function's directory, enter the following Fn Project command to build the function and its dependencies as a single architecture image, push the image to the specified Docker registry, and deploy the function to OCI Functions:
fn -v deploy --app <app-name>
where
<app-name>
is the name of the application with the single architecture shape, in which you want to create the function.The single architecture image is created, and includes the necessary dependencies for the architecture specified by the application's single architecture shape.
Using the Docker build command to build a single architecture image
You can use the Docker build command to build a single architecture image on which to base a function that you want to deploy to an application with a single architecture shape. For more information, see the docker build command in the Docker documentation.
Note that when you use the Docker build command to build an image, the image includes the necessary dependencies for the architecture of the current platform on which you run the command. So if you run the Docker build command on an AMD platform (an x86 architecture), the image includes the necessary dependencies for the x86 architecture. If you want to build a single architecture image for an architecture different to the current platform, use the Docker buildx plugin and specify the single target architecture as the value of the --platform
argument. See Using the Docker buildx plugin to build a multi-architecture image.