0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Dockerネットワークを理解したい

Last updated at Posted at 2022-08-07

はじめに

コンテナ間をネットワークで繋ぐことができる。という知識くらいしかなかったが、それだと運用でハマるので勉強しようと思った。必要と思ったところだけ記録していきます。

事前知識

仮想ブリッジ

Dockerをインストールした時点で、docker0という名前の仮想ブリッジが生成される。
ブリッジなのでOSI参照モデルのデータリンク層(L2)で動作する。ブリッジの説明は割愛。

仮想NIC

コンテナに対して仮想NICが割り当てられる。

ネットワーク分離

各コンテナは名前空間で分離されている。
なので、ネットワークを繋いでやらないと、コンテナ間で通信ができない。

よく使うネットワーク種別

  • bridge: 同一ネットワーク内でしか通信できない
  • overlay: Swarmモードを有効化するなどしたばネットワークまたぎで通信可能(IPアドレス重複に注意!)

内部DNS

Dockerには内部DNSが動いており、コンテナ名での名前解決をすることができる。
同じネットワークであれば、コンテナ名で通信が可能。

基本的なコマンド

ネットワーク一覧を表示

# docker network ls

ネットワーク詳細を表示

# docker network inspect <ネットワーク名>

ネットワーク作成

bridgeネットワークとして作成されます。
docker-composeで書く場合はコマンドでcreateしなくてもよいです。

# docker network create <ネットワーク名>

ネットワーク削除

不要なネットワークを個別に削除

# docker network rm <ネットワーク名>

利用していないネットワークをまとめて削除

# docker network prune

仮想インターフェースのIPアドレスを確認

# ip a

内部ネットワーク一覧を確認

# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
cbfda3037a97   bridge    bridge    local
e1b9462ba7c6   host      host      local
10b4e5654b78   none      null      local

ネットワークの種類はDRIVERに記されている。
この3つは、初期で作られるネットワークになります。

  • bridge : docker-composeでネットワークを指定せずに構築すると、このネットワークが割り当てられる。このデフォルトネットワークでは、コンテナ間の名前解決ができない。名前解決させたい場合は、ユーザー定義したbridgeネットワークを作成する必要がある。
  • host : ホストと同じネットワークインターフェースを使用する。ホストのポートと、コンテナのポートが一緒になるので、-pオプションを指定しなくても良くなる。(docker-composeの場合、port設定が不要)
  • none : ネットワークを有しない。ループバックインターフェースのみ有する。

docker-compose.ymlへの記述

myappディレクトリに、docker-compose.ymlを保存した状態でコンテナを立てます。

/myapp
  └ docker-compose.yml

ネットワークに何も記載しない場合

version: "3.8"
services:
  web:
    image: nginx:latest
    container_name: nginx_container
    hostname: web_server
    ports:
      - 80:80
    restart: always
    environment:
      TZ: Asia/Tokyo

myapp_defaultという、フォルダ名に_defaultという名前のついたネットワークが作成されました。

defaultネットワークを作成しない方法

トップレベルのnetworksを以下のように記述。
以下の場合、デフォルトで作成されているbridgeという名前のネットワークに所属させることができます。

version: "3.8"
services:
  web:
    image: nginx:latest
    container_name: nginx_container
    hostname: web_server
    ports:
      - 80:80
    restart: always
    environment:
      TZ: Asia/Tokyo
networks:
  default:
    name: bridge

名前付きネットワークを作成

my_networkという名前のついたネットワークを作成します。
トップレベルのnetworksでネットワークを作成しています。
subnetを宣言しない場合、docker内で空いているセグメントが自動的に付与されます。
servicesの中のコンテナ内に宣言されているnetworksでは、どのネットワークに属するかを記載しています。
ここで、ネットワーク内のどのIPアドレスを割り当てるかを記載できます。

version: "3.8"
services:
  web:
    image: nginx:latest
    container_name: nginx_container
    hostname: web_server
    ports:
      - 80:80
    restart: always
    environment:
      TZ: Asia/Tokyo
    networks:
      my_network:
        ipv4_address: 172.20.0.2
networks:
  default:
    name: bridge
  my_network:
    name: my_network
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.20.0.0/24

既存のネットワークを割り当てたい場合

ネットワークの設定内にexternal: trueを付けます。

networks:
  default:
    name: bridge
  my_network:
    name: my_network
    driver: bridge
    external: true
    ipam:
      driver: default
      config:
        - subnet: 172.20.0.0/24

注意したいこと

Dockerネットワーク内のIPアドレスと、ホストが接続できる外部サーバーのIPアドレスが重複している場合、Dockerネットワーク内のIPアドレスが優先されてしまいます。
社内ネットワークで利用する場合は、アドレス重複には注意しましょう。

また、ここで割り当てているIPアドレス(172.20.0.2)は、あくまでdocker内で使われるIPアドレスなので、Nginx(Webサーバ)にアクセスする場合はホストサーバーに割り当てられたIPアドレスからアクセスしましょう。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?