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:

  1. You can re-run a local orchestrated set of containers and pods with minimal input required which can be useful for iterative development.
  2. 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

  1. 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/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
  2. 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.

  3. 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/ubi9/ubi:latest
            name: myubi
            resources: {}
            securityContext:
                  allowPrivilegeEscalation: true
                  capabilities: {}
                  privileged: false
                  readOnlyRootFilesystem: false
            tty: true
            workingDir: /
    status: {}

Additional resources

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 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

  1. Create the pod and the container from the mypod.yaml file:

    $ podman play kube mypod.yaml
    Pod:
    b8c5b99ba846ccff76c3ef257e5761c2d8a5ca4d7ffa3880531aec79c0dacb22
    Container:
    848179395ebd33dd91d14ffbde7ae273158d9695a081468f487af4e356888ece
  2. List all pods:

    $ podman pod ps
    POD ID         NAME    STATUS    CREATED          # OF CONTAINERS   INFRA ID
    b8c5b99ba846   mypod   Running   19 seconds ago   2                 aa4220eaf4bb
  3. 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/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

    The pod IDs from podman ps command matches the pod ID from the podman pod ps command.

Additional resources

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
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:

├── mariadb-conf
│   ├── Containerfile
│   ├── my.cnf

Prerequisites

  • The container-tools meta-package is installed.

Procedure

  1. Display the mariadb-conf/Containerfile file:

    $ cat mariadb-conf/Containerfile
    FROM docker.io/library/mariadb
    COPY my.cnf /etc/mysql/my.cnf
  2. 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/
  3. Build the docker.io/library/mariadb image using mariadb-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
  4. Optional: List all images:

    $ podman images
    LIST IMAGES
    REPOSITORY                                                       TAG         IMAGE ID      CREATED             SIZE
    localhost/mariadb-conf                                           latest      b66fa0fa0ef2  57 seconds ago      416 MB
  5. Create the pod named wordpresspod and configure port mappings between the container and the host system:

    $ podman pod create --name wordpresspod -p 8080:80
  6. Create the mydb container inside the wordpresspod 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
  7. Create the myweb container inside the wordpresspod 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
  8. 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

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

  1. 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
  2. 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

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:

  1. a directory with the same name as the image used in YAML file exists
  2. 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:

    $ podman rmi localhost/mariadb-conf
    $ podman rmi docker.io/library/wordpress
    $ podman rmi docker.io/library/mysql

Procedure

  1. 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 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.
  2. 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

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

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