summaryrefslogtreecommitdiff
path: root/docs/sources/articles/cfengine_process_management.md
blob: ee5ba238a0c25006937267a77739b91b12802613 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
page_title: Process Management with CFEngine
page_description: Managing containerized processes with CFEngine
page_keywords: cfengine, process, management, usage, docker, documentation

# Process Management with CFEngine

Create Docker containers with managed processes.

Docker monitors one process in each running container and the container
lives or dies with that process. By introducing CFEngine inside Docker
containers, we can alleviate a few of the issues that may arise:

 - It is possible to easily start multiple processes within a
   container, all of which will be managed automatically, with the
   normal `docker run` command.
 - If a managed process dies or crashes, CFEngine will start it again
   within 1 minute.
 - The container itself will live as long as the CFEngine scheduling
   daemon (cf-execd) lives. With CFEngine, we are able to decouple the
   life of the container from the uptime of the service it provides.

## How it works

CFEngine, together with the cfe-docker integration policies, are
installed as part of the Dockerfile. This builds CFEngine into our
Docker image.

The Dockerfile's `ENTRYPOINT` takes an arbitrary
amount of commands (with any desired arguments) as parameters. When we
run the Docker container these parameters get written to CFEngine
policies and CFEngine takes over to ensure that the desired processes
are running in the container.

CFEngine scans the process table for the `basename` of the commands given
to the `ENTRYPOINT` and runs the command to start the process if the `basename`
is not found. For example, if we start the container with
`docker run "/path/to/my/application parameters"`, CFEngine will look for a
process named `application` and run the command. If an entry for `application`
is not found in the process table at any point in time, CFEngine will execute
`/path/to/my/application parameters` to start the application once again. The
check on the process table happens every minute.

Note that it is therefore important that the command to start your
application leaves a process with the basename of the command. This can
be made more flexible by making some minor adjustments to the CFEngine
policies, if desired.

## Usage

This example assumes you have Docker installed and working. We will
install and manage `apache2` and `sshd`
in a single container.

There are three steps:

1. Install CFEngine into the container.
2. Copy the CFEngine Docker process management policy into the
   containerized CFEngine installation.
3. Start your application processes as part of the `docker run` command.

### Building the image

The first two steps can be done as part of a Dockerfile, as follows.

    FROM ubuntu
    MAINTAINER Eystein Måløy Stenberg <eytein.stenberg@gmail.com>

    RUN apt-get -y install wget lsb-release unzip ca-certificates

    # install latest CFEngine
    RUN wget -qO- http://cfengine.com/pub/gpg.key | apt-key add -
    RUN echo "deb http://cfengine.com/pub/apt $(lsb_release -cs) main" > /etc/apt/sources.list.d/cfengine-community.list
    RUN apt-get update
    RUN apt-get install cfengine-community

    # install cfe-docker process management policy
    RUN wget https://github.com/estenberg/cfe-docker/archive/master.zip -P /tmp/ && unzip /tmp/master.zip -d /tmp/
    RUN cp /tmp/cfe-docker-master/cfengine/bin/* /var/cfengine/bin/
    RUN cp /tmp/cfe-docker-master/cfengine/inputs/* /var/cfengine/inputs/
    RUN rm -rf /tmp/cfe-docker-master /tmp/master.zip

    # apache2 and openssh are just for testing purposes, install your own apps here
    RUN apt-get -y install openssh-server apache2
    RUN mkdir -p /var/run/sshd
    RUN echo "root:password" | chpasswd  # need a password for ssh

    ENTRYPOINT ["/var/cfengine/bin/docker_processes_run.sh"]

By saving this file as Dockerfile to a working directory, you can then build
your image with the docker build command, e.g.
`docker build -t managed_image`.

### Testing the container

Start the container with `apache2` and `sshd` running and managed, forwarding
a port to our SSH instance:

    $ docker run -p 127.0.0.1:222:22 -d managed_image "/usr/sbin/sshd" "/etc/init.d/apache2 start"

We now clearly see one of the benefits of the cfe-docker integration: it
allows to start several processes as part of a normal `docker run` command.

We can now log in to our new container and see that both `apache2` and `sshd`
are running. We have set the root password to "password" in the Dockerfile
above and can use that to log in with ssh:

    ssh -p222 root@127.0.0.1

    ps -ef
    UID        PID  PPID  C STIME TTY          TIME CMD
    root         1     0  0 07:48 ?        00:00:00 /bin/bash /var/cfengine/bin/docker_processes_run.sh /usr/sbin/sshd /etc/init.d/apache2 start
    root        18     1  0 07:48 ?        00:00:00 /var/cfengine/bin/cf-execd -F
    root        20     1  0 07:48 ?        00:00:00 /usr/sbin/sshd
    root        32     1  0 07:48 ?        00:00:00 /usr/sbin/apache2 -k start
    www-data    34    32  0 07:48 ?        00:00:00 /usr/sbin/apache2 -k start
    www-data    35    32  0 07:48 ?        00:00:00 /usr/sbin/apache2 -k start
    www-data    36    32  0 07:48 ?        00:00:00 /usr/sbin/apache2 -k start
    root        93    20  0 07:48 ?        00:00:00 sshd: root@pts/0
    root       105    93  0 07:48 pts/0    00:00:00 -bash
    root       112   105  0 07:49 pts/0    00:00:00 ps -ef

If we stop apache2, it will be started again within a minute by
CFEngine.

    service apache2 status
     Apache2 is running (pid 32).
    service apache2 stop
             * Stopping web server apache2 ... waiting    [ OK ]
    service apache2 status
     Apache2 is NOT running.
    # ... wait up to 1 minute...
    service apache2 status
     Apache2 is running (pid 173).

## Adapting to your applications

To make sure your applications get managed in the same manner, there are
just two things you need to adjust from the above example:

 - In the Dockerfile used above, install your applications instead of
   `apache2` and `sshd`.
 - When you start the container with `docker run`,
   specify the command line arguments to your applications rather than
   `apache2` and `sshd`.