- 用語
- Namespaces
- Podを外部公開する
- Site内のネットワークトポロジー
- Site間のトポロジー
- Site-Site間の接続
- 仮想ネットワーク
- ゼロタッチプロビジョニング
- OSについて
- 実際にAWSにAMIで起動してみた
- Add AWS VPC Siteでインストールしてみた
- 疑問
用語
名前 | 説明 |
---|---|
Volterra Node | クラウドまたは物理環境に設置されたVolterraManagedなKubernetesが稼働するサーバのこと |
Site | Volterra Nodeがデプロイされた物理orクラウド環境のこと。AWSでいうVPCやAzureのVNetなどが該当する。Siteは1つ以上のVolterraNodeのClusterで構成される。複数のVolterra NodeによるClusterがある場合には、別々のSiteとして管理される。 |
vSite | Virtual Siteのこと。Siteを束ねる概念で、Siteごとの設定をまとめて管理できる。Siteが渋谷支店なら、vsiteは東京グループや関東グループと言うイメージ。Siteは複数のvSiteに所属することができる。 |
Physical Kubernetes | VoltNode上にインストールされているKubernetesのこと |
Virtual Kubernetes | 複数のSiteに存在するPhysical Kubernetesを横断して管理する仮想的なKubernetes。Kubernetesの全てのリソースをラップするのではなく、あくまで1Virtual Kubernetesあたり1 Namespace(こっちはPhysicalの方) を管理できる。たとえば複数のPhysical kubernetesに対してdev/stg/prodの3種類のNamespaceを作って管理したい場合には、Virtual Kubernetesを3つ作らないといけない |
Namespaces | KubernetesのNamespaceとは別の概念(ややこしい) 、わかりやすさのためvNamespaceと記載する(非公式)。Tenantの中のリソースをvNamespaceと言う単位で分割して管理する。複数のvSiteが入っている。すべてのVolterraオブジェクトはユニークなkind,tenant,vnamespace,nameで示されるFQNという識別子で管理される。vNamespaceはTenantのisolationなのでvNamespaceを超えた操作はできない。(金融.マーケティングみたいな組織で分けたり、開発/本番みたいな用途でわける |
Tenant | 特定のテナントIDを持つユーザが作成した、全ての構成物の所有者。テナントは個人ユーザとエンタープライズがあり、エンタプーライズの場合は複数ユーザが参加することができる。(テナントで権限が分かれているのでテナントを跨いだ操作は無理そう) |
Fleet | 各Siteに存在する機器のHWの構成や、接続されるデバイス(NIC/ストレージ/FW/NW)などを管理するもの。vSiteはくまで場所の管理であって、同じ設定や機構のSite(Cluster)を管理するものではないのでFleetを使って管理する |
Label | KubernetesのLabelとは別の概念。(ややこしい)オブジェクトのクラス分類をするためのもの。key&value型。Lebal Selectorをうまく使ってオブジェクトを管理する。 |
単位としては以下の順序
- Tenant > vNamespaces > Virtual Kubernetes > vSite > Site(k8s Cluster/Physical Kubernetes) > Volterra Node(物理/仮想マシン)
- Volterra Site | Volterra Docs
Namespaces
Tenantを作ると以下のNamespaceが作られる。Namespaceを作る時の注意としてはFQDN名として使われることがあるのでRFC1035に準拠して.や/などの文字を使わないようにすること。
- system
- すべてのインフラオブジェクトはここに入る
- site/network/interface など
- 削除できない
- インフラストラクチャ内のsiteオブジェクトは、Tenant内のすべての名前空間に表示されるため、特別です。
- shared
- すべてのNamespaceからみることができるオブジェクトがある
- 削除できない
- default
- 最初に作られるやつ
- ves-io-shared
- すべてのTenantで共有されるオブジェクトがある。GET操作のみ可能。
Podを外部公開する
Origin Pool
外部公開するには対象のService(kubernetesのリソース)に対してOrigin Poolを設定する。Origin PoolはEndpointへのロードバランスを実現したり、ヘルスチェックやエンドポイントへのTLS機能を実現したりする。
※複数のPhysical kubernetesで稼働するServiceをまとめて抽象化するVolterraリソースという感じだろうか。
そしてここで作成したOrigin Poolに対してVolterraのSaaSで提供されるHTTP Load Balancerをアタッチすると、グローバルから各 Site上のPodへの通信が実現するようになる。このとき各SiteとREはIPsec/SSLトンネルにより接続されているので、Site自体がグローバルIPをもっている必要はない。
Origin Poolの設定
名前 | 意味 |
---|---|
Public IP of Origin Server | OriginサーバがグローバルIPを持っている場合。Volterraの外で動くサービスをOriginとして扱うときに使うのだろう。 |
IP address of Origin Server on given Sites | Siteに割り与えられたプライベートIP or グローバルIPを指定する。Volterra Nodeの先にいる別のサーバなどに対して通信をしたいときに使えそう。 |
Public DNS Name of Origin Server | Public IP of Origin ServerのFQDN版 |
DNS Name of Origin Server on given Sites | IP address of Origin Server on given SitesのFQDN版。ただしPrivateでのローカルドメインなどを使っている場合はどのように名前解決がされるか不明なので、使えるかわからない…。Phyisical KubernetesのCoreDNSが判断できればいけるのかな…? |
k8s Service Name of Origin Server on given Sites | Phyisical kubernetesで稼働するServiceに対する接続 |
Consul Service Name of Origin Server on given Sites | HAshicorp Consul Serviceに接続 |
Custom Endpoint Object for Origin Server | 自分で指定したEndpoint。どこのvsiteのどのプロトコルのどのportまで指定できるので、これを1つ設定しておきOriginで使い回すってのは結構使われるパターンっぽい。 |
Site内のネットワークトポロジー
singleNICの場合
1つのNICで全ての通信を賄う。別のSiteへの通信はIPsec/SSLトンネルを利用し通信を行う。(regional edgeというVolterra社のクラウドを経由する or Site-Site間のいずれかの経路)
Multi NIC(以上) の場合
外向け、内向けの2つのセグメントのパターン。別Site向けの通信はSingleNICと同じくIPsec/SSL越し。これを使うケースとしてはVolterraNode達をWANに面したルーティング・FW装置として活用する場合。(Default Gateway モード)
通常のルータと違い、Kubernetesの機能を生かしつつ統合管理もできるエッジ機器なので利便性が高いかも?(性能は劣るが管理が楽そう)
Clusterに対するVIP
複数のVolterra Nodeが存在するときに代表IPとしてVIPを設定することが可能。
Site間のトポロジー
Regional Edge(RE)の接続
Siteが作成・承認されるとClusterは自動で2つのVolterra Regional Edge(グローバルIP持ち) に接続する。このときGeo-IPアドレスによって近いロケーションが選ばれるが、ユーザが後で変更することも可能。
REへの接続はIPsec/SSLの両方が用いられ、基本的にはIPsecが使われる。REと接続が確立すると、REにある分散コントローラーがSiteを管理し始める。この経路はマネジメント用、データ用とで共有している。
Site-Site間の接続
VolterraのSite間の通信は基本的にREを通して行われるが、直接Site間をつなぎたい場合は Site Mesh Group を使うことで実現できる。
Site Mesh Group を使う場合はSite間でIPsec or SSL or Clear/Unencrypted Tunnelのいずれかが利用できる。Groupの作り方によって以下のようなHub&Spokeの構成を取ることも可能。
仮想ネットワーク
VolterraではVolterra Node/Site内のネットワークを抽象的な物として扱うために、Virtual Network/Network Interface/Network Connectorの3種類の概念を用意しています。
仮想ネットワークはSite内のネットワークのことです。一意のIPアドレスを持ち、相互に通信でき、他のエンドポイントから分離されたエンドポイントのコレクションです。ネットワークの世界では、仮想ネットワークはVRF(仮想ルーティングおよび転送)とも呼ばれます。
仮想ネットワークはユーザが作るものと、ブートストラップ時に勝手に作られるものがあります。
種類 | 説明 |
---|---|
Per-Site | Siteごとに存在するNWのこと。別Siteとの疎通性はない。 |
Global | 複数のSiteを跨いで作成される仮想NW。このNWに存在するエンドポイントはSiteに関係なく通信を行うことができる |
Site-Local | 各サイトに1つしか存在できない。ブートストラップ中にシステムによって自動で作られるもの。NATゲートウェイ/ファーウォールを介してパブリックインターネットに接続できます。 |
Site-Local-Inside | 各サイトに1つしか存在できない。2つのNICを持つサイトでのブートストラップ中にシステムによって自動で作られるもの。inside側のNWのこと。 |
Public | REのNWのこと(ユーザ管理外) |
Site-Local-Service | physical kubernetesのcluster IPにallocateされたNW |
VER-Internal | Siteのすべてのコントロールプレーンサービスが存在する場所を表します。これは、コントロールプレーンがテナントサービスにアクセスする必要がある場合にのみ使用されます |
ちなみにVoltConsoleだと作れるNWは以下の通り。(ドキュメントとちがくね?)
- site local inside
- site local outside
- global
- legacy
legacyの中みたら上で解説した Site Local / Site Local Inside / Per Site / Global / Site local inside and outside などがあった。なんやねんlegacyって。
Network Interface
Network InterfaceはFleetで設定される 物理 or 仮想 インターフェース のことを指します。
eth0 や 1といったSite内のNodeが持っているNICのことを 物理インターフェース といい、それにぶら下がるVLANなどのインターフェースを 論理インターフェース と言います。
各インターフェースは以下の2つを満たしている必要があります。
- 仮想ネットワークに所属していること
- IPアドレスをもっていること(静的またはDHCP)
Siteに仮想ネットワークを設定する
2つの方法があります。
- 物理や論理インターフェースを仮想ネットワークに参加させ、それらのインターフェースからアクセスできるエンドポイントを同じ仮想ネットワークのメンバーにします。
例:VolterraNodeのeth0が192.168.0.0/24に所属し、他のサーバからみたらDefaultGatewayだとします。そしてこのeth0を仮想ネットワーク1に参加させるとeth0からアクセスができる192.168.0.0/24上のエンドポイントが全て仮想ネットワーク1のメンバーとなります。(ただしすべてのエンドポイントがユニークなIPを持っている必要があります)
使い方としては、VolterraNodeより先にいるサーバもVolterra経由でアクセスさせるために使えますね。
- すでに存在する仮想ネットワークに対して Network Connector を使う方法があります。詳しくはNetwork Connectorのところに書きます。
Network Connector
Network ConnectorはVirtualNetworkをつなげるものです。異なるネットワークを接続するのでイメージはルータですが、機能がいくつかありフォワードプロキシ、リバースプロキシ、SNAT、Directから選べるようです。
- Two-way connector(Directのこと)
- 2つの仮想ネットワークを接続する。仮想ネットワーク間のIPかぶりはNG。(Local1-Local2でIP被りなし)
- 仮想ルータを2つのネットワークの間に設置して経路交換するイメージ
- site-local-inside ~ global間 / site-local-outside ~ global間 の時に利用可能
- One-way connector
- 2つの仮想ネットワークを接続する。仮想ネットワーク間でIPがかぶっている場合に使う。(Local1-Global-Local2みたいなときにLocal1/2でIP被りしてるとき)
- SNAT/フォワードプロキシ/リバースプロキシを使用してIPを変換して2つのネットワークを接続する。
- 例:複数のSiteがありそれぞれに同じサブネットのローカル仮想ネットワークがあるとお互いに通信ができない。そこでグローバルの仮想ネットワークを作り、そこに各Siteのローカル仮想ネットワークからコネクタを経由して通信をすることでIPがユニークとなり通信ができるようになる。
- Reverse Proxy connector
- 接続する仮想ネットワーク間でIPバッティングする場合に使う(Local1-Local2でIP被り)
- 設定なさそう
ややこしいのがVoltConsole上だと Direct or SNAT ? が聞かれて、それとは別にフォワードプロキシの有無が聞かれます。あとなぜかリバースプロキシは存在しませんでした。
実際に存在したNetwork Connectorの設定
- site local inside - site local outside (SNAT) ←One-way connector
- site local inside - global (Direct) ←Two-way connector
- site local outside - global (Direct) ←Two-way connector
フォワードプロキシ使うときは下2つのいずれかを選んで、フォワードプロキシを設定するんだろうな〜。また Globalに抜けるときはSNATの選択肢がなかったので、フォワードプロキシ強制なのかな?
ローカル仮想ネットワーク
Siteに存在する仮想的なNWのこと。Fleetを利用してたくさんのしてを管理しているケースにおいて、全てのSiteに対してこれを作ると便利らしい。(別のSiteと接続をしたくない場合はlocal設定にすることで、他のsiteとの接続を実施しない)
グローバル仮想ネットワーク
複数のSite間で共有する仮想ネットワーク。複数のSiteをまたがる。SubmarinerやSkupperを使ったマルチクラスタネットワークと同義っぽい。
ゼロタッチプロビジョニング
ゼロタッチプロビジョニングとは利用者が特に設定することなく、起動するとゼロタッチで設定を自動投入してくれる仕組みのこと。
Volterra Stackはこれを採用しており顧客の環境やエッジ、クラウド基盤にいたるまでゼロあっちが可能。なおKubernetesにおけるMasterは最低1台作成され、VolterraNodeを追加していくと2n+1を維持するように勝手にインストールが走る。
OSについて
VoltStackに最適化された軽量なOSを利用。クラウド、オンプレ気にすることなく動作するLinuxベースが採用されている。
OSは遠隔アップデートやロールバックがサポートされている。アップグレード時は新バージョンを別のファイルシステムにインストール しリブート後に新バージョンに切り替えることで、ダウンタイムを短くしたり、ロールバックを容易にしている。
実際にAWSにAMIで起動してみた
いろいろコマンドを実行してみる
OCI/CRIはdockerを使っているっぽい。CNIもdocker bridgeか。
[root@ip-10-0-0-36 net.d]# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 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 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether 0a:5d:50:a5:d4:38 brd ff:ff:ff:ff:ff:ff inet 10.0.0.36/24 brd 10.0.0.255 scope global dynamic eth0 valid_lft 2277sec preferred_lft 2277sec inet6 fe80::85d:50ff:fea5:d438/64 scope link valid_lft forever preferred_lft forever 3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:bd:4b:16:a8 brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 valid_lft forever preferred_lft forever inet6 fe80::42:bdff:fe4b:16a8/64 scope link valid_lft forever preferred_lft forever
バージョンはこちら。
[root@ip-10-0-0-36 net.d]# [root@ip-10-0-0-36 net.d]# [root@ip-10-0-0-36 net.d]# docker version Client: Version: 18.09.9 API version: 1.39 Go version: go1.11.13 Git commit: 039a7df9ba Built: Wed Sep 4 16:51:21 2019 OS/Arch: linux/amd64 Experimental: false Server: Docker Engine - Community Engine: Version: 18.09.1 API version: 1.39 (minimum version 1.12) Go version: go1.10.6 Git commit: 4c52b90 Built: Wed Jan 9 19:06:30 2019 OS/Arch: linux/amd64 Experimental: false [root@ip-10-0-0-36 net.d]# uname -a Linux ip-10-0-0-36.ap-northeast-1.compute.internal 4.18.0-147.5.1.ves4.el7.x86_64 #1 SMP Mon Mar 16 08:47:16 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
特にファイルシステムが分かれている感じもしない。
[root@ip-10-0-0-36 net.d]# df -h ファイルシス サイズ 使用 残り 使用% マウント位置 devtmpfs 383M 0 383M 0% /dev tmpfs 410M 0 410M 0% /dev/shm tmpfs 410M 1.3M 409M 1% /run tmpfs 410M 0 410M 0% /sys/fs/cgroup /dev/mapper/atomicos-root 20G 5.7G 14G 29% /sysroot /dev/xvda1 297M 117M 181M 40% /boot /dev/dm-2 10G 331M 9.7G 4% /var/lib/docker/devicemapper/mnt/c21048249300177feb599e6c3e38cecf195c196aab10934b4d113f6606194fab shm 64M 0 64M 0% /var/lib/docker/containers/c3347fc99e221a71fbf2c2a47edf99faa5d9c05864b4d7b22b3669836b1b8cce/mounts/shm /dev/dm-3 10G 241M 9.8G 3% /var/lib/docker/devicemapper/mnt/1622012e1384118441aab5f777410117cf978cc8ba24c4f35051cad04413946d shm 64M 0 64M 0% /var/lib/docker/containers/402ebb32dbe79f7608d2d843b82885f7c8349bba14a2efb7cb1476057038aa3d/mounts/shm /dev/dm-4 10G 351M 9.7G 4% /var/lib/docker/devicemapper/mnt/5f74428ab43c0dc07502ea6da272cc96aa481fd9cf56bccc2f4e55e5a328a484 shm 64M 0 64M 0% /var/lib/docker/containers/acba7b54607e75110cb11500691c117be2a91e15d94075e15dcf8b23ac0ca519/mounts/shm tmpfs 82M 0 82M 0% /run/user/1000 tmpfs 82M 0 82M 0% /run/user/0
起動しているコンテナプロセス
[root@ip-10-0-0-36 net.d]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES acba7b54607e volterraio/fireball:v1-0 "/bin/fireballd" 21 minutes ago Up 21 minutes fireball 402ebb32dbe7 volterraio/site-console:v1-0 "docker-entrypoint.s…" 22 minutes ago Up 22 minutes site-console c3347fc99e22 volterraio/vpm:latest "/bin/vpmd" 22 minutes ago Up 22 minutes vpm
プロセスのオプションなど。ところどころkube
という文言はあるがkubernetes/kubeletが入っているわけではない。
[root@ip-10-0-0-36 net.d]# ps -ef |grep docker root 4284 1 0 06:45 ? 00:00:06 /usr/bin/dockerd -H fd:// --exec-opt native.cgroupdriver=systemd root 4764 1 0 06:45 ? 00:00:00 /usr/bin/docker run --rm --name vpm --net=host --privileged -v /dev:/dev -v /etc/:/hostetc/:rw -v /usr/bin/:/hostusr/bin/:ro -v /etc/default/:/etc/default/:rw -v /etc/hosts:/etc/hosts -v /etc/machine-id:/etc/machine-id:ro -v /etc/kubernetes/:/etc/kubernetes/:rw -v /etc/os-release:/etc/os-release:ro -v /etc/ssl/certs/ca-certificates.crt:/etc/ssl/certs/ca-certificates.crt:ro -v /etc/systemd/:/etc/systemd/ -v /etc/vpm/:/etc/vpm/ -v /opt/vpm/certs/:/opt/vpm/certs/ -v /etc/wpa_supplicant/:/etc/wpa_supplicant/ -v /mnt/ves/:/mnt/ves/ -v /opt/bin/:/opt/bin/ -v /root/.docker/:/root/.docker/ -v /root/.kube/:/root/.kube/ -v /run/systemd/:/run/systemd/ -v /sys/:/sys/:ro -v /var/lib/etcd/:/var/lib/etcd/:rw -v /var/lib/kubelet/:/var/lib/kubelet/:rw -v /var/lib/vpm/data/:/data/ -v /var/run/:/var/run/:rw volterraio/vpm:latest root 4868 867 0 06:45 ? 00:00:00 containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/c3347fc99e221a71fbf2c2a47edf99faa5d9c05864b4d7b22b3669836b1b8cce -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc -systemd-cgroup root 8695 1 0 06:45 ? 00:00:00 /usr/bin/docker run --rm --name site-console --net=host -v /var/lib/vpm/data/certs/used/:/usr/src/apps/volterra/site-console/certs/:ro -v /etc/vpm/basic-auth.json:/usr/src/apps/volterra/site-console/basic-auth.json:ro volterraio/site-console:v1-0 root 8782 867 0 06:45 ? 00:00:00 containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/402ebb32dbe79f7608d2d843b82885f7c8349bba14a2efb7cb1476057038aa3d -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc -systemd-cgroup root 9014 1 0 06:46 ? 00:00:00 /usr/bin/docker run --privileged --net=host -v /var/lib/vpm/:/var/lib/vpm/ -e CERTIFIED_HW=generic-single-nic --name fireball volterraio/fireball:v1-0 root 9062 867 0 06:46 ? 00:00:00 containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/acba7b54607e75110cb11500691c117be2a91e15d94075e15dcf8b23ac0ca519 -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc -systemd-cgroup root 9308 9149 0 07:09 pts/0 00:00:00 grep --color=auto docker
ここからさらにインストールしていく感じなのだろうか?ドキュメントには続きの手順がなかったので諦め。
Add AWS VPC Siteでインストールしてみた
こちらはSSHするとVolterra専用のconsoleに飛ばされるので叩けるコマンドが制限されていた。しかもconfigure
が初めから勝手に終わっていた。楽ちん。
叩けるコマンド
Available Commands: collect-debug-info Collect debug info produce /tmp/debuginfo/*.bzip2 file for Volterra support configure Initial configuration of the node configure-network Initial configuration of the network exec Exec Custom command exit Exit shell factory-reset Factory reset get-config Get node's config health Status of the node help Help about any command log Get logs from service password-change Change user password ping ping reboot Reboots the node soft-restart Restart specified service status Status of individual services usb usb interaction volterra-status Status of services
execはlsとpingしか叩けない…(全然中身見れない) なんとかして中に入ってみるとこんな感じのpodが起動していた。
NAMESPACE NAME READY STATUS RESTARTS AGE kube-system coredns-d5bdd5f97-lmg6w 1/1 Running 0 7h22m kube-system kube-apiserver-ip-10-45-1-52.ap-northeast-1.compute.internal 1/1 Running 0 7h22m kube-system kube-controller-manager-ip-10-45-1-52.ap-northeast-1.compute.internal 1/1 Running 0 7h22m kube-system kube-proxy-wrmkh 1/1 Running 0 7h23m kube-system kube-scheduler-ip-10-45-1-52.ap-northeast-1.compute.internal 1/1 Running 0 7h22m kube-system kube-state-metrics-6bcb7884db-czkrp 1/1 Running 0 7h22m monitoring blackbox-exporter-6db8c8858-x2hzq 3/3 Running 0 7h22m monitoring event-exporter-594d9d5544-7g2g9 1/1 Running 0 7h21m monitoring fluentbit-xd4nm 2/2 Running 0 7h22m monitoring prometheus-7f967d47b7-74m5z 6/6 Running 0 7h22m monitoring prometheus-node-exporter-qrnsm 1/1 Running 0 7h22m ves-system dnsmasq-79c8bbc76-8lx9n 1/1 Running 0 7h21m ves-system etcd-0 2/2 Running 0 7h21m ves-system etcd-defrag-1612620000-5r5nb 0/2 Completed 0 34m ves-system gubernator-5cd8fdc676-stt95 2/2 Running 0 7h21m ves-system obelix-cpvlw 2/2 Running 0 7h22m ves-system opera-8bptl 2/2 Running 0 7h22m ves-system ver-tmmjt 10/10 Running 0 7h21m webhook voucher-6b449685d5-vqjzd 1/1 Running 0 7h22m
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE default kubernetes ClusterIP 100.127.192.1 <none> 443/TCP 7h27m kube-system kube-dns ClusterIP 100.127.192.10 <none> 53/UDP,53/TCP,9153/TCP 7h26m kube-system kube-state-metrics ClusterIP 100.127.236.48 <none> 65031/TCP,65032/TCP 7h26m monitoring blackbox-exporter ClusterIP 100.127.248.100 <none> 9115/TCP 7h26m monitoring prometheus NodePort 100.127.216.120 <none> 9090:32222/TCP 7h26m monitoring pushgateway ClusterIP 100.127.224.160 <none> 65220/TCP 7h26m ves-system dnsmasq ClusterIP 100.127.192.15 <none> 1067/UDP 7h26m ves-system etcd ClusterIP None <none> 2379/TCP,2380/TCP,23790/TCP,65535/TCP 7h26m ves-system gubernator ClusterIP 100.127.192.26 <none> 65111/TCP,65110/TCP,65112/TCP 7h26m ves-system obelix ClusterIP 100.127.192.16 <none> 18095/TCP,18091/TCP,18092/TCP,18093/TCP,18094/TCP 7h26m ves-system opera ClusterIP 100.127.247.47 <none> 8007/TCP,9007/TCP,8507/TCP,9507/TCP 7h26m ves-system ver NodePort 100.127.192.18 <none> 8005:30805/TCP,9999:31635/TCP,8505:30855/TCP,9005:30905/TCP,9505:30955/TCP 7h26m webhook voucher ClusterIP 100.127.192.40 <none> 65334/TCP,65333/TCP,443/TCP,8443/TCP,8444/TCP 7h26m
verというpodの中に10個ものコンテナが入っているようで、中を見ていくとopenvpnとかBFDとかIKEなどのそれっぽいコンテナがいた。openvpnの引数をみてみるとREが宛先にいたのでこれが通信を実現しているのだろう。
それぞれのpodの起動方法はこんな感じ。IPsecVPNはdaemonsetで起動しているので、各VolterraNode→REに対してVPNを貼っている模様。
$ kubectl get deploy NAME READY UP-TO-DATE AVAILABLE AGE dnsmasq 1/1 1 1 8h gubernator 1/1 1 1 8h $ kubectl get statefulset NAME READY AGE etcd 1/1 8h $ kubectl get daemonset NAMESPACE NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE ves-system obelix 1 1 1 1 1 <none> 8h ves-system opera 1 1 1 1 1 <none> 8h ves-system ver 1 1 1 1 1 <none> 8h
get-config
EmbedEtcdClientPort: 12379 EmbedEtcdDataDir: /data/vpm-embed-etcd EmbedEtcdPeerPort: 12380 GrpcPort: 65000 GrpcTLSPort: 65002 Kubernetes: BootstrapSecretsSubdir: pki ClusterCIDR: xx/18 DNSServiceIP: xx EtcdUseTLS: true Hostname: ip-10-45-1-52 Images: Apiserver: k8s.gcr.io/kube-apiserver:v1.17.9 ControllerManager: k8s.gcr.io/kube-controller-manager:v1.17.9 CoreDNS: k8s.gcr.io/coredns:1.6.5 Etcd: gcr.io/volterraio/etcd@sha256:9299b4fa5e087e9bbe16b371030360e0745d4f6ebb4116633d76e4ae1d8139f9 Proxy: k8s.gcr.io/kube-proxy:v1.17.9 Scheduler: k8s.gcr.io/kube-scheduler:v1.17.9 Server: vip ServiceCIDR: xx/18 SreDnsServiceIp: xx TlsCipherSuites: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 RestPort: 65001 RestTLSPort: 65003 Vpm: CertifiedHardware: aws-byol-voltmesh CertifiedHardwareEndpoint: https://vesio.blob.core.windows.net/releases/certified-hardware/aws.yml ClusterName: test-aws01 ClusterType: ce Config: /etc/vpm/config.yaml ContainerRuntime: docker Labels: ves.io/fleet: "" Latitude: 35.689507 Longitude: 139.6917 MauriceEndpoint: https://register.ves.volterra.io MauricePrivateEndpoint: https://register-tls.ves.volterra.io PrivateNIC: eth0 Token: xxxx Workload: fluentbit: params: fluentbit_forward_host: fluentd.monitoring.svc.cluster.local fluentbit_forward_port: "24224" fluentbit_image: gcr.io/volterraio/fluentbit fluentbit_namespace: monitoring fluentd: params: fluentd_elasticsearch_host: 192.168.112.4 fluentd_elasticsearch_port: "30920" fluentd_image: gcr.io/volterraio/fluentd fluentd_namespace: monitoring prometheus: params: prometheus_app_id: xx prometheus_cluster_id: xxx prometheus_cluster_name: xx prometheus_disable_alerting: "1" prometheus_host_network: "1" prometheus_image: gcr.io/volterraio/prometheus prometheus_namespace: monitoring
health
hostname: xxx osInfo: bios: date: xx vendor: Amazon EC2 version: "1.0" board: assetTag: i-xx vendor: Amazon EC2 chassis: assetTag: Amazon EC2 type: 1 vendor: Amazon EC2 cpu: cache: 36608 cores: 4 cpus: 4 model: Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz speed: 2500 threads: 4 vendor: GenuineIntel kernel: architecture: x86_64 release: 4.18.0-147.5.1.ves4.el7.x86_64 version: '#1 SMP Mon Mar 16 08:47:16 UTC 2020' memory: sizeMb: 15690 type: Other os: architecture: amd64 name: CentOS Linux 7.2003.13 (Core) release: 7.2003.13 vendor: centos version: 7.2003.13 product: name: t3.xlarge serial: xx vendor: Amazon EC2 storage: - model: Amazon Elastic Block Store name: nvme0n1 serial: xx sizeGb: 85 osVersion: 7.2003.13 publicIp: xx/24 softwareVersion: crt-20210203-845 state: PROVISIONED version: | master 3e58813b2838d631f45c50405e28bf63e0c585e4 2021-01-12T10:45:53+00:00 nil
volterra-status
>>> volterra-status │────────────│───────────────────────────────────────────────│────────│─────────│ │ NAME (5) │ NODE │ STATUS │ MESSAGE │ │────────────│───────────────────────────────────────────────│────────│─────────│ │ obelix │ ip-10-45-1-52.ap-northeast-1.compute.internal │ Ready │ │ │ opera │ ip-10-45-1-52.ap-northeast-1.compute.internal │ Ready │ │ │ ver │ ip-10-45-1-52.ap-northeast-1.compute.internal │ Ready │ │ │ dnsmasq │ ip-10-45-1-52.ap-northeast-1.compute.internal │ Ready │ │ │ gubernator │ ip-10-45-1-52.ap-northeast-1.compute.internal │ Ready │ │ │────────────│───────────────────────────────────────────────│────────│─────────│ >>>
VoltConsole
VoltConsole上からはルーティングやtcpdump、USBデバイス、TracerouteなどのNWコマンドやデバイスの状態が確認できるToolsが存在した。
ルーティング
route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 10.45.1.1 0.0.0.0 UG 0 0 0 vhost0 10.45.1.0 0.0.0.0 255.255.255.0 U 0 0 0 vhost0 169.254.0.0 10.45.1.1 255.255.0.0 UG 0 0 0 vhost0 169.254.10.12 0.0.0.0 255.255.255.252 U 0 0 0 keepalived-tap 172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
とくにこれといってVPNを張ってどうこうっていう経路が見当たらない。別Siteへの通信やREへの通信は、keepalived-tapに対して投げてからいい感じに変換して送っている?? (10.45.1.1はAWSのデフォゲ)
26: keepalived-tap: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel state DOWN group default qlen 1000 link/ether 36:6b:b7:45:fd:85 brd ff:ff:ff:ff:ff:ff inet 169.254.10.13/30 brd 169.254.10.15 scope global keepalived-tap valid_lft forever preferred_lft forever
/var/run/keepalived/keepalived.conf
の中を見るとVRRPに対するkeepalivedの設定が入っており(BACKUPしかないのはよく分からないけど)、これによってkeepalived-tapという仮想IFが用意されている。またその時のIPはリンクローカルアドレスの169.254.10.13/32
をバインドしている。
vrrp_instance vrrp_instance_254 { state BACKUP interface keepalived-tap virtual_router_id 254 priority 150 advert_int 1 authentication { auth_type PASS auth_pass ves } virtual_ipaddress { 169.254.10.13/32 } }
中の仕組みの追い方がこれ以上わからないので諦めるが以下のような通信経路だと思われる。
クライアントからVolterraNodeに通信するとき
- クライアント→RE→〜[IPsec]〜→VolterraNode(ver pod→Cluster IP Service→Nginx Pod)
- 実際にはIPsecの貼り方はver pod→REとなるはず
- REはクライアントが指定するHostやPort、IPアドレスなどとVolterraNode内のServiceをMappingしてるんだろう
Site間でPodが通信するとき(REまたぎ)
- SiteAのVolterraNode(Nginx Pod→Cluster IP Service →ver pod→〜[IPsec]〜→RE→〜[IPsec]〜→SiteBのVolterraNode(ver pod→Cluster IP Service→App Pod)
- SiteA側ではSiteBのServiceに対するリクエストについてはRE越しに通信しなければならないので、ver podの中のenvoy proxyがetcdに格納したデータを使ってよしなにハンドリングしてるんじゃないかと思う(妄想)
Virtual Kubernetesへの操作
Virtual Kubernetesを作成しkubeconfigをダウンロードしてkubectlを実行。Siteで起動しているPhysical kubernetesをうまくラップしてくれている。NodeのIPは実際のIPではなくキャリアグレードNATのIP(100.64.0.0/10)が用いられており既存のグローバルIPと被らないような形で採番されている。
おそらくVirtual Kubernetes単位でNodeのIPをユニークにする都合で通常のプライベートIPレンジを使用していない物と思われる。
$ kubectl --kubeconfig=kubeconfig get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deployment-df5f679c-445vv 2/2 Running 0 7m7s 100.127.0.2 test-aws01-ip-10-45-1-52.ap-northeast-1.compute.internal <none> <none> $ kubectl --kubeconfig=kubeconfig get ns -o wide NAME STATUS AGE default Active 9m47s kube-node-lease Active 9m52s kube-public Active 9m52s kube-system Active 9m52s test Active 9m52s $ $ kubectl --kubeconfig=kubeconfig get pod -n kube-system No resources found. $ kubectl --kubeconfig=kubeconfig get pod -n kube-public No resources found. $ kubectl --kubeconfig=kubeconfig get pod -n kube-node-lease No resources found. $ $ kubectl --kubeconfig=kubeconfig get pod -n default No resources found.
またVirtual Kubernetesにて以下のように明示的にnamespace-a
を指定してapplyしたところエラーが発生した。
kind: Deployment metadata: name: nginx-deployment namespace: namespace-a spec: selector: matchLabels: app: nginx replicas: 1 template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80
先ほどは何も指定せずにApplyしたのでWebで作成したtestというVirtual Kubernetes=Namespaceにデプロイされたのだが、namespace-aというVirtual Kubernetesが存在しないので弾かれた。ということはVirtual Kubernetesは複数のKubernetesを束ねるというよりKubernetesのNamespaceリソースとして扱った方がよさそう。
また使用できるリソースが限定的なのでroleとかcluster roleとかその辺も一切ない。どのnamespaceがみれるとかそう言う類の情報はVolterraのManagedContoroller側で全部管理されている。
疑問
- origin PoolのDNS Name of Origin Server on given SitesはPrivate FQDNはどう解決される?
- (Volterraの中の方の回答) CEに設定されたDNSサーバにFQDN引きに行きます。
- distributed control planeがREにいるらしいが、edgeにはAPIサーバなどはいない?それともいて、遠隔からまとめて指示してるのがdistributed control plane?
- edgeにAPIサーバいる。遠隔からvirtual kubernetes用のAPIサーバがいる
- (Volterraの中の方の回答) EdgeのAPIサーバはPhysical K8s (いわゆる普通のK8s)が今後サポートされるので、それを使うとそれぞれのクラスタのAPIをコールできます。GCというVolterraのコンソールでコンフィグを作ると、それが各地のREにコンフィグメッセージを飛ばし、そこに接続しているCEにコンフィグをプッシュするという仕組みです。