Oracle IaaS-Cloud-Native Technologies
By Erik Benner, Ahmed Aboulnaga, Dhrumil Patel
Date: Feb 25, 2026
Sample Chapter is provided courtesy of Oracle Press.
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:
Scalability: Cloud-native applications are designed to be scalable, meaning they can handle a large volume of traffic or workload without experiencing performance degradation. This capability can be especially important for applications that experience sudden spikes in traffic.
Resilience: Cloud-native applications are also designed to be resilient, meaning they are able to recover quickly from failures or disruptions. This capability can help ensure that applications are available and functioning properly, even in the face of unexpected events.
Cost-Effectiveness: By leveraging the cloud, organizations can take advantage of the pay-as-you-go model to pay only for the resources they use, rather than having to invest in and maintain their own infrastructure. This model can help organizations reduce their costs and increase their efficiency by focusing on the core application logic, and not the supporting infrastructure and services.
Speed and Agility: Cloud-native design can also enable organizations to build and deploy applications more quickly and efficiently, thanks to tools like CI/CD and orchestration tools like Kubernetes. This capability can help organizations respond more quickly to changing business needs and stay competitive in the market. Part of this speed is also leveraging PaaS services like building blocks. This way, the developers can rapidly add application functionality by leveraging services managed by OCI.
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:
Oracle Cloud Shell: This tool enables you to use the Oracle Cloud Shell from the OCI console to create, deploy, and invoke functions. It requires minimal setup and is the easiest way to start working with functions and the OCI Command Line Interface (CLI). The shell includes OCI-specific tools and utilities that help the admin be more productive.
Local Host: This host enables you to deploy a Docker instance that enables a command-line interface to create, deploy, and invoke functions. This is a great way for macOS and Linux users to set up the CLI on their daily driver.
Oracle Compute Instance: This tool is similar to a local host but leverages some of the automation to set up Docker on a normal compute instance.
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:
Step 1: Setting Up the Tenancy: This step includes creating a compartment for the function to run in and the network that it will use. You also will set up the security.
Step 2: Creating the Application: Here, you will set up the application that the function will run in.
Step 3: Setting Up the Linux Host: In this step, you will get the API key and set up a Linux host to manage functions.
Step 4: Creating and Running the Function: In this last step, you will create a Python function and learn how to run it. This will also cover an example of having a function use the Python OCI API.
When using functions, you need to be familiar with a few terms:
Application: A logical grouping of functions
Function: Blocks of code stored as a Docker image
Invocation: The process of running a function
Trigger: An action that can automatically invoke a function
Context: A local installation of a development copy of a function
Provider: A service that holds the Docker image and manages the infrastructure that runs the functions
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 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 Navigating to Applications
From here, click Create Application, as shown in 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 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:
Step 1. Install Docker.
Step 2. Install the Fn CLI.
Step 3. Set up Fn.
Step 4. Log in to a Registry.
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 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 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 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 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 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 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 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 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:
func.py: The HelloWorld Python source code
func.yaml: The definition of the function, including the name, what runtime language to use, and also what versions are used
Requirements.txt: The libraries that need to be made available to the function when it runs
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 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 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 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.
Consumer: An entity that reads messages from one or more streams.
Consumer Group: A group of instances that work together to consume messages from all partitions in a stream. At any given time, messages from a specific partition can be consumed by only a single consumer in the group.
Cursor: A reference to a specific position in a stream, such as an offset or time in a partition, or a group’s current location.
Instance: A consumer group member is defined when a group cursor is created and group membership is maintained through interaction. Lack of interaction leads to a timeout and removes the instance from the consumer group.
Key: An identifier used to group related messages.
Message: A message encoded in Base64 is published to a schema-agnostic stream. The stream accepts various message formats, such as XML, JSON, CSV, and gzip. Producers and consumers must agree on the format.
Offset: The offset is the position of a message within a partition. Each message is identified by its offset, and consumers can choose to read messages starting from any offset. If the reading process is interrupted, the offset can be used to restart reading from where it left off in the stream.
Partition: A section of a stream. Partitions make it possible to distribute a stream by splitting messages across multiple nodes. This also enables multiple consumers to read from a stream simultaneously.
Producer: An entity that publishes messages to a stream.
Stream: A partitioned, append-only log of messages.
Stream Pool: A grouping that you can use to organize and manage streams, including any shared Apache Kafka or security settings.
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 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 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 Creating a Bucket
Figure 4-19 Event Rules
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:
Serverless Kubernetes with Virtual Nodes: Virtual nodes offer a serverless Kubernetes experience for running containerized applications at scale, without the need to spend extra resources on managing, scaling, upgrading, and troubleshooting cluster infrastructure.
With virtual nodes, Kubernetes sees these nodes as regular ones, allowing for precise pod scaling with per-pod pricing. This means you can scale your deployments without having to consider the cluster’s capacity, making it easier to handle scalable workloads like high-traffic web applications and data processing jobs.
Managed Nodes: Managed nodes are worker nodes that are created within a customer’s tenancy and operated with shared responsibility between OKE and the customer. Customers can define the desired specifications for their worker node pools, and OKE streamlines the provisioning of these nodes. OKE offers features to automate and simplify key ongoing operations for these worker nodes, including on-demand cycling to automate updating worker nodes, self-healing of worker nodes upon detection of failure, autoscaling, and more. Managed nodes are suitable for customers who require worker nodes with configurations or compute shapes that are not supported by virtual nodes.
Self-Managed Nodes: Self-managed nodes in OKE provide additional customization and control for running containerized workloads that need unique compute configurations or advanced setup across the stack not supported by managed nodes. This allows customers to utilize specialized infrastructure options such as RDMA-enabled bare metal HPC/GPU, confidential computing, or other specialized use cases. While customers still benefit from a managed control plane, they are responsible for managing the worker nodes, including Kubernetes upgrades and OS patching.
Control Plane Nodes: These nodes were previously referred to as master nodes. This is where the scheduler, manager, and the API server run. For redundancy, three nodes are often used.
Worker Nodes: This is where the containers run. They communicate to the control nodes for management.
K8s: This is a common abbreviation for Kubernetes. The 8 represents the numbers of characters between the k and the s!
Managed Cluster: This system utilizes specialized systems to oversee the K8s cluster. While it provides greater control, it comes with a significant cost. Managed nodes are OCI Compute instances that run in your tenancy and can be controlled and configured with shared operational responsibility.
Virtual Cluster: This cluster utilizes VMS for the nodes, which helps reduce costs. Virtual nodes offer precise, pod-level elasticity and pay-per-use pricing. This allows you to scale deployments without worrying about the cluster’s capacity, making it easier to handle scalable workloads like high-traffic web applications and data processing jobs. Resources are allocated at the Pod level.
Authentication and Authorization: You can control access and permissions using native OCI identity and access management (IAM), Oracle Identity Cloud Service, and Kubernetes role-based access control. You can also configure OCI IAM multifactor authentication. Workload Identity allows you to establish secure authentication at the pod level for OCI APIs and services. By following a zero-trust approach, you can ensure that users have access only to necessary resources. This helps enhance your security by reducing the potential for security breaches or unauthorized access.
Compliance: Compliance starts with clusters that already have industry-standard regulatory frameworks approved, such as FedRAMP High, HIPAA, PCI, and SOC 2.
Container Image Scanning: OKE supports container image scanning. This capability allows you to ensure that your application images are free of serious security vulnerabilities and that the integrity of the container images is preserved when deployed by enforcing image signing. You can easily scan for known common vulnerabilities and exposures (CVE).
Encryption: Oracle encrypts block volumes, boot volumes, and volume backups at rest using the Advanced Encryption Standard (AES) algorithm with 256-bit encryption.
Strong Isolation at the Pod Level: Virtual nodes provide strong isolation for each Kubernetes pod. Pods do not share any underlying kernel, memory, or CPU resources. This pod-level isolation enables you or your organization to run untrusted workloads, multitenant applications, and sensitive data.
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:
Enhanced Clusters: Enhanced clusters support all available features, including features not supported by basic clusters (such as virtual nodes, cluster add-on management, workload identity, and additional worker nodes per cluster). Enhanced clusters come with a service-level agreement (SLA).
Basic Clusters: Basic clusters offer all the essential functionality provided by Kubernetes and Container Engine for Kubernetes, but they do not include the advanced features of Container Engine for Kubernetes. Basic clusters have a service-level objective (SLO) but do not come with a service-level agreement.
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 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 K8s Creation Dialog Box
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 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 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 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.