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

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. ▶ @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
  2. 注意点 ▶ Kubernetes v 1 . 2 8 . 2

    ベースでのお話になります ▶ KubernetesそのものやKubernetes Component全体の説明は簡単なものに なるかと思います ▶ あくまでkube-proxyの実装を追った結果での理解の説明になるので、 
 間違いが含まれている可能性があります ▶ 特にネットワーク初⼼者なので、ネットワーク周りの説明は 
 間違いが多いかも…
  3. Kubernetes とは? ▶ Kubernetesはコンテナオーケストレーターの1つ ▶ etcd/control plane/worker nodeによって構成されたクラスターを構築し、 
 様々なコンテナをKubernetes上のnodeで動作させたり、動作させてる

    
 コンテナとネットワークをいい感じに連携できるようにすることができる ▶ デプロイするコンテナなどをmanifestファイルで宣⾔的に記述することで、 
 宣⾔した状態になるようにKubernetesがいい感じに調整処理を⾏ってくれる ▶ Googleが内部で運⽤していたコンテナ基盤であるBorgを 
 OSS向けに作り直したコンテナオーケストレーター ▶ また、KubernetesはCloud Native Computing Foundation(CNCF)に寄贈されており、 CNCFのGraduatedプロジェクトとしてコミュニティベースで管理されている
  4. 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
  5. 基本パターン ▶ Managerプロセス全体の中で1つ、または複数のコントローラーが実⾏ される ▶ コントローラーは1つにつき、1種類のKubernetesリソースのみに対す る調整ループ(Reconciliation Loop)が実⾏される + 調整ループ:

    リソースのあるべき状態(Desired State)と実際の状態 (Actual State)を⽐較~あるべき状態になるように調整処理を⾏うもの + なので、2種類のリソースに対しては、最低2コントローラー以上が 
 あるのが基本
  6. 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
  7. 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リソースに基づくネットワーク設定を⾏うアプリケーション
  8. ▶ Cloud Controller Manager Deep Dive ▶ Kubernetes Internal #

    2 Cloud Controller Managerについては以下のスライドで まとめてあるので参考にしてください
  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
  10. 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 のデュアルスタックのサポートも有り
  11. 補⾜: 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のイメージ
  12. 今回の解説の前提 ▶ OS: Linuxを使⽤ ▶ 動作モード: iptablesモード ▶ IPv 4

    のみを使⽤する想定です ▶ 設定値は基本デフォルトのものを想定してます ▶ 検証はkindで⾏っているのでCNIはkindnetが使⽤されています
  13. ipt.Monitor ▶ ipt=iptablesのこと(多分) ▶ “KUBE-PROXY-CANARY” というチェインを下記のテーブルに作成する + mangle + nat

    + fi lter ▶ 作成後、上記チェインがあるかどうかを監視する ▶ もしチェインが削除されたらproxier.syncProxyRulesを実⾏して、再度“KUBE-PROXY-CANARY” チェインの作成~監視に戻る ▶ → “KUBE-PROXY-CANARY” チェインを作って監視することで iptables のルールを削除されてな いかをチェックしてる 
 (ルールが⼤量にあるとパフォーマンスに影響してくるからルールが存在しない空っぽの チェイ ンを作って監視してるとのこと)
  14. iptablesの基本 ▶ 外部ネットワークからパケットを受信した際にテーブルと 
 テーブル内のチェインの設定に応じてパケットのフィルタリングなどの 
 処理を⾏うことができる ▶ iptablesではnetlinkを介してカーネルのnet fi

    lterの設定を⾏うことが可能で、 
 net fi lterはネットワークパケット処理の各段階でフックを使ってコールバック関数を実⾏す ることで各種操作を実現してるらしい ▶ nftablesというiptablesの後継があるらしい ざっくりこんな感じという理解です
  15. 主なテーブルとチェイン ▶ 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
  16. 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
  17. 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台のノードを起動する
  18. Service 
 type: ClusterIP apiVersion: v 1 kind: Service metadata:

    name: cip-service spec: selector: app: nginx ports: - protocol: TCP port: 8 0 type: ClusterIP
  19. Service 
 type: NodePort apiVersion: v 1 kind: Service metadata:

    name: np-service spec: selector: app: nginx ports: - protocol: TCP port: 8 0 type: NodePort
  20. 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台ずつ配置されるはず
  21. クラスター外からの接続確認 $ 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: 接続できる ちゃんと検証したことなかったけどクラスターに参加してるノードからならクラスター外からのアクセスも可能なのか
  22. クラスター内からの接続確認 $ 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
  23. クラスターに参加してないノードからだとこんな感じ 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のデフォルトクラスターが⽴ってたのでそれで検証した
  24. 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” コマンドをちょい整形したやつの⼀部です
  25. 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に通信が届かないっぽい?
  26. 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 <none> 8 0 : 3 1 7 8 6 /TCP 1 9 h cip-service ClusterIP 1 0 . 9 6 . 2 2 0 . 1 8 8 <none> 8 0 /TCP 1 3 2 m
  27. “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” コマンドをちょい整形したやつの⼀部です
  28. 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” コマンドをちょい整形したやつの⼀部です
  29. 作成した各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
  30. 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
  31. “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 : <BROADCAST,MULTICAST,UP,LOWER_UP> 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 本体が⾏っている
  32. “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” コマンドをちょい整形したやつの⼀部です
  33. 話は変わって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” コマンドをちょい整形したやつの⼀部です
  34. 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” コマンドをちょい整形したやつの⼀部です
  35. 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処理などは特にされない ※ 動作検証したものとソースコードの実装からの解説が混ざってます
  36. 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の設定時のみ 
 チェインが設定されるよう ※ 動作検証したものとソースコードの実装からの解説が混ざってます
  37. 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処理などは特にされない ※ 動作検証したものとソースコードの実装からの解説が混ざってます
  38. mangleテーブル νΣΠϯ໊ δϟϯϓݩ આ໌ KUBE-PROXY-CANARY 無し ‧mangleテーブルがkube-proxy外から削除されたかどうかを検 出するために作成されるチェイン 
 ‧そのためこのチェインを使った処理などは特にされない

    
 ‧ちなみにkube-proxyは他でmangleテーブルにチェインを設定 しないので、これはいらないんじゃないかという 
 気がするんだけどどうなんでしょう? ※ 動作検証したものとソースコードの実装からの解説が混ざってます
  39. まとめ ▶ kube-proxyのアーキテクチャとiptablesモードの際にkube-proxyが設定する 
 iptablesの設定について解説しました ▶ ちゃんとiptablesについて調べたのはこれが初めてだったので勉強になりました 
 (kube-proxyが⾏うiptablesの設定の概要は知ってましたが、改めてコード読んだり 


    動作確認してみて思ったんですけどiptablesっていろんなことできるんですね) ▶ 僕みたいにネットワークに詳しく無い⼈には勉強の取っ掛かりになるのでオススメです ▶ kube-proxyのコード読んだり動作検証した際のメモもあるので良ければ⾒てください
  40. 参考資料 ▶ 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
  41. コードリーディングメモ ▶ https://zenn.dev/bells 1 7 /scraps/ 5 e 4 1

    da 5 9 8 a 8 2 6 6 ▶ コード読んだり動作検証したりのメモ⽤なのできれいに情報整理 できてるわけじゃないけどコードの中⾝読んでいきたい場合は 
 参考になるかも