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

GKE/Kubernetes の Service はどう動いているのか

apstndb
April 20, 2017

GKE/Kubernetes の Service はどう動いているのか

2017/04/20 Kubernetes Meetup Tokyo #4

apstndb

April 20, 2017
Tweet

More Decks by apstndb

Other Decks in Technology

Transcript

  1. GKE/Kubernetes の Service
    はどう動いているのか
    株式会社アカツキ
    @apstndb

    View Slide

  2. 自己紹介
    ● 現職の前はニート
    ○ クラウドもインフラも未経験
    ● AWS 中心の企業の新規事業プロジェクトに参加(2016/6)
    ○ GKE 上で RoR, NodeJS, Elixir/Phoenix(, Go)
    ● 世界で70人目の Google 公認プロフェッショナルクラウドアー
    キテクトに(2017/2)

    View Slide

  3. apstndb
    ● 皆さんご存知 OSI 7 階層モデル
    ○ アプリケーション層
    ○ プレゼンテーション層
    ○ セッション層
    ○ トランスポート層
    ○ ネットワーク層
    ○ データリンク層
    ○ 物理層
    ● 今回はネについて重点的にやります

    View Slide

  4. 経緯
    ● 自分の Kubernetes クラスタのネットワーク周りどう動いているか説
    明できますか?
    ● Slack で説明しようとして理解していないことに気付く

    View Slide

  5. 経緯
    ● 分からないまま運用するのは怖い
    ● というわけで調べた
    ○ GKE/Kubernetes でなぜ Pod と通信できるのか
    ○ http://qiita.com/apstndb/items/9d13230c666db80e74d0
    ● Google Cloud Next '17 にて Kubernetes の Tech Lead Tim
    Hockin から GKE/Kubernetes ネットワークの解説!
    ○ The ins and outs of networking in Google Container Engine
    and Kubernetes
    ○ https://www.youtube.com/watch?v=y2bhV81MfKQ

    View Slide

  6. 目的
    ● 公式に説明されているものと検証した内容を両方合わせてよ
    り深く理解しよう!
    ● ※ GCP 以外で動かしている方には自分たちの環境でどこが
    違うかとかぜひコメントしていただきたいです!

    View Slide

  7. Kubernetes の通信
    Cluster Networking より
    ● Pod 内コンテナ間通信(localhost 通信)
    ● Pod の通信(Kubernetes ネットワーク)
    ● Pod から Service への通信(ClusterIP Service)
    ● クラスタ外部から Service への通信(NodePort,
    LoadBalancer Service)

    View Slide

  8. Node 内の Pod 間通信
    Node 内の仮想ブリッジ cbr0 の先は ARP 解決可能
    ● Node ←→ Pod, Pod ←→ Pod
    Node
    eth0
    cbr0
    vethxx vethyy
    pod1 netns pod2 netns
    eth0
    eth0

    View Slide

  9. Node を跨ぐ通信
    Kubernetes ネットワークは下記を要求
    1. 全 Pod はクラスタ内の全 Pod と直接(NAT なしで)通信可
    2. 全 Node はクラスタ内の全 Pod と直接通信可
    3. Pod は自分自身の IP アドレスにアクセス可
    Node1 Node2
    Pod1a
    Pod1b
    Pod2b
    Pod2b
    1
    2
    3

    View Slide

  10. コンテナネットワークの実装
    要件さえ満たせば実装は自由
    ● トンネリングによるオーバレイネットワーク
    ○ Flannel とか
    ● BGP ルーティング
    ○ Calico
    ● L2, L3 転送
    ● 実装によっては NetworkPolicy のサポートがある

    View Slide

  11. GCE/GKE での Node を超えた通信
    ● Pod への通信
    ○ Node のインスタンスは canIpForward=true 設定済
    ■ src が Pod のままパケットを別の Node に送信可
    ■ NAT 不要
    ● Pod からの通信
    ○ GCE ルートで Pod の IP アドレスから Node に転送
    ■ トンネリング等不要

    View Slide

  12. GCE/GKE での Node を超えた通信
    Node ごとに設定される GCE ルート
    node1
    PodCIDR: 10.76.0.0/24
    node2
    PodCIDR: 10.76.1.0/24
    pod1
    IP: 10.76.0.1
    pod2
    IP: 10.76.1.1
    DEST_RANGE NEXT_HOP
    10.76.0.0/24 node1
    10.76.1.0/24 node2
    src:10.76.0.1
    dst:10.76.1.1

    View Slide

  13. GCE/GKE での Pod からクラスタ外への通信
    ● Pod の IP アドレスはプライベート
    ○ インターネットとの通信不可
    ● インターネットあてのパケットは送信元を Node(GCE インスタンス)
    の IP アドレスに変換
    ○ Source NAT(別名 IP マスカレード)
    -A POSTROUTING ! -d 10.0.0.0/8
    -m comment --comment "kubenet: SNAT for outbound traffic from cluster"
    -m addrtype ! --dst-type LOCAL
    -j MASQUERADE

    View Slide

  14. Pod からクラスタ外への通信
    -A POSTROUTING ! -d 10.0.0.0/8
    -m comment --comment "kubenet: SNAT for outbound traffic from cluster"
    -m addrtype ! --dst-type LOCAL
    -j MASQUERADE
    node1
    pod1
    src:pod1
    dst:example.com
    src:node1-private
    dst:example.com
    src:node1-public
    dst:example.com
    NAT
    src:example.com
    dst:node1-public
    src:example.com
    dst:node1-private
    src:example.com
    dst:pod1
    ① ②




    View Slide

  15. Service の動作モード
    ● ClusterIP
    ○ クラスタ内の仮想 IP
    ● NodePort
    ○ ClusterIP も持つ
    ○ Node のポートを通して外部からアクセス可能
    ● LoadBalancer
    ○ NodePort も持つ
    ○ Service のクラウド LB を自動プロビジョニング

    View Slide

  16. Service を支えるもの
    ● Endpoints
    ○ Service のラベルセレクタに当てはまる Pod の IP アドレ
    スとポートの対を保持するリソース
    ● kube-proxy
    ○ Service と Endpoints を watch して各 Node の iptables
    のルールを更新
    ○ https://github.com/kubernetes/kubernetes/blob/master/pkg/proxy/iptables/
    proxier.go

    View Slide

  17. node2
    ClusterIP Service
    ● Service の ClusterIP へのパケットは Service を構成する Pod に
    転送(DNAT)
    ● Connection Tracking(conntrack) により ClusterIP から返ってきて
    いるように見える
    node1
    pod1
    src:pod1
    dst:svc1
    src:pod99
    dst:pod1
    iptables
    src:pod1
    dst:pod99
    src:svc1
    dst:pod1
    pod99
    app=target
    ① ②


    View Slide

  18. ClusterIP Service に連動した iptables
    ● ClusterIP から Service 個別のルールに振り分け
    ○ -A KUBE-SERVICES -d 10.79.255.4/32 -p tcp -m comment --comment "default/hostnames:
    cluster IP" -m tcp --dport 80 -j KUBE-SVC-NWV5X2332I4OT4T3
    ● Service 個別のルールから Endpoints に確率で振り分け
    ○ -A KUBE-SVC-NWV5X2332I4OT4T3 -m comment --comment "default/hostnames:"
    -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-BWZ646KDVNVKXICT
    ○ -A KUBE-SVC-NWV5X2332I4OT4T3 -m comment --comment "default/hostnames:"
    -j KUBE-SEP-EV2NQKURMPKCP5UI
    ● Endpoint の IP アドレスに実際に DNAT するルール
    ○ -A KUBE-SEP-EV2NQKURMPKCP5UI -s 10.76.0.9/32
    -m comment --comment "default/hostnames:" -j KUBE-MARK-MASQ
    ○ -A KUBE-SEP-EV2NQKURMPKCP5UI -p tcp -m comment --comment "default/hostnames:"
    -m tcp -j DNAT --to-destination 10.76.0.9:9376
    (以下略)

    View Slide

  19. NodePort Service
    ● Node がクラスタ外からの Service への通信ができるポートを
    開く
    ● はじめにアクセスした Node に Pod が無くても中継

    View Slide

  20. node2
    NodePort Service
    node1
    iptables
    src:client
    dst:node1
    pod99
    app=target
    internet
    src:node1
    dst:pod99
    src:pod99
    dst:node1
    src:node1
    dst:client




    各 Node の NodePort 宛のパケットは
    ● 構成する Pod に DNAT
    ● 経路を逆に戻れるように SNAT

    View Slide

  21. NodePort Service に連動した iptables
    ● # 経路を戻ってこれるよう SNAT
    ○ -A KUBE-NODEPORTS -p tcp -m comment --comment
    "default/hostnames:" -m tcp --dport 31358 -j KUBE-MARK-MASQ
    ● # Service のルールを処理する
    ○ -A KUBE-NODEPORTS -p tcp -m comment --comment
    "default/hostnames:" -m tcp --dport 31358 -j
    KUBE-SVC-NWV5X2332I4OT4T3

    View Slide

  22. node2
    LoadBalancer Service
    node1
    iptables
    src:client
    dst:external
    pod99
    app=target
    Network LB
    src:node1
    dst:pod99
    src:pod99
    dst:node1
    src:external
    dst:client




    ● GCE Network LB(Maglev) は DSR(Direct Server Return)
    ○ 非 Proxy
    ○ iptables に渡る LB の外部 IP アドレスで振り分け
    src:client
    dst:external
    Internet

    転送ルール
    ターゲットプー

    View Slide

  23. LoadBalancer Service に連動した iptables
    ● ExternalIP = LoadBalancer の IP アドレスは Service に転送
    ● -A KUBE-SERVICES -d 104.199.232.159/32 -p tcp -m comment
    --comment "default/hostnames: loadbalancer IP" -m tcp --dport 80 -j
    KUBE-FW-NWV5X2332I4OT4T3
    ● -A KUBE-FW-NWV5X2332I4OT4T3 -m comment --comment
    "default/hostnames: loadbalancer IP" -j KUBE-MARK-MASQ
    ● -A KUBE-FW-NWV5X2332I4OT4T3 -m comment --comment
    "default/hostnames: loadbalancer IP" -j
    KUBE-SVC-NWV5X2332I4OT4T3
    ● -A KUBE-FW-NWV5X2332I4OT4T3 -m comment --comment
    "default/hostnames: loadbalancer IP" -j KUBE-MARK-DROP

    View Slide

  24. LoadBalancer Service
    ● GCE では NodePort も割り当てられるが使わない
    ○ LB が Proxy や NAT として動作する環境で使われる
    ● クラスタ内で中継されることの弊害も
    ○ ホップ増によるコスト
    ○ クライアントの IP アドレスが取れない
    ○ 回避する場合は OnlyLocal
    ■ 正しく使わないと Node の負荷に偏り

    View Slide

  25. まとめ
    ● GKE も Kubernetes も魔法ではない
    ○ Linux, IaaS, ネットワークの知識があれば説明で
    きる
    ● 環境ごとに違うものと同じものを認識してコミュニティ
    の壁を壊そう

    View Slide

  26. 余談 - プライベートネットワークから Pod への通信
    ● 実はプライベートネットワーク内なら GKE クラスタの外との直
    接通信も可能
    ● > NOTE: This is environment specific. Some environments
    will not need any masquerading at all. Others, such as
    GCE, will not allow pod IPs to send traffic to the internet,
    but have no problem with them inside your GCE Project.

    from Creating a Custom Cluster from Scratch

    View Slide

  27. 余談 - クラスタ外 GCE からの ClusterIP への接続
    ● ClusterIP への GCE ルートさえ設定すれば実は可能
    ● GCE ルートの転送先は固定
    ○ Node の更新時は注意
    ● 高価な GCE 転送ルールを使わずにクラスタ内通信で VIP を
    使いたいなら…

    View Slide

  28. We are hiring!

    View Slide