拡張性の高い CNI プラグイン Coil v2 の紹介

Ae03eb47606f4e0125268d39f8aebfad?s=47 ymmt2005
October 28, 2020

拡張性の高い CNI プラグイン Coil v2 の紹介

Kubernetes Meetup Tokyo #35 登壇資料
https://k8sjp.connpass.com/event/191298/

Ae03eb47606f4e0125268d39f8aebfad?s=128

ymmt2005

October 28, 2020
Tweet

Transcript

  1. 拡張性の高い CNI プラグイン Coil v2 の紹介 サイボウズ株式会社 山本泰宇 @ymmt2005 1

    Kubernetes Meetup Tokyo #35
  2. About me 2 ▌@ymmt2005 ▌サイボウズで Neco プロジェクトを指揮 ⚫Kubernetes ネイティブなデータセンター ⚫ネットワークやストレージを

    k8s 上に実装 Kubernetes Meetup Tokyo #35
  3. Agenda 3 ▌Kubernetes Network の基礎と実装 ▌サイボウズにおける組み合わせ実例 ▌Coil v2 ⚫機能および実装 ⚫デモ

    Kubernetes Meetup Tokyo #35
  4. Kubernetes Network の基礎 4 Kubernetes Meetup Tokyo #35

  5. The Kubernetes network model 5 ▌3つの条件を満たす実装なら何でもよい ⚫ Pods on a

    node can communicate with all pods on all nodes without NAT ⚫ Agents on a node (e.g. system daemons, kubelet) can communicate with all pods on that node ⚫ Pods in the host network of a node can communicate with all pods on all nodes without NAT ▌実装次第なもの ⚫IP アドレスの割り当て方式 ⚫Pod と Node の通信方式 ⚫ルーティング方式 ⚫外部ネットワークとの通信方式 Kubernetes Meetup Tokyo #35
  6. Kubernetesのネットワーク機能 6 ▌Pod 間通信 ▌NetworkPolicy ▌Service (UDP/TCP LoadBalancer) ▌Ingress (HTTP

    LoadBalancer) Kubernetes Meetup Tokyo #35 あれ、Egress は・・? ☞標準仕様はありません
  7. Container Networking Interface (CNI) 7 ▌ネットワーク機能をプラグインする規格 ▌インタフェースはコマンド呼び出し ⚫kubelet や containerd

    がプラグインを直接実行 ▌複数のプラグインを数珠繋ぎできる Kubernetes Meetup Tokyo #35
  8. CNI の設定例 (JSON) 8 { "cniVersion": "0.4.0", "name": "k8s-pod-network", "plugins":

    [ { "type": "coil", }, { "type": "tuning", "mtu": 1400 }, { "type": "bandwidth", "capabilities": {"bandwidth": true} } ] } /opt/cni/bin にあるコマンド名 Pod のアノテーション で bandwidth 制御 apiVersion: v1 kind: Pod metadata: annotations: kubernetes.io/ingress-bandwidth: 1M kubernetes.io/egress-bandwidth: 1M ... Kubernetes Meetup Tokyo #35
  9. 代表的な実装方式 9 Kubernetes Meetup Tokyo #35

  10. IP アドレスの割り当て方式 (IPAM) 10 ▌各ノードに Pod 用サブネットを割り当て ⚫node.spec.podCIDR フィールドで指定 ⚫kube-controller-manager

    に割り当てさせることも可能 ▌アドレスプール方式 ⚫用途に応じたプールを複数定義 ⚫グローバル IP アドレスを一部 Pod に割り当てる等 Kubernetes Meetup Tokyo #35 Flannel 他 Calico: Node 単位 Coil: Namespace 単位
  11. Pod と Node の通信方式 11 ▌Linux Bridge ⚫node.spec.podCIDR の通信をブリッジ内で行う ⚫Node

    やブロードキャスト用アドレスが必要 ▌Point-to-point 方式 ⚫Veth 両端にリンクローカルアドレスを付与 ⚫Veth ひとつひとつをルーティングテーブルに登録 Kubernetes Meetup Tokyo #35 ちょっともったいない
  12. Bridge vs Point-to-Point 12 Kubernetes Meetup Tokyo #35 Node bridge

    Pod Pod Pod 10.1.2.0/24 10.1.2.1 10.1.2.2 10.1.2.3 10.1.2.4 Bridge は .0, .1, .255 が使えない 10.1.2.2 → Veth1 10.1.2.3 → Veth2 10.1.2.4 → Veth3 Pod Pod Pod 10.1.2.2 10.1.2.3 10.1.2.4 10.1.2.0/24 のアドレスすべて利用できる 169.254.1.1 169.254.1.1 169.254.1.1 169.254.1.2 169.254.1.2 169.254.1.2 Veth1 Veth2 Veth3
  13. ルーティング方式 13 ▌オーバーレイネットワーク ⚫Pod 間通信のパケットを IPIP などでカプセル化 ⚫ノード間通信ができる環境ならどこでも動作 ▌BGP 等で経路広告

    ⚫各ノードに割り当てられた Pod アドレスを広告 ⚫既存ネットワークにうまく適合させる必要がある Kubernetes Meetup Tokyo #35 お手軽だけど遅め
  14. 外部ネットワークへの通信 14 ▌Node NAT 方式 ⚫外部向けのパケットを Node のアドレスでNAT ⚫ノードが外部に通信できることが前提 ▌Gateway

    方式 ⚫特定の Pod or Node を出口として経由 ⚫monzo/egress-operator や Calico Enterprise 等 Kubernetes Meetup Tokyo #35
  15. NetworkPolicy 15 ▌Calico ⚫Policy-only モードで他のプラグインに組込可能 ⚫Veth の命名を Calico に合わせる必要あり ▌Cilium

    ⚫CNI の機能で Veth を使うプラグインに組込可能 Kubernetes Meetup Tokyo #35
  16. Service type=LoadBalancer 16 ▌マネージドな場合、IaaS ベンダーが提供 ▌オンプレミスの場合選択肢は多くない ⚫自前で実装を頑張る ⚫MetalLB ⚫L2 mode:

    特定 Node にトラフィック管理を任せる ⚫L3 mode: BGP で経路を広告 Kubernetes Meetup Tokyo #35 ロードバランスしてない…
  17. PureLB 17 ▌つい最近発表された MetalLB 派生実装 ⚫ https://purelb.gitlab.io/docs/ ▌BGP を自力で話さないのが違い ⚫任意のルーティングソフトウェアと連携

    ⚫Calico と併用可能 Kubernetes Meetup Tokyo #35
  18. サイボウズにおける組み合わせ実例 18 Kubernetes Meetup Tokyo #35

  19. ネットワーク環境 19 Kubernetes Meetup Tokyo #35 DC3 DC1 DC2 インターネット

    BGPで制御されたノードネットワーク 閉域網
  20. 実現したいこと 20 ▌既設 BGP ネットワークとの接続 ▌グローバル IP アドレスを動的に管理 ▌NetworkPolicy は必須

    ▌LoadBalancer も必須 ▌Pod が外部ネットワークと自由に接続 Kubernetes Meetup Tokyo #35
  21. Calico を使いたかったが… 21 ▌BIRD (BGPデーモン)が組み込まれていて 既設ネットワークとうまく接続できない ▌MetalLB と解決が困難な接続問題がある ⚫Issues with

    Calico https://metallb.universe.tf/configuration/calico/ Kubernetes Meetup Tokyo #35
  22. Coil を開発して解決 22 ▌任意のルーティングソフトウェアと連携 ▌Calico, Cilium の NetworkPolicy と併用可能 ▌MetalLB

    と併用可能 Kubernetes Meetup Tokyo #35
  23. 実際の組み合わせ 23 • NetworkPolicy 実装 • LoadBalancer実装 • ノード間ルーティング •

    IPAM, ノード内ルーティング • 外部への NAT 接続 Coil BIRD (BGP) Calico MetalLB Kubernetes Meetup Tokyo #35
  24. Coil v2 24 Kubernetes Meetup Tokyo #35

  25. 特徴 25 ▌効率的なアドレス管理 ▌任意のルーティングソフトウェアと連携 ▌IPv4/v6/デュアルスタックに対応 ▌カスタムリソースで制御 ▌Opt-in 方式の Egress NAT

    Kubernetes Meetup Tokyo #35
  26. システム図 26 Kubernetes Meetup Tokyo #35

  27. 余談:Coil v1 → v2 27 ▌Coil v1 は k8s に詳しくない頃設計・開発

    ⚫etcd に直接データ保存 ⚫専用 CLI による設定操作 ⚫Prometheus メトリクスなし ⚫CNI プラグインで直接ネットワーク操作 ▌Egress NAT 開発を期に v2 として全面刷新 Kubernetes Meetup Tokyo #35
  28. 実装詳解 28 Kubernetes Meetup Tokyo #35

  29. CNI 処理を gRPC サーバーに委譲 29 ▌CNI はコマンド呼び出し ⚫コマンドは Pod で動かせない

    → ログが Pod ログとして取れない → メトリクスの収集も困難 ▌コマンドから gRPC サーバーに処理を委譲 ⚫gRPC サーバーは Pod で動作 Kubernetes Meetup Tokyo #35
  30. システム図(再掲) 30 Kubernetes Meetup Tokyo #35

  31. 効率的なアドレス管理 31 ▌AddressPool ⚫アドレスブロック単位でノードに割り当て ⚫最小 1 アドレス単位 ▌Bridge を使わない ⚫1

    アドレスも無駄なく利用可能 Kubernetes Meetup Tokyo #35 apiVersion: coil.cybozu.com/v2 kind: AddressPool metadata: name: internet spec: blockSizeBits: 0 subnets: - ipv4: 103.79.13.192/28 ipv6: …
  32. プールの指定は Namespace 単位 32 ▌「インターネット用ノード」は不要 ▌ここに Squid pod を置けば、インターネット につながる

    HTTP Proxy のできあがり Kubernetes Meetup Tokyo #35 apiVersion: v1 kind: Namespace metadata: name: internet-egress annotations: coil.cybozu.com/pool: internet
  33. 豆知識:CNI における Pod の情報 33 ▌CNI は Kubernetes を前提としていない ⚫Pod

    の Namespace, Name は仕様にない ▌実際は CNI_ARGS 環境変数で渡される ⚫Kubernetes 用コンテナランタイムはすべて ⚫e.g. K8S_POD_NAMESPACE=test;K8S_POD_NAME=test-pod Kubernetes Meetup Tokyo #35
  34. ルーティングソフトウェアとの連携 34 ▌各ノードが持つアドレスブロックを広告する必要がある ⚫Coil はブロックをカーネルのルーティングテーブル 119 に出力 ⚫ルーティングソフトウェアはテーブル 119 をインポートして広告

    Kubernetes Meetup Tokyo #35 $ ip route show table 119 10.64.1.64/27 dev lo proto 30 103.79.13.194 dev lo proto 30 $ birdc show route table coiltab Table coiltab: 103.79.13.194/32 unicast [coil 2020-10-16] (10) dev lo 10.64.1.64/27 unicast [coil 2020-10-16] (10) dev lo
  35. システム図(再々掲) 35 Kubernetes Meetup Tokyo #35

  36. 自力ルーティング 36 ▌全ノードが同一 L2 ネットワークにある場合、 Coil は自力でルーティング可能 ▌kind (Kubernetes in

    Docker) で手軽に動作可能 Kubernetes Meetup Tokyo #35
  37. Calico NetworkPolicy 対応 37 ▌Calico は veth の名前を決め打ちしている ⚫同じ命名規則で実装しないと併用できない ▌Cilium

    は CNI の plugin チェーンを正し く使っており、任意の veth 名で併用可能 Kubernetes Meetup Tokyo #35 func calicoVethName(podName, podNS string) string { sum := sha1.Sum([]byte(fmt.Sprintf("%s.%s", podNS, podName))) return "cali" + hex.EncodeToString(sum[:])[:11] }
  38. IPv4/v6/デュアルスタック 38 ▌AddressPool にどれを含めるかで決定 ⚫v4 だけなら v4 シングルスタック ⚫v6 だけなら

    v6 シングルスタック ⚫v4/v6 両方あればデュアルスタック ▌v4/v6 で機能差なし ▌余談:k8s のデュアルスタック対応は 1.20 で 一部再設計予定(second alpha) Kubernetes Meetup Tokyo #35
  39. Opt-in 方式の Egress NAT 39 ▌Egress: 外部ネットワークへの出口を定義 Kubernetes Meetup Tokyo

    #35 apiVersion: coil.cybozu.com/v2 kind: Egress metadata: namespace: internet name: egress spec: destinations: - 0.0.0.0/0 replicas: 2 apiVersion: coil.cybozu.com/v2 kind: Egress metadata: namespace: domestic-network name: egress spec: destinations: - 172.20.0.0/16 - fd04::/64 replicas: 3
  40. Egress から NAT Pod を作成 40 ▌Service で冗長化 Kubernetes Meetup

    Tokyo #35
  41. NAT を利用したい Pod は Opt-in 41 ▌アノテーションで使いたい Egress を指定 Kubernetes

    Meetup Tokyo #35 apiVersion: v1 kind: Pod metadata: name: nat-client namespace: default annotations: egress.coil.cybozu.com/internet: egress egress.coil.cybozu.com/domestic-network: egress spec: …
  42. クライアント Pod → Egress Pod 42 ▌外向けのパケットをそのまま送ると、Egress Pod に届かず捨てられてしまう ▌Egress

    の宛先ネットワークに送るパケットは、 Foo-over-UDP でトンネルして送る ⚫トンネル方式は色々あるが、Foo-over-UDP は UDP パケットなので Service で冗長化できる Kubernetes Meetup Tokyo #35
  43. Foo-over-UDP 43 ▌IP パケットを以下のように加工して送信 ▌受信側で UDP ヘッダを除去 ▌IPIPトンネルデータとして処理 Kubernetes Meetup

    Tokyo #35 IPヘッダ(外行き) ペイロード IPヘッダ(Egress 行き) IPヘッダ(外行き) ペイロード UDPヘッダ 付加 IPヘッダ(Egress 行き) IPヘッダ(外行き) ペイロード
  44. デモ 44 Kubernetes Meetup Tokyo #35

  45. デモ内容 45 ▌AddressPool と AddressBlock ▌Squid Pod で外部通信 ▌Egress NAT

    機能 ▌coild のログで CNI 動作確認 Kubernetes Meetup Tokyo #35
  46. まとめ 46 Kubernetes Meetup Tokyo #35 ▌Coil v2 なら ⚫MetalLB,

    BIRD, Calico, Cilium と連携可能 ⚫外部ネットワークと簡単に接続 ⚫Kubernetes ネイティブで楽々導入&管理 ▌Check it out! ⚫https://github.com/cybozu-go/coil