IronicをDevstackでサク?っと試してみた

日本OpenStackユーザ会勉強会で、Ironicのハッカソン日本OpenStackユーザ会 第21回勉強会があるということで、参加しようとIronic環境をDevstackで構築しようとしたが、詰まりどころが満載だったのででデバッグの記録をメモ

とりあえず、Document通りに。。。

git clone https://github.com/openstack-dev/devstack.git devstack

local.conf作成

cat <<END >local.conf
[[local|localrc]]
# Credentials
ADMIN_PASSWORD=password
DATABASE_PASSWORD=password
RABBIT_PASSWORD=password
SERVICE_PASSWORD=password
SERVICE_TOKEN=password

# Enable Ironic API and Ironic Conductor
enable_service ironic
enable_service ir-api
enable_service ir-cond

# Enable Neutron which is required by Ironic and disable nova-network.
disable_service n-net
enable_service q-svc
enable_service q-agt
enable_service q-dhcp
enable_service q-l3
enable_service q-meta
enable_service neutron

# Create 3 virtual machines to pose as Ironic's baremetal nodes.
IRONIC_VM_COUNT=3
IRONIC_VM_SSH_PORT=22
IRONIC_BAREMETAL_BASIC_OPS=True

# The parameters below represent the minimum possible values to create
# functional nodes.
IRONIC_VM_SPECS_RAM=1024
IRONIC_VM_SPECS_DISK=10

# Size of the ephemeral partition in GB. Use 0 for no ephemeral partition.
IRONIC_VM_EPHEMERAL_DISK=0

VIRT_DRIVER=ironic

# By default, DevStack creates a 10.0.0.0/24 network for instances.
# If this overlaps with the hosts network, you may adjust with the
# following.
NETWORK_GATEWAY=10.1.0.1
FIXED_RANGE=10.1.0.0/24
FIXED_NETWORK_SIZE=256

# Log all output to files
LOGFILE=$HOME/devstack.log
SCREEN_LOGDIR=$HOME/logs
IRONIC_VM_LOG_DIR=$HOME/ironic-bm-logs

END

stack.shで構築

$ ./stack.sh

インストールは、うまく行った、Horizonの画面も確認できた。

さっそく、Ironicノードをプロビジョニングを実行

$nova boot --flavor baremetal --image cirros-0.3.3-uec
$nova list
+--------------------------------------+---------+--------+------------+-------------+------------------+
| ID                                   | Name    | Status | Task State | Power State | Networks         |
+--------------------------------------+---------+--------+------------+-------------+------------------+
| a2c7f812-e386-4a22-b393-fe1802abd56e | testing | ERROR | -          | ERROR     | private=10.1.0.4 |
+--------------------------------------+---------+--------+------------+-------------+------------------+

うまく行き過ぎだとは思ってた、エラーですね。

ログを見てみると、「No valid host was found. There are not enough hosts available」というエラーが。。

早速デバッグ

nova-scheduleのlogより、下記のことが分かった

  1. nova-schedulerは、フィルタしてホストの選定はすんでいる
  2. ホストの選定の結果プロビジョニングに失敗するので、またフィルタする
  3. その結果のホストのぷろびじょにングも失敗するので、retry回数のフィルタにひっかかり
  4. No valid host was found エラーになっている

プロビジョンでコケているので、

nova-conductorのログを見てみる

  1. エラーメッセージ「"Failed to add deploy parameters on node"」を確認
  2. novaのソースをgrep
    • virt/ironic/driver.pyで例外を吐いていることを確認
    • ironic-apiを叩いているので、ironic-api,condを見てみる

ironic-apiのログを見てみる

  1. エラーメッセージ「"No conductor service registered which supports driver"」を確認

    • なぜか、ironic-conductorが動いていない模様
    • ironic-conductorを再起動
    • まだ、「No valid host was found」のまま
  2. エラーメッセージ「"Cannot validate PXE bootloader"」を確認

    • ironic-apiのdo_node_deploy apiの実際の処理をironic-conductorが行っており、do_node_deployのレスポンスが「Cannot validate PXE bootloader」なので詳細な情報を見るために、ironic-conductorへ

ironic-conductorのログを見てみる

  1. エラーメッセージ「" Can not validate PXE bootloader. The following paramenters were not passed to ironic:['deploy_kernel', 'deploy_ramdisk']"」
    • PXEDriverが、プロビジョンに必要なパラメータをチェックしているところでエラーを起こしている模様
    • PXEDriverでは、[deploy_kernel, deploy_ramdisk]の値が定義されているかチェックしている
    • deploy_kernel,ramdiskは、nodeのdriver_infoという情報を引っ張っているようなので、値を更新
 $ironic node-update <node-id> add driver_info/pxe_deploy_kernel=<deploy_kernel>
 $ironic node-update <node-id> add driver_info/pxe_deploy_ramdisk=<deploy_ramdisk>
  • まだ、「No valid host was found」のまま

  • エラーメッセージ「"Cannot execute SSH cmd"」

    • libvirtが動いているホストのsshdのポートを変更していたので、nodeのdriver_info/ssh_port,ssh_usernameを変更
    • まだ、「No valid host was found」のまま
  • エラーメッセージ「"connecting to monitor: Cannot set up guest memory"」

    • SSHPowerDriverが実行するvirshを実行した時のエラーのようだ。
    • エラー内容的には、メモリーが足りないと言われているので、swap領域を作成
    • まだ、「No valid host was found」のまま
  • 目立ったエラーメッセージが出なくなったが、プロビジョニングが終わらない現象に遭遇

    • よく調べると、ironicのノードstatusが「wait callback」のまま固まっている模様
    • Driverからの応答待ちというstatusなので、PXE関連で不具合が起きてる模様
    • neutronのdnsmasq(dhcp-agent)がPXEブートのDHCPを担当しているのだが、そもそも疎通が取れていない
    • Devstackでironicをインストールすると、brbmというベアメタル用のbridgeを作ってくれて、そこにnodeがぶら下がっているのだが、brbmブリッジとneutronのl2スイッチをつなげる必要がある(方法はいろいろある、br-tun経由、br-intに直接指す等)とりあえずは、br-intブリッジとbrbmブリッジを接続

    • それでも、ノードstatusが「wait callback」のまま固まっている・・・・

    • tftpサーバのアドレスが、ironic-conductorが動いているホストのIPであることに気づく、ironicノードがironic-conductorが動いているホストと通信できないといけないことに気づく。下記手順で通信可能にする
      • (1) 仮想L2NWをテナントの仮想ルータに接続
      • (2) ホスト側のルーティングテーブルに、仮想L2NWの経路を、仮想ルータの外部アドレスIF経由で追加

ここまできて、やっと動きました。 そもそも、なぜこんなにデバッグに時間がかかったかというと、ironicのプロビジョニングプロセスをまったく調べずに実行したことが原因ですね。

ただ、今回調べたところ、いろいろと制約があるなと感じました。

  1. nodeからtftpサーバにアクセスできる必要がある。

    • 現状ironic.confの設定ファイルで、tftpサーバのIPアドレスを指定するので、テナントごとにtftpサーバを分けることはできない。
    • つまり、tftpサーバから見て、IPアドレス帯が被ってはいけない(routingできないから)のでユーザが好きなサブネットでironicノードをプロビジョニングすることはできない
  2. nodeからIronic APIを叩ける必要がある

    • つまり、Managementセグメントとユーザセグメントを完全に分けることはできない
    • もし、やるならdeployフェーズのみ収容スイッチのポートのvlanを変更してアクセス可能にする等を行う必要がある。
    • もし、やるならironic apiのみ、nodeからアクセスできるIFを設けて、ironic api用のセグメントを作成する
  3. Ironic conductorからnodeにアクセスできる必要がある

    • tftpと同様で、ironic conductorから見て、nodeが所属するサブネットが被ってはいけない(routingできないから)

ネットワーク周りが、結構難しいなぁという印象。

Publicクラウドとして、仮想ネットワーク作り放題で、vmとベアを意識せずにポコポコプロビジョニングというのは、まだ難しいのかぁ。

Ironicは少し面白そうなので、もう少し追いかけてみる。