Rahul Bajaj

Blog

linux, ruby, containers, kubernetes, javascript, reactjs, redux

Managing Containers with Systemd

To reduce the need for manual intervention, use systemd to manage container-based applications on a health check.

Rahul Bajaj

3-Minute Read

Systemd

Containers are inherently ephemeral, making them more difficult to manage than traditional programmes operating on virtual or bare metal servers. Container monitoring, on the other hand, is a critical capability for applications based on current microservices architectures in order to achieve maximum performance.

Containerized applications frequently necessitate monitoring. Performing health-checks is one technique to keep these containers up and running at all times. The usage of the curl command to verify if the application within the container is still up and running is one of the approaches I’ve come across for doing health-checks. The cronjob utility is used to perform curl commands on the container application at a periodic basis. If the container is not in a running state, a configuration management tool like Ansible can be used to start/restart it. Although this method does not need direct human intervention, it does not seem to have a mechanism for logging the event i.e. reason for downtime of the application/container. Therefore, it is not the best option for enhancing the container’s self-healing capabilities.

Instead, we make use of the systemd utility of Linux which is ubiquitous across most of the Linux distributions. The systemd utility makes it easy to dynamically start/restart/stop configuration files for each deamon.

In this blog, we will:

  1. Create an Ansible role.
  2. Define the required variables.
  3. Create the service file usign a Jinja2 template
  4. Manage unit files within the containers using a playbook

With the aid of systemd, we’ll start an apache container and control its daemon. The Jinja2 templates are used to construct the unit file. We save the template files in the /usr/lib/systemd/system/ directory after they’ve been created. We can then use thesystemd ansible module to administer the deamon once the files have been stored in the correct location with the required permissions.

Create an Ansible role

cd roles
mkdir -p apache/{defaults,tasks,templates,handlers}

Define the required variables

---
apache_image: "httpd"
apache_image_tag: "latest"

Create the service file usign a Jinja2 template

[Unit]
Description=run apache container
After=network.target docker.service
Requires=docker.service

[Service]
ExecStartPre=-/usr/bin/docker stop apache
ExecStartPre=-/usr/bin/docker rm apache
ExecStartPre=/usr/bin/docker pull {{ apache_image }}:{{ apache_image_tag }}
ExecStart=/usr/bin/docker run \
  --port='8080:8080' \
  --name=apache \
  --volume={{ apache_data_dir }}:{{ apache_data_container_dir }}:ro \
  --restart=always \
  --log-driver=journald \
  {{ apache_image }}:{{ apache_image_tag }}
Restart=always

[Install]
WantedBy=multi-user.target

Manage unit files within the containers using a playbook

/roles/apache/handlers/main.yml

---
- name: restart container-apache
  systemd:
    name: container-apache.service
    daemon_reload: yes
    state: restarted
/roles/apache/tasks/main.yml

---
- name: set selinux boolean value
  seboolean:
    name: container_manage_cgroup
    state: yes
    persistent: yes

- name: create the apache container unit file
  template:
    src: container-apache.service.j2
    dest: /usr/lib/systemd/system/container-apache.service
    owner: root
    mode: 0660
  notify: restart container-apache

- name: link and enable container-apacahe
  systemd:
    name: container-apache
    enabled: yes

- name: run apache container
  systemd:
    name: container-apache
    state: started
comments powered by Disqus

Recent Posts

Category

About

I am a Software Engineer at Red Hat, working as a fullstack developer for the Foreman Project.