【はじめに】
本学では3年生の学生実験で、仮想環境上でUbuntuを立ち上げてホストとルーターに見立てて経路制御やファイアウォールとはなんぞやというのを知るための実験をします。
昨年までは仮想環境にVirtualboxを使用していましたが、学生全員にUbuntuのイメージを共有するのにデータ量莫大になることや、インストールやセットアップ、起動に時間がかかるというデメリットがかなり浮き彫りになってしまいました。
そこで、今回は卒業研究のおまけとしてDockerを使ってこの実験環境を構築するという命を受けましたのでやってみました。
ちなみに僕はDockerはなんとなく使っているだけで特別Dockerに詳しいわけでもネットワークに詳しいわけでもありませんのでご容赦くださいね!
【開発環境】
今回開発に使った環境は以下の2つです。
どちらでも同様に動作することを確認しています。
Windows
- Windows10 Home Edition
- Docker version 20.10.14, build a224086
- Docker Compose version v2.4.1
macOS
- macOS Monterey version 12.3.1
- Docker version 20.10.12, build e91ed57
- Docker Compose version version 1.29.2, build 5becea4c
【完成形】
はじめに完成形をわかりやすくしておきましょう。
作成するサービス
サービス名 | IPアドレス |
---|---|
host4 | 192.168.9.2 |
host5 | 192.168.8.2 |
router1 | 192.168.9.254, 192.168.1.254 |
router2 | 192.168.1.253, 192.168.8.254 |
作成するネットワーク
ネットワーク名 | IPアドレス範囲 |
---|---|
route1 | 192.168.1.0/24 |
route8 | 192.168.8.0/24 |
route9 | 192.168.9.0/24 |
これらのネットワーク上にhostとrouterを立ち上げて経路制御の実験をします。
【ホストとルーターに使用するDockerfileについて】
今回ホストとルーターにはUbuntu20.04の公式Docker imageをもとにしたDocker imageを作成します。
具体的に変更点は、Docker公式のUbuntu20.04にはネットワーク系のコマンド(pingやroute等)が入っていません。
そのため、Dockerfileを自作してビルド時にそれらのコマンドをインストールさせます。
完成したDockerfileは以下のとおりです。
FROM ubuntu:20.04
RUN apt-get update -y && apt-get upgrade -y
RUN apt-get install -y iputils-ping net-tools netcat traceroute ufw systemctl
【Docker-compose.ymlでネットワークとコンテナの設定をする】
Docker-compose.ymlで先程の完成図にあったようなネットワークとすでに作ってあるDockerfileからビルドするように定義していきます。
全文は下記のとおりです。
version: '3'
networks:
route1_network:
ipam:
driver: default
config:
- subnet: 192.168.1.0/24
route8_network:
ipam:
driver: default
config:
- subnet: 192.168.8.0/24
route9_network:
ipam:
driver: default
config:
- subnet: 192.168.9.0/24
services:
host4:
build:
context: .
dockerfile: ./host/dockerfile
command: tail -f /dev/null
privileged: true
networks:
route9_network:
ipv4_address: 192.168.9.2
host5:
build:
context: .
dockerfile: ./host/dockerfile
command: tail -f /dev/null
privileged: true
networks:
route8_network:
ipv4_address: 192.168.8.2
router1:
build:
context: .
dockerfile: ./host/dockerfile
command: tail -f /dev/null
privileged: true
networks:
route1_network:
ipv4_address: 192.168.1.254
route9_network:
ipv4_address: 192.168.9.254
router2:
build:
context: .
dockerfile: ./host/dockerfile
command: tail -f /dev/null
privileged: true
networks:
route1_network:
ipv4_address: 192.168.1.253
route8_network:
ipv4_address: 192.168.8.254
ネットワークの作成
まずはネットワークを作成します。
networks:
route1_network:
ipam:
driver: default
config:
- subnet: 192.168.1.0/24
networksの下に、作成したいネットワークの名前をつけておきます。今回であればroute1_networkです。
重要なのはsubnetの部分ですね。
こちらで設定したいIPアドレスとその範囲を指定しておきます。
続いてがこの設定したネットワークをサービスに割り当てていく作業になります。
サービスの作成とネットワークの割り当て
router1:
build:
context: .
dockerfile: ./host/dockerfile
command: tail -f /dev/null
privileged: true
networks:
route1_network:
ipv4_address: 192.168.1.254
route9_network:
ipv4_address: 192.168.9.254
はじめにbuildの部分でcontextとdockerfileの位置を指定してあげます。
このcontextの設定によってそのコンテナのルート位置が決まってアクセスできる場所が決まってきますので、開発するサービスによって適宜変更してください。
参考にできそうなページはこちら
そしてcommandを指定しているのもポイントです。
Dockerのコンテナは実行するものがなくなれば自動的に落ちますので、このコマンドでコンテナを立ち上げっぱなしにします。
さぁ本題のnetworkの部分をごらんください。
networks:
route1_network:
ipv4_address: 192.168.1.254
route9_network:
ipv4_address: 192.168.9.254
見ただけで何が書いてあるかわかりますね、先程作成したネットワークを割り当てて、このコンテナに割り当てるIPアドレスを書く。
それだけです。
【まとめ】
なんとも簡単でした。
この後はdocker-compose upして、ルーターやホストのルーティングテーブルを作ってあげれば完璧ですね。
今後はルーティングテーブルを手動で設定するのではなく、動的経路制御ができればいいなと思っております。
やったことのメモにどんどん記事書いていきますのでまたどこかで。