Posted at

仮想化以前に構築した自宅インフラをDockerとOpen vSwtichで何とかする話

More than 1 year has passed since last update.


要求

Dockerを用いて、常用するインフラをいざという時にすぐ再展開できるようにしたい。

しかも、既存のインフラとの運用を考えると、L2で地続きになっていてほしい。


導入前提条件

DockerとOpenvSwitchが動くこと。特にovs-dockerコマンドが動けば良い。


何故Docker+OpenvSwitchを使うのか

SoftEtherVPNやDHCP等に代表される、L2の疎通ができたほうが望ましいサービス群を一発展開するのに最適だった。

Ipvlanや、Macvlanも悪くはないが、特にSoftEtherVPNを利用する場合は、

コンテナ内へL2のプロミスキャスポートを設定する必要があり、要件を満たさない。

また、今後開発環境として個人的に利用するとしても、L2疎通が取れたほうが、

ネットワーク系のスクリプトを書いたときに、遥かに検証が容易となる。


  • SoftEtherVPN


    • ローカルブリッジに必要

    • 利用しない場合、やけに接続性が高いだけとなりあまり旨味がない



  • DHCP


    • DHCP Relay Agentによる中継も可能

    • Docker内にそのような仕組みを置くのは可能な限り回避したい




何故シェルスクリプトで展開するのか

OpenvSwitchのDockerプラグインのIssueが一年前から放置されている等、メンテナンスが行き届いておらず、動作が怪しかったりしたため、docker-composeの利用を断念した。そもそも、このプラグインを利用したしても、docker-composeの文法的にL2の挙動を記述する内容が見当たらないので、シェルスクリプトで展開する決意をした。

また、今度はOpenStackNeutronをDockerで利用する方法もあるが、オーケストレーションは不要なので機能過剰と判断、利用しないことにした。

成果物と最低限の説明だけ欲しい人は、Github:fono09/infra_portaleをご利用ください。


構成

コンテナは、既存のインフラから見ても、L2で完全に独立したホストに見えるように展開する。

OpenvSwtichと物理スイッチへの接続はL2でブリッジされている。

Untitled Diagram.png


基本的な作り方


ネットワーク周り


  1. 既存の物理ネットワークへの出口にプロミスキャスポートを用意する

  2. Open vSwtichで仮想ブリッジを作る

  3. 仮想ブリッジとプロミスキャスポートを繋げて既存のネットワークとL2疎通を取る

以上をまとめて

ip link set $IFACE promisc on

ovs-vsctl add-br $VSWITCH_NAME
ovs-vsctl add-port $VSWITCH_NAME $IFACE


各々のサービスに関して


  1. Dockerコンテナを立てる


    • Dockerの標準ネットワーク不使用

    • 勿論、設定ファイルやオプションで一発動作するように



  2. Open vSwtichの仮想ブリッジと接続

以上をまとめて

docker run -d --name $CT_NAME --net=none -v foo:bar alice/great-service

ovs-docker add-port $VSWTICH_NAME $CT_IF0 $CT_NAME --ipaddress=$CT_ADDR --gateway=$CT_GATEWAY


撤収時はただ逆の操作をします


  1. DockerのコンテナをOpen vSwtichの仮想ブリッジから外す

  2. コンテナを消す

  3. 仮想ブリッジの撤収

以上をまとめて

ovs-docker del-port $VSWTICH_NAME $CT_IF0 $CT_NAME

docker rm -f $CT_NAME
ovs-vsctl del-br $VSWTICH_NAME


詰まりやすいところ


ホスト再起動への耐性


  • OpenvSwitch


    • 独自にデータベースを持っており再起動に耐える



  • ovs-docker


    • 動作中のdockerを名前で引いた後PIDで追跡する為、再起動でPIDが変更され仮想I/Fが孤立するとCTIDで再追跡する仕組みがない



  • docker


    • CTIDは固定されている



以上のように、ovs-dockerに再起動耐性がないので、systemdのUnitファイルを作成し、登録。

システム終了時にきれいに撤収するようしている。


SoftEtherVPN

L2疎通をコンテナへ取れるようにすること。出来ていない場合、接続したクライアントは、

SoftEtherVPNのSecureNATにぶら下がってしまい、ルーティングが厄介に。

そもそも、既存のインフラとL2の疎通を取るという要求を満たせない。今回は、2つの仮想I/Fを利用した。

vim


Samba

id (username)コマンドで利用ユーザーのUIDを把握して、設定に流し込むこと。

これを設定しないと、ユーザーは自分のファイルにアクセスできない。


DHCP

コンテナを立ち上げた後、仮想I/Fを後付するので、ネットワークの立ち上がりを全く待たないイメージを引いて動作不良に悩まされた。

ネットワークが上がってくるのが間に合わない場合もある。

今回使用したイメージに含まれているシェルスクリプト、chakphanu/docker-kea:master/src/starter.shにあるように、

ネットワークの立ち上がりを待つ動作はなんだかんだで重要なので、イメージ作成時に考慮すべきだとは思った。