$30 off During Our Annual Pro Sale. View Details »

kube-proxy入門

bells17
November 09, 2023

 kube-proxy入門

Kubernetes Novice Tokyo #28 の登壇資料です

イベントURL: https://k8s-novice-jp.connpass.com/event/293157/
配信URL: https://www.youtube.com/watch?v=LSW51Cm0Wc0

コードリーディングメモ:
https://zenn.dev/bells17/scraps/5e41da598a8266

参考資料:
https://github.com/kubernetes/kubernetes/tree/v1.28.2
https://speakerdeck.com/ryusa/servicewotazunete3000xing-kuberneteskodorideingufalselu
https://qiita.com/Tocyuki/items/6d90a1ec4dd8e991a1ce
https://oxynotes.com/?p=6361#5
https://atmarkit.itmedia.co.jp/ait/articles/1002/09/news119.html
https://hana-shin.hatenablog.com/entry/2022/06/21/215757
https://qiita.com/syui/items/27020b970775a0c508ba
https://www.digitalocean.com/community/tutorials/iptables-essentials-common-firewall-rules-and-commands
https://www.asahi-net.or.jp/~aa4t-nngk/ipttut/output/explicitmatches.html
https://github.com/torvalds/linux/blob/master/Documentation/networking/nf_conntrack-sysctl.rst
https://tech-blog.rakus.co.jp/entry/20220301/iptables
https://linuxjm.osdn.jp/html/iptables/man8/iptables-extensions.8.html
https://man.archlinux.org/man/conntrack.8.en
https://nomeu.net/8380/
https://knowledge.sakura.ad.jp/4048/
https://docs.openshift.com/container-platform/4.10/rest_api/network_apis/service-v1.html
https://stackoverflow.com/questions/75835169/kubernetes-loadbalancer-how-does-healthchecknodeport-work
https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip
https://kubernetes.io/docs/concepts/services-networking/service-traffic-policy/
https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/
https://hyoublog.com/2020/05/20/kubernetes-externalip-service/
https://qiita.com/dingtianhongjie/items/8f3c320c4eb5cf25d9de
https://milestone-of-se.nesuke.com/nw-basic/as-nw-engineer/loopback-address-interface/
https://kubernetes.io/docs/reference/networking/virtual-ips/
https://kubernetes.io/docs/concepts/services-networking/service/
https://kubernetes.io/ja/docs/concepts/services-networking/connect-applications-service/
https://knowledge.sakura.ad.jp/22636/
https://netfilter.org/index.html
https://madomadox.hatenablog.com/entry/2021/01/03/190730
https://qiita.com/bashaway/items/e405d59d92670fbc5341
https://www.digitalocean.com/community/tutorials/a-deep-dive-into-iptables-and-netfilter-architecture
https://tech-blog.rakus.co.jp/entry/20220301/iptables
https://www.asahi-net.or.jp/~aa4t-nngk/ipttut/output/explicitmatches.html
https://eng-entrance.com/linux-firewall

画像引用元:
https://github.com/kubernetes/community/tree/master/icons
https://github.com/kubernetes/kubernetes/tree/master/logo
https://github.com/cncf/artwork/tree/master/projects/kubernetes
https://github.com/kubernetes/kubeadm/tree/main/logos

bells17

November 09, 2023
Tweet

More Decks by bells17

Other Decks in Programming

Transcript

  1. kube-proxy⼊⾨
    Kubernetes Novice Tokyo #
    2 8
    (
    2 0 2 3
    /
    1 1
    /
    9
    )


    @bells
    1 7

    View Slide

  2. ▶ @bells
    1
    7


    ▶ Software Engineer@
    3
    -shake inc.


    ▶ kubernetes & kubernetes-csi member


    ▶ Kubernetes Internal Organizer


    ▶ #kubenews


    ▶ X(Twitter): @bells
    1
    7
    _


    ▶ GitHub: @bells
    1
    7

    View Slide

  3. 今⽇話すこと
    ▶ kube-proxyについて


    ▶ kube-proxyが設定するiptablesについて

    View Slide

  4. 注意点
    ▶ Kubernetes v
    1
    .
    2 8
    .
    2
    ベースでのお話になります


    ▶ KubernetesそのものやKubernetes Component全体の説明は簡単なものに
    なるかと思います


    ▶ あくまでkube-proxyの実装を追った結果での理解の説明になるので、

    間違いが含まれている可能性があります


    ▶ 特にネットワーク初⼼者なので、ネットワーク周りの説明は

    間違いが多いかも…


    View Slide

  5. そもそもKubernetesとは?

    View Slide

  6. Kubernetes とは?
    ▶ Kubernetesはコンテナオーケストレーターの1つ


    ▶ etcd/control plane/worker nodeによって構成されたクラスターを構築し、

    様々なコンテナをKubernetes上のnodeで動作させたり、動作させてる

    コンテナとネットワークをいい感じに連携できるようにすることができる


    ▶ デプロイするコンテナなどをmanifestファイルで宣⾔的に記述することで、

    宣⾔した状態になるようにKubernetesがいい感じに調整処理を⾏ってくれる


    ▶ Googleが内部で運⽤していたコンテナ基盤であるBorgを

    OSS向けに作り直したコンテナオーケストレーター


    ▶ また、KubernetesはCloud Native Computing Foundation(CNCF)に寄贈されており、
    CNCFのGraduatedプロジェクトとしてコミュニティベースで管理されている

    View Slide

  7. manifestをKubernetesに適⽤することで


    宣⾔されたmanifestの通りにコンテナが作成される

    View Slide

  8. Kubernetesコントローラー

    View Slide

  9. https://github.com/kubernetes/website/blob/fb
    6 3 6 4
    da
    0
    afd
    1 9
    e
    8
    a
    9 5 1 5
    aaae
    2
    de
    9
    bc
    7 4
    a
    0
    a
    6
    abd/static/images/docs/components-of-kubernetes.png

    View Slide

  10. View Slide

  11. 基本パターン
    ▶ Managerプロセス全体の中で1つ、または複数のコントローラーが実⾏
    される


    ▶ コントローラーは1つにつき、1種類のKubernetesリソースのみに対す
    る調整ループ(Reconciliation Loop)が実⾏される


    + 調整ループ: リソースのあるべき状態(Desired State)と実際の状態
    (Actual State)を⽐較~あるべき状態になるように調整処理を⾏うもの


    + なので、2種類のリソースに対しては、最低2コントローラー以上が

    あるのが基本

    View Slide

  12. 調整ループ
    ▶ 主に以下の2種類の⽅法で実⾏される


    + Event Handlers: 監視対象のKubernetes Resourceの更新といった、
    なんらかのイベントを元に実⾏される


    + 無限ループによる定期実⾏: 設定値に基づいて数秒毎などの間隔で定
    期実⾏が⾏われる

    View Slide

  13. https://github.com/kubernetes/sample-controller/blob/master/docs/images/client-go-controller-interaction.jpeg

    View Slide

  14. View Slide

  15. ▶ Kubernetesのコードリーディングをする上で知っておくと良さそうなこと


    ▶ Kubernetes Internal #
    1

    こういったKubernetesコントローラー実装周りについてはコード
    リーディングについての記事の中で書いたので良ければ⾒てください

    View Slide

  16. Kubernetes Core Component

    View Slide

  17. https://github.com/kubernetes/website/blob/fb
    6 3 6 4
    da
    0
    afd
    1 9
    e
    8
    a
    9 5 1 5
    aaae
    2
    de
    9
    bc
    7 4
    a
    0
    a
    6
    abd/static/images/docs/components-of-kubernetes.png

    View Slide

  18. Core Component
    ▶ etcd: API Serverのバックエンドで使⽤されている分散型のKVS


    ▶ Control Plane


    ▶ API Server: KubernetesのAPIリクエストを処理するサーバー


    ▶ Kube Controller Manager: Kubernetesの様々なリソースのためのロジックを動かす

    様々なコントローラーを動作させるマネージャー


    ▶ Cloud Controller Manager: Kubernetesとクラウド(実⾏基盤)を連携するための

    コントローラーを動作させるマネージャー


    ▶ Scheduler: PodをどのWorker Nodeに配置するかを決める


    ▶ Worker Node


    ▶ Kubelet: Worker Nodeで実⾏するコンテナを管理するアプリケーション


    ▶ Kube Proxy: Service/EndpointSliceリソースに基づくネットワーク設定を⾏うアプリケーション

    View Slide

  19. ▶ Cloud Controller Manager Deep Dive


    ▶ Kubernetes Internal #
    2

    Cloud Controller Managerについては以下のスライドで
    まとめてあるので参考にしてください

    View Slide

  20. ▶ Kubeletから読み解くKubernetesのコンテナ管理の裏側


    ▶ Kubernetes Internal #
    4

    ▶ Kubeletから読み解くKubernetesのコンテナ管理の裏側


    Kubeletについても以前発表しているセッションや書籍が
    あるので良ければ参考にしてください

    View Slide

  21. https://github.com/kubernetes/website/blob/fb
    6 3 6 4
    da
    0
    afd
    1 9
    e
    8
    a
    9 5 1 5
    aaae
    2
    de
    9
    bc
    7 4
    a
    0
    a
    6
    abd/static/images/docs/components-of-kubernetes.png

    View Slide

  22. kube-proxyとは?

    View Slide

  23. kube-proxy とは?
    ▶ Worker Nodeで動作するCore Componentの1つ


    ▶ 主にServiceリソースとEndpointSliceリソースを元にネットワーク設定を

    ⾏い、Serviceのエンドポイント(e.g. foo.bar.svc.cluster.local)にアクセス

    した際にPodにリクエストが届くようにしてくれるコンポーネント


    ▶ 動作モードには下記の3つがある(userspaceというモードもあったが削除された)


    ▶ iptables(デフォルト)


    ▶ ipvs


    ▶ kernelspace(Windows⽤)


    ▶ IPv
    4
    とIPv
    6
    のデュアルスタックのサポートも有り

    View Slide

  24. 補⾜: ServiceとEndpointSliceの関係
    apiVersion: discovery.k
    8
    s.io/v
    1

    kind: EndpointSlice


    metadata:


    name: np-service-
    7 2
    gzs


    namespace: default


    ...


    addressType: IPv
    4

    ports:


    - name: ""


    port:
    8 0 8 0

    protocol: TCP


    endpoints:


    - addresses:


    -
    1 0
    .
    2 4 4
    .
    2
    .
    3

    nodeName: kube-proxy-example-worker
    2

    targetRef:


    kind: Pod


    name: nginx-
    6
    c
    6 6 5 6
    d
    8
    f
    6
    -
    6
    zv
    7
    t


    namespace: default


    uid:
    4
    ad
    3
    a
    7
    cc-
    3 1 4 4
    -
    4 2
    fd-
    9 3
    e
    4
    -
    1 6 0 4 4 5
    ebcc
    3
    b


    ...
    Serviceで指定したセレクタにマッチしたPodの情報をEndpointSliceとして⽣成する


    LBで⾔うとServiceのCluster IPはLBに割り当てるIP、EndpointSliceはPodを紐付けるIP Poolのイメージ

    View Slide

  25. 今回の解説の前提
    ▶ OS: Linuxを使⽤


    ▶ 動作モード: iptablesモード


    ▶ IPv
    4
    のみを使⽤する想定です


    ▶ 設定値は基本デフォルトのものを想定してます


    ▶ 検証はkindで⾏っているのでCNIはkindnetが使⽤されています

    View Slide

  26. kube-proxyの全体像はだいたいこんなん

    View Slide

  27. ipt.Monitor
    ▶ ipt=iptablesのこと(多分)


    ▶ “KUBE-PROXY-CANARY” というチェインを下記のテーブルに作成する


    + mangle


    + nat


    +
    fi
    lter


    ▶ 作成後、上記チェインがあるかどうかを監視する


    ▶ もしチェインが削除されたらproxier.syncProxyRulesを実⾏して、再度“KUBE-PROXY-CANARY”
    チェインの作成~監視に戻る


    ▶ → “KUBE-PROXY-CANARY” チェインを作って監視することで iptables のルールを削除されてな
    いかをチェックしてる

    (ルールが⼤量にあるとパフォーマンスに影響してくるからルールが存在しない空っぽの チェイ
    ンを作って監視してるとのこと)

    View Slide

  28. ServiceCon
    fi
    g
    ▶ Serviceリソースの更新時に下記の処理を⾏う


    + kube-proxy⽤のデータキャッシュ処理


    + proxier.syncProxyRulesの実⾏依頼


    View Slide

  29. endpointSliceCon
    fi
    g
    ▶ EndpointSliceリソースの更新時に下記の処理を⾏う


    + kube-proxy⽤のデータキャッシュ処理


    + proxier.syncProxyRulesの実⾏依頼


    View Slide

  30. nodeCon
    fi
    g
    ▶ Nodeリソースの更新時に下記の処理を⾏う


    + kube-proxy⽤のデータキャッシュ処理


    + proxier.syncProxyRulesの実⾏依頼


    ▶ ここで処理されるNodeリソースはkube-proxyを実⾏しているNode⾃⾝のみ

    View Slide

  31. watcher
    ▶ kube-proxy.confの内容変更を監視 ~ 検知したら⾃⾝のプロセスをkillする


    ▶ kube-proxyはDaemonSetやstatic podなどで起動されているはずなので、

    killされたら再起動される

    View Slide

  32. iptablesについて

    View Slide

  33. iptablesの基本
    ▶ 外部ネットワークからパケットを受信した際にテーブルと

    テーブル内のチェインの設定に応じてパケットのフィルタリングなどの

    処理を⾏うことができる


    ▶ iptablesではnetlinkを介してカーネルのnet
    fi
    lterの設定を⾏うことが可能で、

    net
    fi
    lterはネットワークパケット処理の各段階でフックを使ってコールバック関数を実⾏す
    ることで各種操作を実現してるらしい


    ▶ nftablesというiptablesの後継があるらしい
    ざっくりこんな感じという理解です

    View Slide

  34. 主なテーブルとチェイン

    fi
    lter: パケットフィルタリングに使われるテーブル


    + 主なチェイン: INPUT, FORWARD, OUTPUT


    ▶ nat: NAT処理に使われるテーブル


    + 主なチェイン: PREROUTING, OUTPUT, POSTROUTING


    ▶ mangle: パケットのTTL設定など、特定のパケットのヘッダー情報を変更する際に使⽤


    + 主なチェイン: PREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING


    ▶ raw: パケットがコネクショントラッキングシステムをバイパスすることを許可するために使⽤


    + 主なチェイン: PREROUTING, OUTPUT


    ▶ security: SELinux ルールの適⽤に使⽤される


    + INPUT, OUTPUT, FORWARD

    View Slide

  35. https://stu
    ff
    philwrites.com/wp-content/uploads/
    2 0 1 4
    /
    0 9
    /FW-IDS-iptables-Flowchart-
    2 0 1 4
    -
    0 9
    -
    2 5
    .png

    View Slide

  36. 例えばNodePortとCluster IPのServiceをそれぞれ使って


    Podにリクエストが届く際はこんな感じになる

    View Slide

  37. kindで試した例

    View Slide

  38. 環境構築

    View Slide

  39. kind-con
    fi
    g.yaml
    kind: Cluster


    apiVersion: kind.x-k
    8
    s.io/v
    1
    alpha
    4

    nodes:


    - role: control-plane


    - role: worker


    - role: worker
    # クラスター起動コマンド


    $ kind create cluster \


    --name kube-proxy-example \


    --con
    fi
    g kind-con
    fi
    g.yaml
    control-plane:
    1
    worker:
    2
    合計3台のノードを起動する

    View Slide

  40. Service

    type: ClusterIP
    apiVersion: v
    1

    kind: Service


    metadata:


    name: cip-service


    spec:


    selector:


    app: nginx


    ports:


    - protocol: TCP


    port:
    8 0

    type: ClusterIP

    View Slide

  41. Service

    type: NodePort
    apiVersion: v
    1

    kind: Service


    metadata:


    name: np-service


    spec:


    selector:


    app: nginx


    ports:


    - protocol: TCP


    port:
    8 0

    type: NodePort

    View Slide

  42. Deployment
    apiVersion: apps/v
    1

    kind: Deployment


    metadata:


    name: nginx


    spec:


    replicas:
    2

    selector:


    matchLabels:


    app: nginx


    template:


    metadata:


    labels:


    app: nginx


    spec:


    a
    ff
    i
    nity:


    podAntiA
    ffi
    nity:


    preferredDuringSchedulingIgnoredDuringExecution:


    - weight:
    1

    podA
    ffi
    nityTerm:


    labelSelector:


    matchExpressions:


    - key: app


    operator: In


    values:


    - nginx


    topologyKey: "kubernetes.io/hostname"


    containers:


    - name: nginx


    image: nginx


    ports:


    - containerPort:
    8 0
    2台をpreferredDuringSchedulingIgnoredDuringExecutionで分散配置してるのでworkerノードに1台ずつ配置されるはず

    View Slide

  43. 動作確認

    View Slide

  44. クラスター外からの接続確認
    $ docker exec -it
    8 8 9 2
    dd
    1 4 0
    b
    3
    e /bin/bash


    root@kube-proxy-example-control-plane:/# curl
    1 9 2
    .
    1 6 8
    .
    2 2 8
    .
    4
    :
    3 1 7 8 6
    -o /dev/null -w '%
    {http_code}\n' -s


    200 # ノードのIPとNodePort: 接続できる


    root@kube-proxy-example-control-plane:/# curl
    1 0
    .
    9 6
    .
    1 9 1
    .
    1 2 4
    -o /dev/null -w '%
    {http_code}\n' -s


    2 0 0
    # np-serviceのClusterIP: 接続できる


    root@kube-proxy-example-control-plane:/# curl
    1 0
    .
    9 6
    .
    2 2 0
    .
    1 8 8
    -o /dev/null -w '%
    {http_code}\n' -s


    2 0 0
    # cip-serviceのClusterIP: 接続できる
    ちゃんと検証したことなかったけどクラスターに参加してるノードからならクラスター外からのアクセスも可能なのか

    View Slide

  45. クラスター内からの接続確認
    $ kubectl exec -it nginx-
    5 9
    b
    8
    fdd
    4 6 4
    -tq
    6
    k
    6
    -- bash


    root@nginx-
    5 9
    b
    8
    fdd
    4 6 4
    -tq
    6
    k
    6
    :/# curl np-service.default.svc.cluster.local -o /dev/null -w
    '%{http_code}\n' -s


    2 0 0

    root@nginx-
    5 9
    b
    8
    fdd
    4 6 4
    -tq
    6
    k
    6
    :/# curl cip-service.default.svc.cluster.local -o /dev/null -w
    '%{http_code}\n' -s


    2 0 0

    View Slide

  46. クラスターに参加してないノードからだとこんな感じ
    docker exec -it
    8 8 9 2
    dd
    1 4 0
    b
    3
    e /bin/bash


    root@kind-control-plane:/# curl
    1 9 2
    .
    1 6 8
    .
    2 2 8
    .
    4
    :
    3 1 7 8 6
    -o /dev/null -w '%{http_code}\n' -s


    200 # ノードのIPとNodePort: 接続できる


    root@kind-control-plane:/# curl
    1 0
    .
    9 6
    .
    1 9 1
    .
    1 2 4
    -o /dev/null -w '%{http_code}\n' -s


    ^C # ノードのIPとNodePort: 接続できない


    root@kind-control-plane:/# curl
    1 0
    .
    9 6
    .
    2 2 0
    .
    1 8 8
    -o /dev/null -w '%{http_code}\n' -s


    ^C # cip-serviceのClusterIP: 接続できない


    kindのデフォルトクラスターが⽴ってたのでそれで検証した

    View Slide

  47. iptablesの設定を確認してみる

    View Slide

  48. PREROUTINGにKUBE-SERVICESが設定される
    Chain PREROUTING (policy ACCEPT)


    target prot opt source destination


    KUBE-SERVICES all --
    0
    .
    0
    .
    0
    .
    0
    /
    0 0
    .
    0
    .
    0
    .
    0
    /
    0
    /* kubernetes service portals */


    DOCKER_OUTPUT all --
    0
    .
    0
    .
    0
    .
    0
    /
    0 1 9 8
    .
    1 9
    .
    2 4 8
    .
    2 5 4
    ↑は“iptables -t nat -L -n -v” コマンドをちょい整形したやつの⼀部です

    View Slide

  49. KUBE-SERVICESに作成したServiceのCluster IPの

    チェインが設定される
    Chain KUBE-SERVICES (
    2
    references)


    pkts bytes target prot opt in out source destination


    2 1 2 0
    KUBE-SVC-OI
    3
    ES
    3
    UZPSOHIVZW tcp -- * *
    0
    .
    0
    .
    0
    .
    0
    /
    0 1 0
    .
    9 6
    .
    1 9 1
    .
    1 2 4
    /* default/np-service cluster
    IP */ tcp dpt:
    8 0

    8 7 7 6
    KUBE-SVC-TCOU
    7
    JCQXEZGVUNU udp -- * *
    0
    .
    0
    .
    0
    .
    0
    /
    0 1 0
    .
    9 6
    .
    0
    .
    1 0
    /* kube-system/kube-
    dns:dns cluster IP */ udp dpt:
    5 3

    0 0
    KUBE-SVC-ERIFXISQEP
    7
    F
    7
    OF
    4
    tcp -- * *
    0
    .
    0
    .
    0
    .
    0
    /
    0 1 0
    .
    9 6
    .
    0
    .
    1 0
    /* kube-system/kube-dns:dns-tcp
    cluster IP */ tcp dpt:
    5 3

    0 0
    KUBE-SVC-JD
    5
    MR
    3
    NA
    4
    I
    4
    DYORP tcp -- * *
    0
    .
    0
    .
    0
    .
    0
    /
    0 1 0
    .
    9 6
    .
    0
    .
    1 0
    /* kube-system/kube-
    dns:metrics cluster IP */ tcp dpt:
    9 1 5 3

    2 1 2 0
    KUBE-SVC-ERVH
    2
    TYUWKPRTIBA tcp -- * *
    0
    .
    0
    .
    0
    .
    0
    /
    0 1 0
    .
    9 6
    .
    2 2 0
    .
    1 8 8
    /* default/cip-service cluster
    IP */ tcp dpt:
    8 0

    0 0
    KUBE-SVC-NPX
    4 6
    M
    4
    PTMTKRN
    6
    Y tcp -- * *
    0
    .
    0
    .
    0
    .
    0
    /
    0 1 0
    .
    9 6
    .
    0
    .
    1
    /* default/kubernetes:https
    cluster IP */ tcp dpt:
    4 4 3

    6 3 6 0
    KUBE-NODEPORTS all -- * *
    0
    .
    0
    .
    0
    .
    0
    /
    0 0
    .
    0
    .
    0
    .
    0
    /
    0
    /* kubernetes service nodeports; NOTE: this
    must be the last rule in this chain */ ADDRTYPE match dst-type LOCAL
    クラスターに参加してないノードだと↑のNAT設定が無いからCluster IPにアクセスしてもPodに通信が届かないっぽい?

    View Slide

  50. Serviceを⾒ると”10.96.191.124”と”10.96.220.188”のIPが

    設定されてるのが確認できる
    $ kubectl get svc np-service cip-service


    NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE


    np-service NodePort
    1 0
    .
    9 6
    .
    1 9 1
    .
    1 2 4

    8 0
    :
    3 1 7 8 6
    /TCP
    1 9
    h


    cip-service ClusterIP
    1 0
    .
    9 6
    .
    2 2 0
    .
    1 8 8

    8 0
    /TCP
    1 3 2
    m

    View Slide

  51. “statistic mode random probability
    0
    .
    5
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    ”の設定によって
    “KUBE-SEP-XXX”のチェインがそれぞれ50%ずつの確率で選択される
    Chain KUBE-SVC-OI
    3
    ES
    3
    UZPSOHIVZW (
    2
    references)


    pkts bytes target prot opt in out source destination


    0 0
    KUBE-MARK-MASQ tcp -- * * !
    1 0
    .
    2 4 4
    .
    0
    .
    0
    /
    1 6 1 0
    .
    9 6
    .
    1 9 1
    .
    1 2 4
    /* default/np-service cluster IP */ tcp dpt:
    8 0

    3 1 8 0
    KUBE-SEP-P
    5
    JHP
    7 5
    IHX
    6 4
    MSBB all -- * *
    0
    .
    0
    .
    0
    .
    0
    /
    0 0
    .
    0
    .
    0
    .
    0
    /
    0
    /* default/np-service ->
    1 0
    .
    2 4 4
    .
    1
    .
    4
    :
    8 0
    */ statistic mode random probability
    0
    .
    5 0 0 0 0 0 0 0 0 0 0

    3 1 8 0
    KUBE-SEP-VLQJIV
    5
    HGZHFWOG
    3
    all -- * *
    0
    .
    0
    .
    0
    .
    0
    /
    0 0
    .
    0
    .
    0
    .
    0
    /
    0
    /* default/np-service ->
    1 0
    .
    2 4 4
    .
    2
    .
    4
    :
    8 0
    */


    Chain KUBE-SVC-ERVH
    2
    TYUWKPRTIBA (
    1
    references)


    pkts bytes target prot opt in out source destination


    0 0
    KUBE-MARK-MASQ tcp -- * * !
    1 0
    .
    2 4 4
    .
    0
    .
    0
    /
    1 6 1 0
    .
    9 6
    .
    2 2 0
    .
    1 8 8
    /* default/cip-service cluster IP */ tcp dpt:
    8 0

    1 6 0
    KUBE-SEP-KBDPBHDFQFJCC
    6
    G
    2
    all -- * *
    0
    .
    0
    .
    0
    .
    0
    /
    0 0
    .
    0
    .
    0
    .
    0
    /
    0
    /* default/cip-service ->
    1 0
    .
    2 4 4
    .
    1
    .
    4
    :
    8 0
    */ statistic mode random probability
    0
    .
    5 0 0 0 0 0 0 0 0 0 0

    1 6 0
    KUBE-SEP-RRD
    2
    VMIQOEDDLHII all -- * *
    0
    .
    0
    .
    0
    .
    0
    /
    0 0
    .
    0
    .
    0
    .
    0
    /
    0
    /* default/cip-service ->
    1 0
    .
    2 4 4
    .
    2
    .
    4
    :
    8 0
    */
    ↑は“iptables -t nat -L -n -v” コマンドをちょい整形したやつの⼀部です

    View Slide

  52. ちなみにDNATする先が3つ以上ある場合こんな感じで

    計算された数値が配置されるので各⾃0.2とかにはならないらしい
    https://github.com/kubernetes/kubernetes/issues/
    3 7 9 3 2

    View Slide

  53. NodePort側の“KUBE-SEP-T
    4
    U
    2
    PF
    7
    3
    XRV
    2
    7
    O
    6
    N”チェインが選択された場合

    DNATで”10.244.2.4:80”にアドレスが変換される
    Chain KUBE-SEP-VLQJIV
    5
    HGZHFWOG
    3
    (
    1
    references)


    pkts bytes target prot opt in out source destination


    2 1 2 0
    KUBE-MARK-MASQ all -- * *
    1 0
    .
    2 4 4
    .
    2
    .
    4 0
    .
    0
    .
    0
    .
    0
    /
    0
    /* default/np-service */


    3 1 8 0
    DNAT tcp -- * *
    0
    .
    0
    .
    0
    .
    0
    /
    0 0
    .
    0
    .
    0
    .
    0
    /
    0
    /* default/np-service */ tcp to:
    1 0
    .
    2 4 4
    .
    2
    .
    4
    :
    8 0
    ↑は“iptables -t nat -L -n -v” コマンドをちょい整形したやつの⼀部です

    View Slide

  54. 作成した各PodのIPを⾒ると”10.244.2.4”は

    “kube-proxy-example-worker
    2
    ”で動いてることがわかる
    $ kubectl get pod -l app=nginx -o yaml | egrep "ip|nodeName"


    nodeName: kube-proxy-example-worker


    - ip:
    1 0
    .
    2 4 4
    .
    1
    .
    4

    nodeName: kube-proxy-example-worker
    2

    - ip:
    1 0
    .
    2 4 4
    .
    2
    .
    4

    View Slide

  55. EndpointSliceにもIPが設定されてるのがわかる
    $ kubectl get endpointslice np-service-
    7 2
    gzs cip-service-
    2 7
    ldz


    NAME ADDRESSTYPE PORTS ENDPOINTS AGE


    np-service-
    7 2
    gzs IPv
    4 8 0 1 0
    .
    2 4 4
    .
    1
    .
    4
    ,
    1 0
    .
    2 4 4
    .
    2
    .
    4 1 9
    h


    cip-service-
    2 7
    ldz IPv
    4 8 0 1 0
    .
    2 4 4
    .
    1
    .
    4
    ,
    1 0
    .
    2 4 4
    .
    2
    .
    4 1 4 3
    m

    View Slide

  56. “kube-proxy-example-worker
    2
    ”のルーティングテーブルを確認すると

    ”10.244.2.4”は”veth
    1
    ba
    6
    bf
    7
    1
    ”というvethにルーティングされることがわかる

    (このルーティングテーブルやvethはCNIのkindnetが設定したもののよう)
    $ ip route


    default via
    1 9 2
    .
    1 6 8
    .
    2 2 8
    .
    1
    dev eth
    0

    1 0
    .
    2 4 4
    .
    0
    .
    0
    /
    2 4
    via
    1 9 2
    .
    1 6 8
    .
    2 2 8
    .
    3
    dev eth
    0

    1 0
    .
    2 4 4
    .
    1
    .
    0
    /
    2 4
    via
    1 9 2
    .
    1 6 8
    .
    2 2 8
    .
    5
    dev eth
    0

    1 0
    .
    2 4 4
    .
    2
    .
    4
    dev veth
    1
    ba
    6
    bf
    7 1
    scope host


    1 9 2
    .
    1 6 8
    .
    2 2 8
    .
    0
    /
    2 4
    dev eth
    0
    proto kernel scope link src
    1 9 2
    .
    1 6 8
    .
    2 2 8
    .
    4 


    $ ip addr show


    5
    : vethd
    7
    b
    5
    df
    7
    f@if
    3
    : mtu
    1 5 0 0
    qdisc noqueue state UP group default


    link/ether
    2 6
    :
    1 9
    :
    3
    f:
    7 9
    :
    5 5
    :
    2 0
    brd
    ff
    :
    ff
    :
    ff
    :
    ff
    :
    ff
    :
    ff
    link-netns cni-d
    1
    e
    5
    dd
    4 4
    -b
    7 8
    c-
    7 4 1 5
    -f
    0 0 0
    -
    0
    d
    6 0
    e
    1 2 2 0
    b
    0 2

    inet
    1 0
    .
    2 4 4
    .
    2
    .
    1
    /
    3 2
    scope global vethd
    7
    b
    5
    df
    7
    f


    valid_lft forever preferred_lft forever



    Vethの作成はkindnetが使⽤している ptp plugin が⾏っていて、ルーティングテーブルの作成は kindnet 本体が⾏っている

    View Slide

  57. “kube-proxy-example-worker
    2
    ”がパケットを受信した場合”10.244.2.4”は

    ローカルで動作しているPodなので次は
    fi
    lterテーブルのINPUTチェインに移る
    Chain INPUT (policy ACCEPT
    0
    packets,
    0
    bytes)


    pkts bytes target prot opt in out source destination


    3 6 2 8 7 0
    KUBE-PROXY-FIREWALL all -- * *
    0
    .
    0
    .
    0
    .
    0
    /
    0 0
    .
    0
    .
    0
    .
    0
    /
    0
    ctstate NEW /*
    kubernetes load balancer
    fi
    rewall */


    6 2 1 9 7 3
    M KUBE-NODEPORTS all -- * *
    0
    .
    0
    .
    0
    .
    0
    /
    0 0
    .
    0
    .
    0
    .
    0
    /
    0
    /* kubernetes health
    check service ports */


    3 6 2 8 7 0
    KUBE-EXTERNAL-SERVICES all -- * *
    0
    .
    0
    .
    0
    .
    0
    /
    0 0
    .
    0
    .
    0
    .
    0
    /
    0
    ctstate NEW /*
    kubernetes externally-visible service portals */


    6 4 3 9 7 3
    M KUBE-FIREWALL all -- * *
    0
    .
    0
    .
    0
    .
    0
    /
    0 0
    .
    0
    .
    0
    .
    0
    /
    0

    デフォルトがACCEPTで、上記チェインでは”10.244.2.3”宛のパケットがDROPなどはされないのでACCEPTされる(各チェインの詳細は省略)


    ちなみに↑は“iptables -t
    fi
    lter -L -n -v” コマンドをちょい整形したやつの⼀部です

    View Slide

  58. 話は変わってNodePortのNodeの宛先にリクエストされた場合

    “KUBE-NODEPORTS”チェインにマッチする
    Chain KUBE-SERVICES (
    2
    references)


    pkts bytes target prot opt in out source destination


    2 1 2 0
    KUBE-SVC-OI
    3
    ES
    3
    UZPSOHIVZW tcp -- * *
    0
    .
    0
    .
    0
    .
    0
    /
    0 1 0
    .
    9 6
    .
    1 9 1
    .
    1 2 4
    /* default/np-service cluster
    IP */ tcp dpt:
    8 0

    8 7 7 6
    KUBE-SVC-TCOU
    7
    JCQXEZGVUNU udp -- * *
    0
    .
    0
    .
    0
    .
    0
    /
    0 1 0
    .
    9 6
    .
    0
    .
    1 0
    /* kube-system/kube-
    dns:dns cluster IP */ udp dpt:
    5 3

    0 0
    KUBE-SVC-ERIFXISQEP
    7
    F
    7
    OF
    4
    tcp -- * *
    0
    .
    0
    .
    0
    .
    0
    /
    0 1 0
    .
    9 6
    .
    0
    .
    1 0
    /* kube-system/kube-dns:dns-tcp
    cluster IP */ tcp dpt:
    5 3

    0 0
    KUBE-SVC-JD
    5
    MR
    3
    NA
    4
    I
    4
    DYORP tcp -- * *
    0
    .
    0
    .
    0
    .
    0
    /
    0 1 0
    .
    9 6
    .
    0
    .
    1 0
    /* kube-system/kube-
    dns:metrics cluster IP */ tcp dpt:
    9 1 5 3

    2 1 2 0
    KUBE-SVC-ERVH
    2
    TYUWKPRTIBA tcp -- * *
    0
    .
    0
    .
    0
    .
    0
    /
    0 1 0
    .
    9 6
    .
    2 2 0
    .
    1 8 8
    /* default/cip-service cluster
    IP */ tcp dpt:
    8 0

    0 0
    KUBE-SVC-NPX
    4 6
    M
    4
    PTMTKRN
    6
    Y tcp -- * *
    0
    .
    0
    .
    0
    .
    0
    /
    0 1 0
    .
    9 6
    .
    0
    .
    1
    /* default/kubernetes:https
    cluster IP */ tcp dpt:
    4 4 3

    6 3 6 0
    KUBE-NODEPORTS all -- * *
    0
    .
    0
    .
    0
    .
    0
    /
    0 0
    .
    0
    .
    0
    .
    0
    /
    0
    /* kubernetes service nodeports; NOTE: this
    must be the last rule in this chain */ ADDRTYPE match dst-type LOCAL
    ↑は“iptables -t nat -L -n -v” コマンドをちょい整形したやつの⼀部です

    View Slide

  59. 31786ポート宛にリクエストが来た場合


    “KUBE-EXT-OI
    3
    ES
    3
    UZPSOHIVZW”チェインにジャンプして

    更にそこから“KUBE-SVC-OI
    3
    ES
    3
    UZPSOHIVZW”に⾶ばされる
    Chain KUBE-NODEPORTS (
    1
    references)


    target prot opt source destination


    KUBE-EXT-OI
    3
    ES
    3
    UZPSOHIVZW tcp --
    0
    .
    0
    .
    0
    .
    0
    /
    0 0
    .
    0
    .
    0
    .
    0
    /
    0
    /* default/np-service
    */ tcp dpt:
    3 1 7 8 6

    Chain KUBE-EXT-OI
    3
    ES
    3
    UZPSOHIVZW (
    1
    references)


    target prot opt source destination


    KUBE-MARK-MASQ all --
    0
    .
    0
    .
    0
    .
    0
    /
    0 0
    .
    0
    .
    0
    .
    0
    /
    0
    /* masquerade tra
    ff i
    c for default/
    np-service external destinations */


    KUBE-SVC-OI
    3
    ES
    3
    UZPSOHIVZW all --
    0
    .
    0
    .
    0
    .
    0
    /
    0 0
    .
    0
    .
    0
    .
    0
    /
    0
    ↑は“iptables -t nat -L -n -v” コマンドをちょい整形したやつの⼀部です

    View Slide

  60. ざっくりだけどこの流れのようにPodにパケットが届きそうなのが確認できた

    View Slide

  61. その他kube-proxyで設定されるiptables

    View Slide

  62. natテーブル
    νΣΠϯ໊ δϟϯϓݩ આ໌
    KUBE-SERVICES PREROUTING, OUTPUT
    ‧PREROUTINGなどで⾏うKubernetesのNAT処理の

    エントリーポイント
    KUBE-POSTROUTING POSTROUTING
    ‧KUBE-MARK-MASQで設定したマークが無いパケットなら

    何もしない

    ‧マークがあれば、そのマークを消した上で

    MASQUERADEチェインでIPマスカレード(SNAT)を⾏う
    KUBE-MARK-MASQ KUBE-SVC-XXX, KUBE-EXT-XXX, KUBE-SEP-XXX,
    ‧Podから通信を⾏う際にジャンプされる

    ‧MARKチェインを使⽤してパケットに”0x
    4 0 0 0
    ”の

    マークを付ける

    ‧このマークはKUBE-POSTROUTINGでIPマスカレードを

    するかの判定のために利⽤される
    KUBE-NODEPORTS KUBE-SERVICES
    ‧NodePortのためのノードへのアクセス処理⽤

    ‧更にKUBE-EXT-XXXへのジャンプしてServiceにつなげる

    ‧NodePort⽤のポートへのアクセスかのチェックを⾏う
    KUBE-PROXY-CANARY 無し
    ‧natテーブルがkube-proxy外から削除されたかどうかを検出
    するために作成されるチェイン

    ‧そのためこのチェインを使ったnat処理などは特にされない
    ※ 動作検証したものとソースコードの実装からの解説が混ざってます

    View Slide

  63. natテーブル
    νΣΠϯ໊ δϟϯϓݩ આ໌
    KUBE-SVC-XXX KUBE-SERVICES, KUBE-EXT-XXX
    ‧KUBE-SERVICES, KUBE-EXT-XXXからジャンプされる


    ‧ここから更に各Pod IPにDNATを⾏うKUBE-SEP-XXXへと

    ジャンプする

    ‧statistic mode random probabilityを使⽤して利⽤する

    KUBE-SEP-XXXをランダムに振り分ける
    KUBE-EXT-XXX KUBE-NODEPORTS, KUBE-SERVICES
    ‧NodePortのためのノードアクセスの際にKUBE-NODEPORTS
    からジャンプしてくる

    ‧また、externalPsを使⽤してる場合はKUBE-SERVICESから

    ジャンプしてくる

    ‧ここから更にKUBE-SVC-XXXにジャンプすることでServiceに

    接続できるようにする
    KUBE-SEP-XXX KUBE-SVC-XXX
    ‧KUBE-SVC-XXXからジャンプされる

    ‧このチェインに紐づくPod IPに対してDNATを⾏う
    KUBE-SVL-XXX KUBE-SERVICES
    ‧Serviceでspec.internalTra
    ff
    i
    cPolicy: Localを設定したときに
    設定される

    ‧KUBE-SVC-XXXの代わりにKUBE-SVL-XXXが設定される

    ‧KUBE-SVC-XXXと違いローカルにいるPodにのみ

    トラフィックを流す
    KUBE-FW-XXX KUBE-SERVICES
    ‧KUBE-EXT-XXXにジャンプするNATルールを設定する

    ‧ Serviceでtype: LoadBalancerを利⽤していて、
    spec.loadBalancerTra
    ffi
    cChainの設定時のみ

    チェインが設定されるよう
    ※ 動作検証したものとソースコードの実装からの解説が混ざってます

    View Slide

  64. fi
    lterテーブル
    νΣΠϯ໊ δϟϯϓݩ આ໌
    KUBE-SERVICES FORWARD, OUTPUT
    ‧設定したServiceがEndpointを持たない場合にDROPもしくは
    REJECTを⾏う設定が追加される
    KUBE-EXTERNAL-
    SERVICES
    INPUT, FORWARD
    ‧Endpointが無いケースなどにREJECTやDROPが

    設定されるよう
    KUBE-NODEPORTS INPUT
    ‧ Serviceでtype: LoadBalancerを利⽤していて、

    .specexternalTra
    ffi
    cPolicy: Localを指定していて、

    かつ.spec.healthCheckNodePortを指定している場合に

    指定のポートからのパケットをACCEPTするよう
    KUBE-FORWARD FORWARD
    ‧FORWARDの際”ctstate INVALID”なパケットはDROPする


    ‧KUBE-MARK-MASQで設定される”0x
    4 0 0 0
    ”マークがあれば
    ACCEPTする

    ‧”ctstate RELATED,ESTABLISHED”であればACCEPTする
    KUBE-PROXY-
    FIREWALL
    INPUT, FORWARD, OUTPUT
    ‧Serviceでtype: LoadBalancerを利⽤していて、

    .spec.loadBalancerIPStringsを設定している場合のDROP設定を
    ⾏うよう
    KUBE-FIREWALL INPUT, OUTPUT
    ‧外部から127.0.0.0/8(ループバックアドレス)への

    アクセスを⾏うパケットをDROPする
    KUBE-PROXY-CANARY 無し

    fi
    lterテーブルがkube-proxy外から削除されたかどうかを検出
    するために作成されるチェイン

    ‧そのためこのチェインを使った
    fi
    lter処理などは特にされない
    ※ 動作検証したものとソースコードの実装からの解説が混ざってます

    View Slide

  65. mangleテーブル
    νΣΠϯ໊ δϟϯϓݩ આ໌
    KUBE-PROXY-CANARY 無し
    ‧mangleテーブルがkube-proxy外から削除されたかどうかを検
    出するために作成されるチェイン

    ‧そのためこのチェインを使った処理などは特にされない

    ‧ちなみにkube-proxyは他でmangleテーブルにチェインを設定
    しないので、これはいらないんじゃないかという

    気がするんだけどどうなんでしょう?
    ※ 動作検証したものとソースコードの実装からの解説が混ざってます

    View Slide

  66. まとめ

    View Slide

  67. まとめ
    ▶ kube-proxyのアーキテクチャとiptablesモードの際にkube-proxyが設定する

    iptablesの設定について解説しました


    ▶ ちゃんとiptablesについて調べたのはこれが初めてだったので勉強になりました

    (kube-proxyが⾏うiptablesの設定の概要は知ってましたが、改めてコード読んだり

    動作確認してみて思ったんですけどiptablesっていろんなことできるんですね)


    ▶ 僕みたいにネットワークに詳しく無い⼈には勉強の取っ掛かりになるのでオススメです


    ▶ kube-proxyのコード読んだり動作検証した際のメモもあるので良ければ⾒てください

    View Slide

  68. 参考資料
    ▶ https://github.com/kubernetes/kubernetes/tree/v
    1
    .
    2 8
    .
    2

    ▶ https://speakerdeck.com/ryusa/servicewotazunete
    3 0 0 0
    xing-
    kuberneteskodorideingufalselu


    ▶ https://qiita.com/Tocyuki/items/
    6
    d
    9 0
    a
    1
    ec
    4
    dd
    8
    e
    9 9 1
    a
    1
    ce


    ▶ https://oxynotes.com/?p=
    6 3 6 1
    #
    5

    ▶ https://atmarkit.itmedia.co.jp/ait/articles/
    1 0 0 2
    /
    0 9
    /news
    1 1 9
    .html


    ▶ https://hana-shin.hatenablog.com/entry/
    2 0 2 2
    /
    0 6
    /
    2 1
    /
    2 1 5 7 5 7

    ▶ https://qiita.com/syui/items/
    2 7 0 2 0
    b
    9 7 0 7 7 5
    a
    0
    c
    5 0 8
    ba


    ▶ https://www.digitalocean.com/community/tutorials/iptables-essentials-common-
    fi
    rewall-
    rules-and-commands


    ▶ https://www.asahi-net.or.jp/~aa
    4
    t-nngk/ipttut/output/explicitmatches.html


    ▶ https://github.com/torvalds/linux/blob/master/Documentation/networking/nf_conntrack-
    sysctl.rst


    ▶ https://tech-blog.rakus.co.jp/entry/
    2 0 2 2 0 3 0 1
    /iptables


    ▶ https://linuxjm.osdn.jp/html/iptables/man
    8
    /iptables-extensions.
    8
    .html


    ▶ https://man.archlinux.org/man/conntrack.
    8
    .en


    ▶ https://nomeu.net/
    8 3 8 0
    /


    ▶ https://knowledge.sakura.ad.jp/
    4 0 4 8
    /


    ▶ https://docs.openshift.com/container-platform/
    4
    .
    1 0
    /rest_api/network_apis/service-
    v
    1
    .html


    ▶ https://stackover
    fl
    ow.com/questions/
    7 5 8 3 5 1 6 9
    /kubernetes-loadbalancer-how-does-
    healthchecknodeport-work


    ▶ https://github.com/kubernetes/kubernetes/pull/
    8 1 5 1 7
    /commits/
    3 9 4 8
    f
    1 6 ff 4 0 6 0 9 5 5
    b
    7
    f
    2 5
    d
    2 6
    d
    2 6 1
    b
    9 9 5 8 9 9 6 3
    ade
    ▶ https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/
    #preserving-the-client-source-ip


    ▶ https://kubernetes.io/docs/concepts/services-networking/service-tra
    ff i
    c-policy/


    ▶ https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/


    ▶ https://hyoublog.com/
    2 0 2 0
    /
    0 5
    /
    2 0
    /kubernetes-externalip-service/


    ▶ https://qiita.com/dingtianhongjie/items/
    8
    f
    3
    c
    3 2 0
    c
    4
    eb
    5
    cf
    2 5
    d
    9
    de


    ▶ https://milestone-of-se.nesuke.com/nw-basic/as-nw-engineer/loopback-address-interface/


    ▶ https://kubernetes.io/docs/reference/networking/virtual-ips/


    ▶ https://kubernetes.io/docs/concepts/services-networking/service/


    ▶ https://kubernetes.io/ja/docs/concepts/services-networking/connect-applications-service/


    ▶ https://knowledge.sakura.ad.jp/
    2 2 6 3 6
    /


    ▶ https://net
    fi
    lter.org/index.html


    ▶ https://madomadox.hatenablog.com/entry/
    2 0 2 1
    /
    0 1
    /
    0 3
    /
    1 9 0 7 3 0

    ▶ https://qiita.com/bashaway/items/e
    4 0 5
    d
    5 9
    d
    9 2 6 7 0
    fbc
    5 3 4 1

    ▶ https://www.digitalocean.com/community/tutorials/a-deep-dive-into-iptables-and-
    net
    fi
    lter-architecture


    ▶ https://tech-blog.rakus.co.jp/entry/
    2 0 2 2 0 3 0 1
    /iptables


    ▶ https://www.asahi-net.or.jp/~aa
    4
    t-nngk/ipttut/output/explicitmatches.html


    ▶ https://eng-entrance.com/linux-
    fi
    rewall


    ▶ https://github.com/kubernetes/kubernetes/issues/
    3 7 9 3 2

    ▶ https://github.com/aojea/kindnet?tab=readme-ov-
    fi
    le#kindnet-components


    ▶ https://github.com/aojea/kindnet/blob/
    3 5
    d
    8 3 4 8 8
    ea
    2
    b
    5
    ef
    1 8 3
    c
    5 5
    a
    4
    c
    7
    a
    1 6
    f
    4 4 5 9 4 9 0 8 9
    ae/
    cmd/kindnetd/routes.go#L
    2 7
    -L
    5 3

    View Slide

  69. 画像引⽤元
    ▶ https://github.com/kubernetes/community/tree/master/icons


    ▶ https://github.com/kubernetes/kubernetes/tree/master/logo


    ▶ https://github.com/cncf/artwork/tree/master/projects/kubernetes


    ▶ https://github.com/kubernetes/kubeadm/tree/main/logos

    View Slide

  70. コードリーディングメモ
    ▶ https://zenn.dev/bells
    1 7
    /scraps/
    5
    e
    4 1
    da
    5 9 8
    a
    8 2 6 6

    ▶ コード読んだり動作検証したりのメモ⽤なのできれいに情報整理
    できてるわけじゃないけどコードの中⾝読んでいきたい場合は

    参考になるかも

    View Slide

  71. Thanks / Question?
    ▶ @bells
    1 7

    ▶ Slide: https://speakerdeck.com/bells
    1 7

    ▶ @bells
    1 7
    _

    View Slide