A docker image to run Keepalived
100K+
a docker container which runs keepalived.org
orginally based on the work of linkvt but simplified the approach for my own needs along the way.
This image require the kernel module ip_vs loaded on the host;
# modprobe ip_vs
and needs to be run with the NET_ADMIN linux capability using the host network mode;
$ docker run --cap-add=NET_ADMIN --cap-add=NET_BROADCAST --cap-add=NET_RAW --net=host --name keepalived --rm visibilityspots/keepalived:latest
Environment variables defaults are set in the Dockerfile and can be overriden;
ENV KEEPALIVED_INTERFACE eth0
ENV KEEPALIVED_STATE BACKUP
ENV KEEPALIVED_ROUTER_ID 21
ENV KEEPALIVED_PRIORITY 150
ENV KEEPALIVED_ADVERT_INT 1
ENV KEEPALIVED_VERSION 2
ENV KEEPALIVED_UNICAST_PEERS 192.168.0.11 - 192.168.0.12
ENV KEEPALIVED_VIRTUAL_IPS 192.168.0.10
ENV KEEPALIVED_VIRTUAL_ROUTES 192.168.0.0/24 dev eth0 scope link src 192.168.0.10
ENV KEEPALIVED_PASSWORD d0ck3r
ENV KEEPALIVED_NOTIFY notify "/usr/local/bin/keepalived-notify.sh"
ENV KEEPALIVED_CHECK_COMMAND
ENV KEEPALIVED_CHECK_INTERVAL 2
ENV KEEPALIVED_CHECK_TIMEOUT 2
ENV KEEPALIVED_CHECK_FALL 2
ENV KEEPALIVED_CHECK_RISE 2
ENV KEEPALIVED_USE_VMAC false
ENV KEEPALIVED_CONF /etc/keepalived/keepalived.conf
By default the virtual ip only follows the host: it moves when keepalived stops
answering, not when the service behind the address is broken. Setting
KEEPALIVED_CHECK_COMMAND renders a vrrp_script and a track_script that run
the command every KEEPALIVED_CHECK_INTERVAL seconds;
$ docker run --cap-add=NET_ADMIN --cap-add=NET_BROADCAST --cap-add=NET_RAW --net=host --env KEEPALIVED_CHECK_COMMAND="wget -q -O /dev/null http://127.0.0.1:8082/ping" --name keepalived --rm visibilityspots/keepalived:latest
The script runs with weight 0: after KEEPALIVED_CHECK_FALL failures the
instance goes to FAULT and releases the virtual ip to a peer, rather than
lowering its own priority. Leaving KEEPALIVED_CHECK_COMMAND empty renders
neither block, so nothing changes for an existing configuration.
KEEPALIVED_ADVERT_INT is the advertisement interval in seconds and accepts
fractions. It only matters when a host disappears without warning: a backup
waits roughly three intervals before it declares the master gone. A master that
fails its health check, or that is stopped cleanly, sends a priority 0 advert
and is taken over right away no matter what this is set to.
Values below one second need KEEPALIVED_VERSION=3: VRRPv2 only accepts whole
seconds and refuses the configuration otherwise. VRRPv3 in turn has no
authentication - the protocol dropped it - so the authentication block is left
out of the configuration when version 3 is selected. On a shared segment that
trade needs to be a deliberate one.
Without a virtual mac the virtual ip migrates between the real mac addresses of
the participating hosts, which mac aware equipment reports as an ip conflict
after every failover. KEEPALIVED_USE_VMAC=true gives the address its own
00:00:5e:00:01:<router_id> mac that travels with it, and adds vmac_xmit_base
so the vrrp adverts keep going out over the underlying interface - without that
the unicast adverts would be sourced from an interface that only carries the
virtual ip.
Environment variables can be set by adding the --env argument in the command line, for example:
$ docker run --cap-add=NET_ADMIN --cap-add=NET_BROADCAST --cap-add=NET_RAW --net=host --env KEEPALIVED_INTERFACE="eno1" --env KEEPALIVED_PASSWORD="password!" --env KEEPALIVED_PRIORITY="100" --name keepalived --rm visibilityspots/keepalived:latest
$ docker build -t visibilityspots/keepalived:latest .
$ docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
$ docker buildx build -t visibilityspots/keepalived:latest --platform linux/amd64,linux/arm/v6,linux/arm/v7 --push .
I wrote some tests in a goss.yaml file which can be executed by dgoss to test the created image
$ dgoss run visibilityspots/keepalived:2.2.8
INFO: Starting docker container
INFO: Container ID: 6e6ea44f
INFO: Sleeping for 0.2
INFO: Container health
INFO: Running Tests
File: /usr/local/bin/keepalived-notify.sh: exists: matches expectation: true
File: /etc/keepalived/keepalived.conf: exists: matches expectation: true
File: /etc/keepalived/keepalived.conf.tmpl: exists: matches expectation: true
Command: keepalived --version: exit-status: matches expectation: 0
Package: keepalived: installed: matches expectation: true
Package: keepalived: version: matches expectation: ["2.2.8-r0"]
Package: envsubst: gettext-envsubst: installed: matches expectation: true
Total Duration: 0.006s
Count: 7, Failed: 0, Skipped: 0
INFO: Deleting container
using act for local testing of the written github actions makes my life and commit history a lot easier;
Stage Job ID Job name Workflow name Workflow file Events
0 update update docker-hub-description docker-hub-description.yml push
0 main main CI main.yml push
0 scan scan trivy trivy.yml push,schedule
Distributed under the MIT license
Content type
Image
Digest
sha256:0567b009a…
Size
4.4 MB
Last updated
7 days ago
docker pull visibilityspots/keepalived