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. 拡張性の高い CNI プラグイン
    Coil v2 の紹介
    サイボウズ株式会社
    山本泰宇 @ymmt2005
    1
    Kubernetes Meetup Tokyo #35

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  6. Kubernetesのネットワーク機能
    6
    ▌Pod 間通信
    ▌NetworkPolicy
    ▌Service (UDP/TCP LoadBalancer)
    ▌Ingress (HTTP LoadBalancer)
    Kubernetes Meetup Tokyo #35
    あれ、Egress は・・? ☞標準仕様はありません

    View Slide

  7. Container Networking Interface (CNI)
    7
    ▌ネットワーク機能をプラグインする規格
    ▌インタフェースはコマンド呼び出し
    ⚫kubelet や containerd がプラグインを直接実行
    ▌複数のプラグインを数珠繋ぎできる
    Kubernetes Meetup Tokyo #35

    View Slide

  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

    View Slide

  9. 代表的な実装方式
    9
    Kubernetes Meetup Tokyo #35

    View Slide

  10. IP アドレスの割り当て方式 (IPAM)
    10
    ▌各ノードに Pod 用サブネットを割り当て
    ⚫node.spec.podCIDR フィールドで指定
    ⚫kube-controller-manager に割り当てさせることも可能
    ▌アドレスプール方式
    ⚫用途に応じたプールを複数定義
    ⚫グローバル IP アドレスを一部 Pod に割り当てる等
    Kubernetes Meetup Tokyo #35
    Flannel 他
    Calico: Node 単位
    Coil: Namespace 単位

    View Slide

  11. Pod と Node の通信方式
    11
    ▌Linux Bridge
    ⚫node.spec.podCIDR の通信をブリッジ内で行う
    ⚫Node やブロードキャスト用アドレスが必要
    ▌Point-to-point 方式
    ⚫Veth 両端にリンクローカルアドレスを付与
    ⚫Veth ひとつひとつをルーティングテーブルに登録
    Kubernetes Meetup Tokyo #35
    ちょっともったいない

    View Slide

  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

    View Slide

  13. ルーティング方式
    13
    ▌オーバーレイネットワーク
    ⚫Pod 間通信のパケットを IPIP などでカプセル化
    ⚫ノード間通信ができる環境ならどこでも動作
    ▌BGP 等で経路広告
    ⚫各ノードに割り当てられた Pod アドレスを広告
    ⚫既存ネットワークにうまく適合させる必要がある
    Kubernetes Meetup Tokyo #35
    お手軽だけど遅め

    View Slide

  14. 外部ネットワークへの通信
    14
    ▌Node NAT 方式
    ⚫外部向けのパケットを Node のアドレスでNAT
    ⚫ノードが外部に通信できることが前提
    ▌Gateway 方式
    ⚫特定の Pod or Node を出口として経由
    ⚫monzo/egress-operator や Calico Enterprise 等
    Kubernetes Meetup Tokyo #35

    View Slide

  15. NetworkPolicy
    15
    ▌Calico
    ⚫Policy-only モードで他のプラグインに組込可能
    ⚫Veth の命名を Calico に合わせる必要あり
    ▌Cilium
    ⚫CNI の機能で Veth を使うプラグインに組込可能
    Kubernetes Meetup Tokyo #35

    View Slide

  16. Service type=LoadBalancer
    16
    ▌マネージドな場合、IaaS ベンダーが提供
    ▌オンプレミスの場合選択肢は多くない
    ⚫自前で実装を頑張る
    ⚫MetalLB
    ⚫L2 mode: 特定 Node にトラフィック管理を任せる
    ⚫L3 mode: BGP で経路を広告
    Kubernetes Meetup Tokyo #35
    ロードバランスしてない…

    View Slide

  17. PureLB
    17
    ▌つい最近発表された MetalLB 派生実装
    ⚫ https://purelb.gitlab.io/docs/
    ▌BGP を自力で話さないのが違い
    ⚫任意のルーティングソフトウェアと連携
    ⚫Calico と併用可能
    Kubernetes Meetup Tokyo #35

    View Slide

  18. サイボウズにおける組み合わせ実例
    18
    Kubernetes Meetup Tokyo #35

    View Slide

  19. ネットワーク環境
    19
    Kubernetes Meetup Tokyo #35
    DC3
    DC1
    DC2
    インターネット
    BGPで制御されたノードネットワーク
    閉域網

    View Slide

  20. 実現したいこと
    20
    ▌既設 BGP ネットワークとの接続
    ▌グローバル IP アドレスを動的に管理
    ▌NetworkPolicy は必須
    ▌LoadBalancer も必須
    ▌Pod が外部ネットワークと自由に接続
    Kubernetes Meetup Tokyo #35

    View Slide

  21. Calico を使いたかったが…
    21
    ▌BIRD (BGPデーモン)が組み込まれていて
    既設ネットワークとうまく接続できない
    ▌MetalLB と解決が困難な接続問題がある
    ⚫Issues with Calico
    https://metallb.universe.tf/configuration/calico/
    Kubernetes Meetup Tokyo #35

    View Slide

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

    View Slide

  23. 実際の組み合わせ
    23
    • NetworkPolicy 実装
    • LoadBalancer実装
    • ノード間ルーティング
    • IPAM, ノード内ルーティング
    • 外部への NAT 接続
    Coil BIRD
    (BGP)
    Calico
    MetalLB
    Kubernetes Meetup Tokyo #35

    View Slide

  24. Coil v2
    24
    Kubernetes Meetup Tokyo #35

    View Slide

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

    View Slide

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

    View Slide

  27. 余談:Coil v1 → v2
    27
    ▌Coil v1 は k8s に詳しくない頃設計・開発
    ⚫etcd に直接データ保存
    ⚫専用 CLI による設定操作
    ⚫Prometheus メトリクスなし
    ⚫CNI プラグインで直接ネットワーク操作
    ▌Egress NAT 開発を期に v2 として全面刷新
    Kubernetes Meetup Tokyo #35

    View Slide

  28. 実装詳解
    28
    Kubernetes Meetup Tokyo #35

    View Slide

  29. CNI 処理を gRPC サーバーに委譲
    29
    ▌CNI はコマンド呼び出し
    ⚫コマンドは Pod で動かせない
    → ログが Pod ログとして取れない
    → メトリクスの収集も困難
    ▌コマンドから gRPC サーバーに処理を委譲
    ⚫gRPC サーバーは Pod で動作
    Kubernetes Meetup Tokyo #35

    View Slide

  30. システム図(再掲)
    30
    Kubernetes Meetup Tokyo #35

    View Slide

  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: …

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  35. システム図(再々掲)
    35
    Kubernetes Meetup Tokyo #35

    View Slide

  36. 自力ルーティング
    36
    ▌全ノードが同一 L2 ネットワークにある場合、
    Coil は自力でルーティング可能
    ▌kind (Kubernetes in Docker) で手軽に動作可能
    Kubernetes Meetup Tokyo #35

    View Slide

  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]
    }

    View Slide

  38. IPv4/v6/デュアルスタック
    38
    ▌AddressPool にどれを含めるかで決定
    ⚫v4 だけなら v4 シングルスタック
    ⚫v6 だけなら v6 シングルスタック
    ⚫v4/v6 両方あればデュアルスタック
    ▌v4/v6 で機能差なし
    ▌余談:k8s のデュアルスタック対応は 1.20 で
    一部再設計予定(second alpha)
    Kubernetes Meetup Tokyo #35

    View Slide

  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

    View Slide

  40. Egress から NAT Pod を作成
    40
    ▌Service で冗長化
    Kubernetes Meetup Tokyo #35

    View Slide

  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:

    View Slide

  42. クライアント Pod → Egress Pod
    42
    ▌外向けのパケットをそのまま送ると、Egress
    Pod に届かず捨てられてしまう
    ▌Egress の宛先ネットワークに送るパケットは、
    Foo-over-UDP でトンネルして送る
    ⚫トンネル方式は色々あるが、Foo-over-UDP は
    UDP パケットなので Service で冗長化できる
    Kubernetes Meetup Tokyo #35

    View Slide

  43. Foo-over-UDP
    43
    ▌IP パケットを以下のように加工して送信
    ▌受信側で UDP ヘッダを除去
    ▌IPIPトンネルデータとして処理
    Kubernetes Meetup Tokyo #35
    IPヘッダ(外行き) ペイロード
    IPヘッダ(Egress 行き) IPヘッダ(外行き) ペイロード
    UDPヘッダ
    付加
    IPヘッダ(Egress 行き) IPヘッダ(外行き) ペイロード

    View Slide

  44. デモ
    44
    Kubernetes Meetup Tokyo #35

    View Slide

  45. デモ内容
    45
    ▌AddressPool と AddressBlock
    ▌Squid Pod で外部通信
    ▌Egress NAT 機能
    ▌coild のログで CNI 動作確認
    Kubernetes Meetup Tokyo #35

    View Slide

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

    View Slide