Chapter 13. Porting containers to OpenShift using Podman You can generate portable descriptions of containers and pods by using the YAML ("YAML Ain't Markup Language") format. The YAML is a text format used to describe the configuration data. The YAML files are: Readable. Easy to generate. Portable between environments (for example between RHEL and OpenShift). Portable between programming languages. Convenient to use (no need to add all the parameters to the command line). Reasons to use YAML files: You can re-run a local orchestrated set of containers and pods with minimal input required which can be useful for iterative development. You can run the same containers and pods on another machine. For example, to run an application in an OpenShift environment and to ensure that the application is working correctly. You can use podman generate kube command to generate a Kubernetes YAML file. Then, you can use podman play command to test the creation of pods and containers on your local system before you transfer the generated YAML files to the Kubernetes or OpenShift environment. Using the podman play command, you can also recreate pods and containers originally created in OpenShift or Kubernetes environments. Note The podman kube play command supports a subset of Kubernetes YAML capabilities. For more information, see the support matrix of supported YAML fields . 13.1. Generating a Kubernetes YAML file using Podman You can create a pod with one container and generate the Kubernetes YAML file using the podman generate kube command. Prerequisites The container-tools meta-package is installed. The pod has been created. For details, see section Creating pods . Procedure List all pods and containers associated with them: Use the pod name or ID to generate the Kubernetes YAML file: Note that the podman generate command does not reflect any Logical Volume Manager (LVM) logical volumes or physical volumes that might be attached to the container. Display the mypod.yaml file: Additional resources podman-generate-kube man page on your system Podman: Managing pods and containers in a local container runtime 13.2. Generating a Kubernetes YAML file in OpenShift environment In the OpenShift environment, use the oc create command to generate the YAML files describing your application. Procedure Generate the YAML file for your myapp application: The oc create command creates and run the myapp image. The object is printed using the --dry-run option and redirected into the myapp.yaml output file. Note In the Kubernetes environment, you can use the kubectl create command with the same flags. 13.3. Starting containers and pods with Podman With the generated YAML files, you can automatically start containers and pods in any environment. The YAML files can be generated using tools other than Podman, such as Kubernetes or Openshift. The podman play kube command allows you to recreate pods and containers based on the YAML input file. Prerequisites The container-tools meta-package is installed. Procedure Create the pod and the container from the mypod.yaml file: List all pods: List all pods and containers associated with them: The pod IDs from podman ps command matches the pod ID from the podman pod ps command. Additional resources podman-play-kube man page on your system Podman can now ease the transition to Kubernetes and CRI-O 13.4. Starting containers and pods in OpenShift environment You can use the oc create command to create pods and containers in the OpenShift environment. Procedure Create a pod from the YAML file in the OpenShift environment: Note In the Kubernetes environment, you can use the kubectl create command with the same flags. 13.5. Manually running containers and pods using Podman The following procedure shows how to manually create a WordPress content management system paired with a MariaDB database using Podman. Suppose the following directory layout: Prerequisites The container-tools meta-package is installed. Procedure Display the mariadb-conf/Containerfile file: Display the mariadb-conf/my.cnf file: Build the docker.io/library/mariadb image using mariadb-conf/Containerfile : Optional: List all images: Create the pod named wordpresspod and configure port mappings between the container and the host system: Create the mydb container inside the wordpresspod pod: Create the myweb container inside the wordpresspod pod: Optional: List all pods and containers associated with them: Verification Verify that the pod is running: Visit the http://localhost:8080/wp-admin/install.php page or use the curl command: Additional resources Build Kubernetes pods with Podman play kube podman-play-kube man page on your system 13.6. Generating a YAML file using Podman You can generate a Kubernetes YAML file using the podman generate kube command. Prerequisites The container-tools meta-package is installed. The pod named wordpresspod has been created. For details, see section Creating pods . Procedure List all pods and containers associated with them: Use the pod name or ID to generate the Kubernetes YAML file: Verification Display the wordpresspod.yaml file: Additional resources Build Kubernetes pods with Podman play kube podman-play-kube man page on your system 13.7. Automatically running containers and pods using Podman You can use the podman play kube command to test the creation of pods and containers on your local system before you transfer the generated YAML files to the Kubernetes or OpenShift environment. The podman play kube command can also automatically build and run multiple pods with multiple containers in the pod using the YAML file similarly to the docker compose command. The images are automatically built if the following conditions are met: a directory with the same name as the image used in YAML file exists that directory contains a Containerfile Prerequisites The container-tools meta-package is installed. The pod named wordpresspod has been created. For details, see section Manually running containers and pods using Podman . The YAML file has been generated. For details, see section Generating a YAML file using Podman . To repeat the whole scenario from the beginning, delete locally stored images: Procedure Create the wordpress pod using the wordpress.yaml file: The podman play kube command: Automatically build the localhost/mariadb-conf:latest image based on docker.io/library/mariadb image. Pull the docker.io/library/wordpress:latest image. Create a pod named wordpresspod with two containers named wordpresspod-mydb and wordpresspod-myweb . List all containers and pods: Verification Verify that the pod is running: Visit the http://localhost:8080/wp-admin/install.php page or use the curl command: Additional resources Build Kubernetes pods with Podman play kube podman-play-kube man page on your system 13.8. Automatically stopping and removing pods using Podman The podman play kube --down command stops and removes all pods and their containers. Note If a volume is in use, it is not removed. Prerequisites The container-tools meta-package is installed. The pod named wordpresspod has been created. For details, see section Manually running containers and pods using Podman . The YAML file has been generated. For details, see section Generating a YAML file using Podman . The pod is running. For details, see section Automatically running containers and pods using Podman . Procedure Remove all pods and containers created by the wordpresspod.yaml file: Verification Verify that all pods and containers created by the wordpresspod.yaml file were removed: Additional resources Build Kubernetes pods with Podman play kube podman-play-kube man page on your system

Commands:
podman ps -a --pod CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES POD 5df5c48fea87 registry.access.redhat.com/ubi9/ubi:latest /bin/bash Less than a second ago Up Less than a second ago myubi 223df6b390b4 3afdcd93de3e k8s.gcr.io/pause:3.1 Less than a second ago Up Less than a second ago 223df6b390b4-infra 223df6b390b4
podman generate kube mypod > mypod.yaml
cat mypod.yaml Generation of Kubernetes YAML is still under development! # Save the output of this file and use kubectl create -f to import it into Kubernetes. # Created with podman-1.6.4 apiVersion: v1 kind: Pod metadata: creationTimestamp: "2020-06-09T10:31:56Z" labels: app: mypod name: mypod spec: containers: - command: - /bin/bash env: - name: PATH value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin - name: TERM value: xterm - name: HOSTNAME - name: container value: oci image: registry.access.redhat.com/ubi9/ubi:latest name: myubi resources: {} securityContext: allowPrivilegeEscalation: true capabilities: {} privileged: false readOnlyRootFilesystem: false tty: true workingDir: / status: {}
oc create myapp --image=me/myapp:v1 -o yaml --dry-run > myapp.yaml
podman play kube mypod.yaml Pod: b8c5b99ba846ccff76c3ef257e5761c2d8a5ca4d7ffa3880531aec79c0dacb22 Container: 848179395ebd33dd91d14ffbde7ae273158d9695a081468f487af4e356888ece
podman pod ps POD ID NAME STATUS CREATED # OF CONTAINERS INFRA ID b8c5b99ba846 mypod Running 19 seconds ago 2 aa4220eaf4bb
podman ps -a --pod CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES POD 848179395ebd registry.access.redhat.com/ubi9/ubi:latest /bin/bash About a minute ago Up About a minute ago myubi b8c5b99ba846 aa4220eaf4bb k8s.gcr.io/pause:3.1 About a minute ago Up About a minute ago b8c5b99ba846-infra b8c5b99ba846
oc create -f mypod.yaml
├── mariadb-conf │ ├── Containerfile │ ├── my.cnf
cat mariadb-conf/Containerfile FROM docker.io/library/mariadb COPY my.cnf /etc/mysql/my.cnf
Port or socket location where to connect port = 3306 socket = /run/mysqld/mysqld.sock Import all .cnf files from the configuration directory [mariadbd] skip-host-cache skip-name-resolve bind-address = 127.0.0.1 !includedir /etc/mysql/mariadb.conf.d/ !includedir /etc/mysql/conf.d/
cd mariadb-conf podman build -t mariadb-conf . cd .. STEP 1: FROM docker.io/library/mariadb Trying to pull docker.io/library/mariadb:latest Getting image source signatures Copying blob 7b1a6ab2e44d done Storing signatures STEP 2: COPY my.cnf /etc/mysql/my.cnf STEP 3: COMMIT mariadb-conf --> ffae584aa6e Successfully tagged localhost/mariadb-conf:latest ffae584aa6e733ee1cdf89c053337502e1089d1620ff05680b6818a96eec3c17
podman images LIST IMAGES REPOSITORY TAG IMAGE ID CREATED SIZE localhost/mariadb-conf latest b66fa0fa0ef2 57 seconds ago 416 MB
podman pod create --name wordpresspod -p 8080:80
podman run --detach --pod wordpresspod -e MYSQL_ROOT_PASSWORD=1234 -e MYSQL_DATABASE=mywpdb -e MYSQL_USER=mywpuser -e MYSQL_PASSWORD=1234 --name mydb localhost/mariadb-conf
podman run --detach --pod wordpresspod -e WORDPRESS_DB_HOST=127.0.0.1 -e WORDPRESS_DB_NAME=mywpdb -e WORDPRESS_DB_USER=mywpuser -e WORDPRESS_DB_PASSWORD=1234 --name myweb docker.io/wordpress
podman ps --pod -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES POD ID PODNAME 9ea56f771915 k8s.gcr.io/pause:3.5 Less than a second ago Up Less than a second ago 0.0.0.0:8080->80/tcp 4b7f054a6f01-infra 4b7f054a6f01 wordpresspod 60e8dbbabac5 localhost/mariadb-conf:latest mariadbd Less than a second ago Up Less than a second ago 0.0.0.0:8080->80/tcp mydb 4b7f054a6f01 wordpresspod 045d3d506e50 docker.io/library/wordpress:latest apache2-foregroun... Less than a second ago Up Less than a second ago 0.0.0.0:8080->80/tcp myweb 4b7f054a6f01 wordpresspod
curl http://localhost:8080/wp-admin/install.php <!DOCTYPE html> <html lang="en-US" xml:lang="en-US"> <head> </head> <body class="wp-core-ui"> <p id="logo">WordPress</p> <h1>Welcome</h1>
podman ps --pod -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES POD ID PODNAME 9ea56f771915 k8s.gcr.io/pause:3.5 Less than a second ago Up Less than a second ago 0.0.0.0:8080->80/tcp 4b7f054a6f01-infra 4b7f054a6f01 wordpresspod 60e8dbbabac5 localhost/mariadb-conf:latest mariadbd Less than a second ago Up Less than a second ago 0.0.0.0:8080->80/tcp mydb 4b7f054a6f01 wordpresspod 045d3d506e50 docker.io/library/wordpress:latest apache2-foregroun... Less than a second ago Up Less than a second ago 0.0.0.0:8080->80/tcp myweb 4b7f054a6f01 wordpresspod
podman generate kube wordpresspod >> wordpresspod.yaml
cat wordpresspod.yaml apiVersion: v1 kind: Pod metadata: creationTimestamp: "2021-12-09T15:09:30Z" labels: app: wordpresspod name: wordpresspod spec: containers: - args: value: podman - name: MYSQL_PASSWORD value: "1234" - name: MYSQL_MAJOR value: "8.0" - name: MYSQL_VERSION value: 8.0.27-1debian10 - name: MYSQL_ROOT_PASSWORD value: "1234" - name: MYSQL_DATABASE value: mywpdb - name: MYSQL_USER value: mywpuser image: mariadb name: mydb ports: - containerPort: 80 hostPort: 8080 protocol: TCP - args: - name: WORDPRESS_DB_NAME value: mywpdb - name: WORDPRESS_DB_PASSWORD value: "1234" - name: WORDPRESS_DB_HOST value: 127.0.0.1 - name: WORDPRESS_DB_USER value: mywpuser image: docker.io/library/wordpress:latest name: myweb
podman rmi localhost/mariadb-conf podman rmi docker.io/library/wordpress podman rmi docker.io/library/mysql
podman play kube wordpress.yaml STEP 1/2: FROM docker.io/library/mariadb STEP 2/2: COPY my.cnf /etc/mysql/my.cnf COMMIT localhost/mariadb-conf:latest --> 428832c45d0 Successfully tagged localhost/mariadb-conf:latest 428832c45d07d78bb9cb34e0296a7dc205026c2fe4d636c54912c3d6bab7f399 Trying to pull docker.io/library/wordpress:latest Getting image source signatures Copying blob 99c3c1c4d556 done Storing signatures Pod: 3e391d091d190756e655219a34de55583eed3ef59470aadd214c1fc48cae92ac Containers: 6c59ebe968467d7fdb961c74a175c88cb5257fed7fb3d375c002899ea855ae1f 29717878452ff56299531f79832723d3a620a403f4a996090ea987233df0bc3d
podman ps --pod -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES POD ID PODNAME a1dbf7b5606c k8s.gcr.io/pause:3.5 3 minutes ago Up 2 minutes ago 0.0.0.0:8080->80/tcp 3e391d091d19-infra 3e391d091d19 wordpresspod 6c59ebe96846 localhost/mariadb-conf:latest mariadbd 2 minutes ago Exited (1) 2 minutes ago 0.0.0.0:8080->80/tcp wordpresspod-mydb 3e391d091d19 wordpresspod 29717878452f docker.io/library/wordpress:latest apache2-foregroun... 2 minutes ago Up 2 minutes ago 0.0.0.0:8080->80/tcp wordpresspod-myweb 3e391d091d19 wordpresspod
curl http://localhost:8080/wp-admin/install.php <!DOCTYPE html> <html lang="en-US" xml:lang="en-US"> <head> </head> <body class="wp-core-ui"> <p id="logo">WordPress</p> <h1>Welcome</h1>
podman play kube --down wordpresspod.yaml Pods stopped: 3e391d091d190756e655219a34de55583eed3ef59470aadd214c1fc48cae92ac Pods removed: 3e391d091d190756e655219a34de55583eed3ef59470aadd214c1fc48cae92ac
podman ps --pod -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES POD ID PODNAME