Bundle Walk-Through


This is a walk-through for demonstrating Pacemaker's "bundle" feature, which manages multiple instances of a container image, along with the networking and storage that the container needs.


  • Configure a test cluster of at least two cluster nodes with Pacemaker 1.1.17 or later. This walk-through assumes Pacemaker 2.0.1 or later has been compiled and installed on the cluster nodes.
  • The test cluster must be connected to a network with three sequential, unused IP addresses available for the test. For this walk-through, we'll use through, on the eth0 interface. If you use different values, replace them accordingly in the commands below.
  • Each node should have at least 450MB free disk space.


Repeat on every node:

  • Install the desired container management software; Pacemaker supports podman (since 2.0.1), docker (since 1.1.17), and rkt (since 1.1.18).
  • Create a place to store logs from the container instances:
# mkdir -p /var/log/pacemaker/bundles/httpd-bundle-{0,1,2}
  • For this walk-through, we'll use a web server container, so we need to create a sample web page for our container to serve. For a real web server, this would be identical on all nodes (often via shared storage), but here we will create a slightly different page for each host, so we can tell which container instance and underlying host are being used when we visit the web page:
# mkdir -p /var/local/containers/httpd-bundle-{0,1,2}
# for i in 0 1 2; do cat >/var/local/containers/httpd-bundle-$i/index.html <<EOF
<head><title>Bundle test</title></head>
<h1>httpd-bundle-$i @ $(hostname)</h1>
  • We'll use Apache httpd as our web server. To enable monitoring of the web server inside the container, we need a configuration snippet to enable its server-status URL:
cat <<-END >/var/local/containers/status.conf
 <Location /server-status>
    SetHandler server-status
    Require local
  • Obtain or create the desired container image. The image must contain Pacemaker 1.1.12 or later (for Pacemaker Remote support), but 1.1.17 or later is highly recommended. Of course, it should also contain whatever service you wish to provide. For this walk-through, we'll assume a web server image named pcmktest:httpd is available, containing the server-status configuration snippet from the previous step. Examples for creating the image using docker and podman are given in the appendix below.

Configure the cluster

  • Start the cluster on all nodes.
  • From any one node, configure a bundle using the test image. Here, we will show the raw XML used by Pacemaker; see the documentation for your favorite higher-level tool for a more user-friendly interface. This example uses a <podman> tag, which you should replace with <docker> or <rkt> (possibly with slightly different options) according to your choice of container software. Our example needs the run-command option only because we are running Pacemaker 1.1 inside the container:
# cibadmin --modify --allow-create --scope resources -X '<bundle id="httpd-bundle">
  <podman image="localhost/pcmktest:http" replicas="3" run-command="/usr/sbin/pacemaker_remoted" />
  <network ip-range-start="" host-interface="eth0" host-netmask="24">
    <port-mapping id="httpd-port" port="80"/>
    <storage-mapping id="httpd-root"
    <storage-mapping id="httpd-logs"
  <primitive class="ocf" id="httpd" provider="heartbeat" type="apache">
    <instance_attributes id="httpd-attrs">
      <nvpair id="httpd-attrs-statusurl" name="statusurl" value="http://localhost/server-status"/>
      <op id="httpd-monitor" name="monitor" interval="30s"/>
  • Test away. Three containers should come up, and the Web page we created should be reachable at the specified IPs. You can also modify the bundle configuration to try different values. The container instances will be named like httpd-bundle-podman-0, so you can use standard podman commands with that (e.g. podman inspect or podman exec).

Appendix: Container Setup


On each node:

  • Install buildah and podman.
  • Pull a base image for the container OS (CentOS 7 is used here as an example, but any distribution with a recent Pacemaker will work):
# podman pull docker://centos:centos7
  • Build the container image:
CNAME=working-pcmktest-http # pick any name you want for the working container
buildah rm "$CNAME"         # remove any previous working container by the same name
CONTAINER=$(buildah from --name "$CNAME" centos:centos7)
buildah run $CONTAINER -- yum update -y
buildah run $CONTAINER -- yum install -y bind-utils curl httpd lsof wget which pacemaker pacemaker-remote resource-agents
buildah add $CONTAINER /var/local/containers/status.conf /etc/httpd/conf.d/status.conf
buildah commit --format docker $CONTAINER pcmktest:http
  • If desired, you can verify that the image was created:
# buildah containers

The output should look something like:

f9e04462b4e9     *     1e1148e4cc2c docker.io/library/centos:centos7 working-pcmktest-http


On each node:

  • Enable the docker daemon to run at boot. For example, if systemd is used:
# systemctl enable --now docker
  • Pull a base image for the container OS (CentOS 7 is used here as an example, but any distribution with a recent Pacemaker will work):
# docker pull centos:centos7
  • Create a Dockerfile:
# cat >/var/local/containers/Dockerfile <<EOF
FROM centos:centos7
COPY status.conf /etc/httpd/conf.d/status.conf
RUN yum update -y
RUN yum install -y httpd bind-utils curl lsof wget which pacemaker pacemaker-remote resource-agents
  • Build the container image. Doing this once is sufficient, but you should repeat this step if you make changes to the Dockerfile.
# cd /var/local/containers
# docker rmi pcmktest:http # remove any previous image by the same name
# docker build -t pcmktest:http .
  • If desired, you can verify that the image was created:
# docker images

The output should look something like:

REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
pcmktest            http                aab04ad64ab0        About a minute ago   412 MB
centos              centos7             98d35105a391        12 days ago          192 MB
  • You may encounter a docker "waiting for lo to become free" bug. Reboot the node to avoid this possibility.