BGP in the Data Centerを読みました (6/6) : Chapter 6 - BGP on the Host
Chapter 5では、BGPの運用とトラブルシューティングについて見てきました。 最後のChapter 6では、BGPをホスト (サーバ) まで拡張する方法について見ていきます。
データセンタネットワーク全般については、”Cloud-Native Data Center Networking” を読むのがおすすめです。 筆者が同じ方で、 "BGP in the Data Center" に記載されている内容も含まれています。 この本はCumulus Networksにより無償で公開されています。 ぜひ読んでみてください。
Download your copy of latest book by Dinesh Dutt, "Cloud Native Data Center Networking." It's a 400-page must-read for all network architects, developers and operators. Don't miss out! #CumulusResources https://t.co/JwAAiOHh1f pic.twitter.com/nVJUZyw67Z
— CumulusNetworks (@CumulusNetworks) 2020年1月13日
各Chapterまとめ
- Chapter 1 - Introduction to Data Center Networks
- Chapter 2 - How BGP Has Been Adapted to the Data Center
- Chapter 3 - Building an Automatable BGP Configuration
- Chapter 4 - Reimagining BGP Configuration
- Chapter 5 - BGP Life Cycle Management
- Chapter 6 - BGP on the Host
従来のネットワーク運用者の管轄はToRスイッチまでであり、サーバの構成と管理はサーバ運用者の担当でした。 BGPをサーバで実行すると、サーバ運用者とネットワーク運用者が1人の統合的なデータセンタ運用者に置き換えられるか、 ネットワーク運用者がサーバ運用者と協力してホスト上でルーティングを設定する必要があります。 どちらの場合でも、ホスト上のBGPの設定によってネットワークの整合性が失われないようにすることが重要です。
仮想サービスの台頭
従来のデータセンタネットワークでは、ファイアウォールやロードバランサ等のサービスが展開される場所は、ブリッジング (L2) とルーティング (L3) の境界のaggregation switchでした。 ファイアウォールやロードバランサは専用アプライアンスであり、スケールインモデルで拡張されてきました。
Closネットワークでは、ファイアウォールやロードバランサなどのサービスは一般に、border leafに展開されます。
これらのサービスはBorder Leafエンドホスト上の仮想マシンあるいは非仮想化エンドホストとして提供されます。 トラフィック量の増減に合わせて、動的に仮想マシンの台数を増減できるスケールアウトモデルが採用されるようになっています。 同一サービスを複数の仮想マシンで動作させるために、同じIPアドレスであるエニーキャストアドレスを利用します。
エニーキャストアドレス
サービスを提供するサーバまたは仮想マシンは、データセンタ内のどこにでも展開される可能性があるため、 IPアドレスを単一のラックまたはルータに制限することはできません。 同じIPアドレスを複数のラックが広報する可能性があります。 パケットはECMPにより、サービスを提供している最も近くのノードのうち1つに流れます。
複数のエンドポイントによって広報されるこのIPアドレスは、 エニーキャストアドレスと呼ばれます。
マルチキャストやブロードキャストで複数の宛先に送信されるのとは対照的に、エニーキャストでは単一の宛先に送信されます。 選択される宛先はルーティングにより決定され、異なるエンドポイントは同じサービスを提供する異なるノードを選択することになります。
サブネットは通常ラックごとに割り当てられます。
Chapter 1のとおり1ラックあたり40台のサーバを収容すると、ToRは /26
のサブネットを広報することになります。
( /26
= 64個のIPアドレスがあれば40台のサーバにIPアドレスを割り当てられるという計算です。)
しかし、エニーキャストアドレスはサブネットアドレスではありません。 ToRスイッチがエニーキャストアドレスをどのように発見して広報するのか見ていきます。
サーバとのBGPピアリング
サーバとToRスイッチの間のBGPピアリングには2種類のモデルがあります。
- BGP unnumbered (Chapter 4)
- Dynamic neighbor
まずは、両方のモデルに共通している「ASNの割り当て方式」および「ToRスイッチとサーバの間の経路交換」について見ていきます。
ASNの割り当て方式
はじめに、サーバのASNの割り当て方式について見ていきます。
(スイッチのASNの割り当て方式についてはChapter 3で触れています。)
方式1: すべてのサーバに単一のASNを割り当てる
この方式は、設定および自動化が簡単かつ、サーバからの経路の識別とフィルタリングが容易です。
しかし、ホストに対しデフォルトルート以外も広報する必要がある場合、サーバの設定が複雑になります。 また、すべてのサーバが同じASNを共有するため、サーバがどの経路を広報したか追跡するのに手間がかかります。
方式2: 同じスイッチに接続されている (=同一ラック内の) すべてのサーバに単一のASNを割り当てる
この方法は、サーバがClosネットワークの追加の1つの層のように見えるのが利点です。
欠点は方式1と同様ですが、経路広報元のサーバを特定のラックに絞り込むことができます。
方式3: 各サーバに一意のASNを割り当てる
この方式は、Closネットワークの仕様に完全に適合しています。 どのサーバが経路広報しているのかを容易に識別可能です。
サーバ台数が膨大な場合は4-byte ASNを使用する必要があります。
経路交換モデル
次に、スイッチとサーバの間の経路交換について見ていきます。
スイッチがホストからどの経路を受け入れるかを制御しない場合、問題が発生する恐れがあります。
ホストが故意または過失によりデフォルトルート (または自身のものでない他のルート) を広報すると、 誤った宛先にトラフィックが流れる恐れがあります。
サーバに接続されているスイッチは、ホストへの過剰なルートのプッシュを防止するため、 サーバに対してデフォルトルートのみを広報します。 ホストに大量の経路情報が載っている場合、 経路情報が変更されるたびにベストパス計算が必要になってしまいます。
これらの問題に対処するため、Chapter 3と同様にルーティングポリシーを適用します。
ToRスイッチが peer-group SERVERS
に属するneighbor (= サーバ) から受け入れる経路は、 ANYCAST_VIP
で定義されているエニーキャストアドレスのみです。
そして、peer-group SERVERS
に属するneighborに対しては、デフォルトルートのみを広報します。
# デフォルトルートの広報、エニーキャストアドレスの経路の受信に関するleafスイッチの設定の抜粋 dc-leaf-01:~$ sudo cat /etc/frr/frr.conf frr version 7.0+cl4u11 frr defaults datacenter hostname dc-leaf01 ! router bgp 4210000001 bgp router-id 10.0.254.1 no bgp default ipv4-unicast bgp bestpath as-path multipath-relax neighbor SERVERS peer-group neighbor SERVERS remote-as external ! address-family ipv4 unicast neighbor SERVERS activate neighbor SERVERS default-originate # SERVERSに自身をネクストホップとするデフォルトルートを広報 neighbor SERVERS route-map ADVERTISE_DEFONLY out # デフォルトルートのみをSERVERSに広報するroute-mapを適用 neighbor SERVERS route-map ACCEPT_ONLY_ANYCAST in # エニーキャストアドレスのみをSERVERSに広報するroute-mapを設定 exit-address-family ! ! ip prefix-list ANYCAST_VIP seq 5 permit 20.1.1.1/32 # prefix-listでエニーキャストアドレスを定義 ip prefix-list ANYCAST_VIP seq 10 permit 20.5.10.110/32 # prefix-listでエニーキャストアドレスを定義 ip prefix-list DEFONLY seq 5 permit 0.0.0.0/0 # prefix-listでデフォルトルートを定義 ! route-map ACCEPT_ONLY_ANYCAST permit 10 # エニーキャストアドレス用のroute-mapを定義 match ip address prefix-list ANYCAST_VIP ! route-map ADVERTISE_DEFONLY permit 10 # デフォルトルート用のroute-mapを定義 match ip address prefix-list DEFONLY !
サーバのBGPピアリングモデル
Dynamic neighbor
ラック内のサーバは通常、同一ラック内の他のサーバとサブネットを共有します (次の図)。
ToRスイッチに接続された40台のサーバが図のように 10.1.0.0/26
のサブネットに属する場合、ToRスイッチの設定は次のようになります (一部のみ抜粋) 。
# サーバ40台とのピアリングを1台ずつ設定した場合のleafスイッチの設定の抜粋 dc-leaf-01:~$ sudo cat /etc/frr/frr.conf frr version 7.0+cl4u11 frr defaults datacenter hostname dc-leaf01 ! router bgp 4210000001 router-id 10.0.254.1 no bgp default ipv4-unicast bgp bestpath as-path multipath-relax neighbor SERVERS peer-group neighbor SERVERS remote-as external neighbor 10.1.0.2 peer-group SERVERS # サーバ1台目 neighbor 10.1.0.3 peer-group SERVERS # サーバ2台目 (中略) neighbor 10.1.0.41 peer-group SERVERS # サーバ40台目 !
40台のサーバすべてをneighborに書くのは手間ですし、設定が長くなります。 これをシンプルにするためにBGP dynamic neighborを利用します。
BGPはTCP上で動作するため、一方のエンドが接続を開始し、もう一方は結果的にパッシブに接続されることになります。 (両エンドが同時に接続を開始した場合はconnection collisionが発生するため、片方のBGPセッションは切断します。)
dynamic neighborは一部の実装でサポートされる機能です。 dynamic neighborが設定されたノードは、他のノードからのBGPの接続要求を受け入れますが、自身から動的に接続を開始しません。
ToRスイッチに接続された40台のサーバが図のように 10.1.0.0/26
のサブネットに属する場合、
ToRスイッチのBGP dynamic neighborの設定は次のとおりです。接続を受け入れるサブネットは peer-group SERVERS
に関連付けられます。
# leafスイッチのDynamic neighborの設定の抜粋 dc-leaf-01:~$ sudo cat /etc/frr/frr.conf frr version 7.0+cl4u1 frr defaults datacenter hostname dc-leaf-01 ! router bgp 4210000001 bgp router-id 10.0.254.1 no bgp default ipv4-unicast bgp bestpath as-path multipath-relax neighbor SERVERS peer-group neighbor SERVERS remote-as 4220000000 # peer-group SERVERSのASNは4220000000 neighbor swp1 interface peer-group ISL neighbor swp2 interface peer-group ISL bgp listen range 10.1.0.0/26 peer-group SERVERS # peer-group SERVERSで10.1.0.0/26のサブネットのみBGP接続を受け入れる !
BGPデーモンは、port 179 (well-known BGP port) でlistenし始めます。
BGPデーモンは、サブネットが 10.1.0.0/26
でASNが 4220000000
である接続要求を受け入れるとBGPセッションが確立されます。
サーバ側では、スイッチのピアリングIPアドレスは通常、デフォルトゲートウェイです。
サブネット 10.1.0.0/26
のゲートウェイアドレスは通常 10.1.0.1
です。
そのため、サーバのBGP設定は次のとおりです。
# サーバのBGP設定 dc-server-01:~$ sudo cat /etc/frr/frr.conf frr version 7.4-dev-MyOwnFRRVersion frr defaults traditional hostname dc-server-01 ! interface ens4.10 ip address 10.1.0.2/26 # ToRスイッチとサーバはVLAN10 (10.1.0.0/26) で接続 ! interface lo ip address 20.1.1.1/32 # エニーキャストアドレスをloに割り当て ! router bgp 4220000000 bgp route-id 10.1.0.2 no bgp default ipv4-unicast neighbor ISL peer-group neighbor ISL remote-as external neighbor 10.1.0.1 peer-group ISL # ToRスイッチ (10.1.0.1) とBGPセッションを確立 ! address-family ipv4 unicast redistribute connected route-map ADV_LO # エニーキャストアドレスを広報 neighbor ISL activate exit-address-family ! route-map ADV_LO permit 10 # エニーキャストアドレス広報用のroute-map match interface lo !
サーバ上で実行されているBGPデーモンがスイッチへの接続を開始し、BGPセッションが確立されます。
なお、dynamic neighborでは、インタフェース名によるneighborの指定はサポートされていません。
例えば、bgp listen interface vlan 10 peer-group SERVERS
は使用できません。
インタフェース名をneighborとして使用するFRRoutingのトリックは、
/30
または /31
のサブネットでのみ機能する (Chapter 3参照) ため、
サーバ側でインタフェース名を指定することもできません。
dynamic neighborがサポートするピア数の上限は bgp listen limit limit-number
で制限可能です。
この制限は、スイッチに予定より大きな負荷をかけてしまうことを防ぐために設定します。
bgp listen limit 20` #dynamic neighborを20台まで許可
dynamic neighborの利点は、single attach serverモデル (Chapter 1参照) や、 PXE (Preboot Execution Environment) を介したサーバの起動がうまく機能する点です。
Dynamic neighborの検証
図のような環境を構築し、dynamic neighborの動作を検証しました。
leafとサーバの間はVLANを利用して、 /26
の同一サブネットを構築しています。
検証ではVLAN ID 10を使用しました。
Spineノードの設定
spineの設定は、これまでのChapterで見てきたBGP unnumberedと同様です。spine-01の設定は次のとおりです。
dc-spine-01~$ sudo cat /etc/frr/frr.conf frr version 7.0+cl4u1 frr defaults datacenter hostname dc-spine-01 log syslog informational service integrated-vtysh-config ! router bgp 4200000000 bgp router-id 10.0.254.254 no bgp default ipv4-unicast bgp bestpath as-path multipath-relax neighbor ISL peer-group neighbor ISL remote-as external neighbor ISL bfd neighbor ISL timers connect 5 neighbor ISL capability extended-nexthop neighbor swp1 interface peer-group ISL neighbor swp2 interface peer-group ISL neighbor swp3 interface peer-group ISL neighbor swp4 interface peer-group ISL ! address-family ipv4 unicast redistribute connected route-map ADV_LO neighbor ISL activate maximum-paths 64 exit-address-family ! address-family ipv6 unicast redistribute connected neighbor ISL activate maximum-paths 64 exit-address-family ! route-map ADV_LO permit 10 match interface lo ! line vty !
Leafノードの設定
これまでChapter 6で見てきたとおり、leafは、サーバ用にdynamic neighborを受け入れる設定をします。
また、spineとの間 ( peer-group ISL
) はBGP unnumberedを設定します。
dc-leaf-01~$ sudo cat /etc/frr/frr.conf [sudo] password for cumulus: frr version 7.0+cl4u1 frr defaults datacenter hostname dc-leaf-01 log syslog informational service integrated-vtysh-config ! router bgp 4210000001 bgp router-id 10.0.254.1 no bgp default ipv4-unicast bgp bestpath as-path multipath-relax neighbor ISL peer-group neighbor ISL remote-as external neighbor ISL bfd neighbor ISL timers connect 5 neighbor ISL capability extended-nexthop neighbor SERVERS peer-group neighbor SERVERS remote-as 4220000000 neighbor swp1 interface peer-group ISL neighbor swp2 interface peer-group ISL bgp listen limit 20 bgp listen range 10.1.0.0/26 peer-group SERVERS ! address-family ipv4 unicast redistribute connected route-map ACCEPT_DC_LOCAL neighbor ISL activate neighbor SERVERS activate neighbor SERVERS default-originate neighbor SERVERS route-map ACCEPT_ONLY_ANYCAST in neighbor SERVERS route-map ADVERTISE_DEFONLY out maximum-paths 64 exit-address-family ! address-family ipv6 unicast redistribute connected neighbor ISL activate maximum-paths 64 exit-address-family ! ip prefix-list ANYCAST_VIP seq 5 permit 20.1.1.1/32 ip prefix-list ANYCAST_VIP seq 10 permit 20.5.10.110/32 ip prefix-list DC_LOCAL_SUBNET seq 5 permit 10.1.0.0/16 ge 26 ip prefix-list DC_LOCAL_SUBNET seq 10 permit 10.0.254.0/24 ge 32 ip prefix-list DEFONLY seq 5 permit 0.0.0.0/0 ! route-map ACCEPT_DC_LOCAL permit 10 match ip address prefix-list DC_LOCAL_SUBNET ! route-map ACCEPT_ONLY_ANYCAST permit 10 match ip address prefix-list ANYCAST_VIP ! route-map ADVERTISE_DEFONLY permit 10 match ip address prefix-list DEFONLY ! line vty !
サーバとの接続用にVLAN ID 10のVLANインタフェース (SVI) を作成しています。
dc-leaf-01~$ sudo cat /etc/network/interfaces auto lo iface lo inet loopback address 10.254.0.1/32 auto swp1 iface swp1 auto swp2 iface swp2 auto swp3 iface swp3 auto bridge iface bridge bridge-ports swp3 bridge-vids 10 bridge-vlan-aware yes auto vlan10 iface vlan10 address 10.1.0.1/26 vlan-id 10 vlan-raw-device bridge
サーバの設定
サーバにはUbuntu 18.04を利用しました。FRRoutingの設定は次のとおりです。
ループバックインタフェース lo
にエニーキャストアドレスを設定したため、 route-id
は異なる一意の値を定義しています。
user@dc-server-01:~$ sudo cat /etc/frr/frr.conf frr version 7.4-dev-MyOwnFRRVersion frr defaults traditional hostname dc-server-01 log syslog informational service integrated-vtysh-config ! vrf mgmt ip route 0.0.0.0/0 192.168.20.1 exit-vrf ! interface ens3 ip address 192.168.20.120/24 ! interface ens4.10 ip address 10.1.0.2/26 ! interface lo ip address 20.1.1.1/32 ! router bgp 4220000000 bgp router-id 10.1.0.2 no bgp default ipv4-unicast neighbor ISL peer-group neighbor ISL remote-as external neighbor 10.1.0.1 peer-group ISL ! address-family ipv4 unicast redistribute connected route-map ADV_LO neighbor ISL activate exit-address-family ! route-map ADV_LO permit 10 match interface lo ! line vty !
BGPの状態を確認
spineとサーバの両方とBGPセッションを確立しているleafにて、BGPセッションの状態を確認してみます。 leaf-01のBGPセッションは次のとおりです。
dc-leaf-01~$ sudo vtysh -c 'show ip bgp summary' IPv4 Unicast Summary: BGP router identifier 10.0.254.1, local AS number 4210000001 vrf-id 0 BGP table version 11 RIB entries 18, using 3312 bytes of memory Peers 3, using 62 KiB of memory Peer groups 2, using 128 bytes of memory Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd dc-spine-01(swp1) 4 4200000000 12 16 0 0 0 00:00:04 6 dc-spine-02(swp2) 4 4200000000 11 15 0 0 0 00:00:03 6 *dc-server-01(10.1.0.2) 4 4220000000 8 6 0 0 0 00:00:03 1 Total number of neighbors 3 * - dynamic neighbor 1 dynamic neighbor(s), limit 20
FIBの確認
BGPセッションが確立できているので、次にFIBの状態を確認します。
spineノードのFIBは次のとおりです。 leaf4台のループバックアドレス、そしてサーバの2つのエニーキャストアドレスに対する経路がインストールされています。 エニーキャストアドレス宛のパケットはECMPにしたがいバランシングされます。
dc-spine-01~$ ip -4 route show 10.1.0.0/26 via 169.254.0.1 dev swp1 proto bgp metric 20 onlink 10.1.1.0/26 via 169.254.0.1 dev swp2 proto bgp metric 20 onlink 10.1.2.0/26 via 169.254.0.1 dev swp3 proto bgp metric 20 onlink 10.1.3.0/26 via 169.254.0.1 dev swp4 proto bgp metric 20 onlink 20.1.1.1 proto bgp metric 20 nexthop via 169.254.0.1 dev swp2 weight 1 onlink nexthop via 169.254.0.1 dev swp1 weight 1 onlink 20.5.10.110 proto bgp metric 20 nexthop via 169.254.0.1 dev swp3 weight 1 onlink nexthop via 169.254.0.1 dev swp4 weight 1 onlink
leafノードのFIBは次のとおりです。 spine, leaf, そしてサーバのエニーキャストアドレスに対する経路を持っています。 直接接続されているサーバのエニーキャストアドレスへのパスは1つのみです。
cumulus@dc-leaf-01~$ ip -4 route show 10.0.254.253 via 169.254.0.1 dev swp2 proto bgp metric 20 onlink 10.0.254.254 via 169.254.0.1 dev swp1 proto bgp metric 20 onlink 10.1.0.0/26 dev vlan10 proto kernel scope link src 10.1.0.1 10.1.1.0/26 proto bgp metric 20 nexthop via 169.254.0.1 dev swp1 weight 1 onlink nexthop via 169.254.0.1 dev swp2 weight 1 onlink 10.1.2.0/26 proto bgp metric 20 nexthop via 169.254.0.1 dev swp1 weight 1 onlink nexthop via 169.254.0.1 dev swp2 weight 1 onlink 10.1.3.0/26 proto bgp metric 20 nexthop via 169.254.0.1 dev swp1 weight 1 onlink nexthop via 169.254.0.1 dev swp2 weight 1 onlink 20.1.1.1 via 10.1.0.2 dev vlan10 proto bgp metric 20 20.5.10.110 proto bgp metric 20 nexthop via 169.254.0.1 dev swp1 weight 1 onlink nexthop via 169.254.0.1 dev swp2 weight 1 onlink
最後に、サーバのFIBを確認します。 サーバの経路情報は次のとおりです。 サーバはleafからデフォルトルートのみを学習しています。
dc-server-01:~$ ip -4 route show default via 10.1.0.1 dev ens4.10 proto 186 metric 20 10.1.0.0/26 dev ens4.10 proto kernel scope link src 10.1.0.2
エニーキャストアドレスの動作確認
ping
により簡易的にエニーキャストアドレスの動作を確認します。
2台のサーバからエニーキャストアドレス 20.5.10.110
宛に ping
を実行します。
送信元には ens4.10
のIPアドレスを利用します。
dc-server-01:~$ ping 20.5.10.110 -I ens4.10
dc-server-02:~$ ping 20.5.10.110 -I ens4.10
宛先のエニーキャストアドレスが設定されているサーバ側で tcpdump
してみると、それぞれの送信元から宛先へバランシングしていることが確認できました。
BGP unnumbered
スイッチ間のBGPセッションと同様に、サーバとスイッチの間でもBGP unnumberedを使用してBGPセッションを確立できます。 BGP uunumberedは、LinuxのFRRoutingで動作します。
dynamic neighborの共有サブネットと異なり、BGP unnumberedでは共有のサブネットは使用しません。 スイッチとのピアリングにはIPv6リンクローカルアドレスが使用されます。
ルータのように、サーバのIPアドレスはインタフェースから独立しており、ループバックアドレスが割り当てらます。
すべてのサーバに独立した /32
のIPアドレスを割り当てることができます。
スイッチ側の設定は次のとおりです。
router bgp 4210000001
...
neighbor SERVERS peer-group
neighbor SERVERS remote-as external
neighbor swp3 peer-group SERVERS
neighbor swp4 peer-group SERVERS
...
サーバ側の設定は次のとおりです。
router bgp 4220000001
...
neighbor ens4 remote-as external
...
BGP unnumberedの利点は、ブリッジングを完全に排除してルーティングのみでデータセンタネットワークを構築できることです。 dual-attached serverの場合にもMLAGとLACPを使用する必要はありません。 サーバとスイッチの間にVLANは不要です。
欠点は、DHCPv4やPXE-booted serverのサポートが難しい点です。 PXE-boot中はルーティングスタックがなく、スイッチが特定のサーバにパケットを転送する方法を知りません。 解決策はこの本の範囲外です。
これまでのChapterで見てきたBGP unnumberedと設定が同様であるため、動作検証は割愛します。
ホスト上のルーティングソフトウェア
サーバ上で稼働させるBGPは単なるBGPスピーカーであればよく、ベストパス計算、ルーティングテーブルへの経路プログラミング等のフル機能を実装する必要はありません。 先駆者はこれを認識し、BGPスピーカーとしてのみ機能していたExaBGPなどのソフトウェアを実行していました (参考) 。
今日では、FRRoutingやBIRD、GoBGPといったフル機能をサポートするオープンソースルーティングスイートがLinuxやBSDのサーバで利用可能です。
まとめ
- サーバでルーティングプロトコルを動作させることにより、ネットワーク運用とサーバ運用のような運用部門の分け方からは変更が求められる
- 仮想サービスの台頭により、ファイアウォールやロードバランサもスケールアウトモデルを採用するようになった
- サービスにはエニーキャストアドレスを割り当てて利用する
- 過剰なルートのプッシュを防止するため、サーバにはデフォルトルートのみを広報する
- サーバとBGPのピアリングモデルにはDynamic neighborとBGP unnumberedの2種類がある
- Dynamic neighborはサーバのPXE-bootがうまく機能する
- BGP unnumberedではL3を完全に撤廃できる
- サーバ上で稼働させるBGPはフル機能を実装する必要はない
- しかし、今日ではフル機能をサポートするFRRouting等のオープンソースルーティングスイートが利用可能