vagrantのmulti-machinにてVMをshellにてprovisioning

vagrantを利用して複数のVMを起動する場合にVM間でsshの鍵配布を自動で実施する場合のサンプル。 VM間でクラスタを構成する環境等を作成したい場合に鍵配布などが面倒なので自動化する。

ssh-keygenで秘密鍵と公開鍵を予め作成し、各VM秘密鍵を配布して、公開鍵を登録する。

ローカル環境のVMの場合には良いが、本来セキュリティ上好ましくないため注意が必要。

初めにホスト(Mac)のVagrantfileを作成するディレクトリにて鍵ペアを作成する。

※コメント(-C)に"vagrant-common"を入力してそれが各VMのauthorized_keysに未登録の場合は登録されるようにしています。

$ ssh-keygen -q -t rsa -P "" -C vagrant-common -f ./id_rsa

$ ls -l id_rsa*
-rw-------  1 root  staff  1679  4 29 23:20 id_rsa
-rw-r--r--  1 root  staff   396  4 29 23:20 id_rsa.pub

$ cat ./id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDRUaG6Dft0uv4TBZyCqvRr3T5npaOk0AK+aI7fjclwp0MgbxS9RYuALrZzluUR5vg/wyuaLPsxWQpSJoNNsTc28neCfKHSz8r79PvpSa6M9jp2FLPcI/VDhdMyuW/8ZO+Jl2UeCWqRHgSjWSJ80P38yahY0fayqyUh1G4dwgUGCIpsnUezDQ0kRPrX4VU4eQmerFDKktcgWHAkwLkj7Y1t3AvJKvk34iQdVFh7eg3K3VxuLB8JjW8fAl51m9iPUP4/kxnJ7AEim430s50zC3gGoTjb68mffMN4wtOSiFSAQWrvXPtEJsqUwArf9crMMNdUYusavR5uNZMWlZ6CkXk9 vagrant-common

VMを3台起動するVagrantfileを作成する。

provisionにてshellで各VMに鍵を配布し、その他、VMの共通設定を施す。

chefでcookbook作るようにしたほうがベター。

shellの場合でも冪等性は保てる様にif、testの判定は行う様にすべき。

# -*- mode: ruby -*-
# vi: set ft=ruby :

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|

  # Operating System
  config.vm.box = "centos6.5"
  config.vm.box_url = "https://github.com/2creatives/vagrant-centos/releases/download/v6.5.1/centos65-x86_64-20131205.box"
  config.vm.boot_timeout = 300

  config.vm.define :mhost01 do |mhost01|
    mhost01.vm.hostname = "mhost01"
    mhost01.vm.network "private_network", ip: "192.168.33.11"
    mhost01.vm.provider "virtualbox" do |vb|
      vb.name = "mhost01"
      vb.customize ["modifyvm", :id, "--cpus", 1]
      vb.customize ["modifyvm", :id, "--memory", 768]
      #vb.gui = true
    end
  end

  config.vm.define :mhost02 do |mhost02|
    mhost02.vm.hostname = "mhost02"
    mhost02.vm.network "private_network", ip: "192.168.33.12"
    mhost02.vm.provider "virtualbox" do |vb|
      vb.name = "mhost02"
      vb.customize ["modifyvm", :id, "--cpus", 1]
      vb.customize ["modifyvm", :id, "--memory", 768]
      #vb.gui = true
    end
  end

  config.vm.define :mhost03 do |mhost03|
    mhost03.vm.hostname = "mhost03"
    mhost03.vm.network "private_network", ip: "192.168.33.13"
    mhost03.vm.provider "virtualbox" do |vb|
      vb.name = "mhost03"
      vb.customize ["modifyvm", :id, "--cpus", 1]
      vb.customize ["modifyvm", :id, "--memory", 768]
      #vb.gui = true
    end
  end

  $script = <<-EOT
echo "* stop iptables" service iptables stop chkconfig iptables off echo "* disable selinux" setenforce 1 sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/sysconfig/selinux echo "* add guests /etc/hosts" test `grep ^192.168.33.11 /etc/hosts | wc -l` -eq 0 && echo "192.168.33.11 mhost01" >>/etc/hosts test `grep ^192.168.33.12 /etc/hosts | wc -l` -eq 0 && echo "192.168.33.12 mhost02" >>/etc/hosts test `grep ^192.168.33.13 /etc/hosts | wc -l` -eq 0 && echo "192.168.33.13 mhost03" >>/etc/hosts echo "* rsa key put" if [ ! -f ~vagrant/.ssh/id_rsa ]; then cp -p /vagrant/id_rsa ~vagrant/.ssh/ chmod 600 ~vagrant/.ssh/id_rsa fi if [ ! -f ~vagrant/.ssh/authorized_keys -o `grep vagrant-common ~vagrant/.ssh/authorized_keys | wc -l` -eq 0 ]; then cat /vagrant/id_rsa.pub >> ~vagrant/.ssh/authorized_keys chmod 600 ~vagrant/.ssh/authorized_keys fi echo "* update sshd_config" sed -i 's/# StrictHostKeyChecking ask/ StrictHostKeyChecking no/' /etc/ssh/ssh_config sed -i 's/#UseDNS yes/UseDNS no/' /etc/ssh/sshd_config sed -i 's/#IgnoreUserKnownHosts no/IgnoreUserKnownHosts yes/' /etc/ssh/sshd_config service sshd restart echo "* update yum repo site jp only" sed -i 's/^#include_only=.*$/include_only=.jp/' /etc/yum/pluginconf.d/fastestmirror.conf
EOT
config.vm.provision :shell, inline: $script

end

vagrant upする。

$ vagrant up
Bringing machine 'mhost01' up with 'virtualbox' provider...
Bringing machine 'mhost02' up with 'virtualbox' provider...
Bringing machine 'mhost03' up with 'virtualbox' provider...
==> mhost01: Importing base box 'centos6.5'...
==> mhost01: Matching MAC address for NAT networking...
==> mhost01: Setting the name of the VM: mhost01
==> mhost01: Clearing any previously set network interfaces...
==> mhost01: Preparing network interfaces based on configuration...
    mhost01: Adapter 1: nat
    mhost01: Adapter 2: hostonly
==> mhost01: Forwarding ports...
    mhost01: 22 => 2222 (adapter 1)
==> mhost01: Running 'pre-boot' VM customizations...
==> mhost01: Booting VM...
==> mhost01: Waiting for machine to boot. This may take a few minutes...
    mhost01: SSH address: 127.0.0.1:2222
    mhost01: SSH username: vagrant
    mhost01: SSH auth method: private key
    mhost01: Warning: Connection timeout. Retrying...
    mhost01: Warning: Connection timeout. Retrying...
    mhost01: Warning: Remote connection disconnect. Retrying...
==> mhost01: Machine booted and ready!
==> mhost01: Checking for guest additions in VM...
==> mhost01: Setting hostname...
==> mhost01: Configuring and enabling network interfaces...
==> mhost01: Mounting shared folders...
    mhost01: /vagrant => /Users/turubee/vagrant/multi-machine
==> mhost01: Running provisioner: shell...
    mhost01: Running: inline script
* stop iptables
* disable selinux
setenforce: SELinux is disabled
* add guests /etc/hosts
* rsa key put
* update sshd_config
Stopping sshd: [  OK  ]
Starting sshd: [  OK  ]
* update yum repo site jp only
==> mhost02: Importing base box 'centos6.5'...
==> mhost02: Matching MAC address for NAT networking...
==> mhost02: Setting the name of the VM: mhost02
==> mhost02: Fixed port collision for 22 => 2222. Now on port 2201.
==> mhost02: Clearing any previously set network interfaces...
==> mhost02: Preparing network interfaces based on configuration...
    mhost02: Adapter 1: nat
    mhost02: Adapter 2: hostonly
==> mhost02: Forwarding ports...
    mhost02: 22 => 2201 (adapter 1)
==> mhost02: Running 'pre-boot' VM customizations...
==> mhost02: Booting VM...
==> mhost02: Waiting for machine to boot. This may take a few minutes...
    mhost02: SSH address: 127.0.0.1:2201
    mhost02: SSH username: vagrant
    mhost02: SSH auth method: private key
    mhost02: Warning: Connection timeout. Retrying...
    mhost02: Warning: Connection timeout. Retrying...
    mhost02: Warning: Remote connection disconnect. Retrying...
==> mhost02: Machine booted and ready!
==> mhost02: Checking for guest additions in VM...
==> mhost02: Setting hostname...
==> mhost02: Configuring and enabling network interfaces...
==> mhost02: Mounting shared folders...
    mhost02: /vagrant => /Users/turubee/vagrant/multi-machine
==> mhost02: Running provisioner: shell...
    mhost02: Running: inline script
* stop iptables
* disable selinux
setenforce: SELinux is disabled
* add guests /etc/hosts
* rsa key put
* update sshd_config
Stopping sshd: [  OK  ]
Starting sshd: [  OK  ]
* update yum repo site jp only
==> mhost03: Importing base box 'centos6.5'...
==> mhost03: Matching MAC address for NAT networking...
==> mhost03: Setting the name of the VM: mhost03
==> mhost03: Fixed port collision for 22 => 2222. Now on port 2202.
==> mhost03: Clearing any previously set network interfaces...
==> mhost03: Preparing network interfaces based on configuration...
    mhost03: Adapter 1: nat
    mhost03: Adapter 2: hostonly
==> mhost03: Forwarding ports...
    mhost03: 22 => 2202 (adapter 1)
==> mhost03: Running 'pre-boot' VM customizations...
==> mhost03: Booting VM...
==> mhost03: Waiting for machine to boot. This may take a few minutes...
    mhost03: SSH address: 127.0.0.1:2202
    mhost03: SSH username: vagrant
    mhost03: SSH auth method: private key
    mhost03: Warning: Connection timeout. Retrying...
    mhost03: Warning: Connection timeout. Retrying...
    mhost03: Warning: Connection timeout. Retrying...
    mhost03: Warning: Remote connection disconnect. Retrying...
==> mhost03: Machine booted and ready!
==> mhost03: Checking for guest additions in VM...
==> mhost03: Setting hostname...
==> mhost03: Configuring and enabling network interfaces...
==> mhost03: Mounting shared folders...
    mhost03: /vagrant => /Users/turubee/vagrant/multi-machine
==> mhost03: Running provisioner: shell...
    mhost03: Running: inline script
* stop iptables
* disable selinux
setenforce: SELinux is disabled
* add guests /etc/hosts
* rsa key put
* update sshd_config
Stopping sshd: [  OK  ]
Starting sshd: [  OK  ]
* update yum repo site jp only

問題なく起動したようなのでVMのステータスを確認。

$ vagrant status
Current machine states:
mhost01                   running (virtualbox)
mhost02                   running (virtualbox)
mhost03                   running (virtualbox)

VM間のssh接続を確認。

$ vagrant ssh mhost01
[vagrant@mhost01 ~]$ ssh mhost02
Warning: Permanently added 'mhost02,192.168.33.12' (RSA) to the list of known hosts.
[vagrant@mhost02 ~]$ ssh 192.168.33.13
Warning: Permanently added '192.168.33.13' (RSA) to the list of known hosts.
[vagrant@mhost03 ~]$
[vagrant@mhost03 ~]$ ssh mhost01
Warning: Permanently added 'mhost01,192.168.33.11' (RSA) to the list of known hosts.
Last login: Wed Apr 30 16:57:45 2014 from 10.0.2.2
[vagrant@mhost01 ~]$ ssh 192.168.33.12
Last login: Wed Apr 30 16:59:59 2014 from 192.168.33.11
[vagrant@mhost02 ~]$

VM間でsshで鍵認証のパスワードなしでログインできました。

複数VMの環境を利用する作業がはかどりそうですね。