Tutorial
Run multiple OCI container workloads on IBM Hyper Protect Virtual Servers for VPC
Use Kubernetes Pod descriptors in a Hyper Protect Virtual Servers contractIf you’re running IBM Hyper Protect Virtual Servers, you’ve already put security at the top of your priority list. Hyper Protect Virtual Servers protects sensitive Linux workloads from internal and external threats.
In this tutorial, you'll learn how to run multiple OCI container-based workloads on an instance of IBM Hyper Protect Virtual Servers for VPC (Virtual Private Cloud). (Review our previous tutorial on how to bring up a single OCI container on Hyper Protect Virtual Servers.) Note that multi-OCI container support is available for Hyper Protect Virtual Servers only with Podman play kube (Pod descriptors). It is not available with a docker-compose file.
The Open Container Initiative, or OCI, is "an open governance structure for the express purpose of creating open industry standards around container formats and runtimes."
This tutorial will show you how to use Kubernetes Pod descriptors in a Hyper Protect Virtual Servers contract. (For Pod descriptor details, see the Kubernetes documentation.)
You will start by running a single OCI container and then learn how to run multiple containers.
Notes:
- Hyper Protect Virtual Servers for VPC supports multiple containers only with Pod descriptors, which means that if you want to run only one container on Hyper Protect Virtual Servers, you can either use Docker Compose or a Pod descriptor. However, if you want to run multiple containers, you must use Pod descriptors with the Hyper Protect Virtual Servers contract.
- The contract workload section can either have containers defined with Docker Compose or Podman
play kube, but not both, within the same contract.
We will cover the following use cases:
- Bring up a single container (PostgreSQL) workload on Hyper Protect Virtual Servers using
play - Bring up multiple container-based workloads on Hyper Protect Virtual Servers using
play
Prerequisites
- Review the tutorial on bringing up a single OCI container on Hyper Protect Virtual Servers. It explains how to get started with Hyper Protect Virtual Servers for VPC in IBM Cloud and how to create a simple Hyper Protect Virtual Servers contract.
- Basic knowledge of Hyper Protect Virtual Servers for VPC and how to get started with a Hyper Protect Virtual Servers contact.
- A valid IBM Cloud account. See these instructions.
- Recommended: Review the official IBM Cloud documentation on Confidential Computing with LinuxONE in IBM Cloud. Also review the documentation on using Podman
playwith Hyper Protect Virtual Servers contracts. - Recommended: Review this IBM Hyper Protect technical paper. It provides rich content on the Hyper Protect platform.
Recommended: Review the Kubernetes documentation on Pods.
Note: The IBM Cloud UI menus can change over time. If you have any questions about the UI or documentation, contact the IBM Hyper Protect Accelerator at: hpa@ibm.com.
Estimated time
This tutorial will take approximately 30 minutes to complete, including the preparation time, depending on your previous experience working with pod definition files. Creating the Hyper Protect Virtual Servers instance should take only a few seconds.
Steps
Step 1. Construct a Pod definition file
In a previous tutorial, you learned how a PostgreSQL container can be defined using a Docker Compose file with Hyper Protect Virtual Servers. Now you'll explore how to use a Pod descriptor for the same container.
The first step is to create a Pod definition file with the container details.
Create a directory called
pod_postgres:root@podman-postgres:~# mkdir pod_postgres root@podman-postgres:~# cd pod_postgres/ root@podman-postgres:~/pod_postgres# ls root@podman-postgres:~/pod_postgres#Create a simple pod YAML file called
pod_postgres.yamlwith the following content. This example shows the publicly available container image for PostgreSQL. Note: The example is for your reference only. See the official Red Hat documentation to learn more about Pod definition files.apiVersion: v1 kind: Pod metadata: name: postgresdb spec: containers: - name: postgres image: docker.io/library/postgres:12@sha256:429c57f9ae8f379601df6df7448b0c2c8df4da23d7ba2cb57fee8da8f262eda0 env: - name: POSTGRES_HOST_AUTH_METHOD valueFrom: configMapKeyRef: name: env-user key: POSTGRES_HOST_AUTH_METHOD - name: POSTGRES_PASSWORD valueFrom: configMapKeyRef: name: env-user key: POSTGRES_PASSWORD ports: - containerPort: 5432 hostPort: 5432 restartpolicy: AlwaysCreate a file named
configmaps_postgres.yamlwith the following contents. Note: You must include akindattribute with a value ofConfigMap. Use a password of your choice for thePOSTGRES_PASSWORDenvironment variable's value. The following example usespassw0rd.apiVersion: v1 kind: ConfigMap metadata: name: env-user data: POSTGRES_HOST_AUTH_METHOD: trust POSTGRES_PASSWORD: passw0rdReview the folder structure to ensure it looks like the following example, with both the newly created files within the same directory:
root@podman-postgres:~/pod_postgres# ls -l total 8 -rw-r--r-- 1 root root 129 Nov 21 08:53 configmaps_postgres.yaml -rw-r--r-- 1 root root 596 Nov 21 08:50 pod_postgres.yamlValidate that the files are in the correct format by running them in your local environment where podman is installed.
- Start the PostgreSQL workload using the
podman play kubecommand. Optional: You can also use a LinuxONE Virtual Server Instance to set up podman and run the following command if a local environment is not available. (See Bringing up container-based workloads on LinuxONE zVSI to learn more about how to create a LinuxONE Virtual Server instance.)
root@podman-postgres:~/pod_postgres# podman play kube pod_postgres.yaml --configmap ./configmaps_postgres.yaml Trying to pull docker.io/library/postgres@sha256:429c57f9ae8f379601df6df7448b0c2c8df4da23d7ba2cb57fee8da8f262eda0... Getting image source signatures Copying blob 9595ad34963d done Copying blob a7cd1b5b2e3c done Copying blob 1c2e5a5a3305 done Copying blob aeb5658447e2 done Copying blob fe2887f3dc6c done Copying blob acaae8b3f317 done Copying blob 31d443c42a10 done Copying blob 9e57daa6420a done Copying blob e08ed989481b done Copying blob d62a513ca1cd done Copying blob cfe91422bc2d done Copying blob a4a8c236b9a9 done Copying blob 1f11052fcdc0 done Copying config c6bf1b141f done Writing manifest to image destination Storing signatures Pod: 336a5645bc3e3a6a8cd83c02592b505c7ffd17f6b9d26592ff34eda3b372b5b1 Container: 7410865682a8de1d07ec6ca20114a80140e339a30d3b17a064868b6a53471afaCheck that the pod and container are running as expected using the following commands.
root@podman-postgres:~/pod_postgres# podman pod ps POD ID NAME STATUS CREATED INFRA ID # OF CONTAINERS 336a5645bc3e postgresdb Running 6 hours ago 00d0b39e6ef4 2 root@podman-postgres:~/pod_postgres# podman ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7410865682a8 docker.io/library/postgres@sha256:429c57f9ae8f379601df6df7448b0c2c8df4da23d7ba2cb57fee8da8f262eda0 postgres 6 hours ago Up 6 hours ago 0.0.0.0:5432->5432/tcp postgresdb-postgres
- Start the PostgreSQL workload using the
When the PostgreSQL container is running in your local environment, you need to check whether it's accessible (either locally or remotely). Note: You might have to install the following packages before you can start using the
psqlutility.sudo apt install postgresql-client-common sudo apt install postgresql-client psql -h <PostgreSQL host IP> -p 5432 -U postgres
Now that you have validated your Pod descriptor files in a local environment, you can prepare to use it with Hyper Protect Virtual Servers for VPC.
Step 2. Run PostgreSQL container-based workloads
In the following steps, you'll create a contract with the Pod descriptors. In the previous tutorial, we discussed the different sections of a Hyper Protect Virtual Servers contract, specifically env and workload. For this tutorial, the contents of the env section remain unchanged. Only the workload section changes when you switch to using Pod descriptors.
The workload section of the contract can either have the compose or play subsection. The Hyper Protect Virtual Servers instance internally uses either Docker Compose or Podman play kube to manage the OCI containers, depending on which subsection is used.
See Run container-based workloads on IBM Hyper Protect Virtual Servers for VPC to learn more about how to create a Hyper Protect Virtual Servers for VPC instance from IBM Cloud.
For more details on the play subsection, see the IBM Cloud VPC documentation.
To create a .tar file of the pod descriptors that you created previously, run the following command:
root@podman-postgres:~/pod_postgres# tar czvf pod.tgz * configmaps_postgres.yaml pod_postgres.yamlConvert the .tar file to base64 format:
root@podman-postgres:~/pod_postgres# base64 -w0 pod.tgz > pod.b64 root@podman-postgres:~/pod_postgres# cat pod.b64 H4sIAAAAAAAAA+3UX2/aMBAA8DznU/gLtHUc5w9+Gtq6IU0VCOj2iC6xQyOSOLIDFd9+hgFllJY9dJ2m3e8l8fkUX5ycc90U5byG1s5abbu5UfZ6DXXlvSHqxJxvr87plTIaeAGPWEITNwg96gY08gh9yyJesrQdGEI8o3X3Wt6l+X8UtOU3ZWypG0FWgb8oGynIx+1PcQetX6sOJHQgfEIaqJUgqlldLa0y/j48Gk6mX8a3k9nA3cz699PB7O52Ohh+EqQzbnePU0b9yeT7cOymWrD2kRrp/+0N+M+1Wv65xt+50P9BwPiu/+OEJ5Hr/zCIE+z/93C2/0danun8/W8iM9+2Kt9M5LrpoGzcAzajq5NEFyKkrGHuYlLnC2WuS31TlZkBs77ZZ4mAfbAPwKJYcNbLo6TogUqLMOnFNJBFLIuE8zSjOctTWXAJLJRJBizPXKpSqYS0YDFTEuh2QXdAie3NU0EvHlG7PEJWUC3VZ6NrcQhtXu7nKfhVrceqOJp5dhYezSzU+vKCzwrbH4xnCiK/V9ErJZ3U9MtarTadfdqvwwcdubggEQ/Z4UkP7oOdhN3nc93Ttboqc7dEv3qEtcUjHSGEEEIIIYQQQgghhBBCCCGEEHpnPwADkUAAA==Add the base 64 content created in the previous step to the contract
workloadsection (atworkload > play > archive).workload: | type: workload play: archive: H4sIAAAAAAAAA+3UX2/aMBAA8DznU/gLtHUc5w9+Gtq6IU0VCOj2iC6xQyOSOLIDFd9+hgFllJY9dJ2m3e8l8fkUX5ycc90U5byG1s5abbu5UfZ6DXXlvSHqxJxvr87plTIaeAGPWEITNwg96gY08gh9yyJesrQdGEI8o3X3Wt6l+X8UtOU3ZWypG0FWgb8oGynIx+1PcQetX6sOJHQgfEIaqJUgqlldLa0y/j48Gk6mX8a3k9nA3cz699PB7O52Ohh+EqQzbnePU0b9yeT7cOymWrD2kRrp/+0N+M+1Wv65xt+50P9BwPiu/+OEJ5Hr/zCIE+z/93C2/0danun8/W8iM9+2Kt9M5LrpoGzcAzajq5NEFyKkrGHuYlLnC2WuS31TlZkBs77ZZ4mAfbAPwKJYcNbLo6TogUqLMOnFNJBFLIuE8zSjOctTWXAJLJRJBizPXKpSqYS0YDFTEuh2QXdAie3NU0EvHlG7PEJWUC3VZ6NrcQhtXu7nKfhVrceqOJp5dhYezSzU+vKCzwrbH4xnCiK/V9ErJZ3U9MtarTadfdqvwwcdubggEQ/Z4UkP7oOdhN3nc93Ttboqc7dEv3qEtcUjHSGEEEIIIYQQQgghhBBCCCGEEHpnPwADkUAAA==Combine the
workloadsection with theenvsection. (For details on creating the contract and sections, see the previous tutorial.)env: | type: env logging: logDNA: hostname: syslog-x.us-south.logging.cloud.ibm.com ingestionKey: axxxxxxxxxxx3 port: 6514 workload: | type: workload play: archive: H4sIAAAAAAAAA+3UX2/aMBAA8DznU/gLtHUc5w9+Gtq6IU0VCOj2iC6xQyOSOLIDFd9+hgFllJY9dJ2m3e8l8fkUX5ycc90U5byG1s5abbu5UfZ6DXXlvSHqxJxvr87plTIaeAGPWEITNwg96gY08gh9yyJesrQdGEI8o3X3Wt6l+X8UtOU3ZWypG0FWgb8oGynIx+1PcQetX6sOJHQgfEIaqJUgqlldLa0y/j48Gk6mX8a3k9nA3cz699PB7O52Ohh+EqQzbnePU0b9yeT7cOymWrD2kRrp/+0N+M+1Wv65xt+50P9BwPiu/+OEJ5Hr/zCIE+z/93C2/0danun8/W8iM9+2Kt9M5LrpoGzcAzajq5NEFyKkrGHuYlLnC2WuS31TlZkBs77ZZ4mAfbAPwKJYcNbLo6TogUqLMOnFNJBFLIuE8zSjOctTWXAJLJRJBizPXKpSqYS0YDFTEuh2QXdAie3NU0EvHlG7PEJWUC3VZ6NrcQhtXu7nKfhVrceqOJp5dhYezSzU+vKCzwrbH4xnCiK/V9ErJZ3U9MtarTadfdqvwwcdubggEQ/Z4UkP7oOdhN3nc93Ttboqc7dEv3qEtcUjHSGEEEIIIYQQQgghhBBCCCGEEHpnPwADkUAAA==See the previous tutorial for instructions on how to create an instance of Hyper Protect Virtual Servers for VPC and substitute the contract that you just created:
~# psql -h <floating ip or VM ip> -p 5432 -U postgres psql (12.16 (Ubuntu 12.16-0ubuntu0.20.04.1), server 12.12 (Debian 12.12-1.pgdg110+1)) Type "help" for help.
Step 3. Prepare to run multiple OCI containers
You will use the play subsection of workload to create a contract that can bring up multiple containers on Hyper Protect Virtual Servers for VPC. You'll enhance the contract that you created in the previous step to add support for multiple containers.
The following example has a ReactJS app container definition added to the descriptor, along with the PostgreSQL definition:
apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
containers:
- name: postgres. #container 1 spec
image: docker.io/library/postgres:12@sha256:429c57f9ae8f379601df6df7448b0c2c8df4da23d7ba2cb57fee8da8f262eda0
env:
- name: POSTGRES_HOST_AUTH_METHOD
valueFrom:
configMapKeyRef:
name: env-user
key: POSTGRES_HOST_AUTH_METHOD
- name: POSTGRES_PASSWORD
valueFrom:
configMapKeyRef:
name: env-user
key: POSTGRES_PASSWORD
ports:
- containerPort: 5432
hostPort: 5432
restartpolicy: Always
- name: react-nodejs-app. #container 2 spec
image: docker.io/{reponame}/myreactapp:0.0.1@sha256:94bf6cae0902b33b6840e045fd2bae212f0bd538776b325a6daff123a1bf5
env:
- name: POSTGRES_PASSWORD
valueFrom:
configMapKeyRef:
name: env-user
key: POSTGRES_PASSWORD
- name: POSTGRES_PORT
valueFrom:
configMapKeyRef:
name: env-user
key: POSTGRES_PORT
ports:
- containerPort: 5173
hostPort: 80
restartpolicy: Always
Summary
In this tutorial, you've learned how to use the play subsection of a contract to prepare to run multiple OCI containers on an instance of Hyper Protect Virtual Servers for VPC.
Watch for future tutorials, where we will explore additional features of Hyper Protect Virtual Servers for VPC.
Next steps
Now that you understand how to configure Hyper Protect Virtual Servers contracts and run multiple OCI containers on a single instance, continue to explore Hyper Protect Virtual Servers resources:
- IBM Developer hub: IBM Cloud Hyper Protect Services for more articles, tutorials, and other resources
- IBM Hyper Protect Virtual Servers
- IBM Cloud Hyper Protect Virtual Servers