Linking Containers with Podman

Users of the Docker engine might find that their container runtime isn’t featured prominently in Oracle Linux 8. In fact, unless you change the default confifguration a dnf search does not reveal the engine at all. For better or for worse, it appears the industry has been gradually switching from Docker to Podman and its related ecosystem.

Whilst most Docker commands can be translated 1:1 to the Podman world, some differences exist. Instead of highlighting all the changes here please have a look at the Podman User Guide.

Overview

This article explains how to create a network link between 2 containers:

  1. Oracle XE 21c
  2. SQLcl client

These containers are going to be run “rootless”, which has a few implications. By default Podman will allocate storage for containers in ~/.local/share/containers/ so please ensure you have sufficient space in your home directory.

The article refers to Gerald Venzl’s Oracle-XE images and you will create another image for SQLcl.

Installation

If you haven’t already installed Podman you can do so by installing the container-tools:ol8 module:

[opc@podman ~]$ $ sudo dnf module install container-tools:ol8
Last metadata expiration check: 0:06:04 ago on Mon 21 Mar 2022 13:19:40 GMT.
Dependencies resolved.
========================================================================================================================
Package Arch Version Repository Size
========================================================================================================================
Installing group/module packages:
buildah x86_64 1:1.23.1-2.0.1.module+el8.5.0+20494+0311868c ol8_appstream 7.9 M
cockpit-podman noarch 39-1.module+el8.5.0+20494+0311868c ol8_appstream 483 k
conmon x86_64 2:2.0.32-1.module+el8.5.0+20494+0311868c ol8_appstream 55 k
container-selinux noarch 2:2.173.0-1.module+el8.5.0+20494+0311868c ol8_appstream 57 k
containernetworking-plugins x86_64 1.0.1-1.module+el8.5.0+20494+0311868c ol8_appstream 19 M
containers-common noarch 2:1-8.0.1.module+el8.5.0+20494+0311868c ol8_appstream 62 k
criu x86_64 3.15-3.module+el8.5.0+20416+d687fed7 ol8_appstream 518 k
crun x86_64 1.4.1-1.module+el8.5.0+20494+0311868c ol8_appstream 205 k
fuse-overlayfs x86_64 1.8-1.module+el8.5.0+20494+0311868c ol8_appstream 73 k
libslirp x86_64 4.4.0-1.module+el8.5.0+20416+d687fed7 ol8_appstream 70 k
podman x86_64 1:3.4.2-9.0.1.module+el8.5.0+20494+0311868c ol8_appstream 12 M
python3-podman noarch 3.2.1-1.module+el8.5.0+20494+0311868c ol8_appstream 148 k
runc x86_64 1.0.3-1.module+el8.5.0+20494+0311868c ol8_appstream 3.1 M
skopeo x86_64 2:1.5.2-1.0.1.module+el8.5.0+20494+0311868c ol8_appstream 6.7 M
slirp4netns x86_64 1.1.8-1.module+el8.5.0+20416+d687fed7 ol8_appstream 51 k
udica noarch 0.2.6-1.module+el8.5.0+20494+0311868c ol8_appstream 48 k
Installing dependencies:
fuse-common x86_64 3.2.1-12.0.3.el8 ol8_baseos_latest 22 k
fuse3 x86_64 3.2.1-12.0.3.el8 ol8_baseos_latest 51 k
fuse3-libs x86_64 3.2.1-12.0.3.el8 ol8_baseos_latest 95 k
libnet x86_64 1.1.6-15.el8 ol8_appstream 67 k
podman-catatonit x86_64 1:3.4.2-9.0.1.module+el8.5.0+20494+0311868c ol8_appstream 345 k
policycoreutils-python-utils noarch 2.9-16.0.1.el8 ol8_baseos_latest 252 k
python3-pytoml noarch 0.1.14-5.git7dea353.el8 ol8_appstream 25 k
python3-pyxdg noarch 0.25-16.el8 ol8_appstream 94 k
yajl x86_64 2.1.0-10.el8 ol8_appstream 41 k
Installing module profiles:
container-tools/common
Enabling module streams:
container-tools ol8

Transaction Summary
========================================================================================================================
Install 25 Packages

If you like DNS on your container network, install podman-plugins and dnsmasq. This article assumes you do so. The latter of the 2 services needs to be enabled and started:

[opc@podman ~]$ for task in enable start is-active; do sudo systemctl ${task} dnsmasq; done
active

If you see active in the output as in the example dnsmasq is working. If your system is part of a more elaborate setup, the use of dnsmasq is discouraged and you should ask your friendly network admin for advice.

Virtual Network Configuration

This section describes setting up a virtual network. That way you are emulating the way you’d previously have worked with Docker. If I should find the time for it I’ll write a second article and introduce you to Podman’s PODs, an elegant concept similar to Kubernetes that is not available with the Docker engine.

Before containers can communicate with one another, they need to be told which network to use. The easiest way to do so is by creating a new, custom network as shown in this example:

[opc@podman ~]$ podman network create oranet
/home/opc/.config/cni/net.d/oranet.conflist
[opc@podman ~]$ podman network ls
NETWORK ID NAME VERSION PLUGINS
2f259bab93aa podman 0.4.0 bridge,portmap,firewall,tuning
4f4bfc6d2c15 oranet 0.4.0 bridge,portmap,firewall,tuning,dnsname
[opc@podman ~]$

As you can see the new network – oranet – has been created and it’s capable of using DNS thanks for the dnsname extension. If you opted not to install podman-plugins and dnsmasq this feature won’t be availble. Testing showed that availability of DNS on the container network made life a lot easier.

Storage Volumes

Containers are transient by nature, things you store in them are ephemeral by design. Since that’s not ideal for databases, a persistence layer should be used instead. The industry’s best known method to do so is by employing (Podman) volumes. Volumes are crated using the podman volume create command, for example:

[opc@podman ~]$ podman volume create oradata
oradata

As it is the case with the Container images, by default alll the volume’s data will reside in ~/.local/share/containers.

Database Secrets

The final step while preparing for running a database in Podman is to create a secret. Secrets are a relatively new feature in Podman and relieve you from having to consider workarounds passing sensitive data to containers. The Oracle XE containers to be used need to be initialised with a DBA password and it is prudent not to pass this in clear text on the command line.

For this example the necessary database password has been created as a secret and stored as oracle-password using podman secret create ...

[opc@podman ~]$ podman secret create oracle-password ~/.passwordFileToBeDeletedAfterUse
0c5d6d9eff16c4d30d36c6133
[opc@podman ~]$ podman secret ls
ID NAME DRIVER CREATED UPDATED
0c5d6d9eff16c4d30d36c6133 oracle-password file 2 minutes ago 2 minutes ago

This concludes the necessary preparations.

Let there be Containers

With all the setup completed the next step is to start an Oracle 21c XE instance and build the SQLcl container.

Oracle XE

Using the instructions by Gerald Venzl’s GitHub repository, adapted for this use case, a call to podman run might look like this:

[opc@podman ~]$ podman run --name oracle21xe --secret oracle-password \
-e ORACLE_PASSWORD_FILE=/run/secrets/oracle-password -d \
--net oranet -v oradata:/opt/oracle/oradata \
docker.io/gvenzl/oracle-xe:21-slim
5d94c0c3620f811bbe522273f73cbcb7c5210fecc0f88b0ecacc1f5474c0855a

The necessary flags are as follows:

  • --name assigns a name to the container so you can reference it later
  • --secret passes a named secret to the container, accessible in /run/secrets/oracle-password
  • -d tells the container to run in the background
  • --net defines the network the container should be attached to
  • -v maps the newly created volume to a directory in the container

You can check whether the container is up an running by executing podman ps:

[opc@podman ~]$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5d94c0c3620f docker.io/gvenzl/oracle-xe:21-slim 53 seconds ago Up 54 seconds ago oracle21xe

Creating a small SQLcl container:

Creating a container to run sqlcl is really quite straight forward. A suitable Dockerfile is shown here, please ensure you update the ZIPFILE with the current SQLcl release.

FROM docker.io/openjdk:11

RUN useradd --comment "sqlcl owner" --home-dir /home/sqlcl --uid 1000 --create-home --shell $(which bash) sqlcl

USER sqlcl
WORKDIR /home/sqlcl

ENV ZIPFILE=sqlcl-21.4.1.17.1458.zip

RUN curl -LO "https://download.oracle.com/otn_software/java/sqldeveloper/${ZIPFILE}" && \
/usr/local/openjdk-11/bin/jar -xf ${ZIPFILE} && \
rm ${ZIPFILE}

ENTRYPOINT ["bash", "/home/sqlcl/sqlcl/bin/sql", "/nolog"]

You could of course pull the latest sqlcl ZIP from https://download.oracle.com/otn_software/java/sqldeveloper/sqlcl-latest.zip. Using a named release should simplify the non-trivial task of naming (“tagging”) your container image.

The image can be build using podman much in the same way Docker images were built:

[opc@podman ~]$ podman build . -t tools/sqlcl:21.4.1.17.1458

As you can see from the ENTRYPOINT the image cannot be sent to the backround (-d) by podman, it needs to be run interactively as you will see in the next section.

Linking Containers

The last step is to start the sqlcl container and connect to the database.

podman run --rm -it --name sqlcl --net oranet localhost/tools/sqlcl:21.4.1.17.1458

Here is an example how this works in my container:

[opc@podman ~]$ podman run --rm -it --name sqlcl --net oranet localhost/tools/sqlcl:21.4.1.17.1458


SQLcl: Release 21.4 Production on Mon Mar 21 13:35:05 2022

Copyright (c) 1982, 2022, Oracle. All rights reserved.

SQL> connect system@oracle21xe/xepdb1
Password? (**********?) ***************
Connected.
SQL> show con_name
CON_NAME
------------------------------
XEPDB1

The connection string consists of a username (system) and the container name assigned as part of the call to podman run ... --name. Thanks to the dnsname extension and linking the container to the oranet network it is possible to address systems by name. XEPDB1 is the default name of the XE instance’s Pluggable Database.

Instead of connecting to a Pluggable Database it is of course possible to connect to the Container Database’s Root (CDB$ROOT).

Summary

Podman is very compatible to Docker, easing the transition. In this part of the mini-series you could read how to use Podman functionality with Oracle Linux 8 to link a container running Oracle XE and SQLcl.

Blog at WordPress.com.