CNCF CNIシリーズの2:CNI(container network interface)の概要(macvlanを例に)


一、前言
CNCFのCNIはインタフェース仕様であり、この仕様は入力、出力の標準と呼び出しのインタフェースを定義する.CNIプラグインを呼び出すエンティティがこの仕様に従う限り、CNIからIPアドレス、ゲートウェイ、ルーティング、DNSなどのネットワーク相互接続条件を満たすネットワークパラメータを取得することができ、これらのネットワークパラメータはcontainerインスタンスを構成することができる.
本論文では,macvlan CNIを手動で呼び出すプロセスを解析することによって,CNIインタフェース仕様の動作モードを理解する.
転載先https://blog.csdn.net/cloudvtech
二、containerホスト構成
所在するセグメント:192.168.122.0/24
NIC構成:
 eth0:  mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 52:54:00:d8:d2:1e brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.135/24 brd 192.168.122.255 scope global dynamic eth0
       valid_lft 2355sec preferred_lft 2355sec
    inet6 fe80::5054:ff:fed8:d21e/64 scope link
       valid_lft forever preferred_lft forever 

転載先https://blog.csdn.net/cloudvtech
三、CNIインタフェース規範
1.CNIインタフェースがサポートする呼び出し方法
ネットワークの追加、ネットワークの削除、ネットワークリストの追加、ネットワークリストの削除.
CNI pluginの機能は、containerをネットワークに追加し、containerのネットワークインタフェースによってネットワーク情報を構成することに概括することができる.
2.CNIカード
CNIプラグインは実行可能ファイルでなければなりません.CNIプラグインは、vethの一端などのネットワークインタフェースをcontainer network namespaceに挿入し、vethの他端などのホスト上でlink level構成を行い、containerのlink levelがホストに接続できるようにします.次に、CNIは、IPをネットワークインタフェースに構成し、関連するルーティングを設定する.
3.設計考慮
CNI設計の際に以下の問題を考慮した(https://github.com/containernetworking/cni/blob/master/SPEC.md, "General considerations"):
  • CRT(container run time)は、CNI pluginを呼び出す前にコンテナにnetwork namespaceを作成する必要があります.
  • CRIは、このcontainerがどのネットワークに属するべきかを決定し、各ネットワークのためにどのプラグインが実行されるべきかを決定しなければならない.
  • ネットワーク構成はJSON形式である.ネットワーク構成には、nameやtype、プラグイン(タイプ)などの必須フィールドが含まれます.ネットワーク構成では、異なるCNI pluginにカスタムパラメータの一部を許可します.そのため、特定のCNI pluginに必要な異なる情報を含むオプションフィールドargsがあります.
  • CRIは、各ネットワークに対して適切なCNI pluginを順次実行し、containerを各ネットワークに追加しなければならない.
  • containerライフサイクルが完了した後、実行時には、containerをネットワークから切断するために、containerを追加する順序に対して反対の順序でプラグインを実行する必要があります.
  • CRIはCNI pluginのADDおよびDEL動作に注目し、DEL動作は等べき乗性を有する.
  • containerは、ContainerIDによって一意に識別される必要があります.
  • CRIは、同じネットワーク名またはcontainerIDを呼び出してADDを2回実行することはできない(対応するDELがない).すなわち、与えられたcontainer IDは、特定のネットワークに1回しか追加できない必要がある.
  • 4.ADD操作
    パラメータ
  • Container ID
  • Network namespaceパス、例えば/proc/[pid]/ns/net
  • JSONフォーマットCNIネットワーク構成パラメータは、containerがどのようなネットワークに参加する必要があるかを示す
  • 異なるCNI plugin固有のパラメータ
  • container内部のNIC名
  • 戻り値
  • container内部ネットワークカードまたはシンクホスト上で影響を受けるネットワークカード(macvlan pluginなど)リスト
  • 各NICに割り当てるネットワーク構成(IP、ゲートウェイ、ルーティング)
  • .
  • DNS情報
  • 5.DEL操作
    ADD動作と同様
    6.環境変数パラメータ
  • CNI_COMMAND:CNI操作、ADD、DEL or VERSION.
  • CNI_CONTAINERID: Container ID
  • CNI_NETNS:container network namespaceファイルへのパス
  • CNI_IFNAME:container内部ネットワークインタフェースの名前
  • CNI_ARGS:key-valueペアの追加パラメータ
  • CNI_PATH:CNI plugin binaryの経路
  • 以上の構成は、CNI plugin実行可能ファイルが呼び出されたときにCNI pluginのstdIN(JSONファイル)または環境変数としてCNI pluginに転送される必要がある.
    転載先https://blog.csdn.net/cloudvtech
    四、手動でmacvlan CNI pluginを構成して呼び出す
    1.containerを起動する
    docker run --net=none -dt centos
    ffecae44150e #container ID
    
    docker inspect -f '{{ .State.Pid }}'  ffecae44150e
    7077 #container   

    2.JSON形式CNIに加入する必要があるネットワークの記述ファイルを準備する
    /etc/cni/net.d/10-maclannet.conf 
    {
        "name": "macvlannet", #CNI    
        "type": "macvlan",    #CNI  
        "master": "eth0",     #CNI     
        "ipam": {             #IP    plugin   
    
            "type": "host-local", #IP  plugin   
            "subnet": "192.168.122.0/24", #IP  plugin       
            "routes": [ #IP  plugin       
                { "dst": "0.0.0.0/0" }
            ]
        } 
    }

    3.CNIの環境変数パラメータ
    export CNI_COMMAND=ADD #CNI   ,ADD  DEL
    export CNI_IFNAME=eth0 #container      
    export CNI_CONTAINERID=ffecae44150e #container ID
    export CNI_PATH=/opt/cni/bin/ #CNI        
    export CNI_NETNS=/proc/7077/ns/net #CNI   container namespace   

    4.手動でCNI plugin実行可能ファイルを実行する
    /opt/cni/bin/macvlan 出力結果は次のとおりです.
    {
        "ip4": {
            "ip": "192.168.122.3/24",
            "gateway": "192.168.122.1",
            "routes": [
                {
                    "dst": "0.0.0.0/0",
                    "gw": "192.168.122.1"
                }
            ]
        },
        "dns": {}
    } 

    割り当てられたIPアドレス、ゲートウェイ、ルーティングなどの情報を含む
    5.container内でCNIの返却結果を検証する
    docker exec -it ff bash
    [root@ffecae44150e /]# ifconfig
    eth0: flags=4163  mtu 1500
            inet 192.168.122.3  netmask 255.255.255.0  broadcast 0.0.0.0
            inet6 fe80::858:c0ff:fea8:7a03  prefixlen 64  scopeid 0x20
            ether 0a:58:c0:a8:7a:03  txqueuelen 0  (Ethernet)
            RX packets 5589  bytes 15085040 (14.3 MiB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 5155  bytes 356496 (348.1 KiB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    lo: flags=73  mtu 65536
            inet 127.0.0.1  netmask 255.0.0.0
            inet6 ::1  prefixlen 128  scopeid 0x10
            loop  txqueuelen 1  (Local Loopback)
            RX packets 0  bytes 0 (0.0 B)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 0  bytes 0 (0.0 B)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0 

    ホストping container IPから
    [root@os-cni-test ~]# ping 192.168.122.3
    PING 192.168.122.3 (192.168.122.3) 56(84) bytes of data.
    64 bytes from 192.168.122.3: icmp_seq=1 ttl=64 time=0.312 ms
    64 bytes from 192.168.122.3: icmp_seq=2 ttl=64 time=0.518 ms
    64 bytes from 192.168.122.3: icmp_seq=3 ttl=64 time=0.449 ms
    ^C
    --- 192.168.122.3 ping statistics ---
    3 packets transmitted, 3 received, 0% packet loss, time 2000ms
    rtt min/avg/max/mdev = 0.312/0.426/0.518/0.087 ms 

    転載先https://blog.csdn.net/cloudvtech