SlideShare a Scribd company logo
©2020 VMware, Inc.
宣言的(Declarative)ネットワーキング
Jan. 22, 2020
CTO, North Asia (Japan, Korea and Greater China)
Motonori Shindo (@motonori_shindo)
OVN のコントロールプレーンの例
2©2020 VMware, Inc.
ネットワークは非常に複雑な分散型システム
・非同期に起こる多重障害の可能性
・一部の操作は冪等ではない
さまざまな実装を試したが、最もうまく動いたのは Dalalog
をベースにした Nlog というエンジンを使った宣言的なコン
トローラであった。
Nicira のコントローラ (NVP) はどう動いていたか?
Napkin Talk with Martin Casado
Source: Computer History Museum
3©2020 VMware, Inc.
オープンソースな仮想ネットワークの実装
Open vSwitch (OVS) と共に開発されている(主に C で記述)
主な機能:
• 論理スイッチ
• 論理ルータ(IPv4、IPv6)
• オーバーレイネットワーク
• ACL
• Native NAT、Load Balancer、DHCP
• L2、L3 ゲートウェイ
• DPDK 対応
• Linux / Hyper-V で利用可能
• 複数のオーケストレータ(OpenStack、Kubernetes、Docker、Mesos、oVirt など)に対応
OVN (Open Virtual Network) とは
4©2020 VMware, Inc.
OVN のアーキテクチャ
HV-1
ovn-northd
ovn-controller
ovsdb-
server
ovs-
vswitchd
HV-n
ovn-controller
ovsdb-
server
ovs-
vswitchd
CMS
Desired State:
Logical Switch
Logical Port
Logical Router
Logical Router Port
ACL
Runtime State:
Chassis
Datapath Binding
Encap
Logical Flow
Multicast Group
Port Binding
• Converts NB DB -> SB DB
• Generates Logical Flow
South Bound DB
North Bound DB
South Bound DB
South Bound DB
・・・・・・・・・・・・・・・・・
• Register
Chassis & VIFs
to SB DB
• Converts logical
flow -> physical
flows
• Push config to
local OVSDB
and OF
5©2020 VMware, Inc.
OVN 内部の動き
lport1
br-int
sw0-port2sw0-port1
00:00:00:00:00:0200:00:00:00:00:01
lport2
sw0
$ ovn-nbctl lswitch-add sw0 (論理スイッチ追加)
$ ovn-nbctl lport-add sw0 sw0-port1 (論理ポートの追加)
$ ovn-nbctl lport-add sw0 sw0-port2
$ ovn-nbctl lport-set-addresses sw0-port1 00:00:00:00:00:01 (MAC アドレスの設定)
$ ovn-nbctl lport-set-addresses sw0-port2 00:00:00:00:00:02
$ ovn-nbctl lport-set-port-security sw0-port1 00:00:00:00:00:01 (Port Security の設定)
$ ovn-nbctl lport-set-port-security sw0-port2 00:00:00:00:00:02 (Port Security の設定)
$ ovs-vsctl add-port br-int lport1 -- set Interface lport1  (br-int にポートを追加し、
external_ids:iface-id=sw0-port1 インターフェースを接続)
$ ovs-vsctl add-port br-int lport2 -- set Interface lport2 
external_ids:iface-id=sw0-port2
ovn-northd
South Bound DB
North Bound DB
South Bound DB
South Bound DB
Logical Switch Table
Logical Flow Table
Logical Port Table
Chassis Table
Encap Table
Datapath Biding Table
Port Binding Table
6©2020 VMware, Inc.
VM / コンテナ環境は巨大かつ非常にダイナミック
7©2020 VMware, Inc.
Host 1 Host 2
Controller
tunnel
2 3
1
Match Action
dst=10.10.10.101 output:1 //tunnel port
dst=10.10.10.102 output:1 //tunnel port
dst=10.10.10.103 output:2 //local port
Match Action
dst=10.10.10.101 output:2 //local port
dst=10.10.10.102 output:3 //local port
dst=10.10.10.103 output:1 //tunnel port
2
1
vm ip host port
VM1 10.10.10.101 Host 1 2
VM2 10.10.10.102 Host 1 3
VM3 10.10.10.103 Host 2 2
Table: VM
8©2020 VMware, Inc.
Host 1 Host 2
Controller
tunnel
2 3
1
Match Action
dst=10.10.10.101 output:1 //tunnel port
dst=10.10.10.102 output:1 //tunnel port
dst=10.10.10.103 output:2 //local port
Match Action
dst=10.10.10.101 output:2 //local port
dst=10.10.10.102 output:3 //local port
dst=10.10.10.103 output:1 //tunnel port
2
1
vm ip host port
VM1 10.10.10.101 Host 1 2
VM2 10.10.10.102 Host 1 3
VM3 10.10.10.103 Host 2 2
Table: VM
for h in Hosts:
for vm in VM:
if vm.host == h:
h.add_flow(match=“dst={vm.ip}”,action=“output:{vm.port}”)
else:
h.add_flow(match=“dst={vm.ip}”,action=“output:{tunport}”)
9©2020 VMware, Inc.
Host 1 Host 2
Controller
tunnel
2 3
1
2
1
vm ip host port
VM1 10.10.10.101 Host 1 2
VM2 10.10.10.102 Host 1 3
VM3 10.10.10.103 Host 2 2
Table: VM
3
Match Action
dst=10.10.10.101 output:1 //tunnel port
dst=10.10.10.102 output:1 //tunnel port
dst=10.10.10.103 output:2 //local port
Match Action
dst=10.10.10.101 output:2 //local port
dst=10.10.10.102 output:3 //local port
dst=10.10.10.103 output:1 //tunnel port
10©2020 VMware, Inc.
Host 1 Host 2
Controller
tunnel
2 3
1
2
1
vm ip host port
VM1 10.10.10.101 Host 1 2
VM2 10.10.10.102 Host 1 3
VM3 10.10.10.103 Host 2 2
Table: VM
3
VM2 10.10.10.102 Host 1 3Host 2 3
Match Action
dst=10.10.10.101 output:1 //tunnel port
dst=10.10.10.102 output:1 //tunnel port
dst=10.10.10.103 output:2 //local port
Match Action
dst=10.10.10.101 output:2 //local port
dst=10.10.10.102 output:3 //local port
dst=10.10.10.103 output:1 //tunnel port
dst=10.10.10.102 output:1 //tunnel port dst=10.10.10.102 output:3 //local port
11©2020 VMware, Inc.
Host 1 Host 2
Controller
tunnel
2 3
1
2
1
vm ip host port
VM1 10.10.10.101 Host 1 2
VM2 10.10.10.102 Host 1 3
VM3 10.10.10.103 Host 2 2
Table: VM
3
VM2 10.10.10.102 Host 1 3Host 2 3
Match Action
dst=10.10.10.101 output:1 //tunnel port
dst=10.10.10.102 output:1 //tunnel port
dst=10.10.10.103 output:2 //local port
Match Action
dst=10.10.10.101 output:2 //local port
dst=10.10.10.102 output:3 //local port
dst=10.10.10.103 output:1 //tunnel port
dst=10.10.10.102 output:1 //tunnel port dst=10.10.10.102 output:3 //local port
案1: 全てのフローを1から再計算する
for h in Hosts:
for vm in VM:
if vm.host == h:
h.add_flow(match=“dst={vm.ip}”,action=“output:{vm.port}”)
else:
h.add_flow(match=“dst={vm.ip}”,action=“output:{tunport}”)
どのようにフローテーブルをアップデートするか?
• CPU サイクルの無駄遣い
• ネットワーク帯域の無駄遣い
• 設定遅延の増大
12©2020 VMware, Inc.
Host 1 Host 2
Controller
tunnel
2 3
1
2
1
vm ip host port
VM1 10.10.10.101 Host 1 2
VM2 10.10.10.102 Host 1 3
VM3 10.10.10.103 Host 2 2
Table: VMs
3
VM2 10.10.10.102 Host 1 3Host 2 3
Match Action
dst=10.10.10.101 output:1 //tunnel port
dst=10.10.10.102 output:1 //tunnel port
dst=10.10.10.103 output:2 //local port
Match Action
dst=10.10.10.101 output:2 //local port
dst=10.10.10.102 output:3 //local port
dst=10.10.10.103 output:1 //tunnel port
dst=10.10.10.102 output:1 //tunnel port dst=10.10.10.102 output:3 //local port
案2: インクリメンタルな更新のアルゴリズムを作る
for h in Hosts:
if old_vm.host == h:
h.del_flow(…)
else:
h.del_flow(…)
if new_vm.host == h:
h.add_flow(match=“dst={new_vm.ip}”,
action=“output:{new_vm.port}”)
else:
h.add_flow(match=“dst={new_vm.ip}”,
action=“output:{tunport}”)
どのようにフローテーブルをアップデートするか?
13©2020 VMware, Inc.
Host 1 Host 2
Controller
tunnel
2 3
1
2
1
vm ip host port
VM1 10.10.10.101 Host 1 2
VM2 10.10.10.102 Host 1 3
VM3 10.10.10.103 Host 2 2
Table: VMs
3
VM2 10.10.10.102 Host 1 3Host 2 3
Match Action
dst=10.10.10.101 output:1 //tunnel port
dst=10.10.10.102 output:1 //tunnel port
dst=10.10.10.103 output:2 //local port
Match Action
dst=10.10.10.101 output:2 //local port
dst=10.10.10.102 output:3 //local port
dst=10.10.10.103 output:1 //tunnel port
dst=10.10.10.102 output:1 //tunnel port dst=10.10.10.102 output:3 //local port
案2: インクリメンタルな更新のアルゴリズムを作る
for h in Hosts:
if old_vm.host == h:
h.del_flow(…)
else:
h.del_flow(…)
if new_vm.host == h:
h.add_flow(match=“dst={new_vm.ip}”,
action=“output:{new_vm.port}”)
else:
h.add_flow(match=“dst={new_vm.ip}”,
action=“output:{tunport}”)
どのようにフローテーブルをアップデートするか?
• 複雑になりがち
• エラー処理、部分障害、バッチ更新、等々…
• テーブルごとに専用のアルゴリズムが必要
• ovn_northd には47個、NSX には数百のテーブルが存在する
14©2020 VMware, Inc.
• コントロール -> データプレンのマッピング設定を宣言的行う
• マッピングを差分更新するために汎用的な推論エンジンを用いる
• プログラマは差分更新について心配する必要なし
解決策
”Differential Datalog”
15©2020 VMware, Inc.
一階述語論理にもとづいた宣言的論理プログラミング言語(DSL)
• しばしば Query Language として使われる
文法的には Prolog に似ているが、Prolog と違い、
• Function symbol がない
• 停止することが保証されている
• 説の順序は無関係
• リストの概念がない
• カット(!)や fail オペレータがない
Datalog
16©2020 VMware, Inc.
Datalog 入門
parent child
Anakin Luke
sibling1 sibling2
Table: Parent Table: Sibling
?
Sibling(c1,c2) :- Parent(p,c1),
Parent(p,c2),
c1 != c2.
Anakin Leia
Luke Leia
Leia Luke
Head Body
17©2020 VMware, Inc.
Datalog 入門
host match action
1 dst=10.10.10.101 output:2
1 dst=10.10.10.102 output:3
1 dst=10.10.10.103 output:1
2 dst=10.10.10.101 output:1
2 dst=10.10.10.102 output:1
2 dst=10.10.10.103 output:2
Table: Flow
vm ip host port
VM1 10.10.10.101 1 2
VM2 10.10.10.102 1 3
VM3 10.10.10.103 2 2
Table: VM
id
1
2
Table: Host
18©2020 VMware, Inc.
Datalog 入門
host match action
1 dst=10.10.10.101 output:2
1 dst=10.10.10.102 output:3
1 dst=10.10.10.103 output:1
2 dst=10.10.10.101 output:1
2 dst=10.10.10.102 output:1
2 dst=10.10.10.103 output:2
Table: Flow
Flow(h,”dst={ip}”,”output:{p}”) :-
Host(h),
VM(_, ip, h, p).
Flow(h,”dst={ip}”,”output:1”) :-
Host(h),
VM(_, ip, other_host, _),
other_host != h.
vm ip host port
VM1 10.10.10.101 1 2
VM2 10.10.10.102 1 3
VM3 10.10.10.103 2 2
Table: VM
id
1
2
Table: Host
VM2 10.10.10.102 2 3 1 dst=10.10.10.102 output:1
1 dst=10.10.10.102 output:3
19©2020 VMware, Inc.
Differential Datalog (a.k.a. DDlog)
Timely Dataflow
Differential Dataflow
Differential Datalog
低遅延な巡回データフロー計算モデル
大量のデータを効率よく処理し、任意の入力集合の変
化に素早く対応することができるデータ並列プログラ
ミングフレームワーク
Differential Dataflow にもとづく Datalog エンジン
20©2020 VMware, Inc.
DDlog による効果
よりメンテナンスし
易いコード
インクリメンタルな
更新による性能の向
上
21©2020 VMware, Inc.
C vs DDlog
struct band_entry {
int64_t rate;
int64_t burst_size;
const char *action;
};
static int
band_cmp(const void *band1_, const void *band2_)
{
const struct band_entry *band1p = band1_;
const struct band_entry *band2p = band2_;
if (band1p->rate != band2p->rate) {
return band1p->rate > band2p->rate ? -1 : 1;
} else if (band1p->burst_size != band2p->burst_size) {
return band1p->burst_size > band2p->burst_size ? -1 : 1;
} else {
return strcmp(band1p->action, band2p->action);
}
}
static bool
bands_need_update(const struct nbrec_meter *nb_meter,
const struct sbrec_meter *sb_meter)
{
if (nb_meter->n_bands != sb_meter->n_bands) {
return true;
}
/* A single band is the most common scenario, so speed up that
* check. */
if (nb_meter->n_bands == 1) {
struct nbrec_meter_band *nb_band = nb_meter->bands[0];
struct sbrec_meter_band *sb_band = sb_meter->bands[0];
return !(nb_band->rate == sb_band->rate
&& nb_band->burst_size == sb_band->burst_size
&& !strcmp(sb_band->action, nb_band->action));
}
/* Place the Northbound entries in sorted order. */
struct band_entry *nb_bands;
nb_bands = xmalloc(sizeof *nb_bands * nb_meter->n_bands);
for (size_t i = 0; i < nb_meter->n_bands; i++) {
struct nbrec_meter_band *nb_band = nb_meter->bands[i];
nb_bands[i].rate = nb_band->rate;
nb_bands[i].burst_size = nb_band->burst_size;
nb_bands[i].action = nb_band->action;
}
qsort(nb_bands, nb_meter->n_bands, sizeof *nb_bands, band_cmp);
/* Place the Southbound entries in sorted order. */
struct band_entry *sb_bands;
sb_bands = xmalloc(sizeof *sb_bands * sb_meter->n_bands);
for (size_t i = 0; i < sb_meter->n_bands; i++) {
struct sbrec_meter_band *sb_band = sb_meter->bands[i];
sb_bands[i].rate = sb_band->rate;
sb_bands[i].burst_size = sb_band->burst_size;
sb_bands[i].action = sb_band->action;
}
qsort(sb_bands, sb_meter->n_bands, sizeof *sb_bands, band_cmp);
bool need_update = false;
for (size_t i = 0; i < nb_meter->n_bands; i++) {
if (nb_bands[i].rate != sb_bands[i].rate
|| nb_bands[i].burst_size != sb_bands[i].burst_size
|| strcmp(nb_bands[i].action, nb_bands[i].action)) {
need_update = true;
goto done;
}
}
done:
free(nb_bands);
free(sb_bands);
return need_update;
}
/* Each entry in the Meter and Meter_Band tables in OVN_Northbound have
* a corresponding entries in the Meter and Meter_Band tables in
* OVN_Southbound.
*/
static void
sync_meters(struct northd_context *ctx)
{
struct shash sb_meters = SHASH_INITIALIZER(&sb_meters);
const struct sbrec_meter *sb_meter;
SBREC_METER_FOR_EACH (sb_meter, ctx->ovnsb_idl) {
shash_add(&sb_meters, sb_meter->name, sb_meter);
}
const struct nbrec_meter *nb_meter;
NBREC_METER_FOR_EACH (nb_meter, ctx->ovnnb_idl) {
bool new_sb_meter = false;
sb_meter = shash_find_and_delete(&sb_meters, nb_meter->name);
if (!sb_meter) {
sb_meter = sbrec_meter_insert(ctx->ovnsb_txn);
sbrec_meter_set_name(sb_meter, nb_meter->name);
new_sb_meter = true;
}
if (new_sb_meter || bands_need_update(nb_meter, sb_meter)) {
struct sbrec_meter_band **sb_bands;
sb_bands = xcalloc(nb_meter->n_bands, sizeof *sb_bands);
for (size_t i = 0; i < nb_meter->n_bands; i++) {
const struct nbrec_meter_band *nb_band = nb_meter->bands[i];
sb_bands[i] = sbrec_meter_band_insert(ctx->ovnsb_txn);
sbrec_meter_band_set_action(sb_bands[i], nb_band->action);
sbrec_meter_band_set_rate(sb_bands[i], nb_band->rate);
sbrec_meter_band_set_burst_size(sb_bands[i],
nb_band->burst_size);
}
sbrec_meter_set_bands(sb_meter, sb_bands, nb_meter->n_bands);
free(sb_bands);
}
sbrec_meter_set_unit(sb_meter, nb_meter->unit);
}
struct shash_node *node, *next;
SHASH_FOR_EACH_SAFE (node, next, &sb_meters) {
sbrec_meter_delete(node->data);
shash_delete(&sb_meters, node);
}
shash_destroy(&sb_meters);
}
/* Meter_Band table */
for (mb in nb.Meter_Band) {
sb.Out_Meter_Band(.uuid_name = uuid2str(mb._uuid),
.action = mb.action,
.rate = mb.rate,
.burst_size = mb.burst_size)
}
/* Meter table */
for (meter in nb.Meter) {
sb.Out_Meter(.name = meter.name,
.unit = meter.unit,
.bands = set_map_uuid2str(meter.bands))
}
22©2020 VMware, Inc.
DDlog によるパフォーマンスの改善
論理ポート追加にかかる時間
23©2020 VMware, Inc.
DDlog によるパフォーマンスの改善
論理ポート追加にかかる時間
DDlog
OVN
24©2020 VMware, Inc.
予定
• ovn-northd と ovn-controller のロジックを DDlog で実装
• Test、Test、and Test !!
– C バージョンと DDlog バージョンで同じフローテーブルが計算されるかを比較
• NSX-T での適用?
課題
• 新しいプログラミング・パラダイムの学習コスト
• 新しいツールチェーン(Rust、Haskel、デバッガ、etc.)
• C 実装への追従
今後の予定と課題
25©2020 VMware, Inc.
• “RFC: incremental computation for OVN with DDlog”, discussion on ovs-discuss mailing list,
– https://mail.openvswitch.org/pipermail/ovs-discuss/2018-November/047665.html
• “OVN Controller Incremental Processing”, Han Zhou, Open vSwitch 2018 Fall Conference
– http://www.openvswitch.org/support/ovscon2018/6/1350-zhou.pptx
• ”Toward Leaner, Faster ovn-northd”, Leonid Ryzhyk, OVS Orbit Episode 58
– https://ovsorbit.org/#e58
• “DDlog in OVN – Current State and Future Challenges”, OVS and OVN 2019 Fall Conference
– https://www.youtube.com/watch?v=Sf6QjyoZk34&feature=youtu.be
• Differential Datalog
– https://github.com/ryzhyk/differential-datalog
– https://research.vmware.com/files/attachments/0/0/0/0/0/8/8/ddlog.pdf
• Timely Dataflow & Differential Dataflow
– https://github.com/TimelyDataflow
– https://www.youtube.com/watch?v=nRp3EQy6ccw
References
©2020 VMware, Inc.
Thank You

More Related Content

PPTX
コンテナネットワーキング(CNI)最前線
PPTX
Dockerと外部ルータを連携させる仕組みを作ってみた
PPTX
ConfD で Linux にNetconfを喋らせてみた
PDF
Mastodonインスタンスをセットアップできるスタートアップスクリプトについて
PDF
Ansible npstudy-shtsuchi
PPTX
WebRTC getStats - WebRTC Meetup Tokyo 5 LT
PDF
Lagopus + DockerのDPDK接続
PDF
Bird in show_net
コンテナネットワーキング(CNI)最前線
Dockerと外部ルータを連携させる仕組みを作ってみた
ConfD で Linux にNetconfを喋らせてみた
Mastodonインスタンスをセットアップできるスタートアップスクリプトについて
Ansible npstudy-shtsuchi
WebRTC getStats - WebRTC Meetup Tokyo 5 LT
Lagopus + DockerのDPDK接続
Bird in show_net

What's hot (20)

KEY
Vyatta 改造入門
PDF
VTI の中身
PPTX
さくらのクラウドでVyOS使ってみた
PDF
「さくらのクラウド」におけるVyattaの活用事例
PDF
WebSocketプロトコル
PDF
10分で作るクラスライブラリ
PDF
HTTP/2, QUIC入門
PPTX
ネットワーク機器のAPIあれこれ入門 (NetOpsCoding#2)
PPTX
pipework - Advanced Docker Networking
PDF
VyOSでMPLS
PDF
Havana版 RDO-QuickStart-3 (140421-Havana-RDO-QuickStart-3.pdf)
PDF
自動でできるかな?
PDF
【さくらのクラウド】ローカルルータ導入ガイド
PDF
いまさら聞けないNGINXコンフィグ_F5-NGINX-Community-20200805
PDF
第20回 OpenStack勉強会 Neutron Deep Dive - DVR
PDF
OpenStack Neutronの機能概要 - OpenStack最新情報セミナー 2014年12月
PDF
Havana版 RDO-QuickStart-4 (140421-Havana-RDO-QuickStart-4.pdf)
PDF
「Photon OS + Docker」VLAN 環境の構築
PDF
「Docker +VLAN 環境」アプリケーション実行環境の構築
PDF
さくらのクラウドインフラの紹介
Vyatta 改造入門
VTI の中身
さくらのクラウドでVyOS使ってみた
「さくらのクラウド」におけるVyattaの活用事例
WebSocketプロトコル
10分で作るクラスライブラリ
HTTP/2, QUIC入門
ネットワーク機器のAPIあれこれ入門 (NetOpsCoding#2)
pipework - Advanced Docker Networking
VyOSでMPLS
Havana版 RDO-QuickStart-3 (140421-Havana-RDO-QuickStart-3.pdf)
自動でできるかな?
【さくらのクラウド】ローカルルータ導入ガイド
いまさら聞けないNGINXコンフィグ_F5-NGINX-Community-20200805
第20回 OpenStack勉強会 Neutron Deep Dive - DVR
OpenStack Neutronの機能概要 - OpenStack最新情報セミナー 2014年12月
Havana版 RDO-QuickStart-4 (140421-Havana-RDO-QuickStart-4.pdf)
「Photon OS + Docker」VLAN 環境の構築
「Docker +VLAN 環境」アプリケーション実行環境の構築
さくらのクラウドインフラの紹介
Ad

Similar to 宣言的(Declarative)ネットワーキング (20)

KEY
Openvswitch vps 20120429資料
PDF
Cloud stack徹底入門7章 20130514
PDF
OpenIndiana+KVMによる仮想マシン
PPTX
FD.io VPP事始め
PPTX
VPP事始め
PPTX
Trema での Open vSwitch
PDF
配布用Beginnerならきっと役立つmaster slave環境
PDF
もしCloudStackのKVMホストでPCIパススルーできるようになったら
KEY
P2Pって何?
PDF
Hol012 windowsコンテナー始動
PDF
東京Node学園#3 Domains & Isolates
KEY
OpenvswitchでVPS
ODP
Xen4.0 and vt-d Network Performance Benchmark
PDF
AWS + Windows(C#)で構築する.NET最先端技術によるハイパフォーマンスウェブアプリケーション開発実践
PDF
OpenStack Kilo with 6Wind VA High-Performance Networking Using DPDK - OpenSta...
PDF
Apache cloudstack4.0インストール
PDF
Docker ComposeでMastodonが必要なものを梱包する話
ODP
Bhyve code reading
PDF
osoljp 2011.08
PDF
openstack_neutron-ovs_osc2014tf_20141019
Openvswitch vps 20120429資料
Cloud stack徹底入門7章 20130514
OpenIndiana+KVMによる仮想マシン
FD.io VPP事始め
VPP事始め
Trema での Open vSwitch
配布用Beginnerならきっと役立つmaster slave環境
もしCloudStackのKVMホストでPCIパススルーできるようになったら
P2Pって何?
Hol012 windowsコンテナー始動
東京Node学園#3 Domains & Isolates
OpenvswitchでVPS
Xen4.0 and vt-d Network Performance Benchmark
AWS + Windows(C#)で構築する.NET最先端技術によるハイパフォーマンスウェブアプリケーション開発実践
OpenStack Kilo with 6Wind VA High-Performance Networking Using DPDK - OpenSta...
Apache cloudstack4.0インストール
Docker ComposeでMastodonが必要なものを梱包する話
Bhyve code reading
osoljp 2011.08
openstack_neutron-ovs_osc2014tf_20141019
Ad

More from Motonori Shindo (20)

PPTX
おうち Lab で GitDNSOps / GitDNS Ops in My Home Lab
PPTX
Tanzu Mission Control における Open Policy Agent (OPA) の利用
PDF
Open Policy Agent (OPA) と Kubernetes Policy
PDF
Open Policy Agent (OPA) 入門
PPTX
急速に進化を続けるCNIプラグイン Antrea
PPTX
Cluster API によるKubernetes環境のライフサイクル管理とマルチクラウド環境での適用
PPTX
Service Mesh for Enterprises / Cloud Native Days Tokyo 2019
PDF
Idea Hackathon at vFORUM 2019 Tokyo
PPTX
Containers and Virtual Machines: Friends or Enemies?
PPTX
Open Source Projects by VMware
PPTX
Serverless Framework "Disptach" の紹介
PPTX
フロー技術によるネットワーク管理
PDF
Viptela 顧客事例
PDF
ViptelaのSD-WANとクラウド最適化ネットワーク
PDF
OpenStack Congress and Datalog (English)
PDF
OpenStack Congress and Datalog (Japanese)
PPTX
L2 over l3 ecnaspsulations (english)
PDF
L2 over L3 ecnaspsulations
PDF
VMware NSXがサポートするトンネル方式について
PPTX
CloudStack 4.1 + NVP Integration
おうち Lab で GitDNSOps / GitDNS Ops in My Home Lab
Tanzu Mission Control における Open Policy Agent (OPA) の利用
Open Policy Agent (OPA) と Kubernetes Policy
Open Policy Agent (OPA) 入門
急速に進化を続けるCNIプラグイン Antrea
Cluster API によるKubernetes環境のライフサイクル管理とマルチクラウド環境での適用
Service Mesh for Enterprises / Cloud Native Days Tokyo 2019
Idea Hackathon at vFORUM 2019 Tokyo
Containers and Virtual Machines: Friends or Enemies?
Open Source Projects by VMware
Serverless Framework "Disptach" の紹介
フロー技術によるネットワーク管理
Viptela 顧客事例
ViptelaのSD-WANとクラウド最適化ネットワーク
OpenStack Congress and Datalog (English)
OpenStack Congress and Datalog (Japanese)
L2 over l3 ecnaspsulations (english)
L2 over L3 ecnaspsulations
VMware NSXがサポートするトンネル方式について
CloudStack 4.1 + NVP Integration

宣言的(Declarative)ネットワーキング

  • 1. ©2020 VMware, Inc. 宣言的(Declarative)ネットワーキング Jan. 22, 2020 CTO, North Asia (Japan, Korea and Greater China) Motonori Shindo (@motonori_shindo) OVN のコントロールプレーンの例
  • 2. 2©2020 VMware, Inc. ネットワークは非常に複雑な分散型システム ・非同期に起こる多重障害の可能性 ・一部の操作は冪等ではない さまざまな実装を試したが、最もうまく動いたのは Dalalog をベースにした Nlog というエンジンを使った宣言的なコン トローラであった。 Nicira のコントローラ (NVP) はどう動いていたか? Napkin Talk with Martin Casado Source: Computer History Museum
  • 3. 3©2020 VMware, Inc. オープンソースな仮想ネットワークの実装 Open vSwitch (OVS) と共に開発されている(主に C で記述) 主な機能: • 論理スイッチ • 論理ルータ(IPv4、IPv6) • オーバーレイネットワーク • ACL • Native NAT、Load Balancer、DHCP • L2、L3 ゲートウェイ • DPDK 対応 • Linux / Hyper-V で利用可能 • 複数のオーケストレータ(OpenStack、Kubernetes、Docker、Mesos、oVirt など)に対応 OVN (Open Virtual Network) とは
  • 4. 4©2020 VMware, Inc. OVN のアーキテクチャ HV-1 ovn-northd ovn-controller ovsdb- server ovs- vswitchd HV-n ovn-controller ovsdb- server ovs- vswitchd CMS Desired State: Logical Switch Logical Port Logical Router Logical Router Port ACL Runtime State: Chassis Datapath Binding Encap Logical Flow Multicast Group Port Binding • Converts NB DB -> SB DB • Generates Logical Flow South Bound DB North Bound DB South Bound DB South Bound DB ・・・・・・・・・・・・・・・・・ • Register Chassis & VIFs to SB DB • Converts logical flow -> physical flows • Push config to local OVSDB and OF
  • 5. 5©2020 VMware, Inc. OVN 内部の動き lport1 br-int sw0-port2sw0-port1 00:00:00:00:00:0200:00:00:00:00:01 lport2 sw0 $ ovn-nbctl lswitch-add sw0 (論理スイッチ追加) $ ovn-nbctl lport-add sw0 sw0-port1 (論理ポートの追加) $ ovn-nbctl lport-add sw0 sw0-port2 $ ovn-nbctl lport-set-addresses sw0-port1 00:00:00:00:00:01 (MAC アドレスの設定) $ ovn-nbctl lport-set-addresses sw0-port2 00:00:00:00:00:02 $ ovn-nbctl lport-set-port-security sw0-port1 00:00:00:00:00:01 (Port Security の設定) $ ovn-nbctl lport-set-port-security sw0-port2 00:00:00:00:00:02 (Port Security の設定) $ ovs-vsctl add-port br-int lport1 -- set Interface lport1 (br-int にポートを追加し、 external_ids:iface-id=sw0-port1 インターフェースを接続) $ ovs-vsctl add-port br-int lport2 -- set Interface lport2 external_ids:iface-id=sw0-port2 ovn-northd South Bound DB North Bound DB South Bound DB South Bound DB Logical Switch Table Logical Flow Table Logical Port Table Chassis Table Encap Table Datapath Biding Table Port Binding Table
  • 6. 6©2020 VMware, Inc. VM / コンテナ環境は巨大かつ非常にダイナミック
  • 7. 7©2020 VMware, Inc. Host 1 Host 2 Controller tunnel 2 3 1 Match Action dst=10.10.10.101 output:1 //tunnel port dst=10.10.10.102 output:1 //tunnel port dst=10.10.10.103 output:2 //local port Match Action dst=10.10.10.101 output:2 //local port dst=10.10.10.102 output:3 //local port dst=10.10.10.103 output:1 //tunnel port 2 1 vm ip host port VM1 10.10.10.101 Host 1 2 VM2 10.10.10.102 Host 1 3 VM3 10.10.10.103 Host 2 2 Table: VM
  • 8. 8©2020 VMware, Inc. Host 1 Host 2 Controller tunnel 2 3 1 Match Action dst=10.10.10.101 output:1 //tunnel port dst=10.10.10.102 output:1 //tunnel port dst=10.10.10.103 output:2 //local port Match Action dst=10.10.10.101 output:2 //local port dst=10.10.10.102 output:3 //local port dst=10.10.10.103 output:1 //tunnel port 2 1 vm ip host port VM1 10.10.10.101 Host 1 2 VM2 10.10.10.102 Host 1 3 VM3 10.10.10.103 Host 2 2 Table: VM for h in Hosts: for vm in VM: if vm.host == h: h.add_flow(match=“dst={vm.ip}”,action=“output:{vm.port}”) else: h.add_flow(match=“dst={vm.ip}”,action=“output:{tunport}”)
  • 9. 9©2020 VMware, Inc. Host 1 Host 2 Controller tunnel 2 3 1 2 1 vm ip host port VM1 10.10.10.101 Host 1 2 VM2 10.10.10.102 Host 1 3 VM3 10.10.10.103 Host 2 2 Table: VM 3 Match Action dst=10.10.10.101 output:1 //tunnel port dst=10.10.10.102 output:1 //tunnel port dst=10.10.10.103 output:2 //local port Match Action dst=10.10.10.101 output:2 //local port dst=10.10.10.102 output:3 //local port dst=10.10.10.103 output:1 //tunnel port
  • 10. 10©2020 VMware, Inc. Host 1 Host 2 Controller tunnel 2 3 1 2 1 vm ip host port VM1 10.10.10.101 Host 1 2 VM2 10.10.10.102 Host 1 3 VM3 10.10.10.103 Host 2 2 Table: VM 3 VM2 10.10.10.102 Host 1 3Host 2 3 Match Action dst=10.10.10.101 output:1 //tunnel port dst=10.10.10.102 output:1 //tunnel port dst=10.10.10.103 output:2 //local port Match Action dst=10.10.10.101 output:2 //local port dst=10.10.10.102 output:3 //local port dst=10.10.10.103 output:1 //tunnel port dst=10.10.10.102 output:1 //tunnel port dst=10.10.10.102 output:3 //local port
  • 11. 11©2020 VMware, Inc. Host 1 Host 2 Controller tunnel 2 3 1 2 1 vm ip host port VM1 10.10.10.101 Host 1 2 VM2 10.10.10.102 Host 1 3 VM3 10.10.10.103 Host 2 2 Table: VM 3 VM2 10.10.10.102 Host 1 3Host 2 3 Match Action dst=10.10.10.101 output:1 //tunnel port dst=10.10.10.102 output:1 //tunnel port dst=10.10.10.103 output:2 //local port Match Action dst=10.10.10.101 output:2 //local port dst=10.10.10.102 output:3 //local port dst=10.10.10.103 output:1 //tunnel port dst=10.10.10.102 output:1 //tunnel port dst=10.10.10.102 output:3 //local port 案1: 全てのフローを1から再計算する for h in Hosts: for vm in VM: if vm.host == h: h.add_flow(match=“dst={vm.ip}”,action=“output:{vm.port}”) else: h.add_flow(match=“dst={vm.ip}”,action=“output:{tunport}”) どのようにフローテーブルをアップデートするか? • CPU サイクルの無駄遣い • ネットワーク帯域の無駄遣い • 設定遅延の増大
  • 12. 12©2020 VMware, Inc. Host 1 Host 2 Controller tunnel 2 3 1 2 1 vm ip host port VM1 10.10.10.101 Host 1 2 VM2 10.10.10.102 Host 1 3 VM3 10.10.10.103 Host 2 2 Table: VMs 3 VM2 10.10.10.102 Host 1 3Host 2 3 Match Action dst=10.10.10.101 output:1 //tunnel port dst=10.10.10.102 output:1 //tunnel port dst=10.10.10.103 output:2 //local port Match Action dst=10.10.10.101 output:2 //local port dst=10.10.10.102 output:3 //local port dst=10.10.10.103 output:1 //tunnel port dst=10.10.10.102 output:1 //tunnel port dst=10.10.10.102 output:3 //local port 案2: インクリメンタルな更新のアルゴリズムを作る for h in Hosts: if old_vm.host == h: h.del_flow(…) else: h.del_flow(…) if new_vm.host == h: h.add_flow(match=“dst={new_vm.ip}”, action=“output:{new_vm.port}”) else: h.add_flow(match=“dst={new_vm.ip}”, action=“output:{tunport}”) どのようにフローテーブルをアップデートするか?
  • 13. 13©2020 VMware, Inc. Host 1 Host 2 Controller tunnel 2 3 1 2 1 vm ip host port VM1 10.10.10.101 Host 1 2 VM2 10.10.10.102 Host 1 3 VM3 10.10.10.103 Host 2 2 Table: VMs 3 VM2 10.10.10.102 Host 1 3Host 2 3 Match Action dst=10.10.10.101 output:1 //tunnel port dst=10.10.10.102 output:1 //tunnel port dst=10.10.10.103 output:2 //local port Match Action dst=10.10.10.101 output:2 //local port dst=10.10.10.102 output:3 //local port dst=10.10.10.103 output:1 //tunnel port dst=10.10.10.102 output:1 //tunnel port dst=10.10.10.102 output:3 //local port 案2: インクリメンタルな更新のアルゴリズムを作る for h in Hosts: if old_vm.host == h: h.del_flow(…) else: h.del_flow(…) if new_vm.host == h: h.add_flow(match=“dst={new_vm.ip}”, action=“output:{new_vm.port}”) else: h.add_flow(match=“dst={new_vm.ip}”, action=“output:{tunport}”) どのようにフローテーブルをアップデートするか? • 複雑になりがち • エラー処理、部分障害、バッチ更新、等々… • テーブルごとに専用のアルゴリズムが必要 • ovn_northd には47個、NSX には数百のテーブルが存在する
  • 14. 14©2020 VMware, Inc. • コントロール -> データプレンのマッピング設定を宣言的行う • マッピングを差分更新するために汎用的な推論エンジンを用いる • プログラマは差分更新について心配する必要なし 解決策 ”Differential Datalog”
  • 15. 15©2020 VMware, Inc. 一階述語論理にもとづいた宣言的論理プログラミング言語(DSL) • しばしば Query Language として使われる 文法的には Prolog に似ているが、Prolog と違い、 • Function symbol がない • 停止することが保証されている • 説の順序は無関係 • リストの概念がない • カット(!)や fail オペレータがない Datalog
  • 16. 16©2020 VMware, Inc. Datalog 入門 parent child Anakin Luke sibling1 sibling2 Table: Parent Table: Sibling ? Sibling(c1,c2) :- Parent(p,c1), Parent(p,c2), c1 != c2. Anakin Leia Luke Leia Leia Luke Head Body
  • 17. 17©2020 VMware, Inc. Datalog 入門 host match action 1 dst=10.10.10.101 output:2 1 dst=10.10.10.102 output:3 1 dst=10.10.10.103 output:1 2 dst=10.10.10.101 output:1 2 dst=10.10.10.102 output:1 2 dst=10.10.10.103 output:2 Table: Flow vm ip host port VM1 10.10.10.101 1 2 VM2 10.10.10.102 1 3 VM3 10.10.10.103 2 2 Table: VM id 1 2 Table: Host
  • 18. 18©2020 VMware, Inc. Datalog 入門 host match action 1 dst=10.10.10.101 output:2 1 dst=10.10.10.102 output:3 1 dst=10.10.10.103 output:1 2 dst=10.10.10.101 output:1 2 dst=10.10.10.102 output:1 2 dst=10.10.10.103 output:2 Table: Flow Flow(h,”dst={ip}”,”output:{p}”) :- Host(h), VM(_, ip, h, p). Flow(h,”dst={ip}”,”output:1”) :- Host(h), VM(_, ip, other_host, _), other_host != h. vm ip host port VM1 10.10.10.101 1 2 VM2 10.10.10.102 1 3 VM3 10.10.10.103 2 2 Table: VM id 1 2 Table: Host VM2 10.10.10.102 2 3 1 dst=10.10.10.102 output:1 1 dst=10.10.10.102 output:3
  • 19. 19©2020 VMware, Inc. Differential Datalog (a.k.a. DDlog) Timely Dataflow Differential Dataflow Differential Datalog 低遅延な巡回データフロー計算モデル 大量のデータを効率よく処理し、任意の入力集合の変 化に素早く対応することができるデータ並列プログラ ミングフレームワーク Differential Dataflow にもとづく Datalog エンジン
  • 20. 20©2020 VMware, Inc. DDlog による効果 よりメンテナンスし 易いコード インクリメンタルな 更新による性能の向 上
  • 21. 21©2020 VMware, Inc. C vs DDlog struct band_entry { int64_t rate; int64_t burst_size; const char *action; }; static int band_cmp(const void *band1_, const void *band2_) { const struct band_entry *band1p = band1_; const struct band_entry *band2p = band2_; if (band1p->rate != band2p->rate) { return band1p->rate > band2p->rate ? -1 : 1; } else if (band1p->burst_size != band2p->burst_size) { return band1p->burst_size > band2p->burst_size ? -1 : 1; } else { return strcmp(band1p->action, band2p->action); } } static bool bands_need_update(const struct nbrec_meter *nb_meter, const struct sbrec_meter *sb_meter) { if (nb_meter->n_bands != sb_meter->n_bands) { return true; } /* A single band is the most common scenario, so speed up that * check. */ if (nb_meter->n_bands == 1) { struct nbrec_meter_band *nb_band = nb_meter->bands[0]; struct sbrec_meter_band *sb_band = sb_meter->bands[0]; return !(nb_band->rate == sb_band->rate && nb_band->burst_size == sb_band->burst_size && !strcmp(sb_band->action, nb_band->action)); } /* Place the Northbound entries in sorted order. */ struct band_entry *nb_bands; nb_bands = xmalloc(sizeof *nb_bands * nb_meter->n_bands); for (size_t i = 0; i < nb_meter->n_bands; i++) { struct nbrec_meter_band *nb_band = nb_meter->bands[i]; nb_bands[i].rate = nb_band->rate; nb_bands[i].burst_size = nb_band->burst_size; nb_bands[i].action = nb_band->action; } qsort(nb_bands, nb_meter->n_bands, sizeof *nb_bands, band_cmp); /* Place the Southbound entries in sorted order. */ struct band_entry *sb_bands; sb_bands = xmalloc(sizeof *sb_bands * sb_meter->n_bands); for (size_t i = 0; i < sb_meter->n_bands; i++) { struct sbrec_meter_band *sb_band = sb_meter->bands[i]; sb_bands[i].rate = sb_band->rate; sb_bands[i].burst_size = sb_band->burst_size; sb_bands[i].action = sb_band->action; } qsort(sb_bands, sb_meter->n_bands, sizeof *sb_bands, band_cmp); bool need_update = false; for (size_t i = 0; i < nb_meter->n_bands; i++) { if (nb_bands[i].rate != sb_bands[i].rate || nb_bands[i].burst_size != sb_bands[i].burst_size || strcmp(nb_bands[i].action, nb_bands[i].action)) { need_update = true; goto done; } } done: free(nb_bands); free(sb_bands); return need_update; } /* Each entry in the Meter and Meter_Band tables in OVN_Northbound have * a corresponding entries in the Meter and Meter_Band tables in * OVN_Southbound. */ static void sync_meters(struct northd_context *ctx) { struct shash sb_meters = SHASH_INITIALIZER(&sb_meters); const struct sbrec_meter *sb_meter; SBREC_METER_FOR_EACH (sb_meter, ctx->ovnsb_idl) { shash_add(&sb_meters, sb_meter->name, sb_meter); } const struct nbrec_meter *nb_meter; NBREC_METER_FOR_EACH (nb_meter, ctx->ovnnb_idl) { bool new_sb_meter = false; sb_meter = shash_find_and_delete(&sb_meters, nb_meter->name); if (!sb_meter) { sb_meter = sbrec_meter_insert(ctx->ovnsb_txn); sbrec_meter_set_name(sb_meter, nb_meter->name); new_sb_meter = true; } if (new_sb_meter || bands_need_update(nb_meter, sb_meter)) { struct sbrec_meter_band **sb_bands; sb_bands = xcalloc(nb_meter->n_bands, sizeof *sb_bands); for (size_t i = 0; i < nb_meter->n_bands; i++) { const struct nbrec_meter_band *nb_band = nb_meter->bands[i]; sb_bands[i] = sbrec_meter_band_insert(ctx->ovnsb_txn); sbrec_meter_band_set_action(sb_bands[i], nb_band->action); sbrec_meter_band_set_rate(sb_bands[i], nb_band->rate); sbrec_meter_band_set_burst_size(sb_bands[i], nb_band->burst_size); } sbrec_meter_set_bands(sb_meter, sb_bands, nb_meter->n_bands); free(sb_bands); } sbrec_meter_set_unit(sb_meter, nb_meter->unit); } struct shash_node *node, *next; SHASH_FOR_EACH_SAFE (node, next, &sb_meters) { sbrec_meter_delete(node->data); shash_delete(&sb_meters, node); } shash_destroy(&sb_meters); } /* Meter_Band table */ for (mb in nb.Meter_Band) { sb.Out_Meter_Band(.uuid_name = uuid2str(mb._uuid), .action = mb.action, .rate = mb.rate, .burst_size = mb.burst_size) } /* Meter table */ for (meter in nb.Meter) { sb.Out_Meter(.name = meter.name, .unit = meter.unit, .bands = set_map_uuid2str(meter.bands)) }
  • 22. 22©2020 VMware, Inc. DDlog によるパフォーマンスの改善 論理ポート追加にかかる時間
  • 23. 23©2020 VMware, Inc. DDlog によるパフォーマンスの改善 論理ポート追加にかかる時間 DDlog OVN
  • 24. 24©2020 VMware, Inc. 予定 • ovn-northd と ovn-controller のロジックを DDlog で実装 • Test、Test、and Test !! – C バージョンと DDlog バージョンで同じフローテーブルが計算されるかを比較 • NSX-T での適用? 課題 • 新しいプログラミング・パラダイムの学習コスト • 新しいツールチェーン(Rust、Haskel、デバッガ、etc.) • C 実装への追従 今後の予定と課題
  • 25. 25©2020 VMware, Inc. • “RFC: incremental computation for OVN with DDlog”, discussion on ovs-discuss mailing list, – https://mail.openvswitch.org/pipermail/ovs-discuss/2018-November/047665.html • “OVN Controller Incremental Processing”, Han Zhou, Open vSwitch 2018 Fall Conference – http://www.openvswitch.org/support/ovscon2018/6/1350-zhou.pptx • ”Toward Leaner, Faster ovn-northd”, Leonid Ryzhyk, OVS Orbit Episode 58 – https://ovsorbit.org/#e58 • “DDlog in OVN – Current State and Future Challenges”, OVS and OVN 2019 Fall Conference – https://www.youtube.com/watch?v=Sf6QjyoZk34&feature=youtu.be • Differential Datalog – https://github.com/ryzhyk/differential-datalog – https://research.vmware.com/files/attachments/0/0/0/0/0/8/8/ddlog.pdf • Timely Dataflow & Differential Dataflow – https://github.com/TimelyDataflow – https://www.youtube.com/watch?v=nRp3EQy6ccw References

Editor's Notes

  • #3: Rekhter and Kirk Lougheed in 1989