Note:

Configure Podman Containers with Oracle Linux Automation Engine

Introduction

Oracle Linux Automation Engine enables users to create a playbook for installing Podman and then running and managing containers using the containers.podman collection.

When running playbooks, Oracle Linux Automation Engine runs the tasks on machines matching the hosts: directive in the playbook. These hosts are typically defined in an inventory file and can either be remote or local. In this tutorial, we’ll demonstrate how to run a playbook locally.

Objectives

In this tutorial, you’ll learn to:

Prerequisites

Deploy Oracle Linux Automation Engine

Note: If running in your own tenancy, read the linux-virt-labs GitHub project README.md and complete the prerequisites before deploying the lab environment.

  1. Open a terminal on the Luna Desktop.

  2. Clone the linux-virt-labs GitHub project.

    git clone https://github.com/oracle-devrel/linux-virt-labs.git
    
  3. Change into the working directory.

    cd linux-virt-labs/olam
    
  4. Install the required collections.

    ansible-galaxy collection install -r requirements.yml
    
  5. Update the Oracle Linux instance configuration.

    cat << EOF | tee instances.yml > /dev/null
    compute_instances:
      1:
        instance_name: "ol-control-node"
        type: "control"
    olam_type: olae
    EOF
    
  6. Create an inventory file.

    cat << EOF | tee hosts > /dev/null
    localhost ansible_connection=local ansible_connection=local ansible_python_interpreter=/usr/bin/python3.6
    EOF
    
  7. Deploy the lab environment.

    ansible-playbook create_instance.yml -i hosts -e "@instances.yml"
    

    The free lab environment requires the extra variable ansible_python_interpreter for localhost because it installs the RPM package for the Oracle Cloud Infrastructure SDK for Python. The location for installing this package is under the system’s default Python modules based on your version of Oracle Linux. Using an inventory variable avoids impacting the plays running on hosts other than localhost.

    The default deployment shape uses the AMD CPU. You can change the shape of the instances by passing a new shape variable definition on the command line.

    For example: -e instance_shape="VM.Standard3.Flex"

    Similarly, the default version of the Oracle Linux image uses the variable os_version defined in the `default_vars.yml file. You can modify this value by passing the Oracle Linux major version on the command line.

    For example: -e os_version="9"

    Important: Wait for the playbook to run successfully and reach the pause task. At this stage of the playbook, the installation of Oracle Linux is complete, and the instances are ready. Note the previous play, which prints the public and private IP addresses of the nodes it deploys.

Collections

Collections are a distribution format for Oracle Linux Automation Engine content that can include playbooks, roles, modules, and plugins. This tutorial will install the containers.podman collection using a requirements.yml file. A requirements.yml file enables the installation of collections, roles, or both based on the keys defined within the file.

Create a Requirements File

  1. Open a new terminal and connect to the ol-control-node system via SSH.

    ssh oracle@<ip_address_of_instance>
    
  2. Create a working directory.

    mkdir -p ~/podman-project
    
  3. Create a requirements file.

    cat << 'EOF' | tee ~/podman-project/requirements.yml > /dev/null
    ---
    collections:
      - name: containers.podman
    EOF
    
  4. Install the collection.

    ansible-galaxy collection install -r ~/podman-project/requirements.yml
    

    The output shows the process of retrieving the compressed archive file from the Galaxy site and then installing it into your home directory under .ansible/collections.

    Note: If the output shows ERROR: Ansible requires the locale encoding to be UTF-8; Detected None., this indicates an incorrect locale setting for ansible. Fix the issue by setting these two environment variables:

    export LC_ALL="en_US.UTF-8"
    export LC_CTYPE="en_US.UTF-8"
    

Install Podman

Oracle Linux Automation Engine playbooks consist of plays, which are composed of tasks mapped to specific hosts. These tasks primarily run idempotent modules. Idempotency ensures that you achieve the same result whether the playbook runs once or multiple times. This tutorial will demonstrate idempotency by building the playbook in stages and running it between each change.

Before running a Podman container, we need to install the Podman packages from the Oracle Linux AppStream repository.

  1. Create the playbook file.

    cat << 'EOF' | tee ~/podman-project/podman-playbook.yml > /dev/null
    ---
    - hosts: localhost
      connection: local
    
      tasks:
    
      - name: Install podman
        ansible.builtin.dnf:
          name: '@container-tools:ol8'
          state: present
        become: yes
        when:
          - ansible_distribution == 'OracleLinux'
          - ansible_facts['distribution_major_version'] == '8'
    
      - name: Install podman
        ansible.builtin.dnf:
          name: 'container-tools'
          state: present
        become: yes
        when:
          - ansible_distribution == 'OracleLinux'
          - ansible_facts['distribution_major_version'] == '9'
    EOF
    

    A playbook and the names of the tasks aim to make the playbook self-documenting. The information below provides further explanation of a few key items.

    • hosts: localhost: Instructs the tasks to run against the localhost.
    • connection: local: Ensures the link remains local and does not run over SSH.
    • become: yes: Elevates the task within this playbook section to be run with the sudo privilege by default.
  2. Run the playbook.

    Since we run this playbook against the local host, there is no reason to create or reference an inventory file explicitly. However, if we wanted to run this against a remote host, we would need to update the hosts: entry, remove the connection: line in the playbook, and then create and reference an inventory file. If you are not familiar with this process, you can refer to some of our other tutorials, linked in the Oracle Linux Training Station at the end of this tutorial.

    ansible-playbook ~/podman-project/podman-playbook.yml
    

    The command’s output should show that it runs successfully against localhost, reporting a change in the Install podman task. This status indicates that we have appropriately completed the installation of the container-tools module.

  3. Verify the Podman package installed by displaying its version.

    podman --version
    

Pull an Image

Once we’ve installed Podman, we can pull images from our registry of choice and stage them locally. In this step, we’ll pull the Oracle Linux image from the GitHub Container Registry.

Additional information regarding Oracle Linux Developer images is available here.

  1. Add the task to pull a container image to the playbook.

    cat << EOF | tee -a ~/podman-project/podman-playbook.yml > /dev/null
    
      - name: Pull oraclelinux:9 from GitHub
        containers.podman.podman_image:
          name: ghcr.io/oracle/oraclelinux:9
    EOF
    
  2. Run the playbook.

    ansible-playbook ~/podman-project/podman-playbook.yml
    
  3. Verify that Podman pulled the image.

    podman images
    

    Example output:

    REPOSITORY                  TAG         IMAGE ID      CREATED       SIZE
    ghcr.io/oracle/oraclelinux  9           97e22ab49eea  20 hours ago  254 MB
    

Run a Container Image

Rather than just pulling an image, we can also pull and run a container based on an image in a single step. Let’s pull and run the Oracle Linux NGINX developer image.

  1. Update the playbook file.

    cat << EOF | tee -a ~/podman-project/podman-playbook.yml > /dev/null
    
      - name: Run image
        containers.podman.podman_container:
          name: nginx
          image: ghcr.io/oracle/oraclelinux9-nginx:1.20
          state: started
          detach: yes
          expose:
            - '80'
            - '443'
          publish:
            - '8080:80'
    EOF
    

    Where:

    • name: Name of the container.
    • image: Repository path (or image name) and tag used to create the container.
    • state: Checks for a running container matching the name and configuration. Podman creates and starts a new container when it cannot find a match.
    • detach: Runs the container in detached mode.
    • expose: Expose a port or a range of ports.
    • publish: Publish a container’s port or a range of ports to the host.
  2. Run the playbook.

    ansible-playbook ~/podman-project/podman-playbook.yml
    
  3. Verify the container is running.

    podman ps
    

    Example output:

    [oracle@ol-server podman-project]$ podman ps
    CONTAINER ID  IMAGE                                   COMMAND               CREATED         STATUS             PORTS                 NAMES
    5f7a28cc4c6b  ghcr.io/oracle/oraclelinux9-nginx:1.20  nginx -g daemon o...  2 minutes ago   Up 2 minutes ago   0.0.0.0:8080->80/tcp  nginx
    

    The output shows the container has been up and running for 2 minutes.

  4. Stop the container.

    Using the CONTAINER ID from the output above, run:

    podman stop $(podman ps -q -f name=nginx)
    

    This command uses the CONTAINER ID as the reference to stop the nginx container.

Run a Container Image with a Volume

Podman creates volumes by adding a bind mount, which maps a local directory to a directory within the container. We’ll demonstrate this feature by running the same NGINX container and replacing the default index.html page with a custom one.

  1. Update the playbook file.

    Create the local directory. While we can efficiently and manually perform this step one time from the command line, let’s automate it instead. Automating this step ensures the directory exists anytime the playbook runs. Before running the image, add these tasks, which create a directory and the index.html file.

    Ensure you leave a blank line between tasks for readability and follow YAML syntax rules and alignment guidelines. We’ll use sed to complete this task, as it allows for the easy insertion of blocks of text into a file at a specific line.

    sed -i -e '24 r '<(cat -<< EOF
      - name: Ensure the destination directory exists
        ansible.builtin.file:
          path: "/home/oracle/nginx/"
          state: directory
    
      - name: Create an empty file
        ansible.builtin.file:
          path: "/home/oracle/nginx/index.html"
          state: touch
          mode: '0755'
    
      - name: Create index.html
        ansible.builtin.copy:
          dest: "/home/oracle/nginx/index.html"
          content: |
            Hello! Welcome to Oracle Linux Containers.
    
    EOF
    ) ~/podman-project/podman-playbook.yml
    
  2. Then add the following option at the end of the Run image task.

    cat << EOF | tee -a ~/podman-project/podman-playbook.yml > /dev/null
          volume: "/home/oracle/nginx:/usr/share/nginx/html:Z"
    EOF
    

    The volume option creates a bind mount between the source:destination directory. The :Z option addresses any SELinux permissions issues related to the bind mount. Podman does this by relabeling the volume’s content to match the label inside the container.

    Here is a completed version of the playbook for reference.

  3. Run the playbook.

    ansible-playbook ~/podman-project/podman-playbook.yml
    
  4. Verify the container is running.

    podman ps
    

    Example output:

    CONTAINER ID  IMAGE                                   COMMAND               CREATED         STATUS             PORTS                 NAMES
    f74aa726d470  ghcr.io/oracle/oraclelinux9-nginx:1.20  nginx -g daemon o...  10 minutes ago  Up 10 minutes ago  0.0.0.0:8080->80/tcp  nginx
    
  5. Verify the index.html file exists.

    ls -l /home/oracle/nginx
    

    Example output:

    [oracle@ol-server podman-project]$ ls -l /home/oracle/nginx/
    total 4
    -rwxr-xr-x. 1 oracle oracle 41 Nov  5 16:46 index.html
    
  6. Verify the bind mount.

    Use cURL to display the index.html page from the container and the Welcome message.

    curl localhost:8080
    

    Where 8080 is the local port mapping to port 80 in the container.

Next Steps

By completing this tutorial, you should understand how to automate your work with Podman and containers using Oracle Linux Automation Engine. Explore the other modules in the containers.podman collection to create additional playbooks that automate your infrastructure.

More Learning Resources

Explore other labs on docs.oracle.com/learn or access more free learning content on the Oracle Learning YouTube channel. Additionally, visit education.oracle.com/learning-explorer to become an Oracle Learning Explorer.

For product documentation, visit Oracle Help Center.