自宅サーバ/Kubernetesを支える柔軟なネットワークを目指せ

こんにちは、20のごっちです。この記事はUEC 2 Advent Calendar 2022の14日目の記事です。
みなさん自宅鯖は飼っていますか?私は飼っています。今回は自宅鯖用の便利ツールを開発してるので紹介します。

背景

自宅鯖を初めてやった人はまず最初に家のルータの設定を弄り、DMZや静的NATなどよくわからん設定を弄り、DDNSの設定をし、サーバにグローバルIPを割り当てていると思います。プロバイダごとの差異のアレコレやグローバルIPがかわったり面倒ですよね。
ところでサーバが2台以上になったり実家と下宿に別々にサーバ置いて連携させたいとき、IPアドレスやネットワークの管理がめちゃ面倒になりますよね。実家と下宿の間でVPNを張ってルーティングやればええやんという声もあると思いますが、それをやるには業務用のルータが必要です。実家に置いてあるルータなんてメンテしてられませんね。そんな皆様に。。。

提案

meshover を開発しています。これをセットアップするだけで10.1.2.3のようなアドレスがパソコンにランダムに割り当てられ、オーバーレイネットワークに参加します。他のサーバにも同じようにインストールすればそのIPアドレスを使ってパソコン同士で通信できます。パソコンを置いてる場所やルータの設定なんて関係ありません。
この機能だけ見てるとtailscaleでいいじゃん!ってなると思います。違いとしてはmeshoverはtailscaleと違い自宅サーバのクラスタに特化していてパソコンがBGPを喋ります。そのためパソコンだけでなく、そのパソコンの上で動いているVMやコンテナも1つのネットワークに接続することができます。
これのおかげで自宅と実家の鯖の間のVM同士で通信できます。つまり物理鯖がどこに置いてあるかを考えなくともその上のVMを触ることができるということです。

利点

要求

手順

ここまでmeshoverについて利便性を推してきましたが使うのはある程度面倒です。トラシューにもある程度の知識が必要です。やりたい方は具体的な手順を載せてるGitHubに上げたGetting Startedを見てもらうとして、手順を簡単に説明します。
おわりです。簡単ですね(?)
こんな感じでdummy(loopback)デバイスが追加されます。
25: dummy-meshover0: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
    link/ether <macアドレス> brd ff:ff:ff:ff:ff:ff
    inet 10.1.2.3/32 scope global dummy-meshover0
       valid_lft forever preferred_lft forever
    inet6 fd00:dead:beef:9e0b::1/64 scope global 
       valid_lft forever preferred_lft forever
    inet6 fe80::aaaa:aaaa:aaaa:aaaa/64 scope link 
       valid_lft forever preferred_lft forever
トンネルはこんな感じのGREデバイスが追加されます。
49: meshover0-tun9@NONE: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1396 qdisc noqueue state UNKNOWN group default qlen 1000
    link/gre 10.1.2.4 peer 10.2.3.4
    inet 10.1.2.3/32 scope global meshover0-tun9
       valid_lft forever preferred_lft forever
    inet6 fe80::aaaa:aaaa/64 scope link 
       valid_lft forever preferred_lft forever
ちなみに、ここまでしかやらないならtailscaleの方が対応OS多いしIPアドレスの要件が緩いしでtailscaleの方が良いです。

追加手順

VMやコンテナを動かしましょう。ところでVMやコンテナの管理に何を使っていますか?派閥はあると思いますがmeshoverはKubernetesとの連携を目的として開発したのでKubernetesを使いましょう。

ところでKubernetesのコンテナってどう通信してるの

Kubernetes自身はほぼネットワークに関わらずCNI(Container Network Interface)に任せています。CNIにはいろいろな実装があり、CalicoとかFlannelとかCiliumが有名ではないでしょうか。CNIには次の最低限の2つの機能を持っているのがほとんどで、IPアドレスの割り当て、オーバーレイネットワーク構築などによるコンテナ間通信の確保です。さきほど挙げたCNIは全てBGPやVXLANを使って自身でオーバーレイネットワークを構築するなどの機能を持っています[^cni]。この機能についてはmeshoverが責任を持つためCNIには前者だけやってもらえばいいです。

インストール

前者のIPアドレス管理だけをやるCNIとしてCilium(Native Routingモード)Coilなどがあります[^calico]。Ciliumにはおまけ機能が充実していたりと楽しいので私はCiliumを選択しました。
これも詳細な手順はmeshoverのgithubに上げているので雑に説明します。
さて、さっそくコンテナを動かしてみましょう。meshoverはKubernetesを入れるパソコンと、実際にコマンドを叩くメイン機に導入しています。
このコンテナはKubernetesをインストールしたどのパソコンで動くのかわかりません。自宅で動いている可能性もありますし実家の可能性もあります。(指定はできますが)
以下のコマンドでtmp-shellから始まっているのはコンテナ内で実行したコマンドです。
CiliumのIPマスカレードにより一般の通信はパソコンの通常のプロバイダから出ます。私の自宅はフレッツのIIJ mio光なので、ちゃんと自宅の普通の経路を通っていますね。
bash
$ kubectl run tmp-shell --rm -i --tty --image nicolaka/netshoot
tmp-shell  ~  ip a
149: eth0@if150: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether aa:aa:aa:aa:aa:aa brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.228.0.160/32 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 24xx:xxxx:xxxx.../128 scope global nodad 
       valid_lft forever preferred_lft forever
    inet6 fe80::xxxx/64 scope link 
       valid_lft forever preferred_lft forever
tmp-shell  ~  tracepath 1.1.1.1
 1?: [LOCALHOST]                      pmtu 1500
 1:  no reply
 2:  10.228.0.13                                           0.233ms 
 3:  192.168.1.1                                           0.529ms 
 4:  192.168.1.1                                           0.354ms pmtu 1454
 4:  tokyo**-***.flets.2iij.net                           10.632ms
...
NativeRoutingCIDRに指定した10.0.0.0/8はオーバーレイネットワークを経由します。コンテナからメイン機へ通信してみましょう。数ホップで到達していますね。
bash
tmp-shell  ~  tracepath 10.1.2.3
 1?: [LOCALHOST]                      pmtu 1500
 1:  no reply
 2:  10.228.0.13                                           0.103ms 
 3:  10.228.0.13                                           0.052ms pmtu 1476
 3:  10.228.0.13                                           0.068ms pmtu 1396
 3:  10.1.2.3                                              0.350ms reached
     Resume: pmtu 1396 hops 3 back 3 
こんな感じでKubernetesと連携しコンテナやVMのネットワークとIPアドレスを管理しやすくするmeshoverの紹介でした。

あとがき

このツールは
方向けのツールです。それ以外の方は以下のツールが自宅鯖やるのに楽なのでオススメです。

注釈

[^cni]: meshoverはKubernetesクラスタ外とも通信したりIPv6でVPNを張ったりするため、これらでは代替できません。[^calico]: calicoにも似たような機能があるらしいんですが未調査です。