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 usepodman 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 thepodman play
command, you can also recreate pods and containers originally created in OpenShift or Kubernetes environments.
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
module is installed. - The pod has been created. For details, see section Creating pods.
Procedure
List all pods and containers associated with them:
$ podman ps -a --pod CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES POD 5df5c48fea87 registry.access.redhat.com/ubi8/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
Use the pod name or ID to generate the Kubernetes YAML file:
$ podman generate kube mypod > mypod.yaml
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:$ 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/ubi8/ubi:latest name: myubi resources: {} securityContext: allowPrivilegeEscalation: true capabilities: {} privileged: false readOnlyRootFilesystem: false tty: true workingDir: / status: {}
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:$ oc create myapp --image=me/myapp:v1 -o yaml --dry-run > myapp.yaml
The
oc create
command creates and run themyapp
image. The object is printed using the--dry-run
option and redirected into themyapp.yaml
output file.
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
module is installed.
Procedure
Create the pod and the container from the
mypod.yaml
file:$ podman play kube mypod.yaml Pod: b8c5b99ba846ccff76c3ef257e5761c2d8a5ca4d7ffa3880531aec79c0dacb22 Container: 848179395ebd33dd91d14ffbde7ae273158d9695a081468f487af4e356888ece
List all pods:
$ podman pod ps POD ID NAME STATUS CREATED # OF CONTAINERS INFRA ID b8c5b99ba846 mypod Running 19 seconds ago 2 aa4220eaf4bb
List all pods and containers associated with them:
$ podman ps -a --pod CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES POD 848179395ebd registry.access.redhat.com/ubi8/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
The pod IDs from
podman ps
command matches the pod ID from thepodman 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:
$ oc create -f mypod.yaml
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:
├── mariadb-conf │ ├── Containerfile │ ├── my.cnf
Prerequisites
-
The
container-tools
module is installed.
Procedure
Display the
mariadb-conf/Containerfile
file:$ cat mariadb-conf/Containerfile FROM docker.io/library/mariadb COPY my.cnf /etc/mysql/my.cnf
Display the
mariadb-conf/my.cnf
file:[client-server] # 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/
Build the
docker.io/library/mariadb
image usingmariadb-conf/Containerfile
:$ 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
Optional: List all images:
$ podman images LIST IMAGES REPOSITORY TAG IMAGE ID CREATED SIZE localhost/mariadb-conf latest b66fa0fa0ef2 57 seconds ago 416 MB
Create the pod named
wordpresspod
and configure port mappings between the container and the host system:$ podman pod create --name wordpresspod -p 8080:80
Create the
mydb
container inside thewordpresspod
pod:$ 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
Create the
myweb
container inside thewordpresspod
pod:$ 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
Optional: List all pods and containers associated with them:
$ 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
Verification
Verify that the pod is running: Visit the http://localhost:8080/wp-admin/install.php page or use the
curl
command:$ 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> ...
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
module is installed. -
The pod named
wordpresspod
has been created. For details, see section Creating pods.
Procedure
List all pods and containers associated with them:
$ 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
Use the pod name or ID to generate the Kubernetes YAML file:
$ podman generate kube wordpresspod >> wordpresspod.yaml
Verification
Display the
wordpresspod.yaml
file:$ 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
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
module 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:
$ podman rmi localhost/mariadb-conf $ podman rmi docker.io/library/wordpress $ podman rmi docker.io/library/mysql
Procedure
Create the wordpress pod using the
wordpress.yaml
file:$ 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
The
podman play kube
command:-
Automatically build the
localhost/mariadb-conf:latest
image based ondocker.io/library/mariadb
image. -
Pull the
docker.io/library/wordpress:latest
image. -
Create a pod named
wordpresspod
with two containers namedwordpresspod-mydb
andwordpresspod-myweb
.
-
Automatically build the
List all containers and pods:
$ 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
Verification
Verify that the pod is running: Visit the http://localhost:8080/wp-admin/install.php page or use the
curl
command:$ 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> ...
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.
If a volume is in use, it is not removed.
Prerequisites
-
The
container-tools
module 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:$ podman play kube --down wordpresspod.yaml Pods stopped: 3e391d091d190756e655219a34de55583eed3ef59470aadd214c1fc48cae92ac Pods removed: 3e391d091d190756e655219a34de55583eed3ef59470aadd214c1fc48cae92ac
Verification
Verify that all pods and containers created by the
wordpresspod.yaml
file were removed:$ podman ps --pod -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES POD ID PODNAME
Additional resources
- Build Kubernetes pods with Podman play kube
-
podman-play-kube
man page on your system