InformIT

Oracle IaaS-Cloud-Native Technologies

By , ,

Date: Feb 25, 2026

Sample Chapter is provided courtesy of Oracle Press.

Return to the article

Cloud-native refers to the design and development of applications that are built specifically to take advantage of the cloud computing model. Cloud-native applications are designed to be scalable, resilient, and highly available, and they are built using microservices architecture and containerization technologies such as Docker and serverless computing.

The term cloud-native is also often used to describe applications that are designed to be deployed in a cloud environment, but it can also refer to the infrastructure and tools that support the development and deployment of these applications. This includes cloud-based platforms, tools for continuous integration and continuous delivery (CI/CD), and orchestration tools like Kubernetes. In this chapter, we will focus on several important cloud-native technologies that are commonly used by the DevSecOps team.

In general, the goal of cloud-native design is to enable organizations to build and deploy applications more quickly and efficiently, and to take advantage of the scalability, reliability, and cost benefits of the cloud.

There are several reasons why cloud-native design can be advantageous for organizations:

Overall, the benefits of cloud-native design can help organizations build and deploy applications more effectively, take advantage of the scalability and reliability of the cloud, and reduce costs.

In this chapter, we will cover the most popular cloud-native options available on OCI, from serverless technologies like Functions, Streams, and Events, to containerized technology like Docker containers managed by Kubernetes.

Functions

Oracle Cloud Functions is a serverless computing platform offered by Oracle Cloud. It enables developers to build, deploy, and run applications and functions without having to worry about the underlying infrastructure.

With Oracle Cloud Functions, developers can write and deploy code in a variety of languages, including JavaScript, Python, Go, and Java. The platform automatically scales the code to meet demand and only charges for the actual execution time used.

Oracle Cloud Functions can be triggered by events such as a change in a database, a message being published to a message queue, or a request to an HTTP endpoint. Developers can use Oracle Cloud Functions to build and deploy a wide range of applications, including microservices, data processing pipelines, and event-driven applications.

Overall, Oracle Cloud Functions is designed to make it easier for developers to build and deploy applications quickly and efficiently, taking advantage of the scalability and cost-effectiveness of the cloud.

You can manage functions in one of three ways:

Functions can be deployed in several ways. You can use the Cloud Shell, a server, or an OCI Compute Instance. For this example, we will show how to deploy using a Linux server.

Four basic steps need to be performed:

When using functions, you need to be familiar with a few terms:

Setting Up the Tenancy

When setting up the Tenancy to run functions, you should have a security strategy that plans for what users will have access to, in order to author or run the functions. You also need to decide whether the ability to run functions is limited to a specific compartment for the application or for the entire tenancy. For this example, we will create a user group called FunctionDevelopers and include all users who can create and run functions in that group.

Next, a policy needs to be created. This policy will allow the group access to the abilities that functions require. For this example, the policy is called Functions. While the sample sets the policy for the tenancy, you can also set the allow statement for a compartment for better security. The following statements are added to the policy:

Allow group FunctionDevelopers to use cloud-shell in tenancy
Allow group FunctionDevelopers to manage repos in tenancy
Allow group FunctionDevelopers to read objectstorage-namespaces in tenancy
Allow group FunctionDevelopers to manage logging-family in tenancy
Allow group FunctionDevelopers to read metrics in tenancy
Allow group FunctionDevelopers to manage functions-family in tenancy
Allow group FunctionDevelopers to use virtual-network-family in tenancy
Allow group FunctionDevelopers to use apm-domains in tenancy
Allow group FunctionDevelopers to read vaults in tenancy
Allow group FunctionDevelopers to use keys in tenancy
Allow service faas to use apm-domains in tenancy
Allow service faas to read repos in tenancy where request.operation='ListContainer
  ImageSignatures'
Allow service faas to {KEY_READ} in tenancy where request.
  operation='GetKeyVersion'
Allow service faas to {KEY_VERIFY} in tenancy where request.operation='Verify'

When completed, the policy should look similar to that shown in Figure 4-1.

Creating the Application

Functions are contained within a structure known as an application. An application serves as a logical grouping of functions, providing developers with the capability to assign and set up resources for all functions within the application. Additionally, applications allow for the establishment of a shared context for storing configuration variables that can be accessed by all functions in the application while also facilitating function runtime isolation.

FIGURE 4-1

Figure 4-1 Policy for Functions

Applications are easy to create from the Console. Simply navigate to the main menu and select Developer Services > Functions > Applications. This is seen in Figure 4-2.

FIGURE 4-2

Figure 4-2 Navigating to Applications

From here, click Create Application, as shown in Figure 4-3.

FIGURE 4-3

Figure 4-3 Create Application

Next, you need to set up a few details for the function. The first is the name of the application, in this case Test Application. Next, select the VCN and subnets that the function can run in. Finally, you can select the shape. The shape is the architecture that the function will run on. You can pick Arm, X86, or both. This allows you to limit a function to a specific architecture if it requires features only available to that architecture. This step is important because the Docker image user for the function should match the architecture. For the sample, since the development is being done on Arm, Arm is selected. You can see the configuration in Figure 4-4.

FIGURE 4-4

Figure 4-4 Arm-Based Application

When done, click Create. You will then be redirected to the Application page.

Setting Up the Linux Host

To set up the function, you first need a host. The host can be nearly any modern operating system, but for this example we will use an AMD system, running Oracle Linux 8. The system will have two cores and 8 GB of RAM, with a 50 GB boot drive. The user erik was also configured to have access to root using sudo. Don’t worry about only two cores; this is more than enough for editing and testing functions.

The host setup is done in a few steps:

To install Docker, you should make sure that the addons repo is configured. This is done by running the command sudo dnf repolist, the results of which are shown in Example 4-1.

Example 4-1 Installing Docker

[erik@functions ~]$ sudo dnf repolist
repo id                                     repo name
ol8_MySQL80                                 MySQL 8.0 for Oracle Linux 8 (aarch64)
ol8_MySQL80_connectors_community            MySQL 8.0 Connectors Community for
                                            Oracle Linux 8 (aarch64)
ol8_MySQL80_tools_community                 MySQL 8.0 Tools Community for Oracle
                                            Linux 8 (aarch64)
ol8_UEKR7                                   Latest Unbreakable Enterprise Kernel
                                            Release 7 for Oracle Linux 8 (aarch64)
ol8_addons                                  Oracle Linux 8 Addons (aarch64)
ol8_appstream                               Oracle Linux 8 Application Stream
                                            (aarch64)
ol8_baseos_latest                           Oracle Linux 8 BaseOS Latest (aarch64)
ol8_ksplice                                 Ksplice for Oracle Linux 8 (aarch64)
ol8_oci_included                            Oracle Software for OCI users on
                                            Oracle Linux 8 (aarch64)
[erik@functions ~]$

If ol8_addons is not installed, you can enable it by using the command sudo dnf config-manager --enable ol8_addons.

Next, you need to install Docker. If Docker is already installed, you can skip this step. To check whether Docker is installed, run the command sudo Docker version. (On most new installs, Docker is not installed.)

[erik@functions ~]$ sudo Docker version
sudo: Docker: command not found
[erik@functions ~]$

Next, to install Docker, you first need to add in the Extra Packages for Enterprise Linux (EPEL) library.

sudo dnf install -y epel-release

Next, point dnf to the Docker repo, using the following command:

sudo dnf config-manager -y --add-repo=https://download.Docker.com/linux/centos/
  Docker-ce.repo

Next, install the community edition of Docker:

sudo dnf install Docker-ce -y

The next commands will start the server and enable it to restart on reboot:

sudo systemctl enable Docker
sudo systemctl start Docker

Now, let’s make sure Docker is running by using the following command:

sudo systemctl status Docker

Check the status results to make sure Docker is running. You should see active (running) in the Active: section. Figure 4-5 shows a good example with Docker running.

FIGURE 4-5

Figure 4-5 Docker Running

You can also test that Docker is running by using it to run the hello-world container, as shown in Example 4-2.

Example 4-2 Testing That Docker Is Running by Using It to Run the hello-world Container

[erik@functions ~]$ sudo Docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
478afc919002: Pull complete
Digest: sha256:1408fec50309afee38f3535383f5b09419e6dc0925bc69891e79d84cc4cdcec6
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (arm64v8)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
  4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ Docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.Docker.com/

For more examples and ideas, visit:
 https://docs.Docker.com/get-started/

Now, add the user working on the function to the Docker group

usermod -aG Docker erik

You can test by using the command Docker version. The output should look similar to that shown in Figure 4-6.

FIGURE 4-6

Figure 4-6 Docker Version Output

On some systems, you may need to reboot for this to work for non-root users.

Next up is getting an API key, which is needed for the Fn commands to access OCI. To get an API key, from the OCI console, navigate to Profile > User Settings > Resources - API Keys. This will bring you to the API Key page shown in Figure 4-7.

FIGURE 4-7

Figure 4-7 Create a New API Key

Next, click Add API Key. This takes you to the Add API Key dialog box, where you can download the new private key, as shown in Figure 4-8.

FIGURE 4-8

Figure 4-8 API Key Dialog Box

Once the key is added, you will see the configuration file preview. Go ahead and copy the config file preview as well. Next, take the /pem file you download and the sample config and put them into the ~/.oci directory. Name the config file config.

Now edit the config file and add in the location of the .pem file. Once completed, it should look like the following.

[DEFAULT]
user=ocid1.user.oc1..aaaaaaaac7z4b2mycsdmglfyflz4qomu6cmmltwq3g64vroh622cuqu4puyq
fingerprint=f9:a2:62:59:df:ac:61:08:5a:87:93:98:bf:5f:61:38
tenancy=ocid1.tenancy.oc1..
  aaaaaaaa257pjnvghqbiutozu4nsos4xt667ml34i4vvpyhxe2tcugfyr23e
region=us-ashburn-1
key_file=/home/erik/.oci/oci.pem

Finally, secure the .pem file with the chmod command. Change the name of the file as needed.

chmod go-rwx oci.pem

Next, you need to install the Fn Project CLI by using the following command:

sudo curl -LSs https://raw.githubusercontent.com/fnproject/cli/master/install |
  sh

When completed, you should see a text version of the Fn logo and the version installed, as in Figure 4-9.

FIGURE 4-9

Figure 4-9 Fn Installed

Now you need to create a new context for the function, using OCI as the provider:

fn create context myappcontext --provider oracle

Next, you can use this context:

fn use context myappcontext

Now you can update the context to use the OCI credentials. In this case, use the DEFAULT profile in the Oracle config file.

fn update context oracle.profile DEFAULT

Now, set the compartment that you will use:

fn update context oracle.compartment-id \ ocid1.compartment.oc1..
  aaaaaaaacqtlrn4xkj4xuyozvaljeweem7gfzxmnxe6y3j3p2hrcqjbondnq

Next, you need to point to the API URL. Each OCI region will have a unique URL. This is in the format of functions.$REGION.oci.oraclecloud.com:

fn update context api-url https://functions.us-ashburn-1.oci.oraclecloud.com

The last setup of the context is to set the object storage to be used to hold the images. The format for the Registry is $REGION.ocir.io/$NAMESPACE/$bucket:

fn update context registry iad.ocir.io/idizdwpbvdsb/function_bucket

Next up, you need an authentication token. The token is a short string of text characters; it is used to allow Docker to log in to OCI to access images. Navigate to Console > Identity > My Profile > Auth Tokens and then select the Generate Token button. You should see the dialog box shown in Figure 4-10.

FIGURE 4-10

Figure 4-10 Token Management

The next dialog box will allow you to name the token. First, pick a descriptive name and then click Generate Token, as shown in Figure 4-11.

FIGURE 4-11

Figure 4-11 Generate Token

OCI will generate a token for your use. If you lose the token, you will need to generate a new one. You are limited to only two tokens.

You can easily copy the token by clicking the Copy option in the Generated Token dialog box, shown in Figure 4-12.

FIGURE 4-12

Figure 4-12 Generated Token

Once you have the token, you can log Docker in to OCI by using the Docker login command. You will pass it the $REGION.ocir.io and the $NAMESPACE/$USER variables. The $USER should include the domain when using a user in an identity domain:

Docker login iad.ocir.io -u yournamespace/youruser

The same approach is shown in the following:

Docker login  -u 'idizdwpbvdsb/Default/erik@talesfromthedatacenter.com'
  iad.ocir.io

When prompted for a password, use your auth token.

Now that Docker is connected, you can create a sample function. In this example, you will use the default Python HelloWorld sample. You will use the fn init command, specifying python. This will create a directory named hello in your current directory:

fn init --runtime python hello

The directory has three files:

Creating and Running a Function

Next, you can deploy the application to OCI, using the fn deploy command, passing the application where the function will be located:

fn -v deploy --app "Test Application"

Now that the function is deployed, you can invoke it for testing, using the fn invoke command, passing the application and function name:

fn invoke "Test Application" hello

Now, let’s make a more complex function that will call the hello world function. You can call this function test. Use the fn init command so that you have a good start with the requirements.txt and YAML:

fn init --runtime python test

When you do this, you need to make sure that you add that to the requirements.txt file. Just add the line oci to the existing file, as shown in the following:

[erik@functions test]$ more requirements.txt
fdk>=0.1.75
oci

Now, we will need some information from the existing function—mainly its OCID and invoke endpoint. You can get that from the function info page. To locate it, from the main console, navigate to the main menu and select Developer Services > Applications, then select Test Application then your application, as shown in Figure 4-13.

FIGURE 4-13

Figure 4-13 Selecting the Application

Now you should see a list of all functions for the application. Click the three dots on the right side to copy the OCID and invoke endpoint, as indicated in Figure 4-14.

FIGURE 4-14

Figure 4-14 Accessing Function Options

From here, not only can you copy information about the function, but you can also delete the function, open a support request for the function, and edit the functions. These options are available in the following pop-up function options shown in Figure 4-15.

FIGURE 4-15

Figure 4-15 Function Options

Save the copied endpoint and OCID. You will need it for the sample to set the correct values for the function_endpoint and function_ocid variables. This is shown in Example 4-3.

Example 4-3 Sample Function

import logging
import oci

from fdk import response


def handler(ctx, data: io.BytesIO=None):
    try:
        function_endpoint =  "https://ew5sia72beq.us-ashburn-1.
  functions.oci.oraclecloud.com/20181201/functions/ocid1.fnfunc.oc1.iad.
  aaaaaaaajvhhzrlaxooujpg2tmsye4docs5mqfj6cw4lafcyqucb4izjozyq/actions/invoke"
        function_ocid = "ocid1.fnfunc.oc1.iad.
  aaaaaaaajvhhzrlaxooujpg2tmsye4docs5mqfj6cw4lafcyqucb4izjozyq"
        function_body = ""
    except (Exception) as ex:
        print('ERROR: Missing key in payload', ex, flush=True)
        raise

    signer = oci.auth.signers.get_resource_principals_signer()
    client = oci.functions.FunctionsInvokeClient(config={}, signer=signer,
  service_endpoint=function_endpoint)
    resp = client.invoke_function(function_id=function_ocid, invoke_function_
  body=function_body)
    print(resp.data.text, flush=True)
    return response.Response(
        ctx,
        response_data=resp.data.text,
        headers={"Content-Type": "application/json"}
    )

You can now deploy the function:

fn -v deploy –app "Test Application"

Finally, you can invoke it as follows:

fn invoke "Test Application" test

Streams

Oracle Cloud Streams is a fully managed, cloud-based messaging service offered by Oracle Cloud. It enables organizations to build real-time, event-driven applications by providing a secure and scalable messaging platform. The service allows developers to publish and subscribe to messages, enabling them to build applications that can process and react to events in real time. The platform supports a wide range of messaging patterns and protocols, including publish-subscribe, point-to-point, and request-response.

A producer publishes messages to a stream, which is an append-only log. These messages are distributed among Oracle-managed partitions for scalability. Partitions allow you to distribute a stream by splitting messages across multiple nodes (or brokers). Each partition can be placed on a separate machine, allowing multiple consumers to read a stream in parallel. A consumer reads messages from one or more partitions. Consumers can read from any partition regardless of where the partition is hosted. Each message within a stream is marked with an offset value, so a consumer can pick up where it left off if it is interrupted. Messages from a partition are guaranteed to be delivered in the same order they were produced. Consumers can read messages explicitly by providing the partition and offset, or as a member of a consumer group, which coordinates the consumption of an entire stream by the members of the group.

Some examples of how Oracle Cloud Streams can be used include building microservices architectures, real-time data processing pipelines, and event-driven applications. The platform can be integrated with other Oracle Cloud services, such as Oracle Functions and Oracle Autonomous Transaction Processing, to build and deploy cloud-native applications.

When setting up Streams, you should be aware of the following concepts.

Overall, Oracle Cloud Streams is designed to make it easier for organizations to build real-time, event-driven applications by providing a scalable and secure messaging platform in the cloud.

Events

Oracle Cloud Events is a fully managed, cloud-based event management service offered by Oracle Cloud. It enables organizations to build and run event-driven applications by providing a platform for publishing, subscribing, and reacting to events. With Oracle Cloud Events, developers can create and publish events using various sources, including HTTP requests, database changes, and message queues. They can then subscribe to these events and create actions or functions triggered in response to the events. Oracle Cloud Events supports a wide range of event types and sources, and it can be integrated with other Oracle Cloud services, such as Oracle Functions and Oracle Autonomous Transaction Processing, to build and deploy cloud-native applications.

Before you use events, you need to add in a security policy. You also need to make a user group for the Event admins. In Example 4-4, the group is EventAdmins, and the policy is Events, with the policy being applied to the tenancy. Optionally, you can apply the policy at the compartment level.

Example 4-4 Adding a Security Policy

allow group EventAdmins to inspect compartments in tenancy
allow group EventAdmins to use tag-namespaces in tenancy
allow group EventAdmins to inspect streams in tenancy
allow group EventAdmins to use stream-push in tenancy
allow group EventAdmins to use stream-pull in tenancy
allow group EventAdmins to use virtual-network-family in tenancy
allow group EventAdmins to manage function-family in tenancy
allow group EventAdmins to use ons-topic in tenancy
allow group EventAdmins to manage cloudevents-rules in tenancy

The policy should look similar to that shown in Figure 4-16.

FIGURE 4-16

Figure 4-16 Events Policy

One of the most common event use cases is to run a function when an object is uploaded to object storage. To set this up, you need to navigate to Storage > Object Storage.

From here, you can see all of your buckets (as in Figure 4-17). You can either modify an existing bucket or create a new bucket. In this case, create a new bucket by clicking Create Bucket.

FIGURE 4-17

Figure 4-17 Bucket List

As with any bucket, you have several options. The one of interest here is Emit Object Events. Click Create as highlighted in Figure 4-18.

Next, you need to navigate to Observability & Management > Event Service > Rules. You should see the page shown in Figure 4-19.

Next, click Create Rule, which will bring up the Create Rule dialog box. In this dialog, you will be able to set up the rule. In this case, the condition is an Event Type. The service is Object Storage when an object is created. The rule will then run a function in the DevSecOps compartment from the test application called test. The completed sample is shown in Figure 4-20.

Although you are using the event to run a function, it has many more use cases. You can also generate a notification based on an event or push data to a stream. This is a capability that has many uses to both improve security and automate tasks.

Overall, Oracle Cloud Events is designed to make it easier for organizations to build and run event-driven applications by providing a scalable and reliable event management platform in the cloud.

FIGURE 4-18

Figure 4-18 Creating a Bucket

FIGURE 4-19

Figure 4-19 Event Rules

FIGURE 4-20

Figure 4-20 Object Event

Oracle Kubernetes Engine (OKE)

Oracle Kubernetes Engine is a fully managed Kubernetes service offered by Oracle Cloud. OKE enables organizations to deploy, scale, and manage containerized applications on the Oracle Cloud Infrastructure.

Kubernetes is an open-source container orchestration platform that enables developers to deploy, scale, and manage containerized applications in a cluster of machines. OKE simplifies the utilization of Kubernetes on the Oracle Cloud Infrastructure by offering a fully managed service that handles the underlying infrastructure and maintenance tasks. By using OKE, developers can deploy containerized applications with Kubernetes, and the platform will automatically scale and manage the applications based on demand. Additionally, OKE provides features like load balancing, monitoring, and logging to assist developers in managing and optimizing their applications.

Containers are a method of packaging and distributing software applications, along with all their dependencies and libraries, in a portable and self-contained manner. They allow developers to quickly create and deploy applications without worrying about the underlying infrastructure, specific operating systems, and dependencies needed to run the application. Using containerization technology, containers create a lightweight, standalone, executable package that includes everything an application needs to run, such as the application code, system tools, libraries, and runtime. This makes it easy to deploy applications in any environment, whether it’s on a local machine, in a cloud environment, or on-premises. Containers are often used alongside container orchestration platforms like Kubernetes, which enable developers to manage and deploy large numbers of containers at scale. The most widely used container today is Docker.

Docker

Docker is a containerization platform that enables developers to package and distribute software applications in a portable and self-contained way. Docker uses containers to create lightweight, standalone, executable packages that include everything an application needs to run, including the application code, system tools, libraries, and runtime. Docker allows developers to build and deploy applications quickly and easily, without having to worry about the underlying infrastructure or the specific operating system and dependencies required to run the application. This makes it easy to deploy applications in any environment, whether it’s on a local machine, in a cloud environment, or on-premises.

Key Terms

There are several key technologies that you need to first understand:

A Kubernetes cluster is a collection of nodes, which are machines running applications. Nodes can be either physical machines or virtual machines, and their capacity in terms of the number of CPUs and amount of memory is defined at the time of their creation. Typically, a cluster consists of three control nodes and enough worker nodes to handle the workload. There are two types of clusters:

Creating a cluster is quick and easy to do. Navigate to Developer Services > Kubernetes Clusters (OKE) (see Figure 4-21). From here, you can see any existing clusters in the compartment and create a new cluster.

FIGURE 4-21

Figure 4-21 K8s Clusters

Next, select Create Cluster to start the dialog process shown in Figure 4-22.

For most new clusters, you should use the Quick Create approach. This option will correctly create all new resources for the cluster to isolate it from existing workloads. For this sample, let’s create a managed cluster.

The cluster will have a public endpoint, allowing access to manage the cluster from the Internet, but the workers will be on a private subnet. This is seen in the first part of the creation dialog shown in Figure 4-23.

FIGURE 4-22

Figure 4-22 K8s Creation Dialog Box

FIGURE 4-23

Figure 4-23 K8s Creation Part 1

Next, set the initial node configuration. For the sample, three nodes, each with one OCPU and 9 GB of RAM, will be used. Each uses Oracle Linux 8 with K8s 1.30.1 You can see how the shape is set in Figure 4-24.

FIGURE 4-24

Figure 4-24 K8s Creation Part 2

Click Next to continue to the review page. From here, you can review the settings, shown in Figure 4-25.

FIGURE 4-25

Figure 4-25 K8s Review

Click Create Cluster to continue. The system will then create all of the dependency resources and the K8s cluster. When you return to the list of clusters in the compartment, you should see the cluster now, as shown in Figure 4-26.

FIGURE 4-26

Figure 4-26 K8s Cluster Created

From here, you can manage the cluster by using the kubectl command, just like you would for any other K8s cluster!

Summary

In this chapter, you learned about OCI cloud-native technologies, how to create serverless computing functions, how events can be used, what streams are, and also how to set up a K8s cluster. In the next chapter, you will learn more details about OCI networking options.

800 East 96th Street, Indianapolis, Indiana 46240