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

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

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for ymmt2005 ymmt2005
October 28, 2020

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

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

Avatar for ymmt2005

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