Help us understand the problem. What is going on with this article?

dockerのコンテナを手軽に外部ネットワークへ公開する方法

More than 1 year has passed since last update.

はじめに

dockerのコンテナを外部ネットワークに公開する方法のメモ

dockerのコンテナは基本的にはプライベートネットワーク(デフォルトで172.17.0.0/16)上に構築されるようで、コンテナから外部へのネットワーク接続は仮想ブリッジ(docker0)経由で通信することができますが、逆に外部からコンテナへの接続は(デフォルトでは)できないようです。

色々ググってみてそれらしい記事を参考に試してみるもうまくいかず。
※仮想ブリッジをNICと接続する方法とか試したんですが、動きませんでした・・・。
理由は調べた気がしますが、忘れましたw
dockerがNATの設定をおかしくさせてたような?

なので、ここは純粋にNICへセカンダリIPアドレスを割り振り、firewalldでDNATする方法で解決します。
ちなみに、DNATは Destination Network Address Translation の略だそうです。

環境

環境 バージョン
OS CentOS Linux release 7.2.1511 (Core)
docker 1.12.5

環境構築

まずはサービス公開用のブリッジを作成します。
これは最初に設定しておけば、以降は行う必要はありません。
ここでは、ネットワーク 172.18.0.0/16 で、ブリッジのIPアドレスは 172.18.0.1、ブリッジ名をdocker1、docker上のネットワーク名をserverとしました。

# docker network create --driver bridge --subnet 172.18.0.0/16 --gateway 172.18.0.1 --opt "com.docker.network.bridge.name"="docker1" server

firewalldのzone設定を行います。
これも最初に設定するものです。
ここではdocker1をtrustedゾーンに配置します。
ポート開けの設定が面倒なのでtrustedで横着してますw

# firewall-cmd --zone=trusted --change-interface=docker1

次にNICにセカンダリIPアドレスを割り振ります。
ここから、公開するコンテナごとに必要な設定になります。
ここでは、enp0s3インターフェイスに192.168.0.15を追加しました。

# nmcli connection modify enp0s3 +ipv4.addresses "192.168.0.15/24"

次にDNATを設定します。
セカンダリIPアドレス 192.168.0.15 から、例えば 172.18.0.2 にアドレス変換する場合は下記となります。

# firewall-cmd --permanent --direct --add-rule ipv4 nat PREROUTING_direct 0 -d 192.168.0.15 -j DNAT --to 172.18.0.2
# firewall-cmd --reload

※間違って--directの設定をしてしまった場合、/etc/firewalld/direct.xmlに設定が永続化されているため、ここをいじれば修正できます。

コンテナを作成します。
ネットワークに server を指定、IPアドレスに先ほどの 172.18.0.2 を指定します。
ここでは、nginxサービスをインストールするCentOS7コンテナを作成&起動してみます。
その他のオプションはお好みで。

# docker run --restart always --cap-add=SYS_ADMIN -d --net server --ip 172.18.0.2 --name nginx centos:7 /sbin/init

コンテナが起動するのでbashコマンドで接続します。

# docker exec -it nginx /bin/bash

接続出来たらnginxをインストールします。

# rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
# yum -y install nginx
# systemctl enable nginx
# systemctl start nginx

外部ネットワークから http://192.168.0.15 が開けばOKです。

なお、nginxコンテナを再起動すると/var/log/nginxディレクトリが無くなっていてサービスの起動に失敗してしまいます。
対処方法ご存知の方、コメントください。

暫定対応

ひとまず、再起動がうまくいかないのは実用に耐えられないので、Data Volumeをマウントして強制的に/var/log/nginxを作っています。

# docker run --restart always --cap-add=SYS_ADMIN -d --net server --ip 172.18.0.2 --name nginx -v /var/log/nginx centos:7 /sbin/init
Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away