repl.info

Vagrant + CentOS7+ kdump でVMのメモリサイズが小さいとkdumpの起動に失敗する

別にVagrantに限った話ではないけど。
Vagrantでprovisionする時にkdumpを起動しているのだが、VMのメモリサイズが1GBになっているようなVMだとそれが失敗していた。
原因と対策について整理しておく。

発生した問題

例えば、以下のようなVagrantfileでVMを起動するとする。

# -*- mode: ruby -*-

# vi: set ft=ruby :



Vagrant.configure("2") do |config|

  config.vm.box = "centos/7"



  config.vm.provider "virtualbox" do |vb|

    vb.memory = "1024"

  end



  config.vm.provision "shell", inline: <<-SHELL

    yum install -y kexec-tools

    systemctl start kdump.service

  SHELL

end

 

手元に作る環境なので、productionとは異なりメモリサイズを小さくしておく、ということは十分に有り得る。
この時、vagrant upすると以下のようになりprovisioningに失敗する。

==> default: Running provisioner: shell...

default: Running: inline script

==> default: Loaded plugins: fastestmirror

==> default: Loading mirror speeds from cached hostfile

==> default: * base: ftp.iij.ad.jp

==> default: * extras: ftp.iij.ad.jp

==> default: * updates: ftp.iij.ad.jp

==> default: Package kexec-tools-2.0.7-38.el7_2.1.x86_64 already installed and latest version

==> default: Nothing to do

==> default: Job for kdump.service failed because the control process exited with error code. See "systemctl status kdump.service" and "journalctl -xe" for details.

The SSH command responded with a non-zero exit status. Vagrant

assumes that this means the command failed. The output for this command

should be in the log above. Please read the output to determine what

went wrong.

 

原因

このログからではよくわからないので、VMにログインして状況を確認する。

takaishiryou-no-iMac $ vagrant ssh

[vagrant@localhost ~]$ sudo systemctl status kdump.service

● kdump.service - Crash recovery kernel arming

Loaded: loaded (/usr/lib/systemd/system/kdump.service; enabled; vendor preset: enabled)

Active: failed (Result: exit-code) since 水 2016-08-03 14:01:48 UTC; 2min 55s ago

Process: 1597 ExecStart=/usr/bin/kdumpctl start (code=exited, status=1/FAILURE)

Main PID: 1597 (code=exited, status=1/FAILURE)



8月 03 14:01:48 localhost.localdomain systemd[1]: Starting Crash recovery kernel arming...

8月 03 14:01:48 localhost.localdomain kdumpctl[1597]: No memory reserved for crash kernel.

8月 03 14:01:48 localhost.localdomain kdumpctl[1597]: Starting kdump: [FAILED]

8月 03 14:01:48 localhost.localdomain systemd[1]: kdump.service: main process exited, code=exited, status=1/FAILURE

8月 03 14:01:48 localhost.localdomain systemd[1]: Failed to start Crash recovery kernel arming.

8月 03 14:01:48 localhost.localdomain systemd[1]: Unit kdump.service entered failed state.

8月 03 14:01:48 localhost.localdomain systemd[1]: kdump.service failed.

 

起動に失敗したkdump.serviceのstatusを確認すると、「No memory reserved for crash kernel」と表示されている。
これは、メモリをkdump用に割り当てたいが、VMのメモリサイズが不足していて割り当てられないというエラーのようである。

このページの手順2.1によると、割り当てるメモリの量は/etc/default/grubを見れば分かる。実際に見てみるとcrashkernel=autoとなっている。autoの場合は予約するメモリサイズが自動的に設定される。どういう値になるかはこのページに書かれており、また、自動設定に必要な最小メモリサイズの情報がこのページに書かれている。後者を見ると、x86_64の場合は2GB必要であるということが分かる。つまり、上記Vagrantfileでは1GBしかメモリを用意していなかったためkdump用にメモリを確保しておらず、kdumpの起動に失敗したのである。

解決方法

解決方法として、以下が挙げられる。

  1. VMのメモリサイズを2GB以上にする
  2. crashkernelの値を変更し、固定値にする

てっとり早いのはメモリサイズ変更だが、kdumpのためだけに2倍のメモリを使うというのはなんだかしゃくである。なので、crashkernelの値を変更して、固定値にする方法を採用する。

手動で変更する場合はここの手順通りに作業を進め、crashkernelの値を128Mにして再起動すればよい。しかし、Vagrantの場合再起動した後にkdumpを起動する必要があるため、ややこしい。

そこで、aidanns/vagrant-reloadを使う。これはprovisioningの途中でVMを再起動して、その後のprovisioningをやってくれるというvagrantのプラグイン。Vagrantfileを以下のように修正してやる。

# -*- mode: ruby -*-

# vi: set ft=ruby :



Vagrant.require_plugin "vagrant-reload"



Vagrant.configure("2") do |config|

  config.vm.box = "centos/7"

  config.vm.provider "virtualbox" do |vb|

  vb.memory = "1024"

end



config.vm.provision "shell", inline: <<-SHELL

  sed -i "s/crashkernel=auto/crashkernel=128M/g" /etc/default/grub

  grub2-mkconfig -o /boot/grub2/grub.cfg

  SHELL

config.vm.provision :reload



config.vm.provision "shell", inline: <<-SHELL

  yum install -y kexec-tools

  systemctl start kdump.service

SHELL

end

 

vagrant upするとちゃんとVMが再起動し、sshで再度接続して次のprovisioningに進んでいることがわかる。

==> default: Running provisioner: shell...

default: Running: inline script

==> default: Generating grub configuration file ...

==> default: Found linux image: /boot/vmlinuz-3.10.0-327.22.2.el7.x86_64

==> default: Found initrd image: /boot/initramfs-3.10.0-327.22.2.el7.x86_64.img

==> default: Found linux image: /boot/vmlinuz-0-rescue-cb81bd8ac73c409cb970c217f287cf9f

==> default: Found initrd image: /boot/initramfs-0-rescue-cb81bd8ac73c409cb970c217f287cf9f.img

==> default: done

==> default: Running provisioner: reload...

==> default: Attempting graceful shutdown of VM...

==> default: Checking if box 'centos/7' is up to date...

==> default: Clearing any previously set forwarded ports...

==> default: Clearing any previously set network interfaces...

==> default: Preparing network interfaces based on configuration...

default: Adapter 1: nat

==> default: Forwarding ports...

default: 22 (guest) => 2200 (host) (adapter 1)

==> default: Running 'pre-boot' VM customizations...

==> default: Booting VM...

==> default: Waiting for machine to boot. This may take a few minutes...

default: SSH address: 127.0.0.1:2200

default: SSH username: vagrant

default: SSH auth method: private key

default: Warning: Remote connection disconnect. Retrying...

==> default: Machine booted and ready!

[default] GuestAdditions 5.0.26 running --- OK.

==> default: Checking for guest additions in VM...

==> default: Rsyncing folder: /Users/r_takaishi/src/github.com/takaishi/dev-vm/centos7/ => /home/vagrant/sync

==> default: Machine already provisioned. Run `vagrant provision` or use the `--provision`

==> default: flag to force provisioning. Provisioners marked to run always will still run.

==> default: Running provisioner: shell...

default: Running: inline script

==> default: Loaded plugins: fastestmirror

==> default: Loading mirror speeds from cached hostfile

==> default: * base: ftp.riken.jp

==> default: * extras: ftp.riken.jp

==> default: * updates: ftp.riken.jp

==> default: Package kexec-tools-2.0.7-38.el7_2.1.x86_64 already installed and latest version

==> default: Nothing to do

provisioningする度にVMを再起動するので時間が伸びるのがデメリット。