そんな今日この頃の技術ネタ

本家側に書くほどでもない小ネタ用

突然Dockerコンテナ内からネットワークに繋がらなくなったらiptablesを疑ってみよう

ちょっと前まで問題なく使えていたはずのイメージが、 ある日起動してみたらどうもネットワークに接続できない。

イメージは当然作成時と同じものだし、Dockerまわりの設定は変えてない、 ネットワークも別に阻害するような設定はしてないはずなのに・・・

結論からいえば、 ホスト側のiptablesを別件でも再起動するとDockerのデーモン起動時に設定した項目がリセットされてしまうことが原因だった。

僕は前職でこの件でかなりの時間を無駄にした経験があったのですぐに気づけたけど、 案外こういう話って記事で見かけなくて「これからDockerはじめてみよう」勢に把握されてなさそうなのでメモ的に書いてみた。


Vagrantでテスト環境を作る

実際に試してみる。

環境はCentOS7のfirewalldを無効化してiptablesを入れたもの。

(米国なんかの潮流をみるとUbuntuの方が勢いありそうだけど、 日本だとCentOSの方が安心感あるのか、こういう感じで使ってるとこ多いよね)

ということで以下のようなVagrantfileを用意。

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure(2) do |config|
  config.vm.box = "CentOS7"
  config.vm.box_url = "https://github.com/holms/vagrant-centos7-box/releases/download/7.1.1503.001/CentOS-7.1.1503-x86_64-netboot.box"

  config.vm.provision "shell", inline: <<-SHELL
    # firewalldを停止・無効化してiptablesを入れる
    sudo systemctl stop firewalld.service
    sudo systemctl mask firewalld.service
    sudo yum update
    sudo yum install -y iptables-services
    sudo systemctl start iptables.service
    sudo systemctl enable iptables.service

    # Dockerを入れる
    sudo yum install -y \
      https://yum.dockerproject.org/repo/main/centos/7/Packages/docker-engine-selinux-1.13.0-1.el7.centos.noarch.rpm \
      https://yum.dockerproject.org/repo/main/centos/7/Packages/docker-engine-1.13.0-1.el7.centos.x86_64.rpm
    sudo systemctl start docker.service
    sudo systemctl enable docker.service

    # vagrantユーザをdockerグループに入れておく
    sudo gpasswd -a vagrant docker
  SHELL
end

vagrant up && vagrant sshで入って早速実演。


起動時

起動直後。

[vagrant@localhost ~]$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
ACCEPT     icmp --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     tcp  --  anywhere             anywhere             state NEW tcp dpt:ssh
REJECT     all  --  anywhere             anywhere             reject-with icmp-host-prohibited

Chain FORWARD (policy DROP)
target     prot opt source               destination         
DOCKER-ISOLATION  all  --  anywhere             anywhere            
DOCKER     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
REJECT     all  --  anywhere             anywhere             reject-with icmp-host-prohibited

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain DOCKER (1 references)
target     prot opt source               destination         

Chain DOCKER-ISOLATION (1 references)
target     prot opt source               destination         
RETURN     all  --  anywhere             anywhere

(別になんでも良いけれど)CentOS7の公式イメージを起動してcurlを試す。

[vagrant@localhost ~]$ docker run --rm -it centos:7 bash
[root@ef782eedde62 /]# curl google.com
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>302 Moved</TITLE></HEAD><BODY>
<H1>302 Moved</H1>
The document has moved
<A HREF="http://www.google.co.jp/?gfe_rd=cr&amp;ei=B_mNWL34AuT98wfajq-ADA">here</A>.
</BODY></HTML>

うん、普通につながっていそう


iptablesだけ再起動

さて、本題のiptablesを再起動した後。

[vagrant@localhost ~]$ sudo systemctl restart iptables
[vagrant@localhost ~]$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
ACCEPT     icmp --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     tcp  --  anywhere             anywhere             state NEW tcp dpt:ssh
REJECT     all  --  anywhere             anywhere             reject-with icmp-host-prohibited

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         
REJECT     all  --  anywhere             anywhere             reject-with icmp-host-prohibited

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination  

一目瞭然、DOCKER系の設定がごっそり抜け落ちている。

この状態でさっきと同じことをしようとすると・・・

[vagrant@localhost ~]$ docker run --rm -it centos:7 bash
[root@52e27b38c207 /]#  curl google.com
curl: (6) Could not resolve host: google.com; Unknown error

こんな具合に繋がらなくなるのだ。


Docker再起動

じゃあ回復させるにはどうすればよいか?

Dockerプロセスを再起動すれば良い。

[vagrant@localhost ~]$ sudo systemctl restart docker
[vagrant@localhost ~]$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
ACCEPT     icmp --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     tcp  --  anywhere             anywhere             state NEW tcp dpt:ssh
REJECT     all  --  anywhere             anywhere             reject-with icmp-host-prohibited

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         
DOCKER-ISOLATION  all  --  anywhere             anywhere            
DOCKER     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
REJECT     all  --  anywhere             anywhere             reject-with icmp-host-prohibited

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain DOCKER (1 references)
target     prot opt source               destination         

Chain DOCKER-ISOLATION (1 references)
target     prot opt source               destination         
RETURN     all  --  anywhere             anywhere            


そんなわけで、何かしらの設定を追加してiptablesを再起動したときには、Dockerも再起動することをお忘れなく。

Docker

Docker

  • 作者: Adrian Mouat,Sky株式会社玉川竜司
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2016/08/17
  • メディア: 単行本(ソフトカバー)
  • この商品を含むブログを見る