OpenStackのDHCP問題まとめ

先日、1つの問題に1週間以上ハマって悶絶するも、絞りだすような勘と数えきれない再構築によって、命からがら解決することができました。

その問題とは、2台目以降のホストであるComputeNodeのVMがDHCPからアドレスを取得できない というもので、これについて多くの情報を仕入れたのでまとめておきます。



DHCPからIPアドレスが取得できない現象

ControllerNode1台で構築し(NetworkNodeは分けていない)、VMを作成する分には問題なくDHCPからアドレスがリースされるのに、ComputeNode単体ホストで作ったVMはアドレスを取得できない、という問題でした。

その時どうなるかというと、VMからQuantumネットワークのDHCPサーバにリクエストは飛ぶものの、レスポンスが返せずにレスポンスパケットが永久に垂れ流され続ける状態になりました。

しかも、Quantumネットワークのrestart直後は一瞬、VMでアドレスを取得できるのに、すぐ疎通できなくなって結局DHCPレスポンスが繰り返されるという、中途半端な挙動も多々ありました。

要は、ControllerNode内部だけなら通らない経路で、ComputeNode単体との間の経路に何か問題があることはすぐアタリはついたのですが、調べてみるとDHCP失敗関連の情報があるわあるわ… 自分のネットワーク苦手意識もあり、全てなんとなく試していくも一向に当たらず途方にくれるのでした。


ネットワーク知識の守備範囲

Quantum周りで詰まった時に何が厳しかったかというと、必要とする知識の範囲です。
すなわち、試す範囲が広く、組み合わせも多様ということ。今回だけでも考える必要があったのは

  • カーネルモジュール (vhost_net の有無)
  • カーネルパラメータ (net.*)
  • OpenvSwitch (+カーネルモジュールが brcompat or bridge)
  • Quantum (server, l3, dhcp, metadata, agent)
  • Network NameSpace (ip netns の qrouter と qdhcp)
  • iptables (filter, nat, mangle)
  • route (Host, qrouter, qdhcp, VM)
  • libvirt + QEMU KVM

  • これくらいあり、1つ試してダメならコッチも変えて… と組み合わせまで疑うことになり、途中、何が確実に正しいのか、自分が何やってるのかすら混乱してきて、キレて何度も再構築するなど。

    特にOVSはデリケートで、再構築するにも手順を間違えるとOSがハングしたり、
    お前は今ナニと戦っているんだ状態に何度も陥りました。


    DHCP問題まとめ

    iptableのCHECKSUMターゲット

    vhost_net カーネルモジュールが有効になっている時に、mangleテーブルにCHECKSUMターゲットを入れないと通らないという問題。

    Wheezyの場合はそもそも無効なので関係ないですが、藁にもすがる思いであえて有効にしたり iptables を加えたりするも、今回には関係ありませんでした。

  • VMs cannot communicate with Compute Node. Cannot access Data network. – Ask OpenStack: Q&A Site for OpenStack Users and Developers
  • The challenge of the network | Lorin Hochstein
  • # init 0 Instances in OpenStack are not getting DHCP leases on ubuntu12.10
  • nova network – Instances in OpenStack are not getting DHCP leases – Server Fault
  • quantum-l3-agent-INPUT

    qrouterの quantum-l3-agent-INPUT チェインで、そもそも許可されていない疑惑。
    確かに追加することで、このチェインのこのルールでパケットカウントされ始めた環境条件もあり、有効そうだったのですが解決には至らず。

  • Re: [rhos-list] dnsmasq cannot start properly
  • brctl show に qvo interface

    brctl show の表示に qvo*** というinterfaceが無ければダメなんじゃねって話。
    確かに無い!けど、どうやったらできるんじゃい!!には到達せず…

    一応libvirtのパッチがあったけど、そこまでやらないと解決できるものじゃないはず、と確信していたのでスルー。

  • OpenStack Open Source Cloud Computing Software » Message: [openstack-dev] [Quantum] security groups now enforced w/devstack


  • bridgeカーネルモジュールのsysctlパラメータ

    openvswitch-brcompat を有効にすると brcompat_mod / openvswitch_mod モジュールが有効になりますが、BRCOMPATが無効な状態だと bridge モジュールが有効になります。(どちらも lsmod で確認)

    これは、bridge の機能を落とすことで解決を試みており、一応あえて bridge にして試したりもしましたが解決しないし、それまでの経験則で BRCOMPAT=yes の方が主流だと考えて、廃案としました。

  • iptables – DHCP reply packets do not make it into KVM instance in OpenStack – Server Fault
  • bridge | The Linux Foundation
  • dnsmasq

    全く同じdnsmasqプロセスが2つあったら変じゃね?って話。そんなことなく、正常運行でした。

    ただ、Quantumデーモンを落とした時に dnsmasq や quantum-ns-metadata-proxy プロセスが残るというバグ?があり、Quantum設定変更の際は restart ではなく
    stop -> pkill dnsmasq -> start といった流れで慎重に行ったりしました。が、結果的には関係ありませんでした。

  • 日本OpenStackユーザ会 › ubuntu1010-UEC-localuser-imageの起動中にmountall: Event failedする

  • ていうか、ControllerNode内のVMが取得できてる時点で、DHCPサーバではなく経路が問題だとわかるし…


    libvirt_use_virtio_for_bridges

    /etc/nova/nova-compute.conf のデフォは libvirt_use_virtio_for_bridges=True だけど、DHCP問題に差し掛かったときに libvirt_use_virtio_for_bridges=False にすると解決することがある、という話。

    実際、私も試しましたが、これによって確かにアドレス取得に成功する場合がありました。しかし、VMの kvm プロセスのCPUが100%にお怒りになり続けるという現象と、一般的に True が主流ということで廃案にしました。

  • DHCP lease not accepted when libvirt_use_virtio_for_bridges=true
  • Bug #1029430 “KVM guests networking issues with no virbr0 and wi…” : Bugs : “libvirt” package : Ubuntu


  • libvirt network

    そして調査は libvirt にまで突入していく始末。

  • libvirt: Wiki: Networking
  • libvirt: Wiki: PXE boot (or dhcp) on guest failed

  • さきほども書きましたが、bridge の sysctl を変更したり、

    ネットワークインターフェースの設定にこんなのを入れると安定するかも!みたいな話。

    ウチは brcompat だし!bridgeにして試してもうまくいかないし!で廃案。

    あと、libvirtのXMLで、ネットワークのところに <driver name=’qemu’/> を入れたら… ってのも紹介されてるけど、<model type=’virtio/> で、vhost_net が有効で、iptablesのCHECKSUM非対応で、ホスト上のDHCPから直接取得しようとしてる、4つの条件が揃った場合に!とかあって、明らかに関係ないのに守備範囲だけが広がってく感覚にイライラするなど。


    外道父版DHCP問題の原因と解決策

    原因

    原因が判明してしまえば、やはり苦手意識があったOVS周りで、やはり来たか…という感じでしたが、問題が起きていた間の設定は、Folsomや、初めてGrizzlyを構築した時には問題なかったために回り回って余計時間がかかってしまいました。

    OVSの設定は、
  • 管理&Floating用 : br-ex on eth0
  • Integration Bridge&VM専用 : br-int on StaticAddress無しの eth1

  • という感じで、ControllerNode・ComputeNodeの全ホスト共通で設定していたのですが、
    これをComputeNodeの br-ex をやめて普通に eth0 がStaticAddressを持つように変更したら、DHCP問題 …… いうならば NetworkNode と ComputeNode 間の疎通問題が解決しました。なんとあっけない…

    なぜ全ホストで br-ex ブリッジを作っていたかというと、なんとなく、というのもありますが、後々ネットワークの冗長化を作る時に必要なんじゃないか予想をしていたからで、何か確信があったわけではありませんでした。完全に不安ポイント的中!!

    解決策

    それまで、ネットワークの種類は
  • 管理用アドレス(≒ホストへのSSHやHTTP用)
  • FloatingIP用
  • VM同士用
  • の3つだと思っていたのですが、どうやら br-int は全てのノードで必須の Integration Bridge というもので、VM同士の通信とは別物であるということがわかりました(いっしょくたにしてた)。

    なので、問題切り分けのしやすさを主眼において、OpenvSwitchのブリッジ設定は
  • ControllerNode : br-ex (eth0), br-int (port未指定), br-vm (eth1)
  • ComputeNode : br-int (port未指定), br-vm (eth1)

  • とし、Quantum Agent はvlanでマッピングは
  • ControllerNode : bridge_mappings = physnet1:br-ex,physnet2:br-vm
  • ComputeNode : bridge_mappings = physnet2:br-vm

  • としました。各所にある br-ex, br-int の指定は全てデフォルトのままです。



    切り分けという意味ではNetworkNodeも分けるべきでしょうが、とりあえずこれで解決したのと、tcpdumpなどでデバッグしやすくなって十分綺麗になりました。

    ただ、別にこれが正解と確信しているわけではなく、世界中の人の設定を見るとブリッジやマッピングの構成が少しずつ違っているので、物理NICの数から始まって各種設定の組み合わせによって色々正解がありそうだな、と思う次第。

    今回、引退したくなるほど苦しみましたが、結果的には深くダイブしたことで苦手分野の理解を促進できたので、晴れて一人前のOpenStackerになった気になっています!!