graceful restart可能なHAProxyのDockerイメージ

ふつうに作れそうだったので作ってみた。 以下、関連ファイル。

  • Dockerfile
FROM ubuntu:latest
MAINTAINER Genki Sugawara <sgwr_dts@yahoo.co.jp>

RUN apt-get update
RUN apt-get install -y haproxy

ADD haproxy.cfg /

ADD supervisor.sh /
RUN chmod +x /supervisor.sh

CMD ["/supervisor.sh"]
  • supervisor.sh
#!/bin/bash
RELOAD=0

function set_reload() {
  RELOAD=1
}

trap set_reload USR1

haproxy -f /haproxy.cfg &

while true; do
  if [ $RELOAD -eq 1 ]; then
    haproxy -f /haproxy.cfg -sf `ps -o pid,command | awk '$2 == "haproxy" {print $1}'` &
    RELOAD=0
  fi

  sleep 1
done
  • haproxy.cfg
defaults
  timeout connect 5000ms
  timeout client 50000ms
  timeout server 50000ms

listen example
  mode http
  bind :80
  server example.com example.com:80

これをdocker build

$ docker build -t haproxy .
Sending build context to Docker daemon 4.096 kB
Step 1 : FROM ubuntu:latest
 ---> 3876b81b5a81
Step 2 : MAINTAINER Genki Sugawara <sgwr_dts@yahoo.co.jp>
 ---> Using cache
 ---> 249acbf0fe6a
Step 3 : RUN apt-get update
 ---> Using cache
 ---> f2e5cbbb164f
Step 4 : RUN apt-get install -y haproxy
 ---> Using cache
 ---> 3f518b918618
Step 5 : ADD haproxy.cfg /
 ---> Using cache
 ---> bf5df2e90b51
Step 6 : ADD supervisor.sh /
 ---> Using cache
 ---> 98ae226f35b8
Step 7 : RUN chmod +x /supervisor.sh
 ---> Using cache
 ---> 1ae6d30dca44
Step 8 : CMD /supervisor.sh
 ---> Using cache
 ---> eaae080bd487
Successfully built eaae080bd487

で、docker run

$ docker run -p 10080:80 --name haproxy haproxy
$ curl localhost:10080
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
        <head>
            <title>404 - Not Found</title>
        </head>
        <body>
            <h1>404 - Not Found</h1>
        </body>
</html>

docker execでUSR1を投げる。

$  docker exec haproxy kill -USR1 1

するとgraceful restartされる

[WARNING] 241/130328 (6) : Stopping proxy example in 0 ms.
[WARNING] 241/130328 (6) : Proxy example stopped (FE: 1 conns, BE: 1 conns).
$ curl localhost:10080
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
        <head>
            <title>404 - Not Found</title>
        </head>
        <body>
            <h1>404 - Not Found</h1>
        </body>
</html>

おけおけ。

他のシグナルのこととか、そのままではプロダクションには使えないけど、同じ戦略でいけそう。