docker swarm でコンテナ間通信が再起動後にできなくなる話

はじめに

ほとんどのサービスをdocker swarm で起動していますが、サーバー再起動時にwordpressが通信できなくなるエラーが出たり出なかったり。

ちょくちょくブログが止まるのはこのためです。

主な原因は、DNSキャッシュでした。

どういうことか

docker swarmではdocker composeのサービス設計図が使えますが、linkやdependonのような起動順序の保証はされません。

なので、sql php nginxの起動順が毎回バラバラになります。

なのでsql php nginxの起動順序なら問題ないのですが、

sql nginx php もしくはnginx sql phpのようにnginxがphpより先に起動すると、その時点では通信先のコンテナは起動できていないので、アドレス解決がホストIPになります。nginxにはDNSキャッシュがあるので、この間違ったIPに接続しようと試みまくるので、通信ができなくなります。

解決方法

docker コンテナのサービスは極力DNSキャッシュを使用しないようにしたほうが良さそうです。

こちらにnginxの解決方法があります。

server {
       ...
        # set DNS resolver as Docker internal DNS
        resolver 127.0.0.11 valid=10s;
        resolver_timeout 5s; 
       ...
       location / {
        # prevent dns caching and force nginx to make a dns lookup on each request.
        set $target http://web:8080;
        proxy_pass $target;
       ..
       }
}

これでなんとか解決しました。