物理のトランクリンクをOpenvSwitchで受けて各Dockerコンテナに渡す

ご無沙汰しております(3年ぶり)
仕事?
もちろんしてますよ。あと山登りしてます。

それはそうと、仕事でネットワーク関連の検証をやっていて、ただのPing箱がたくさん欲しくなったとき、こんな感じの構成を作りたかった。

今までただPing返してくれれば良かったので、
この絵で言うコンテナ部分をnetns(Linux Network Namespace)でやっていた。
もちろんnetnsはネットワークの隔離であって、ファイルシステムやプロセス空間までは分けてくれない。
なので、すでにホストOS上でApacheだったりsshdだったりが動いていると、起動スクリプトをいじくったりしないといけない。
ここがコンテナになると、一度にネットワークもファイルシステムもプロセス空間も分離できる。
さらにDockerならDockerfile少し書いたり、出来合いのイメージ拾ってくるだけでサーバとかも一瞬で建てられる。
というわけでやってみよう。

Ubuntu16.04でやっていきます。
openvswitchとdockerはaptで導入済み前提でいきます。

まずはNICの確認。
今回は4portのNICがついたサーバを使います。
流石に物理NICのMACアドレスは隠させてください、許してください何でもしますから(なんでもするとは言ってない)

続いてOpenvSwitchのブリッジを作成。

そして、物理NICの一つをOpenvSwitchにブリッジさせます。

続いてdockerのコンテナを立てます。
今回はPingくらいしかやらないので軽量なAlpine Linuxを使用します。

ネットワーク周りを確認。
デフォルトではホストOS側で見えるvethがdocker0につながっていて、docker0のセグメントから適当なアドレスがついているはずです。

今回はdocker0は使用しないので、vethをdocker0からひっぺがします。

そしてひっぺがしたvethを先程作ったOpenvSwitchのブリッジにくっつけます。
今回はOpenvSwitchでVLAN振り分けるので、VLAN31のタグがついたトラフィックだけを通すようにタグ指定します。
タグ付きでコンテナに渡したければ、タグ指定せずに書けばいるかも?(未検証)

最後に、コンテナ内のNICのアドレスを変更して完了です。

お疲れ様でした。
非常に簡単にできて便利ですね。

最初からopenvswitchにadd-portもできると思うんですが、まだやってないです。
Qiitaでそれっぽい記事を見つけましたが、
LXCドライバを使用すると、起動時のオプションとovsにport-addするスクリプトを少し書けばいけそうです。
Dockerコンテナを直接OpenvSwitchに接続するには(lxcドライバ使用) – Qiita

こんな感じの構成を一度作ると、Ping確認のために端末たくさん用意したり、少ない端末でケーブル頻繁に繋ぎ変えたりが必要なくなります。
適当な多ポートサーバ一台(USB NICとかでも良い)とL2SWを用意して、
あとはL2SWにケーブルプスプス挿してVLAN切ってコンテナ立てていくだけでいくらでもホスト増やせるので便利です。
しかも、Dockerなので公式イメージ拾ってくるだけでサーバー用途のホストだって一瞬で立ちます。

以下、雑記です。
dockerのネットワークは、ホストOSに見えるvethとコンテナ内のeth*がip linkの関係にあり、これを介して通信をします。
ホストOS側のvethから入った通信はコンテナ内のethに飛んでいくイメージです。仮想LANケーブルと言ったほうが良いでしょうか。
どのvethとethがペアになっているのか関係を調べるのは以下の方法が便利そうです。
Relationship between interface

コンテナ内のethのiflinkと、ホストOSのvethのifindexが同一の値になっているとのことです。

なので、単純にホスト側はifindexで引っ張ることができそうです。
ifindexで引っ張る場合、if_indextoname()が利用できそうです。

コンパイル&実行

できた。

この辺上手く使うと、ワンラインで試験用ホスト立てたりが簡単にできそうですね(やるとはいってない)

Comments

コメントを残す

Your email address will not be published / Required fields are marked *