ikke_t.podman_container_systemd

podman-container-systemd

NOTE: This role may still work, but further development is happening in the new linux system roles podman project. It’s actively being improved. Thanks to all contributors over the years!

This role manages container(s) on your host using systemd. Podman handles container events but doesn’t manage their lifecycle. For clusters, Kubernetes does this, while systemd manages it for local setups.

I created this role to help manage the lifecycle of Podman containers on my personal server, which isn’t a cluster. I want systemd to keep them running even after reboots.

What This Role Does:

  • Installs Podman.
  • Downloads required images.
  • On reruns, it downloads the image again and restarts the container if the image has changed (currently not for pods).
  • Creates a systemd service file for the container or pod.
  • Creates a Kubernetes YAML file for the pod.
  • Sets up volume directories for containers if they don’t exist (for pods, uses DirectoryOrCreate).
  • Ensures the container or pod automatically restarts if it crashes.
  • Makes sure the container or pod runs at system boot.
  • Adds or removes exposed ports from the firewall.
  • Allows running rootless containers under a specific user.

For more information, refer to these two blogs about the role:

These blogs explain how to run a single container or multiple containers in a pod using this module.

Note for Running Rootless Containers:

  • The user must exist before you run this role.
  • The user should have entries in the /etc/sub[gu]id files for the namespace range. If not, this role will add some variables there, but it’s best to check them.
  • Some controls, like memory limits, won’t work as user.
  • Increase systemd_TimeoutStartSec as we cannot prefetch images before starting the systemd unit. Systemd needs to wait for Podman to pull images before starting the container, which may take time depending on your network and image size.

Requirements:

  • Requires a system that can run Podman, and Podman must be available in the package repositories. This role installs Podman. It also installs firewalld if you define container_firewall_ports. Installs kubeval for a pod if container_pod_yaml_template_validation: true.

Role Variables:

This role requires several variables upon inclusion. Note that some options only apply to single containers or pods.

  • container_image_list: List of images to run. If more than one, they run in a pod. Can include authentication info per image, like so:
    container_image_list:
      - image: docker.io/imagename
        user: exampleuser
        password: examplepw
      - image: docker.io/imagename2
    
  • container_image_user: Optional default username for authentication with remote registries.
  • container_image_password: Optional default password for authentication with remote registries.
  • container_name: Identifies the container in systemd and Podman commands. The systemd service file will be named container_name--container-pod.service. Can be overridden with service_name.
  • container_run_args: Additional arguments for Podman when running a single container. Not used for pods.
  • container_cmd_args: Any commands and arguments for podman run after specifying the image name. Not used for pods.
  • container_run_as_user: User under which systemd will run the container. Defaults to root.
  • container_run_as_group: Group under which systemd will run the container. Defaults to root.
  • container_dir_owner: Owner of the volume directories. Defaults to container_run_as_user.
  • container_dir_group: Group for the volume directories. Defaults to container_run_as_group.
  • container_dir_mode: Permissions for the volume directories. Defaults to '0755'.
  • container_state: The state of the container. Use running to install and run; absent stops and removes.
  • container_firewall_ports: List of exposed ports to open on the firewall. Closed if container_state is absent. If you don't want firewalld installed, don't use this.
  • systemd_TimeoutStartSec: Time systemd waits for the container to start.
  • systemd_tempdir: Where temporary files for containers are stored. Defaults to /tmp.
  • service_name: Naming convention for systemd service files.
  • service_files_dir: Directory for storing systemd service files.
  • service_files_owner: User that owns the systemd service files.
  • service_files_group: Group that owns the systemd service files.
  • service_files_mode: Permissions for the systemd service files.
  • container_pod_yaml: Path to the pod YAML file (required).
  • container_pod_yaml_deploy: Whether to deploy the pod YAML file (defaults to false).
  • container_pod_yaml_template: Template for the pod YAML deployment.
  • container_pod_yaml_template_validation: Whether to validate the pod YAML file (defaults to false).
  • container_pod_labels: Labels for the pod.
  • container_pod_volumes: Defines volumes for the pod.
  • container_pod_containers: Defines containers for the pod.

This playbook doesn't have a Python module to parse parameters for the Podman command. For now, pass the parameters like you would in the command line. See man podman or Podman tutorials for more info.

To automatically update your images, add this label to container_cmd_args: --label "io.containers.autoupdate=image".

Avoid using ansible.builtin.import_role for this role if you intend to use it multiple times in a playbook to prevent falling into this anti-pattern.

Dependencies:

Example Playbook:

Refer to tests/main.yml for a sample. In short, include the role with variables.

Root Container Example:

- name: tests container
  vars:
    container_image_list: 
      - sebp/lighttpd:latest
    container_name: lighttpd
    container_run_args: >-
      --rm
      -v /tmp/podman-container-systemd:/var/www/localhost/htdocs:Z,U
      --label "io.containers.autoupdate=image"
      -p 8080:80
    container_state: running
    container_firewall_ports:
      - 8080/tcp
      - 8443/tcp
  ansible.builtin.include_role:
    name: podman-container-systemd

Rootless Container Example:

- name: ensure user
  user:
    name: rootless_user
    comment: I run sample container

- name: tests container
  vars:
    container_run_as_user: rootless_user
    container_run_as_group: rootless_user
    container_image_list: 
      - sebp/lighttpd:latest
    container_name: lighttpd
    container_run_args: >-
      --rm
      -v /tmp/podman-container-systemd:/var/www/localhost/htdocs:Z,U
      -p 8080:80
    container_state: running
    container_firewall_ports:
      - 8080/tcp
      - 8443/tcp
  ansible.builtin.include_role:
    name: podman-container-systemd

Rootless Pod Example:

- name: ensure user
  user:
    name: rootless_user
    comment: I run sample container

- name: tests pod
  vars:
    container_run_as_user: rootless_user
    container_run_as_group: rootless_user
    container_image_list:
      - sebp/lighttpd:latest
    container_name: lighttpd-pod
    container_pod_yaml: /home/rootless_user/lighttpd-pod.yml
    container_pod_yaml_deploy: true
    container_pod_yaml_template_validation: true
    container_pod_labels:
      app: "{{ container_name }}"
      io.containers.autoupdate: 'image(1)'
    container_pod_volumes:
      - name: htdocs
        hostPath:
          path: /tmp/podman-container-systemd
          type: DirectoryOrCreate
    container_pod_containers:
      - name: lighttpd
        image: sebp/lighttpd:latest
        volumeMounts:
          - name: htdocs
            mountPath: /var/www/localhost/htdocs:Z
        ports:
          - containerPort: 80
            hostPort: 8080
    container_state: running
    container_firewall_ports:
      - 8080/tcp
      - 8443/tcp
  ansible.builtin.include_role:
    name: podman-container-systemd

License:

GPLv3

Author Information:

Ilkka Tengvall ilkka.tengvall@iki.fi

Informazioni sul progetto

Role sets up container(s) to run on host with help of systemd.

Installa
ansible-galaxy install ikke_t.podman_container_systemd
Licenza
Unknown
Download
13.1k
Proprietario
I nerd around the clock. At day time for Red Hat, at evenings for my hobby projects. Except when family duties interrupt :) All for open source.