Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

ymmt2005
October 28, 2020

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

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

ymmt2005

October 28, 2020
Tweet

More Decks by ymmt2005

Other Decks in Technology

Transcript

  1. 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
  2. Kubernetesのネットワーク機能 6 ▌Pod 間通信 ▌NetworkPolicy ▌Service (UDP/TCP LoadBalancer) ▌Ingress (HTTP

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

    がプラグインを直接実行 ▌複数のプラグインを数珠繋ぎできる Kubernetes Meetup Tokyo #35
  4. 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
  5. IP アドレスの割り当て方式 (IPAM) 10 ▌各ノードに Pod 用サブネットを割り当て ⚫node.spec.podCIDR フィールドで指定 ⚫kube-controller-manager

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

    やブロードキャスト用アドレスが必要 ▌Point-to-point 方式 ⚫Veth 両端にリンクローカルアドレスを付与 ⚫Veth ひとつひとつをルーティングテーブルに登録 Kubernetes Meetup Tokyo #35 ちょっともったいない
  7. 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
  8. ルーティング方式 13 ▌オーバーレイネットワーク ⚫Pod 間通信のパケットを IPIP などでカプセル化 ⚫ノード間通信ができる環境ならどこでも動作 ▌BGP 等で経路広告

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

    方式 ⚫特定の Pod or Node を出口として経由 ⚫monzo/egress-operator や Calico Enterprise 等 Kubernetes Meetup Tokyo #35
  10. Service type=LoadBalancer 16 ▌マネージドな場合、IaaS ベンダーが提供 ▌オンプレミスの場合選択肢は多くない ⚫自前で実装を頑張る ⚫MetalLB ⚫L2 mode:

    特定 Node にトラフィック管理を任せる ⚫L3 mode: BGP で経路を広告 Kubernetes Meetup Tokyo #35 ロードバランスしてない…
  11. ネットワーク環境 19 Kubernetes Meetup Tokyo #35 DC3 DC1 DC2 インターネット

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

    ▌LoadBalancer も必須 ▌Pod が外部ネットワークと自由に接続 Kubernetes Meetup Tokyo #35
  13. 実際の組み合わせ 23 • NetworkPolicy 実装 • LoadBalancer実装 • ノード間ルーティング •

    IPAM, ノード内ルーティング • 外部への NAT 接続 Coil BIRD (BGP) Calico MetalLB Kubernetes Meetup Tokyo #35
  14. 余談:Coil v1 → v2 27 ▌Coil v1 は k8s に詳しくない頃設計・開発

    ⚫etcd に直接データ保存 ⚫専用 CLI による設定操作 ⚫Prometheus メトリクスなし ⚫CNI プラグインで直接ネットワーク操作 ▌Egress NAT 開発を期に v2 として全面刷新 Kubernetes Meetup Tokyo #35
  15. CNI 処理を gRPC サーバーに委譲 29 ▌CNI はコマンド呼び出し ⚫コマンドは Pod で動かせない

    → ログが Pod ログとして取れない → メトリクスの収集も困難 ▌コマンドから gRPC サーバーに処理を委譲 ⚫gRPC サーバーは Pod で動作 Kubernetes Meetup Tokyo #35
  16. 効率的なアドレス管理 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: …
  17. プールの指定は Namespace 単位 32 ▌「インターネット用ノード」は不要 ▌ここに Squid pod を置けば、インターネット につながる

    HTTP Proxy のできあがり Kubernetes Meetup Tokyo #35 apiVersion: v1 kind: Namespace metadata: name: internet-egress annotations: coil.cybozu.com/pool: internet
  18. 豆知識: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
  19. ルーティングソフトウェアとの連携 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
  20. 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] }
  21. IPv4/v6/デュアルスタック 38 ▌AddressPool にどれを含めるかで決定 ⚫v4 だけなら v4 シングルスタック ⚫v6 だけなら

    v6 シングルスタック ⚫v4/v6 両方あればデュアルスタック ▌v4/v6 で機能差なし ▌余談:k8s のデュアルスタック対応は 1.20 で 一部再設計予定(second alpha) Kubernetes Meetup Tokyo #35
  22. 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
  23. 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: …
  24. クライアント Pod → Egress Pod 42 ▌外向けのパケットをそのまま送ると、Egress Pod に届かず捨てられてしまう ▌Egress

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

    Tokyo #35 IPヘッダ(外行き) ペイロード IPヘッダ(Egress 行き) IPヘッダ(外行き) ペイロード UDPヘッダ 付加 IPヘッダ(Egress 行き) IPヘッダ(外行き) ペイロード
  26. デモ内容 45 ▌AddressPool と AddressBlock ▌Squid Pod で外部通信 ▌Egress NAT

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

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