[[PageOutline]] * macvlan/macvtap * [http://virt.kernelnewbies.org/MacVTap MacVTap - Linux Virtualization Wiki] > Macvtap is a new device driver meant to simplify virtualized bridged networking. It replaces the combination of the tun/tap and bridge drivers with a single module based on the macvlan device driver. * [http://seravo.fi/2012/virtualized-bridged-networking-with-macvtap Virtualized bridged networking with MacVTap - Seravo] * 図入りで解説 * [http://d.hatena.ne.jp/syuu1228/20111130/1322603234 macvlanを使ってみる - 驟雨のカーネル探検隊(只今遭難中w] > eth0をpromiscuousモードに切り替える事で、「fe:7b:40:b0:fc:f8」宛のパケットを受け取っているようです。 > 今度はMACアドレスが異なるので新しいIPをDHCPサーバからもらうことも出来ちゃいますね。 > この機能、普通にLinux上で生きていても何の用途も無さそうですが、LXCで使われているようですし、後付で実装されたmacvtapを使えばKVM/QEMUからも使えます。 * [http://d.hatena.ne.jp/defiant/20111221/1324466720 macvtap でつないだ kvm ゲストとホスト間の通信 - TenForwardの日記 (defiantの日記改め)] > この際,ゲスト~ホスト間の通信はできません.まあ,きちんとしたサービスとしてやるときは必要ないかもしれませんが,手元でちょっとテストをやってる時なんかは,ゲスト~ホスト間通信ができると便利な事もあります. > macvtap というのは Linux kernel の持つ機能で macvlan というインターフェースを作れますが,これを Tap として利用するモノのようです.ということは macvlan/macvtap 間の通信は "bridgeモード" に設定しておけば可能です(この辺りのモードについては前述の参考文書を参照) ので,ホスト上に macvlan インターフェースを作成して,そこにホストのアドレスを割り当ててしまえば,ゲスト~ホスト間の通信は可能なはず,ということでやってみました. * [http://d.hatena.ne.jp/syuu1228/20111128/1322502673 libvirtで色々な仮想NICの設定を使い分ける - 驟雨のカーネル探検隊(只今遭難中w] * [http://www.nic.ad.jp/ja/materials/iw/2011/proceedings/s09/s09-02.pdf 仮想化環境における パケットフォワーディング] * [http://www.bertera.it/index.php/2011/10/04/howto-configure-multiple-mac-address-over-a-single-ethernet-interface/ Howto configure multiple mac address over a single ethernet interface ‹ Bertera] * [http://ubuntuforums.org/showthread.php?t=1923806 (ubuntu) save ip link macvlan interfaces after reboot? - Ubuntu Forums] * /etc/network/interfaces 例 {{{ auto macvlan0 iface macvlan0 inet static address 192.168.abc.def netmask 255.255.255.0 pre-up /sbin/ip link add dev macvlan0 link eth0 \ address 00:16:3e:XX:YY:ZZ type macvlan mode bridge post-down /sbin/ip link del dev macvlan0 }}} * twitter:mittyorz/256673272354181121 前後から始まったやりとり > {{{ > mittyorz: LXCは「lxc.network.type=macvlan lxc.network.macvlan.mode=bridge」のようにconfigに書くことで、linux bridgeをあらかじめ用意しなくてもブリッジ接続してくれるぞ。 > mittyorz: 参考: http://www.linuxcertif.com/man/5/lxc.conf/ Linux Certif - Man lxc.conf(5) qemu/kvmも1.0からかな、macvlan/macvtap使えるようになったし、Linux bridgeと共存していくのかなぁ > mittyorz: ぐぐってたら @syuu1228 先生の資料が引っかかった http://www.nic.ad.jp/ja/materials/iw/2011/proceedings/s09/s09-02.pdf 仮想化環境における パケットフォワーディング > _syuu1228: やぁやぁ RT @mittyorz: ぐぐってたら @syuu1228 先生の資料が引っかかった http://www.nic.ad.jp/ja/materials/iw/2011/proceedings/s09/s09-02.pdf 仮想化環境における パケットフォワーディング > mittyorz: あー、ゲスト/ホスト間の通信が出来ないのか。地味に面倒だな…。これはkvmでの例だけど、lxcでも同じく出来ないようだ http://t.co/StS7TiGu macvtap でつないだ kvm ゲストとホスト間の通信 - TenForwardの日記 > mittyorz: @_syuu1228 @syuu1228 どもども。macvlan/macvtapいまいち理解せずkvm/qemuで使ってたんですが、lxcでも使えないか?と思ってググってて、「結局macvlav/vtapってなんやねん」とさらにググってたらたどり着きましたー。 > mittyorz: とはいえ、ここに書いてあることも理解できているのかと言われると、かなり怪しい…。というか他のも読まないと何とも、かなぁ > mittyorz: ホスト/ゲスト間が通信できなくなるのはどういう理由なんだろう > _syuu1228: @mittyorz @syuu1228 KVMで使おうとして後から機能追加(macvtap)してますけど、元々LXC向けの機能(macvlan)っすね > mittyorz: @_syuu1228 @syuu1228 ああー、そうなんですか。なるほど…。macvlanが先だったんですね。違いがよく分からずにいたので、今更ながら色々読んでます。 > mittyorz: この辺が詳しそう? http://virt.kernelnewbies.org/MacVTap MacVTap - Linux Virtualization Wiki > mittyorz: 何らかの方法でホスト/ゲスト間で通信できるように細工したような覚えが。どうやったんだっけかな > _syuu1228: @mittyorz 元々、カーネルの中で完結した機構で、1つのNICに複数のMACを振る仕組みをLXCの為に作ったのがmacvlan。KVMのvNICってそもそもユーザランドで動いてたからtap+bridge使ってたんやけど、vhostnetでカーネルで動くようにもなったので(続 > _syuu1228: @mittyorz より短いパス(macvlanのように)でブリッジ出来るようにしようとしたんだけど、あくまでtapのインタフェースは維持したかったっぽくて(ユーザランドから設定とかする為?よくわからない)その為にmacvlanにtapのインタフェースくっつけたのがmacvtap > _syuu1228: @mittyorz ちなみにVEPAとか書いてあるのはスルーしていいと思います。僕らも調べてIW2011で解説したし、IW2012でも触れるかもしれないけど、現状まず使わないので > mittyorz: @_syuu1228 なるほど。わざわざ経緯の説明ありがとうございます!tapのインタフェースくっつけたのはやはり既存のユーザランドアプリケーションとかから状態を見たり設定変更したりしたかったからですかねぇ…。若干車輪の再発明っぽい感じではありますが、利便性を取ったのかな > _syuu1228: @mittyorz 「vhost-netもqemu-kvmも変えなくていい」というのは大きな動機になりそうですが、ずっと前からここは疑問に思ってます。 > mittyorz: @_syuu1228 なるほど。(ハードウェア)switch側の対応が必要となるとちょっと使えなさそうですね。しかしデフォルトがVEPAになっているように書かれていますが、利用者側からすると混乱しそうな気もしますね…。 > _syuu1228: @mittyorz あれー本当だてっきりbridgeだと思ってたんだけど…でもhairpin_modeが使えるってところだけが違いのはずなので(ちょっと自信なし)、これがデフォルトオフなのか、或いは対応スイッチの下でしかhairpinしないのか、って所なのではないかと妄想します > mittyorz: @_syuu1228 ふむー。そうなるとちょっと使ってみよう、という場合でもデフォルトのVEPAにしておいて大丈夫なのかな…。やってみるか……。 > mittyorz: qemu/kvmでも書いてある通りホスト/ゲスト間で通信できなかった。ただ、 https://twitter.com/mittyorz/status/256674071159382018 で見落としていたけど、ホスト/ゲスト間用に、別にmacvlanを作ってしまえば問題ないようだ。でもそこまでするなら今までもbr0とかでもいい気もする。 > mittyorz: あとは性能次第かなぁ > _syuu1228: @mittyorz すげー単純にいうと、同一ホスト間のブリッジングでも一旦スイッチへパケット送ってスイッチで転送先判断させようという仕組み=VEPAなので(同一ホストならパケット戻ってくる=ヘアピン)、もしデフォルトでヘアピンが実施されるなら普通のスイッチ下では通信エラーするはず > mittyorz: @_syuu1228 それは同じVMM上に無いノード間の通信は問題なく通信できるように見えて、同じVMM上に存在するVM同士で通信しようとするととたんにはまったりしないですかね…。問題への気付きにくさが増しているような。 > mittyorz: VEPAモードにしてみたが、VMノードと、ハードウェア的に別のノードとの間の通信は問題なかった。もちろんホスト/ゲスト間は通信できない。 > _syuu1228: @mittyorz そうなる気がするけど何が起きるか厳密に考えてみた事が無いので、もしかしたら予想と違う現象になるかも。でもまさかそういう設定に最初からなってるはずはないと思うんだけどねぇ… > _syuu1228: @mittyorz 多分このあたりは @m_asama せんせーも詳しいと思うので、と人に振ってみる > mittyorz: virt-managerでVM作る時に、NICをmacvtapにしてsource modeをdefaultにしたら作成に失敗する…w いったんVEPAにしてから、後でDefaultにしようとしても、applyを押下した瞬間にVEPAに戻る。なんじゃこりゃ。 > mittyorz: プルダウンの順番がDefault->VEPAだから、選択出来ないdefaultの代わりにVEPAになっている感がする。virsh editで 'default'ってしたらどうなるんだろう > mittyorz: 「error: internal error Unkown mode has been specified」ふむん… > mittyorz: lxcコンテナA,B間で、ホストとは通信できる必要がない通信をしたい時に、まず思い浮かんだのが、物理NICとは接続されてないbridgeを用意して、それに対してA,Bを接続すればいいや、と思ったのだけれど、macvlanがあるのを思い出して調べてたらだいぶ話が膨らんだなぁ > mittyorz: macvlan使う場合も、ホスト側は通信できる必要無い(IPアドレスとか付与しない)けど、ホスト側でmacvlanデバイスを作ってからLXCコンテナ側でそこに接続する必要があるのかな。外(ホスト側)にデバイスとして見えている必要は無い(むしろ見えない方が良い)のだけれど。 > mittyorz: 外に見える、というのはifconfig -aとかすると見えてしまうアレ。 > mittyorz: @_syuu1228 だめですが、かなりアドホックな回避策はあるようですね。アドホックすぎてちょっといやな感じですが。 ref: https://twitter.com/mittyorz/status/256680074403790848 > m_asama: @_syuu1228 @mittyorz なんでデフォルト vepa なんでしょうね。ちょっとコード眺めたかんじでは bridge と比較してそんなに vepa が軽量になってるとは思えないし。あ、もしかしたら大量に VM ぶら下げた時に差が出てくるのかも。 > mittyorz: @m_asama @_syuu1228 パケット送り先の判断をスイッチにオフロード出来るから、ということなのですかね…。対応しているスイッチが少ない状況ではあまり嬉しくないように思えますけれど。 > syuu1228: @mittyorz @m_asama VEPAモードじゃなくてbridgeモードでもホストと通信できないんでしたっけ? > syuu1228: @mittyorz @m_asama なんとなくだけど、その状況ってVEPAモードで対応スイッチがあればヘアピンされて通信出来るような気がしなくもないのだけれど。どうなんだろ。 > m_asama: @syuu1228 @mittyorz いや、 bridge ならいけると思ってましたけど、試してはないです。 > syuu1228: @m_asama @mittyorz ちょっと理解し難いですね。むしろmacvtapの位置付けがVEPA対応用な感じなんだろうか?? > syuu1228: @m_asama @mittyorz あるいはアレかな、VEPAモードでヘアピンオフだとルータとはスイッチを経由して喋れるけど、同一ノードの別VMやホストとは通信出来ない状態になるとかで、それを意図してるのかな > m_asama: @syuu1228 @mittyorz macvlan/macvtap は zero copy のためのものなんじゃないですかね。 legacy bridge や Open vSwitch では zero copy 実現不可能とおもわれるので。 > syuu1228: @m_asama @mittyorz だと思うんだけども、ならなんでこういうデフォルト値になってんだろなー…と > m_asama: @syuu1228 @mittyorz それは謎w たぶん最初は vepa しかなくて後から bridge 追加したので最初からあった vepa がデフォルトになってるとかそんな理由なのかも。 > mittyorz: @m_asama @syuu1228 試した限りではbridgeでホスト/ゲスト間の通信は出来ませんねー。 > m_asama: @mittyorz @syuu1228 まじですか…。なにが違うんでしょうね…。ちょうど今日 macvlan/macvtap 読もうと思ってたのでなんかわかったらご報告します。 > m_asama: @mittyorz @syuu1228 あー、なんかゲスト間通信できるようにしたのを bridge と言ってるみたいすね。よく考えたら送信はそのまま NIC から出すし、受信はすぐさま rx_handler に奪われるんだからホストと通信できるわけ無かったですね…。すんません…。 > }}} * [http://yskwkzhr.blogspot.jp/2017/06/using-macvtap-with-kvm-on-debian-gnu-linux.html Debian GNU/LinuxのKVMでmacvtapを使用する - Keep It Simple, Stupid] * [http://backreference.org/2014/03/20/some-notes-on-macvlanmacvtap/ Some notes on macvlan/macvtap « \1] macvlanとmacvtapの違いについても詳しく言及 > macvtap interfaces are persistent by default. Once the macvtap interface has been created via netlink, an actual chracter device file appears under /dev (this does not happen with normal tap interfaces), The device file is called /dev/tapNN, where NN is the interface index of the macvtap (can be seen for example with "ip link show"). It's this device file that has to be opened by programs wanting to use the interface (eg libvirtd/qemu to connect a guest). * macvlanはtapデバイスを作らない * [https://wiki.libvirt.org/page/Guest_can_reach_outside_network,_but_can%27t_reach_host_(macvtap) Guest can reach outside network, but can't reach host (macvtap) - Libvirt Wiki] * [https://qiita.com/albatross/items/8c32615b5154acf712f2 macvlan の使い方と挙動のメモ - Qiita] * [http://yskwkzhr.blogspot.jp/2017/06/using-macvtap-with-kvm-on-debian-gnu-linux.html Debian GNU/LinuxのKVMでmacvtapを使用する - Keep It Simple, Stupid] = macvlan vs Linux Bridge = * macvlanとbridgeは両立出来ない 1. root@Microknoppix:~# brctl addbr br0 1. root@Microknoppix:~# brctl addif br0 eth0 1. root@Microknoppix:~# ip link add dev macvlan0 link eth0 address 00:16:3e:xx:yy:zz type macvlan mode bridge {{{ RTNETLINK answers: Device or resource busy }}} 1. root@Microknoppix:~# brctl delif br0 eth0 1. root@Microknoppix:~# ip link add dev macvlan0 link eth0 address 00:16:3e:xx:yy:zz type macvlan mode bridge 1. root@Microknoppix:~# brctl addif br0 eth0 {{{ device eth0 is already a member of a bridge; can't enslave it to bridge br0. }}} 1. root@Microknoppix:~# brctl show {{{ bridge name bridge id STP enabled interfaces br0 8000.000000000000 no }}} * root@Microknoppix:~# ip link {{{ 6: macvlan0@eth0: mtu 1500 qdisc noop state DOWN link/ether 00:16:3e:xx:yy:zz brd ff:ff:ff:ff:ff:ff }}} == bridging macvlan == * macvlanをブリッジすることは可能 * macvlan0 at eth0 * macvlan1 at eth1 * mitty@vlan-gw:~$ ifconfig | grep addr {{{ br-gw Link encap:Ethernet HWaddr 00:16:3e:18:8b:a0 inet6 addr: fe80::216:3eff:fe18:8ba0/64 Scope:Link eth0 Link encap:Ethernet HWaddr 00:16:3e:3d:4f:c9 inet6 addr: fe80::216:3eff:fe3d:4fc9/64 Scope:Link eth1 Link encap:Ethernet HWaddr 00:16:3e:3d:4f:ca inet6 addr: fe80::216:3eff:fe3d:4fca/64 Scope:Link macvlan0 Link encap:Ethernet HWaddr 00:16:3e:18:8b:a0 inet6 addr: fe80::216:3eff:fe18:8ba0/64 Scope:Link macvlan1 Link encap:Ethernet HWaddr 00:16:3e:32:30:c9 inet6 addr: fe80::216:3eff:fe32:30c9/64 Scope:Link }}} * mitty@vlan-gw:~$ brctl show {{{ bridge name bridge id STP enabled interfaces br-gw 8000.00163e188ba0 no macvlan0 macvlan1 }}} * ただし、このmacvlanのブリッジは期待通りには動かない(eth0<->eth1の、NICを超えての疎通不可) * ARP request/replyは上流側の物理デバイス(eth0)に対しては正しく送信・受信されているが、replyがmacvlan0に正しく届かないため下流側のmacvlan1まで回ってこない模様 = nesting macvlan = * macvlan/macvtapを用いてホストと接続したゲスト環境内において、Linux Bridgeあるいはmacvlanをさらに使用するとゲストの外からのパケットを受け取れない * 検証していないが、コンテナをmacvlan/macvtapでネストしても同じだと思われる * [https://serverfault.com/questions/891475/macvlan-containers-inside-virtual-machine linux - macvlan containers inside virtual machine - Server Fault] > The setup I am trying to accomplish is the following: > > {{{HOST --macvlan--> VM --macvlan--> CONTAINER}}} * 回答はついてないが、おそらくうまく動かなかったためこの質問をしたのだと思われる * [[Image(nesting_macvlan-inVM.png,33%)]] * 上記のようになっている場合… * macvlan0とbr0は同時には作成できないことに注意 * macvlan0@eth0 * {{{# dhcpcd eth0}}} -> 問題なくDHCPでアドレスを取得できる * {{{# dhcpcd macvlan0}}} -> timed outでアドレスを取得できない * dhcpcd on {{{lxc-macv}}} -> アドレスを取得できない * br0 with eth0 * {{{# dhcpcd eth0}}} -> 問題なくアドレスを取得できる * {{{# dhcpcd br0}}} -> 問題なくアドレスを取得できる * dhcpcd on {{{lxc-veth}}} -> アドレスを取得できない * ホスト上でDHCPパケットをtcpdumpで観測すると、どの場合でもDHCP Requestは{{{eno0}}}, {{{macvtap}}}, {{{macvlan}}}いずれでも観測できるが、Replyは{{{eno0}}}だけで観測される * DHCPdからは異なるMAC Addressに従って異なるIPアドレスのofferがReplyとして送出されている * ゲスト内がLinux Bridgeの場合でも、eth0とMAC Addressが同じになるbr0においてはIPアドレスを取得できるものの、異なるMAC Addressとなるvethからはアドレスを取得できない * macvlan/macvtapは、Linux Bridgeとは異なり自身に設定されているMAC Address以外のイーサネットフレームを受け取ることができないのではないかと思われる * 他のVMにおいてdhcpcdを動作させて、{{{ff:ff:ff:ff:ff:ff}}}あてのパケットを送出したところ、{{{eth0}}}において観測できたことも裏付けになる * ホストにおいて{{{ip link set macvtap promisc on}}}としてみたが変化はなかった * ゲスト内でL2 VPNのサーバを立てる場合などでも同様に通信できない原因となるので、注意が必要