k 8 sとネットワーク--Flannel解読


前言
dockerの公式はマルチホストのコンテナ通信スキームを提供していないことを知っています.単機ネットワークのモードは主にhost、container、brige、noneです.noneというモデルは、名前の通りdocker自体がネットワークモデルを管理せず、cniのような他の管理と割り当てに渡される.Flannelはkubernetes専用の3層ネットワークソリューションで、主にコンテナのホスト間通信の問題を解決するために使用されます.
まず、flannelは、クラスタ全体のネットワーク構成を格納するためにKubernetes APIまたはetcdを利用し、最も主要な内容はクラスタのネットワークアドレス空間を設定することである.例えば、クラスタ内のすべてのコンテナに設定されたIPは、ネットワークセグメント「10.1.0.0/16」から取られる.次に、flannelは各ホストでagentとしてflanneldを実行し、クラスタのネットワークアドレス空間から、ホスト内のすべてのコンテナのIPアドレスが割り当てられる小さなセグメントsubnetを取得します.その後、flanneldは、本ホストが取得したsubnetおよびホスト間通信のためのPublic IPを、同様にkubernetes APIまたはetcdを介して格納する.最後に、flannelは、udp、vxlan、host−gwなどの様々なbackendを用いて、ホスト間でコンテナ間のネットワークトラフィックを転送し、コンテナ間のホスト間通信を完了する.
Flannel Network
実装の原理
Flannelはホストごとに独立したサブネットを提供し、クラスタ全体のネットワーク情報はetcdに格納される.ホスト間転送の場合,ターゲットコンテナのIPアドレスはetcdから取得する必要がある.まず上の図を見て、比較的に直観的です.
手順:
  • IPデータレポートはカプセル化され、コンテナのeth 0を介して送信される.
  • Container 1のeth 0は、vethペアを介してDocker 0と対話し、パケットをDocker 0に送信する.その後、Docker 0はパケットを転送します.
  • Docker 0は、Container 3のIPアドレスを決定し、ローカルルーティングテーブルを外部コンテナに問い合わせ、パケットを仮想NIC Flannel 0に送信する.
  • Flannel 0が受信したパケットは、Flanneldプロセスに転送される.Flanneldプロセスは、etcdによって維持されているルーティングテーブルをクエリーすることによってパケットをカプセル化し、ホストを通過するeth 0をパケットに送信します.
  • パケットは、ネットワーク内のターゲットホストを決定する.
  • 宛先ホストのFlanneldプロセスは、8285ポートをリスニングし、パッケージの解封を担当します.
  • でカプセル化されていないパケットは、仮想NICFLannel 0に転送されます.
  • Flannel 0はルーティングテーブルを問合せ、パケットを解封し、Docker 0にパケットを送信する.
  • Docker 0は、ターゲットコンテナを決定し、ターゲットコンテナにパケットを送信する.

  • 一般的なvxlanモードでは、前述の手順で説明したパケットの封止およびパケットの取り外しに関連し、これもFlannelネットワークの伝送効率が比較的低い理由である.
    次にhost-gwモードに重点を置いて説明します.hostgwは最も簡単なbackendで、その原理は非常に簡単で、直接ルーティングを追加して、目的のホストをゲートウェイとして、直接元のパッケージをルーティングします.例えば、etcdからEventAddedイベントsubnetが10.1.15.0/24でホストPublic IP 192.168.0.100に割り当てられているのを傍受し、hostgwが行うべき仕事は、ホストにエントリを追加するアドレスが10.1.15.0/24、ゲートウェイアドレスが192.168.0.100、出力デバイスが前述のクラスタ間でインタラクティブなNICであればよい.EventRemovedイベントの場合、対応するルーティングを削除するだけです.
    梱包や取り外しがないのでhost-gwの性能が最高です.
    しかしhost-gwはホストネットワークの2層の直接的な相互接続を要求している.したがって、各ノードにはn−1ルーティングがあり、nノードにはflannelのflatネットワーク能力を保証するためにn(n−1)/2ルーティングがある.
    なぜhost-gwはホストネットワークの2層の直接的な相互接続を要求しますか?まず、パッケージング分析により、パッケージング結果は次の図のようになります.
    host−gwが伝送層を歩いているのはtcpであることがわかる.そして,ネットワーク層のソースIPと宛先IPはいずれもコンテナのIP,仮想IPである.これは,スイッチのみがソースIPと宛先IPに関心を持たないため,二層相互接続を決定する.2台のホストが2つのlanの中で、2層が通じず、3層が通じている場合は、ルータが必要ですが、ルータはコンテナのipを認識できません.もちろんルーティングルールを構成することもできますが、明らかにそうしていません.
    OpenshiftのデフォルトもFlannel host-gwコンテナネットワークスキームを使用しており、その公式サイトにもhost-gwのdata flow diagramが明確に描かれている.
    構成および起動パラメータの例
    構成例:
     {
        "Network": "10.0.0.0/8",
        "SubnetLen": 20,
        "SubnetMin": "10.10.0.0",
        "SubnetMax": "10.99.0.0",
        "Backend": {
            "Type": "udp",
            "Port": 7890
        }
    }

    起動パラメータ:
    --public-ip="": IP accessible by other nodes for inter-host communication. Defaults to the IP of the interface being used for communication.
    --etcd-endpoints=http://127.0.0.1:4001: a comma-delimited list of etcd endpoints.
    --etcd-prefix=/coreos.com/network: etcd prefix.
    --etcd-keyfile="": SSL key file used to secure etcd communication.
    --etcd-certfile="": SSL certification file used to secure etcd communication.
    --etcd-cafile="": SSL Certificate Authority file used to secure etcd communication.
    --kube-subnet-mgr: Contact the Kubernetes API for subnet assignment instead of etcd.
    --iface="": interface to use (IP or name) for inter-host communication. Defaults to the interface for the default route on the machine. This can be specified multiple times to check each option in order. Returns the first match found.
    --iface-regex="": regex expression to match the first interface to use (IP or name) for inter-host communication. If unspecified, will default to the interface for the default route on the machine. This can be specified multiple times to check each regex in order. Returns the first match found. This option is superseded by the iface option and will only be used if nothing matches any option specified in the iface options.
    --iptables-resync=5: resync period for iptables rules, in seconds. Defaults to 5 seconds, if you see a large amount of contention for the iptables lock increasing this will probably help.
    --subnet-file=/run/flannel/subnet.env: filename where env variables (subnet and MTU values) will be written to.
    --subnet-lease-renew-margin=60: subnet lease renewal margin, in minutes.
    --ip-masq=false: setup IP masquerade for traffic destined for outside the flannel network. Flannel assumes that the default policy is ACCEPT in the NAT POSTROUTING chain.
    -v=0: log level for V logs. Set to 1 to see messages related to data path.
    --healthz-ip="0.0.0.0": The IP address for healthz server to listen (default "0.0.0.0")
    --healthz-port=0: The port for healthz server to listen(0 to disable)
    --version: print version and exit

    まとめ
    次に,コードの実装部分に重点を置く.