もぐてっく

人は1つ歳を取る度、1ビットづつ大きくなれると信じてた。

docker-compose.yml毎に別のIPアドレスを付与する

やりたいこと

  • 1つのホストに複数のdocker-compose stackを立ち上げたい
  • docker-compose stackごとに別のIPアドレスを割り当てたい

例えば、ポート番号を変更できないサービス(sambaとか)のスタックを複数立ち上げたいときとか。

やり方

IPエイリアスの作成

docker-compose stackにアサインするIPアドレスエイリアス定義します。

Ubuntu20.04の場合は/etc/netplan/00-installer-config.yamlを編集します。

# This is the network config written by 'subiquity'
network:
  ethernets:
    eno1:
      addresses:
      - 192.168.0.163/24  
      - 192.168.0.222/24 ←追加
      gateway4: 192.168.0.1
      nameservers:
        addresses:
        - 192.168.0.1
  version: 2

docker-compose.ymlにネットワーク設定を追加

version: '2'
  
services:
        samba:
                image: dperson/samba
                ports:
                        - 139:139
                        - 445:445
                networks: ←以下追加
                        - test-net

networks: ←以下追加
        test-net:
                driver: bridge
                driver_opts:
                        com.docker.network.bridge.host_binding_ipv4: 192.168.0.222

解説

dockerの"bridge"ドライバは、デフォルトで以下の様なiptablesルールを生成します。

「どこか」 から
「ホストが持つIPアドレスいずれか」 の 
「docker-compose.ymlのportsに定義したポート番号」 宛てのパケットは

「docker-compose.ymlに定義したdockerコンテナ」 に転送する。

com.docker.network.bridge.host_binding_ipv4を指定することで、以下の様なルールを生成するようになります。

「どこか」 から
「com.docker.network.bridge.host_binding_ipv4で指定したIPアドレス」 の 
「docker-compose.ymlのportsに定義したポート番号」 宛てのパケットは

「docker-compose.ymlに定義したコンテナ」 に転送する。

ちなみにdockerの"host"ドライバは、そもそもネットワーク周りの名前空間を分離せずホストと名前空間を共有する感じで動作するみたいです。 各リソースの名前空間を個別に分離できるLinuxならではの方式ですね。