log.fstn

技術よりなことをざっくばらんにアウトプットします。

Docker, Inc.に買収されたSocketPlaneに関する雑多な話

f:id:foostan:20150330234522p:plain:left:w200 今月始めにDocker, Inc.がSocketPlane, Inc.を買収したと発表がありました(日本記事はこちら)。 SocketPlaneが出来た経緯などは、docker/dockerのIssue#8951 を見るとよさそうです(ここから買収の話に繋がったのかな?)。

SocketPlane は、Open vSwitchによってDockerコンテナのネットワークをマルチホストで接続するためのツールおよびデーモンです。 開発は2014年12月の初め頃から始まってるみたいです。

ちなみに、Dockerのホストが複数になることによってネットワーク周りが複雑になるのはよくある話で、解決方法は既に様々なものがあります。 そのあたりはDockerコンテナ接続パターン (2014年冬)にて詳しくまとめられています。

SocketPlaneには下記のような特徴があります(README.mdより抜粋)。

  • Open vSwitch integration
  • ZeroConf multi-host networking for Docker
  • Elastic growth of a Docker/SocketPlane cluster
  • Support for multiple networks
  • Distributed IP Address Management (IPAM)

既存の解決方法と比べて特筆すべき点としては

  • Open vSwitchにてネットワークを形成している
  • ネットワークおよびクラスタの形成を自動的に行う
  • 高可用性なIPAMを提供している

といったところでしょうか。

Open vSwitchにてネットワークを形成している

DockerのネットワークはNetwork Namespace(このあたりのスライドが詳しいです)を利用していて、仮想的な docker0 ブリッジを作って、その下にコンテナ用のネットワークを形成しています。

一方SocketPlaneでは、Open vSwitchにて仮想的な docker-ovs0 ブリッジを作っています。 Weaveflannelが、docker0 を被せるようにネットワークを形成しているのとは異なり、docker0 そのものを docker-ovs0 に置き換えています。

f:id:foostan:20150330234624p:plain (https://github.com/docker/docker/issues/8951/Figure - 2より転載)

またマルチホストの場合は各ホストの docker-ovs0 がOverlay Tunnelsにて接続されるようです。 f:id:foostan:20150330234755p:plain (https://github.com/docker/docker/issues/8951/Figure - 3より転載)

なおなぜOpen vSwitchなのかについては、Issue#8951のSolution Componentsの1. Programmable vSwitchにて述べられています。

ネットワークおよびクラスタの形成を自動的に行う

SocketPlaneではmulticast DNSを用いてZeroConf を実現しています。 multicast DNSとはその言葉どおりですが、名前解決のリクエストをマルチキャストで送って返答を受け取るというもので、同一セグメント内で起動しているSocketPlaneデーモンを探しだしてConsulのクラスタを形成します。 コードだとこのへん

socketplane/bonjourでmDNSが実装されていて、新しいメンバーが見つかるとJoinDatastoreでConsulクラスタに参加し、AddPeer でOpen vSwitchのネットワークに参加するようです。

高可用性なIPAMを提供している

これがどれだけ有益なことなのかはよくわからないのですが、SocketPlandeで扱っているIPはConsulのKVSに格納されていて自由に参照できるようになっています。 KVSのkeysは以下のようになっていました。

vagrant@socketplane-1:~$ curl -s http://localhost:8500/v1/kv/?keys | jq .
[
  "ipam/10.1.0.0/16",
  "network/default",
  "vlan/vlan"
]

実際に使ってみる

既に試してる方が居ましたので参考にさせて頂きました。 tkhrssk.hatenablog.com

Vagrantfileが用意されているので手っ取り早く試すにはこちらを使うのがよいです。 ただubuntu-14.10をベースにDockerやらSocketPlane用のDockerイメージやらを3台のVMにインストールしていくのでそれなりに時間かかります(手元環境で20分ぐらいかかりました)。

立ち上がったら

$ vagrant ssh socketplane-1

で中に入って、起動しているコンテナの様子を見てみます

vagrant@socketplane-1:~$  sudo docker ps
CONTAINER ID        IMAGE                            COMMAND                CREATED             STATUS              PORTS               NAMES
d9a5a04e708a        clusterhq/powerstrip:v0.0.1      "twistd -noy powerst   11 minutes ago      Up 11 minutes                           powerstrip
0d071143a86c        socketplane/socketplane:latest   "socketplane --iface   13 minutes ago      Up 13 minutes                           socketplane

Powerstrip modeでSocketPlaneが動いてるみたいです。

vagrant@socketplane-1:~$ sudo socketplane network list
[
    {
        "gateway": "10.1.0.1",
        "id": "default",
        "subnet": "10.1.0.0/16",
        "vlan": 1
    }
]
vagrant@socketplane-1:~$ consul members
Node           Address             Status  Type    Build  Protocol
socketplane-1  10.254.101.21:8301  alive   server  0.4.1  2
socketplane-2  10.254.101.22:8301  alive   client  0.4.1  2
socketplane-3  10.254.101.23:8301  alive   client  0.4.1  2

10.1.0.0/16のネットワークが形成されていて、Consulによるクラスタも組まれています。 コンテナの内部に入って様子を見てみます(socketplane run を利用します)。

vagrant@socketplane-1:~$ sudo socketplane run -it ubuntu /bin/bash
root@b103601ab2f5:/# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
18: ovsc34d394: <BROADCAST,UP,LOWER_UP> mtu 1440 qdisc noqueue state UNKNOWN group default
    link/ether 02:42:0a:01:00:02 brd ff:ff:ff:ff:ff:ff
    inet 10.1.0.2/16 scope global ovsc34d394
       valid_lft forever preferred_lft forever
    inet6 fe80::d4e7:3aff:fe1e:641e/64 scope link tentative dadfailed
       valid_lft forever preferred_lft forever

SocketPlaneのネットワークに接続されていることがわかります。 ネットワークを追加してみます。

vagrant@socketplane-1:~$ sudo socketplane network create web 10.2.0.0/16
{
    "gateway": "10.2.0.1",
    "id": "web",
    "subnet": "10.2.0.0/16",
    "vlan": 2
}
vagrant@socketplane-1:~$ sudo socketplane network list
[
    {
        "gateway": "10.1.0.1",
        "id": "default",
        "subnet": "10.1.0.0/16",
        "vlan": 1
    },
    {
        "gateway": "10.2.0.1",
        "id": "web",
        "subnet": "10.2.0.0/16",
        "vlan": 2
    }
]

socketplane run に -n オプションでネットワークIDを指定するとそのネットワークに接続されたコンテナが立ち上がります。

vagrant@socketplane-1:~$ sudo socketplane run -n web -it ubuntu /bin/bash
root@a31cc2a3266c:/# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
22: ovsd77f749: <BROADCAST,UP,LOWER_UP> mtu 1440 qdisc noqueue state UNKNOWN group default
    link/ether 02:42:0a:02:00:02 brd ff:ff:ff:ff:ff:ff
    inet 10.2.0.2/16 scope global ovsd77f749
       valid_lft forever preferred_lft forever
    inet6 fe80::4c10:cdff:fe48:e7a9/64 scope link tentative dadfailed
       valid_lft forever preferred_lft forever

所感

SocketPlaneがどのようなものでどのように使うか紹介しました。 Docker, Inc.に買収されたということで、SocketPlaneがそのまま使われるとは限りませんが、Open vSwitchを使ったリッチなネットワークがデフォルトで提供されるようになるでしょう。

個人的にはConsulの使い方が気になるところで、今のままだとKVSとしてしか使っていないのでcoreos/etcdの方がいいのではないかなと思います。 が、どちらにしてもますますCoreOSが望む方向とは別の方向に進んでいるようですね。