松屋アドベントカレンダー 15日目

この記事は、松屋 Advent Calendar 2015 15日目の記事です。

@kuro_m88 です。
4月から社会人デビューをして、シブヤーで一人前のエンジニアになるために修行しています。

シブヤーはIT系企業が多く、道玄坂界隈には特に密集しているという噂も。
忙しい時や、集中し過ぎた時、気づけばお昼を食べる時間が少ない!みたいな事もあるかもしれない。
そんな時のあなたの食卓が松屋渋谷道玄坂上店である。忙しくなくても行くけど。

ということで、松屋で特に普通に昼食をとるとどれくらいの時間がかかるのか気になったので調べてみました。
特に急いだりとかせず、いつもどおりな感じで。

f:id:kuro_m88:20151215193959p:plain

数字は各フェーズごとに掛かった時間です。

00:00 入店

自動ドアの目の前に食券機がある。

00:27 食券機に並ぶ

前に1人食券を買っている人が居た。
食券機は2台あるけど、Suicaで決済できるのは1台しかないので並ぶ。 オートチャージ最強。

00:15 食券を買う

この日はプレミアム牛丼のミニとサラダでした。
メニューが決まってて、操作に慣れてたら15秒くらいで食券が買える。

00:10 着席

回転率が良いので、今まで着席まで待たされた事はない。
着席と同時に食券を店員さんに受け取ってもらう。
忘れずに「ねぎだく、つゆ抜きでお願いします」と言う。

01:47 待ち

店員さんがキビキビ動いているのを眺めつつ、すごいなーと関心していたらあっという間だった。

09:25 昼食

スマホいじりながら食べている人もそこそこいるけれど、自分は器用じゃないので食べるのに集中する。
なんとなく仕事の事を考えてる事が多いかも。
プレミアム牛丼のねぎだくつゆ抜きにカルビソースを少しだけかけて食べるのが最強。

00:15 退店

ごちそうさまでした。

合計: 12:19

思ったより早かった。20分あれば行って食べて帰ってこれそう。

以上、松屋渋谷道玄坂上店での日常でした。

busybusyboxというDocker imageを作った

busybusybox

簡単な負荷試験や、CPUの使用率制限の実験とかするのに、CPUを使いまくってくれるコンテナが欲しいなと思って作ってみました。

中では、opensslのベンチマークを無限ループさせてるだけです。

github.com

名前ですが、 busybox だと紛らわしいし、 busybox に失礼かなと思い、busybusybox にしてみました(笑)

使い方

Dockerhubに上げたので、

$ docker run -it kurochan/busybusybox

とするだけで、CPUを全部使い切ろうとしてくれるはず。

そういえば

stressコマンドの方が良かったかな…

Dockerでダイナミックルーティング!

前回、Dockerでルータが動くようにできたので、今度はルータを使ってダイナミックルーティングをしようと思います。

kurochan-note.hatenablog.jp

使うもの

  • ubuntu 15.04
  • vyOSのコンテナ
  • open vSwitch

作るネットワーク

以下の図のようなルータ3台のシンプルなネットワーク構成にしました。

RouterAとRouterB、RouterBとRouterCは直接接続されていて、RouterAとRouterCは直接接続されていないので、RouterBにルーティングをしてもらわないと通信ができません。 OSPFで経路情報を交換して、RouterAとRouterC間の疎通が取れるようにする事をゴールにしてみようと思います。 f:id:kuro_m88:20151011095239p:plain

それぞれのRouterがコンテナで動いていて、コンテナ間の接続にopen vSwitchを使います。 イメージとしてはこんな感じです。 f:id:kuro_m88:20151011095316p:plain

環境構築

Ubuntu15.04とdockerとopen vSwitchがあればOKです。

$ sudo aptitude install docker.io openvswitch-common openvswitch-switch
$ sudo service docker start

ovs-docker

dockerのインターフェイスを簡単にopen vSwitchに接続ためのシェルスクリプトです。 今回インストールしたopenvswitch-commonには入っていなかったので、Githubリポジトリからダウンロードしてきます。

ovs/ovs-docker at master · openvswitch/ovs · GitHub

$ wget https://raw.githubusercontent.com/openvswitch/ovs/master/utilities/ovs-docker
$ chmod +x ovs-docker

ネットワークを作る

ルータを作る

ルータを3台用意します。

Ubuntuカーネルモジュールを使用するため、特権コンテナにして、 /lib/modulesをマウントしてあげます。 NICは後で追加するので、 --net=none で起動します。

$ sudo docker run -d --name RouterA --net=none --privileged -v /lib/modules:/lib/modules kurochan/vyos:1.1.6 /sbin/init
$ sudo docker run -d --name RouterB --net=none --privileged -v /lib/modules:/lib/modules kurochan/vyos:1.1.6 /sbin/init
$ sudo docker run -d --name RouterC --net=none --privileged -v /lib/modules:/lib/modules kurochan/vyos:1.1.6 /sbin/init

スイッチを作る

vSwitchを1つ作ります。

$ sudo ovs-vsctl add-br vswitch0

スイッチとルータを接続する

ovs-docker を使ってコンテナのNICの作成、IPアドレスサブネットマスクの設定、スイッチへの接続をします。

RouterBだけNICを2つ作成します。

$ sudo ./ovs-docker add-port vswitch0 eth0 RouterA --ipaddress=192.168.100.1/24
$ sudo ./ovs-docker add-port vswitch0 eth0 RouterB --ipaddress=192.168.100.2/24
$ sudo ./ovs-docker add-port vswitch0 eth1 RouterB --ipaddress=192.168.200.2/24
$ sudo ./ovs-docker add-port vswitch0 eth0 RouterC --ipaddress=192.168.200.1/24

ポートVLANを設定する

ルータの全ポートが同じスイッチに繋がっている状態なので、VLANを使ってネットワークを分割します。ポートとVLANの対応は以下の表のようになります。

Router port vlan
RouterA eth0 100
RouterB eth0 100
RouterB eth1 200
RouterC eth0 200
$ sudo ./ovs-docker set-vlan vswitch0 eth0 RouterA 100
$ sudo ./ovs-docker set-vlan vswitch0 eth0 RouterB 100
$ sudo ./ovs-docker set-vlan vswitch0 eth1 RouterB 200
$ sudo ./ovs-docker set-vlan vswitch0 eth0 RouterC 200

ここまでの確認

ここまでの疎通確認をしてみます。

まだルーティングの設定をしていないので、状態は以下の表のようになるはずです。

Router Router ping
RouterA RouterB
RouterB RouterC
RouterA RouterC

RouterAからRouterB

$ sudo docker exec -it RouterA ping -c 1 192.168.100.2
PING 192.168.100.2 (192.168.100.2) 56(84) bytes of data.
64 bytes from 192.168.100.2: icmp_req=1 ttl=64 time=0.309 ms

--- 192.168.100.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.309/0.309/0.309/0.000 ms

RouterBからRouterC

$ sudo docker exec -it RouterB ping -c 1 192.168.200.1
PING 192.168.200.1 (192.168.200.1) 56(84) bytes of data.
64 bytes from 192.168.200.1: icmp_req=1 ttl=64 time=0.998 ms

--- 192.168.200.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.998/0.998/0.998/0.000 ms

RouterAからRouterC

$ sudo docker exec -it RouterA ping -c 1 192.168.200.1
connect: Network is unreachable

ルータの設定をする

各ルータにOSPFの設定をして、経路情報を交換してルーティングできるようにします。

RouterA

$ sudo docker exec -it RouterA /bin/vbash
vbash-4.1# su - vyos
vyos@vyos:~$ configure
vyos@vyos# set interfaces loopback lo address 1.1.1.1/32
vyos@vyos# set protocols ospf area 0 network 192.168.0.0/16
vyos@vyos# set protocols ospf parameters router-id 1.1.1.1
vyos@vyos# commit
vyos@vyos# exit
vyos@vyos:~$ exit
vbash-4.1# exit

RouterB

$ sudo docker exec -it RouterB /bin/vbash
vbash-4.1# su - vyos
vyos@vyos:~$ configure
vyos@vyos# set interfaces loopback lo address 2.2.2.2/32
vyos@vyos# set protocols ospf area 0 network 192.168.0.0/16
vyos@vyos# set protocols ospf parameters router-id 2.2.2.2
vyos@vyos# commit
vyos@vyos# exit
vyos@vyos:~$ exit
vbash-4.1# exit

RouterC

$ sudo docker exec -it RouterC /bin/vbash
vbash-4.1# su - vyos
vyos@vyos:~$ configure
vyos@vyos# set interfaces loopback lo address 3.3.3.3/32
vyos@vyos# set protocols ospf area 0 network 192.168.0.0/16
vyos@vyos# set protocols ospf parameters router-id 3.3.3.3
vyos@vyos# commit
vyos@vyos# exit
vyos@vyos:~$ exit
vbash-4.1# exit

再び確認

再び疎通確認をしてみます。

OSPFできちんと経路交換をしてルーティングされていれば、状態は以下の表のようになるはずです。

Router Router ping
RouterA RouterB
RouterB RouterC
RouterA RouterC

RouterAからRouterB

$ sudo docker exec -it RouterA ping -c 1 192.168.100.2
PING 192.168.100.2 (192.168.100.2) 56(84) bytes of data.
64 bytes from 192.168.100.2: icmp_req=1 ttl=64 time=0.215 ms

--- 192.168.100.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.215/0.215/0.215/0.000 ms

RouterBからRouterC

$ sudo docker exec -it RouterB ping -c 1 192.168.200.1
PING 192.168.200.1 (192.168.200.1) 56(84) bytes of data.
64 bytes from 192.168.200.1: icmp_req=1 ttl=64 time=0.238 ms

--- 192.168.200.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.238/0.238/0.238/0.000 ms

RouterAからRouterC

$ sudo docker exec -it RouterA ping -c 1 192.168.200.1
PING 192.168.200.1 (192.168.200.1) 56(84) bytes of data.
64 bytes from 192.168.200.1: icmp_req=1 ttl=63 time=0.280 ms

--- 192.168.200.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.280/0.280/0.280/0.000 ms

RouterAからRouterCの通信ができるようになりましたね!

せっかくなのでルーティングテーブルも確認

RouterAのルーティングテーブルを確認してみます。

$ sudo docker exec -it RouterA /bin/vbash
vbash-4.1# su - vyos
vyos@vyos:~$ show ip route
WARNING: terminal is not fully functional
Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF,
       I - ISIS, B - BGP, > - selected route, * - FIB route

C>* 1.1.1.1/32 is directly connected, lo
C>* 127.0.0.0/8 is directly connected, lo
O   192.168.100.0/24 [110/10] is directly connected, eth0, 00:10:38
C>* 192.168.100.0/24 is directly connected, eth0
O>* 192.168.200.0/24 [110/20] via 192.168.100.2, eth0, 00:05:33

さいごに

ルータをコンテナで動かして、実際にルーティングするところまでやってみました。

コンテナで動いているため、ノートPC1台あればルータを10台くらい立てたりできると思うので、ネットワークの勉強をするための環境にはよいかもしれません。

今更ですが、ポートVLANを使わなくてもvSwitchをもう一つ作った方が分かりやすかった気がしてきました(笑)

Dockerでルータをコンテナ化してみた

最近Dockerを触る機会がちょくちょくあって、ルータをコンテナ化したら面白いことできそうだし、便利かもしれないと思ってやってみました。 思い返すと、初めてDockerを触ったのは2013年の12月で、こんな記事を書いたこともあったっぽい。懐かしい。

kurochan-note.hatenablog.jp

vyOSをコンテナ化する!

コンテナ化するルータOS(ネットワークOS)はvyOSです。 そもそもベースイメージが提供されていないOSってどうやってコンテナ化するんだろう?とか調べてたら、すでにやられている方がいました。

VyOS の Docker イメージを作ってみる - higeblog

大まかな流れとしては、

  • docker をインストール
  • overlayroot をインストール
  • ISO をダウンロード
  • ISO をマウント
  • ISO の中身から root パーティションを構築
  • イメージビルド用ディレクトリにコピー
  • イメージビルド用ディレクトリを圧縮
  • Dockerfile を作成
  • docker build

という感じでやればコンテナのベースイメージが作れるようです。コンテナ自身はLinuxカーネルを持つ必要はありませんので、アンインストールしてイメージサイズを減らしたりもしています。

新しいバージョンが使いたかったので、自分でビルドしてみました。 イメージを作るのに使ったスクリプトです。公開されているスクリプトをforkして、ちょこっと変更しました。

mkimage_vyos.sh · GitHub

ビルドしたイメージ

Ubuntu15.04上でやりました。あとは、パッケージ docker.iooverlayroot をインストールしたくらいです。 ビルドしたイメージは、DockerHubで公開しています。

https://hub.docker.com/r/kurochan/vyos/

Repository Description書かないと使い方がわからないですね。。。

起動方法

vyOSはカーネルモジュールが必要なので、通常の起動方法だと、うまく動きません。 特権コンテナとして動かすのと、ホスト側の/lib/modulesをコンテナ内の/lib/modulesにマウントしてあげます。 vyOSはDebian系なので、Ubuntu15.04の上で動かしました。

初回のみdocker imageのpullが必要です。

$ docker pull kurochan/vyos:latest

コンテナを起動するには、

$ docker run -d --privileged -v /lib/modules:/lib/modules kurochan/vyos:latest

と打ちます。

動作確認

container idの取得

container idを取得します。

$ docker ps
CONTAINER ID        IMAGE                  COMMAND             CREATED             STATUS              PORTS               NAMES
de8b263b5332        kurochan/vyos:latest   "/sbin/init"        3 seconds ago       Up 2 seconds                            ecstatic_bhabha

シェルの起動

vbashを起動します。

$ docker exec -it de8b263b5332 /bin/vbash
vbash-4.1#

vyOSユーザでコマンドを実行する必要があるので、シェルを起動した後、 su - vyos でユーザを切り替える必要があります。 あとは、普通のvyOSと同じように使えるはずです!

vbash-4.1# su - vyos
vyos@vyos:~$ configure
[edit]
vyos@vyos# show
WARNING: terminal is not fully functional
 interfaces {URN)
     ethernet eth0 {
         address dhcp
     }
     loopback lo {
     }
 }
 system {
     config-management {
         commit-revisions 20
     }
     console {
         device ttyS0 {
             speed 9600
         }
     }
......

その他

コンテナでvyOSを動かす事ができましたが、カーネルはvyOSのものではなく、Ubuntuのものなので、もしかしたらうまく動かない機能があるかもしれません。今のところうまく動いてくれていますが。 これを使って簡単なネットワークを作ってみたりもしましたので、そのことも別の記事で書いてみようと思います!