diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..ba10274 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,4 @@ +# Changelog + +## 0.1.0 + - Initial release diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e6b8112 --- /dev/null +++ b/Makefile @@ -0,0 +1,20 @@ +NAME = osixia/keepalived +VERSION = 0.1.0 + +.PHONY: all build test tag_latest release + +all: build + +build: + docker build -t $(NAME):$(VERSION) --rm image + +test: + env NAME=$(NAME) VERSION=$(VERSION) bats test/test.bats + +tag_latest: + docker tag -f $(NAME):$(VERSION) $(NAME):latest + +release: build test tag_latest + @if ! docker images $(NAME) | awk '{ print $$2 }' | grep -q -F $(VERSION); then echo "$(NAME) version $(VERSION) is not yet built. Please run 'make build'"; false; fi + docker push $(NAME) + @echo "*** Don't forget to run 'twgit release/hotfix finish' :)" diff --git a/image/Dockerfile b/image/Dockerfile new file mode 100644 index 0000000..07f9a1e --- /dev/null +++ b/image/Dockerfile @@ -0,0 +1,27 @@ +FROM osixia/baseimage:0.10.4 +MAINTAINER Bertrand Gouny + +# This container need run options : +# --privileged=true +# --net=host + +# Use baseimage-docker's init system. +CMD ["/sbin/my_init"] + +# Install Keepalived +RUN apt-get -y update \ + && LC_ALL=C DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + keepalived + +# Add Keepalived assets +ADD service/keepalived/assets /osixia/keepalived + +# Run clean all +RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +# Add default env variables +ADD env.yml /etc/env.yml + +# Add Keepalived container start config & daemon +ADD service/keepalived/container-start.sh /etc/my_init.d/keepalived +ADD service/keepalived/daemon.sh /etc/service/keepalived/run diff --git a/image/env.yml b/image/env.yml new file mode 100644 index 0000000..c0cafad --- /dev/null +++ b/image/env.yml @@ -0,0 +1,14 @@ +KEEPALIVED_PASSWORD: d0cker + +# for electing MASTER, highest priority wins. +# to be MASTER, make 50 more than other machines +KEEPALIVED_PRIORITY: 150 + +KEEPALIVED_UNICAST_PEER: + - 172.17.8.101 + - 172.17.8.102 + - 172.17.8.103 + +KEEPALIVED_VIRTUAL_IPS: + - 192.168.200.17/24 dev eth1 + - 192.168.200.18/24 dev eth2 label eth2:1 diff --git a/image/service/keepalived/assets/README.md b/image/service/keepalived/assets/README.md new file mode 100644 index 0000000..a4695d4 --- /dev/null +++ b/image/service/keepalived/assets/README.md @@ -0,0 +1 @@ +Add your custom keepalived.conf file here or mount one at docker run to /etc/keepalived/keepalived.conf diff --git a/image/service/keepalived/assets/keepalived.conf b/image/service/keepalived/assets/keepalived.conf new file mode 100644 index 0000000..65d53dd --- /dev/null +++ b/image/service/keepalived/assets/keepalived.conf @@ -0,0 +1,19 @@ +vrrp_instance VI_1 { + interface eno1 + state MASTER + virtual_router_id 51 + priority {{ keepalived_priority }} + + unicast_peer { + {{ peer_ip }} + } + + virtual_ipaddress { + {{ floating_ip }} + } + + authentication { + auth_type PASS + auth_pass {{ keepalived_password }} + } +} diff --git a/image/service/keepalived/container-start.sh b/image/service/keepalived/container-start.sh new file mode 100755 index 0000000..8a1c1c5 --- /dev/null +++ b/image/service/keepalived/container-start.sh @@ -0,0 +1,22 @@ +#!/bin/bash -e + +FIRST_START_DONE="/etc/docker-keepalived-first-start-done" + +# container first start +if [ ! -e "$FIRST_START_DONE" ]; then + + # config folder is empty use bootstrap config if available + if [ ! -e /etc/keepalived/keepalived.conf ]; then + echo "No keepalived.conf provided using image default one" + if [ ! -e /osixia/keepalived/keepalived.conf ]; then + echo "Error: No default keepalived.conf found in /osixia/keepalived/keepalived.conf" + exit 1 + else + ln -s /osixia/keepalived/keepalived.conf /etc/keepalived/keepalived.conf + fi + fi + + touch $FIRST_START_DONE +fi + +exit 0 diff --git a/image/service/keepalived/daemon.sh b/image/service/keepalived/daemon.sh new file mode 100755 index 0000000..f4166ff --- /dev/null +++ b/image/service/keepalived/daemon.sh @@ -0,0 +1,2 @@ +#!/bin/bash -e +exec /usr/sbin/keepalived -f /etc/keepalived/keepalived.conf --dont-fork --log-console diff --git a/test/test.bats b/test/test.bats new file mode 100644 index 0000000..fb7fc13 --- /dev/null +++ b/test/test.bats @@ -0,0 +1,9 @@ +#!/usr/bin/env bats +load test_helper + +@test "image build" { + + run build_image + [ "$status" -eq 0 ] + +} diff --git a/test/test_helper.bash b/test/test_helper.bash new file mode 100644 index 0000000..31bdd43 --- /dev/null +++ b/test/test_helper.bash @@ -0,0 +1,101 @@ +setup() { + IMAGE_NAME="$NAME:$VERSION" +} + +# function relative to the current container / image +build_image() { + #disable outputs + docker build -t $IMAGE_NAME $BATS_TEST_DIRNAME/../image &> /dev/null +} + +run_image() { + CONTAINER_ID=$(docker run $@ -d $IMAGE_NAME) + CONTAINER_IP=$(get_container_ip_by_cid $CONTAINER_ID) +} + +start_container() { + start_containers_by_cid $CONTAINER_ID +} + +stop_container() { + stop_containers_by_cid $CONTAINER_ID +} + +remove_container() { + remove_containers_by_cid $CONTAINER_ID +} + +clear_container() { + stop_containers_by_cid $CONTAINER_ID + remove_containers_by_cid $CONTAINER_ID +} + +is_service_running() { + is_service_running_by_cid $CONTAINER_ID $1 +} + +wait_service() { + wait_service_by_cid $CONTAINER_ID $@ +} + + +# generic functions +get_container_ip_by_cid() { + local IP=$(docker inspect -f "{{ .NetworkSettings.IPAddress }}" $1) + echo "$IP" +} + +start_containers_by_cid() { + for cid in "$@" + do + #disable outputs + docker start $cid &> /dev/null + done +} + +stop_containers_by_cid() { + for cid in "$@" + do + #disable outputs + docker stop $cid &> /dev/null + done +} + +remove_containers_by_cid() { + for cid in "$@" + do + #disable outputs + docker rm $cid &> /dev/null + done +} + +clear_containers_by_cid() { + stop_containers_by_cid $@ + remove_containers_by_cid $@ +} + +is_service_running_by_cid() { + docker exec $1 ps cax | grep $2 > /dev/null +} + +wait_service_by_cid() { + + cid=$1 + + # first wait image init end + while ! is_service_running_by_cid $cid syslog-ng + do + sleep 1 + done + + for service in "${@:2}" + do + # wait service + while ! is_service_running_by_cid $cid $service + do + sleep 1 + done + done + + sleep 5 +} \ No newline at end of file