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

OpenShift-K8s 情報共有会 Network/K8s Network Basics

OpenShift-K8s 情報共有会 Network/K8s Network Basics

A9d0b414035afe78da47980a90e62b68?s=128

suzukiry

March 17, 2021
Tweet

Transcript

  1. OpenShift-K8s 情報共有会 Network 3⽉分

  2. https://v1-17.docs.kubernetes.io/ja/docs/concepts/overview/components/

  3. Network

  4. Kubernetes ネットワーク No . 接続⼿段 ホスト 接続Pod いわゆる Pod Networking

    (bridge, veth) Cluster Networking (CNI: VXLAN, BGP) kubelet Service Discovery (Services, CoreDNS, kube-proxy) Ingress 1 IPアドレス 同⼀ホスト内 同⼀Pod内 コンテナ to コンテナ ✔ ✔ 2 同⼀ホスト内 異なるPod Pod to Pod (同じノード) ✔ ✔ 3 異なるホスト 異なるPod Pod to Pod (異なるノード) ✔ ✔ ✔ 4 DNS 同⼀ホスト内 異なるPod Pod to Service (同じノード) ✔ ✔ ✔ 5 異なるホスト 異なるPod Pod to Service (異なるノード) ✔ ✔ ✔ ✔ 6 外部接続 ✔ ✔ ✔ ✔ ✔
  5. IPアドレス接続 No.1 コンテナ to コンテナ No.2 Pod to Pod (同じノード)

    No.3 Pod to Pod (異なるノード) ホスト Pod コンテナ IPアドレス IPアドレス IPアドレス まずはPodのネットワークの理解が必要 → ここが次のPod Networkingのお話
  6. Pod Networking (bridge, veth) IPアドレス接続

  7. NODE 1 Pod Networking (bridge, veth) • IP-per-Podネットワークモデル • Network

    namespaceを利⽤。NW nsとは、NW IF(veth, bridge)とRouting Tableの集合体 • NamespaceごとにRouting TableとARP Tableが存在 • IPアドレスはNamespace単位。 • なので同じポッド内のすべてのコンテナはIPアドレスやネットワークポートなどポッドの ネットワークネームスペースを共有しており、localhostのアドレスとコンテナのポートを 介して相互にアクセスできるようになっています。 • コンテナ⽣成時にNW設定がされる(ここがkubeletとCNI) • NW ns作成 • Bridge、NW IF作成 • 各PodにIPアドレスを割り当て • NAT(ex 8080→80)も。これはServiceで使う? https://access.redhat.com/documentation/en-us/openshift_container_platform/3.7/html-single/architecture/index https://www.praqma.com/stories/debugging-kubernetes-networking/ https://01.org/kubernetes/blogs/qwang10/2019/introduction-kubernetes-networking-and-acceleration-dpdk veth0 10.1.15.2/24 cbr0 10.1.15.1/24 veth0 10.1.15.3/24 NW ns NW ns ARP Table Rou, ng Table ARP Table Rou, ng Table eth0 192.168.0.100 NW ns ARP Table Rou, ng Table 他ノードへ ここにCNIのデーモンがいて、 Cluster間の通信は対応してくれる ✔No.1 コンテナtoコンテナ ✔No.2 Pod to Pod(同じノード) ✔No.3 Pod to Pod(異なるノード)
  8. 動作例 hFps://maFhewpalmer.net/kubernetes-app-developer/arHcles/kubernetes-networking-guide-beginners.html Node No.1 コンテナ to コンテナ No.2 Pod to

    Pod(同じノード) No.3 Pod to Pod(異なるノード) → ここが次のCluster Networkingのお話 Pod Networking (bridge, veth)
  9. Cluster Networking (CNI: VXLAN, BGP) IPアドレス接続

  10. Cluster Networking (CNI: VXLAN, BGP) • Cluster Networkingの⼿法は2つ Bridge⽅式 Point-to-Point⽅式

    概要 代表的な実装 flannel, weave Open vSwitch (多分こっち) Calico hFps://speakerdeck.com/ymmt2005/kuo-zhang-xing-falsegao-i-cni-puraguin-coil-v2-falseshao-jie?slide=12 (Open vSwitchのメリット)hFps://rheb.hatenablog.com/entry/openshiS42ovn ホスト側のNetwork Namespaceに 仮想Bridgeを作成し、各Pod⽤に 作ったvethのホスト側が、bridge に接続されることで、Podとホス トが通信できるようにする⽅式 直接それぞれのPodに対応する vethにルーティングする⽅式 (⼀度仮想bridgeにルーティング して、ARPでつながってるNICの MACアドレスを解決して通信しな い) こうした手法が、CNIプラグインとして提供されていて、要件に合わせてユーザ が選択する(Kubernetesで関与しない) → これが次のCNIのお話
  11. CNI IPアドレス接続

  12. CNI (Cluster Network Interface) • Network namespace、docker、rkt 、Mesos、KubernetesなどそれぞれのコンテナNWの作成ステップを標準化 • CNI要件(⼀部)

    • コンテナランタイムは、CNIプラグインを起動する前に、コンテナ⽤の新しいネットワークネームスペースを作成しなければなりません。 • コンテナランタイムは、コンテナがどのネットワークに属するべきかを決定し、各ネットワークに対して、どのプラグインを実⾏しなければならないかを決定しなければなりませ ん。 • ネットワーク設定はJSON形式。 • コンテナランタイムは、各ネットワークに対応するプラグインを順次実⾏することにより、コンテナを各ネットワークに追加しなければならない。 • コンテナのライフサイクルが完了すると、ランタイムは、コンテナをネットワークから切り離すために、プラグインを逆順に(コンテナを追加するために実⾏された順番と相対 的に)実⾏しなければなりません。 などなど h"ps://github.com/containernetworking/cni h"ps://github.com/containernetworking/cni/blob/master/SPEC.md NW設定のためのキーワード: 1.コンテナランタイムが、 プラグインを実⾏。 プラグインは順次実⾏ 2.設定はJSON形式。
  13. CNIの代表的な実装例 https://itnext.io/benchmark-results-of-kubernetes-network-plugins-cni-over-10gbit-s-network-36475925a560

  14. kubelet IPアドレス接続

  15. kubelet (とCNIプラグイン) • プラグインは数珠つなぎで実⾏。ネットワークの設定はjson形式で⾏われる。 kubelet controlplane $ ps -aux |

    grep kubelet /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --config=/var/lib/kubelet/config.yaml --cgroup-driver=systemd --network-plugin=cni --pod-infra-container-image=k8s.gcr.io/pause:3.1 --cni-bin-dir=/opt/cni/bin controlplane $ ls /opt/cni/bin bandwidth dhcp host-device ipvlan macvlan ptp static vlan weave-net bridge firewall host-local loopback portmap sbr tuning weave-ipam weave-plugin-2.8.1 controlplane $ ls /etc/cni/net.d/ 10-weave.conflist controlplane $ cat /etc/cni/net.d/10-weave.conflist { "cniVersion": "0.3.0", "name": "weave", "plugins": [ { "name": "weave", "type": "weave-net", "hairpinMode": true }, { "type": "portmap", "capabilities": {"portMappings": true}, "snat": true } ] } ※ipam部分の設定は、weave ではなし。 なぜなら常に10.32.0.1/12からIP アドレスをアサインするから。 weave plugin weave-net plugin weave-ipam plugin プラグインのbinaryがここに存在。 NWの定義がここに存在。
  16. kubelet (とCNIプラグイン) • flannelの場合 整理しながら理解するKubernetesネットワークの仕組み(早川さん) https://speakerdeck.com/hhiroshell/kubernetes-network-fundamentals-69d5c596-4b7d-43c0-aac8-8b0e5a633fc2?slide=31

  17. kubelet (からコンテナができるまでの流れ) • CNIやCSI(Container Storage I/F)もコンテナを作る過程でプラグインが呼び出される ※改めてコンテナとは、振り返るにはこちら↓ コンテナランタイムはじめの⼀歩(太⽥さん) hFps://speakerdeck.com/inductor/container-runGme-101?slide=6 hFps://kubernetes.io/blog/2017/11/containerd-container-runGme-opGons-kubernetes/#architecture

  18. Podでできるもの https://kubernetes.io/blog/2017/11/containerd-container-runtime-options-kubernetes/#architecture controlplane $ kubectl get pod --all-namespaces -o wide

    NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES kube-system coredns-f9fd979d6-p524v 1/1 Running 1 10m 10.32.0.2 node03 <none> <none> kube-system coredns-f9fd979d6-t7ngg 1/1 Running 2 11m 10.40.0.1 node02 <none> <none> kube-system etcd-controlplane 1/1 Running 0 12m 172.17.0.36 controlplane <none> <none> kube-system kube-apiserver-controlplane 1/1 Running 0 12m 172.17.0.36 controlplane <none> <none> kube-system kube-controller-manager-controlplane 1/1 Running 0 12m 172.17.0.36 controlplane <none> <none> kube-system kube-proxy-gcvqr 1/1 Running 0 11m 172.17.0.36 controlplane <none> <none> kube-system kube-proxy-gmr54 1/1 Running 1 11m 172.17.0.73 node02 <none> <none> kube-system kube-proxy-k6z26 1/1 Running 2 11m 172.17.0.74 node03 <none> <none> kube-system kube-proxy-sd9q2 1/1 Running 2 11m 172.17.0.72 node01 <none> <none> kube-system kube-scheduler-controlplane 1/1 Running 0 12m 172.17.0.36 controlplane <none> <none> kube-system weave-net-8lz8p 2/2 Running 3 11m 172.17.0.72 node01 <none> <none> kube-system weave-net-gkxbn 2/2 Running 3 11m 172.17.0.73 node02 <none> <none> kube-system weave-net-kbs94 2/2 Running 3 11m 172.17.0.74 node03 <none> <none> kube-system weave-net-lstl4 2/2 Running 1 11m 172.17.0.36 controlplane <none> <none>
  19. 改めて、 Cluster Networking IPアドレス接続

  20. 改めて、Cluster Networking hFps://docs.openshiS.com/container-plaYorm/3.11/admin_guide/sdn_troubleshooHng.html#sdn-flows-inside-a-node iptableは、どこにあるのか? → これが次のflannelでのNW構成のお話。

  21. 改めて、Cluster Networking flannelでのNW構成 VXLANデバイス hFps://tech-lab.sios.jp/archives/7857

  22. 改めて、Cluster Networking flannelでのNW構成 iptable VXLANデバイス※ iptable root nwns pod2 nwns

    pod1 nwns root nwns iptableルール(これ大事) hFps://tech-lab.sios.jp/archives/7857 ※flannel.1はVXLANデバイスで、これ らが持つ転送ルールは、etcdに保存 されている。
  23. DNS (もはやServiceの話) • これから話すServiceを使わずとも、IPアドレスではPod間通信は可能です(前述のとおり)。 • Serviceを使うのは、以下を利⽤したいからです。 ロードバランシング • ロードバランシング •

    複数ポートの割り当て • 名前によるポートの参照 (異なるポートの指定が可能) サービスディスカバリ • 環境変数を使ったサービスディスカバリ • Aレコード使ったサービスディスカバリ • SRVレコードを使ったサービスディスカバリ
  24. DNS Service

  25. Service • Serviceのtype(とりあえず取り上げるのは前の2つ) • ClusterIP:クラスタ内部 • NodePort:クラスタ外部 • LoadBalancer:CSPのロードバランサーを使って、 サービスディスカバリ/ロードバランシングできる

    • ExternalIP • Headless • ExternalName • None-Selector
  26. Service – ClusterIP • クラスタ内の仮想IPで、サービスディスカバリ/ロードバランシングできる • クラスタ内に閉じたサービスとして利⽤する際は、Service(type: ClusterIP)を使えば良い Pod1 veth0

    docker0 flannel eth0 veth0 docker0 iptable flannel eth0 veth0 docker0 iptable flannel eth0 Pod2 Pod3 10.8.0.16 10.8.0.17:80 10.8.0.18:80 ClusterIP Service (10.11.253.80:8080)
  27. Service – ClusterIP Pod1 veth0 docker0 iptable flannel eth0 veth0

    docker0 iptable flannel eth0 veth0 docker0 iptable flannel eth0 Pod2 Pod3 10.8.0.16 10.8.0.17:80 10.8.0.18:80 10.11.253.80:8080が来たら以下のいずれかにLB → 10.8.0.17:80へDNAT → 10.8.0.18:80へDNAT DST: 10.11.253.80 SRC:10.8.0.16 DST: 10.8.0.17 SRC:10.8.0.16 DST: (Nod2 eth0) SRC: flannel.1 • 実際は、全ノードのiptableに共通の変換ルールを追加。 1. ServiceのIPアドレスの払い出しは、api-serverに設定箇所があります。 2. Serviceの仮想的なIPアドレスをiptableでDNAT(SNATも?)して、ロードバランシングを⾏っている。 3. kube-proxyが iptableの更新する※。Serviceが作成されるごとに担当ノードのiptableを更新している。 kube- proxy kube- proxy kube- proxy 1 2 3 Service作成時 ※kube-proxyは、 userspace,iptables,ipvsのモードが選択 が可能。
  28. Service – NodePort • 全てのノードのIPアドレス:Portで、 サービスディスカバリ/ロードバランシングできる Pod1 veth0 docker0 eth0

    veth0 docker0 eth0 veth0 docker0 eth0 Pod2 Pod3 10.8.0.16 10.8.0.17:80 10.8.0.18:80 NodePort Service (*:30080)
  29. Service Discovery • Serviceを使うと、内部DNSでサービスディスカバリが可能になる • Aレコード • SRVレコード 整理しながら理解するKubernetesネットワークの仕組み(早川さん) hFps://speakerdeck.com/hhiroshell/kubernetes-network-fundamentals-69d5c596-4b7d-43c0-aac8-8b0e5a633fc2?slide=31

    K8sの内部DNSとは? → これが次のCoreDNSのお話。
  30. DNS CoreDNS

  31. CoreDNS • Core DNSもPodで構築 • クラスタのPodへの公開のため、Serviceで CoreDNSを公開 • 新規Serviceの作成・削除をWatchするこ とでレコードを更新※

    service: kube-dns deployment: coredns replicaset: coredns-f9fd979d6 pod: coredns-f9fd979d6- 4mzjf pod: coredns-f9fd979d6- l9hn5 Master Node ※どこに作る指定はないが、マスターノードが良さそう configmap: coredns /etc/coredns/ Corefile .:53 { errors health { lameduck 5s } ready kubernetes cluster.local in-addr.arpa ip6.arpa { pods insecure fallthrough in-addr.arpa ip6.arpa ttl 30 } prometheus :9153 forward . /etc/resolv.conf { max_concurrent 1000 } cache 30 loop reload loadbalance } etcd ・特定のドメイン以外の問い合わせ は /etc/resolv.conf を参照して外部の DNSサーバに回すことも可能 ・DNSサフィックス の保管の設定もこ ちらのファイルへ トップレベルドメイン名がここ ※レコードの保存先は、etcdにするこ ともできるそう https://nnstt1.hatenablog.com/entry/2020/11/13/070000
  32. CoreDNS service: kube-dns deployment: coredns replicaset: coredns-f9fd979d6 pod: coredns-f9fd979d6- 4mzjf

    pod: coredns-f9fd979d6- l9hn5 Master Node controlplane $ cat /var/lib/kubelet/config.yaml apiVersion: kubelet.config.k8s.io/v1beta1 : cgroupDriver: systemd clusterDNS: - 10.96.0.10 clusterDomain: cluster.local cpuManagerReconcilePeriod: 0s : Worker Node port:53 configmap: coredns /etc/coredns /Corefile kubelet etcd api-server service1 service2 service3 host IP addr 10-244-1-5 10.244.1.5 service1 10.107.37.188 service2 10.107.38.199 service3 10.107.39.200 10.96.0.10 • DNSレコードが作られるタイミング
  33. DNS Ingress

  34. Ingress • L7 ロードバランシングを⾏いたい場合に利⽤ • Serviceだけでは、L4 ロードバランシング。 • 実装例 •

    クラスタ外のLBを利⽤したIngress • GKE Ingress • クラスタ内にIngress⽤Controllerを⽤意するIngress • Nginx Ingress • HAProxy (OpenShiftはデフォルトがこれ) apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ingress-service-1-and-2 namespace: app-space annotations: nginx.ingress.kubernetes.io/rewrite-target: / nginx.ingress.kubernetes.io/ssl-redirect: "false" spec: rules: - http: paths: - path: /service1 backend: serviceName: service1-service servicePort: 8080 - path: /service2 backend: serviceName: service2-service servicePort: 8080 Nginx Ingress 例 つまり各L7ロードバランサー(ALB)によって、Controllerがいて、そ れに準じたIngressリソースを書くという。カスタムリソースに向かっ て書いてる感じですかね。 → 実装例が次のお話。
  35. Ingress 実装例 ・クラスタ外のLBを利⽤したIngress ・クラスタ内にIngress⽤Controllerを⽤意するIngress GLB /service1 -> service1-svc /service2 ->

    service2-svc NodePort Service : service1-svc NodePort Service : service2-svc NodePort Service : service1-svc NodePort Service : service2-svc LoadBalancer Service : Ingress-controller NodePort Service : Ingress-con-svc Ingress-controller
  36. Ingress 実装例 ・クラスタ外のLBを利⽤したIngress ・クラスタ内にIngress⽤Controllerを⽤意するIngress GLB /service1 -> service1-svc /service2 ->

    service2-svc NodePort Service : service1-svc NodePort Service : service2-svc NodePort Service : service1-svc NodePort Service : service2-svc LoadBalancer Service : Ingress-controller NodePort Service : Ingress-con-svc Ingress-controller ⾚枠がIngressリソースが⾯倒⾒てくれるところ
  37. Ingress vs Route (OpenShift)