はじめに
Ansibleの検証環境を、手元のVirtualBox上にVagrantを使って構築する。
Vagrantを使うとVMの作成は簡単にできるが、Ansibleの検証環境ということで、以下の条件を追加
- 一つのVagrantfileで複数VM作成
- VM間で固定IPアドレスでネットワークがつながる
- VM間のsshアクセスのため同じ秘密鍵・公開鍵を設定
- AnsibleのPlaybookなどをホストOSから簡単に編集するための共有フォルダ設定
Ansibleのインストールも含めてもいいけど、まぁそこは1台なので手動で。(対象VMにshell
でインストールしてもいいけど)
Vagrantfile
急いでいる人向けに、完成品のVagrantfileをまず置いておきます。
ホストOS上のAnsible資材は~/src/ansible
にあります。
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
config.vm.box = "centos/7"
# shared folder
config.vm.synced_folder "~/src/ansible", "/ansible", mount_options: ['dmode=755', 'fmode=644']
# common ssh-private-key
config.ssh.insert_key = false
config.ssh.private_key_path = "~/.vagrant.d/insecure_private_key"
# copy to private-key
config.vm.provision "file", source: "~/.vagrant.d/insecure_private_key", destination: "/home/vagrant/.ssh/id_rsa"
config.vm.provision "shell", privileged: false, inline: <<-SHELL
chmod 600 $HOME/.ssh/id_rsa
SHELL
config.vm.define "ansible-controller" do |ansible_controller|
ansible_controller.vm.network "private_network", ip: "192.168.244.120"
# OS hostname
ansible_controller.vm.hostname = "ansible-controller.localhost"
ansible_controller.vm.provider "virtualbox" do |vb|
# Customize the amount of memory on the VM:
vb.memory = "1024"
# VM name
vb.name = "ansible-controller"
end
end
config.vm.define "ansible-node01" do |ansible_node01|
ansible_node01.vm.network "private_network", ip: "192.168.244.121"
# OS hostname
ansible_node01.vm.hostname = "ansible-node01.localhost"
ansible_node01.vm.provider "virtualbox" do |vb|
# Customize the amount of memory on the VM:
vb.memory = "1024"
# VM name
vb.name = "ansible-node01"
end
end
config.vm.define "ansible-node02" do |ansible_node01|
ansible_node01.vm.network "private_network", ip: "192.168.244.122"
# OS hostname
ansible_node01.vm.hostname = "ansible-node02.localhost"
ansible_node01.vm.provider "virtualbox" do |vb|
# Customize the amount of memory on the VM:
vb.memory = "1024"
# VM name
vb.name = "ansible-node02"
end
end
end
コマンド | 動作 |
---|---|
vagrant up |
全VM起動 |
vagrant halt |
全VM停止 |
vagrant destroy |
全VM削除 |
vagrant reload |
全VM Vagrantfile読みなおし |
vagrant ssh ansible-controller |
ansible-controllerへsshアクセス |
vagrant up ansible-controller |
ansible-controllerのみ起動 |
vagrant halt ansible-controller |
ansible-controllerのみ停止 |
概要図
以下解説
1ファイル複数VMの設定
- Multi-Machine - Vagrant by HashiCorp
- [Vagrant] Vagrant で複数のVM を立ち上げて、お互いに通信できるようにするには [VirtualBox] - Qiita
config.vm.define "ansible-controller" do |ansible_controller|
ansible_controller.vm.network "private_network", ip: "192.168.244.120"
# OS hostname
ansible_controller.vm.hostname = "ansible-controller.localhost"
ansible_controller.vm.provider "virtualbox" do |vb|
# Customize the amount of memory on the VM:
vb.memory = "1024"
# VM name
vb.name = "ansible-controller"
end
end
config.vm.define "ansible-node01" do |ansible_node01|
ansible_node01.vm.network "private_network", ip: "192.168.244.121"
# OS hostname
ansible_node01.vm.hostname = "ansible-node01.localhost"
ansible_node01.vm.provider "virtualbox" do |vb|
# Customize the amount of memory on the VM:
vb.memory = "1024"
# VM name
vb.name = "ansible-node01"
end
end
だいたいこの部分。(node02は省略)
Rubyの読み書きができずに、初めは既存部分からコピペでうまくいかなかったけど、
config.vm.define "ansible-controller" do |ansible_controller|
に対して
- config.vm.network
+ ansible_controller.vm.network
と、定義したansible_controller
で設定を定義してやる必要がある。
これをVMの個数分(そして、ホスト名やIPアドレスなどのVM毎に設定が異なる内容に対して)繰り返す。
各VMで共通の定義については、VM毎の設定に書かずに既存の定義部分のままでよい。
config.vm.box = "centos/7"
ベースになるBoxの種類とかね。
VM間で固定IPアドレスでネットワークがつながる
デフォルトの(インターネットアクセスもできる)NAT用のアドレスだと、VM間でpingは通るけど、IPアドレスが固定ではないので検証には不向き。
ついでにホストOSからもアクセスできないし。
ということでホストオンリーアダプタを使って同セグメントの固定IPアドレスを設定する。
これはVM毎に設定する。
この部分。
config.vm.define "ansible-controller" do |ansible_controller|
ansible_controller.vm.network "private_network", ip: "192.168.244.120"
#[...]
end
config.vm.define "ansible-node01" do |ansible_node01|
ansible_node01.vm.network "private_network", ip: "192.168.244.121"
#[...]
end
config.vm.define "ansible-node02" do |ansible_node01|
ansible_node01.vm.network "private_network", ip: "192.168.244.122"
#[...]
end
VM間のsshアクセスのため同じ秘密鍵・公開鍵を設定
あきらめて手動で設定したろかーと最も苦労した部分。。
Vagrantのssh関連は特に指定がない場合は、VM毎に秘密鍵・公開鍵が作成され、ホストOSからのvagrant ssh [hostname]
実行によるsshアクセスはVM毎の公開鍵で行われる。
そのため、この公開鍵ではVM間の公開鍵認証には使えない。
また、秘密鍵はVM内には保持されず、ホストOS上のみに配置される。
作成・使用されるssh鍵は、VM実行中に以下のコマンドで確認できる。
zaki@mascarpone% vagrant ssh-config
Host ansible-controller
HostName 127.0.0.1
User vagrant
Port 2222
UserKnownHostsFile /dev/null
StrictHostKeyChecking no
PasswordAuthentication no
IdentityFile C:/Users/zaki/src/vagrant/ansible/.vagrant/machines/ansible-controller/virtualbox/private_key
IdentitiesOnly yes
LogLevel FATAL
Host ansible-node01
HostName 127.0.0.1
User vagrant
Port 2200
UserKnownHostsFile /dev/null
StrictHostKeyChecking no
PasswordAuthentication no
IdentityFile C:/Users/zaki/src/vagrant/ansible/.vagrant/machines/ansible-node01/virtualbox/private_key
IdentitiesOnly yes
LogLevel FATAL
zaki@mascarpone%
IdentityFile
に(vagrant ssh
で)使用する秘密鍵のパスが表示され、VM毎に異なるのがわかる。
そこでまずは、「各VMで同じ秘密鍵・公開鍵を使うための設定」を行う。
config.ssh.insert_key = false
このconfig.ssh.insert_key
をfalse
にする設定によって、「VM毎にsshの秘密鍵・公開鍵を作成・設定する」という動作が無くなる。
次に、config.ssh.private_key_path
で、替わりの秘密鍵を指定する。(ちなみにデフォルトで~/.vagrant.d/insecure_private_key
の鍵が使用される)
実はVagrantをインストールすると、ホームディレクトリ以下~/.vagrant.d/insecure_private_key
にパスフレーズなしの共通設定用の鍵が生成されている。今回はこれを使う。
もちろんssh-keygen
でパスフレーズなしの鍵を別途作成してそれを使っても良い。
config.ssh.private_key_path = "~/.vagrant.d/insecure_private_key"
この設定の状態でssh-config
を確認すると、各VMで同じ秘密鍵・公開鍵を使用する設定になる。
zaki@mascarpone% vagrant ssh-config
Host ansible-controller
HostName 127.0.0.1
User vagrant
Port 2222
UserKnownHostsFile /dev/null
StrictHostKeyChecking no
PasswordAuthentication no
IdentityFile C:/Users/zaki/.vagrant.d/insecure_private_key
IdentitiesOnly yes
LogLevel FATAL
Host ansible-node01
HostName 127.0.0.1
User vagrant
Port 2200
UserKnownHostsFile /dev/null
StrictHostKeyChecking no
PasswordAuthentication no
IdentityFile C:/Users/zaki/.vagrant.d/insecure_private_key
IdentitiesOnly yes
LogLevel FATAL
zaki@mascarpone%
ただし、このままでは、ホストOS→ゲストOS間のsshアクセスで使用するssh鍵が、各ゲストOSで同じになっただけで、各ゲストOS上にこの秘密鍵がまだないため、ゲストOS同士で公開鍵認証ができない。(秘密鍵がホストOS上にしかないため)
そこで、このホストOS上の秘密鍵を、作成したVM上にコピーする処理を追加する。
config.vm.provision "file", source: "~/.vagrant.d/insecure_private_key", destination: "/home/vagrant/.ssh/id_rsa"
ホストOS上にあるファイルをゲストOSにコピーするにはFile Provisionerを使用する。
(大項目にPushなんてあるから、こっち使ってできると思い込んでいろいろやってもうまくいかなかったのであきらめかけたけど、別の機能だった…)
これでホストOS上のsource: "~/.vagrant.d/insecure_private_key"
のファイルを、ゲストOSのdestination: "/home/vagrant/.ssh/id_rsa"
へ配布できる。
ただしこれだけだと、mode設定が維持できず他者にもread権限がついてしまってssh実行時にエラーとなるため、手動で権限設定を追加する。
File Provisionで指定できればいいのによくわからなかったので、shellで。
config.vm.provision "shell", privileged: false, inline: <<-SHELL
chmod 600 $HOME/.ssh/id_rsa
SHELL
これで各VMで同じ秘密鍵・公開鍵を使いつつ、VM内に秘密鍵の配布まで設定できる。
AnsibleのPlaybookなどをホストOSから簡単に編集するための共有フォルダ設定
Ansibleの資材はホストOSの~/src/ansible
にあるとする。
この部分。
# shared folder
config.vm.synced_folder "~/src/ansible", "/ansible", mount_options: ['dmode=755', 'fmode=644']
ホストOSの~/src/ansible
を、ゲストOSの/ansible
にマウントする。
オプションを何もつけない場合、ファイルやディレクトリが777のフルオープン状態になり、Ansibleの実行で警告が出力されるなど検証に差し支える。
[WARNING] Ansible is being run in a world writable directory (/ansible/practice), ignoring it as an ansible.cfg source. For more information see https://docs.ansible.com/ansible/devel/reference_appendices/config.html#cfg-in-world-writable-dir
で、共有フォルダ設定自体もすんなりとはいかなかったけど、こちらはエラーメッセージでググればすぐに答えにたどり着いたので問題なかった。
初実行時はこんなエラーが出力された。
==> default: Mounting shared folders...
default: /vagrant_data => C:/Users/zaki/src/vagrant/data
Vagrant was unable to mount VirtualBox shared folders. This is usually
because the filesystem "vboxsf" is not available. This filesystem is
made available via the VirtualBox Guest Additions and kernel module.
Please verify that these guest additions are properly installed in the
guest. This is not a bug in Vagrant and is usually caused by a faulty
Vagrant box. For context, the command attempted was:
mount -t vboxsf -o uid=1000,gid=1000 vagrant_data /vagrant_data
The error output from the command was:
mount: unknown filesystem type 'vboxsf'
調べた感じだと、vboxsfでマウントするためのGuest Additionsが古いのが原因っぽい。
Vagrantのプラグインvagrant-vbguestを入れておくと、VM起動時によしなにしてくれるらしい。
Vagrantで共有フォルダのマウントに失敗するときの対処方法 - Qiita
ので、設定する。
プラグインインストール
zaki@mascarpone% vagrant plugin install vagrant-vbguest
Installing the 'vagrant-vbguest' plugin. This can take a few minutes...
Installed the plugin 'vagrant-vbguest (0.18.0)'!
zaki@mascarpone% vagrant plugin list
vagrant-disksize (0.1.3, global)
vagrant-vbguest (0.18.0, global)
現在のGuest Additionsの確認
zaki@mascarpone% vagrant vbguest --status
[default] No Virtualbox Guest Additions installation found.
なんと入っていなかった。
Guest Additionsのインストール(更新)
vagrant vbguest
と引数・オプションなしで実行する。
zaki@mascarpone% vagrant vbguest
[default] No Virtualbox Guest Additions installation found.
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: ty1.mirror.newmediaexpress.com
* extras: ty1.mirror.newmediaexpress.com
* updates: ty1.mirror.newmediaexpress.com
:
:
Dependencies Resolved
================================================================================
Package Arch Version Repository Size
================================================================================
Installing:
gcc x86_64 4.8.5-36.el7_6.2 updates 16 M
kernel-devel x86_64 3.10.0-957.5.1.el7 updates 17 M
kernel-devel x86_64 3.10.0-957.21.3.el7 updates 17 M
perl x86_64 4:5.16.3-294.el7_6 updates 8.0 M
:
:
インストール処理が始まる。
:
Dependency Updated:
glibc.x86_64 0:2.17-260.el7_6.5 glibc-common.x86_64 0:2.17-260.el7_6.5
libgcc.x86_64 0:4.8.5-36.el7_6.2 libgomp.x86_64 0:4.8.5-36.el7_6.2
Complete!
Copy iso file C:\Program Files\Oracle\VirtualBox\VBoxGuestAdditions.iso into the box /tmp/VBoxGuestAdditions.iso
Mounting Virtualbox Guest Additions ISO to: /mnt
mount: /dev/loop0 is write-protected, mounting read-only
Installing Virtualbox Guest Additions 5.2.26 - guest version is unknown
Verifying archive integrity... All good.
Uncompressing VirtualBox 5.2.26 Guest Additions for Linux........
VirtualBox Guest Additions installer
Copying additional installer modules ...
Installing additional modules ...
VirtualBox Guest Additions: Building the VirtualBox Guest Additions kernel
modules. This may take a while.
VirtualBox Guest Additions: To build modules for other installed kernels, run
VirtualBox Guest Additions: /sbin/rcvboxadd quicksetup <version>
VirtualBox Guest Additions: Building the modules for kernel
3.10.0-957.5.1.el7.x86_64.
VirtualBox Guest Additions: Starting.
Redirecting to /bin/systemctl start vboxadd.service
Redirecting to /bin/systemctl start vboxadd-service.service
Unmounting Virtualbox Guest Additions ISO from: /mnt
zaki@mascarpone% vagrant vbguest --status
[default] GuestAdditions 5.2.26 running --- OK.
zaki@mascarpone%
これでvagrant reload
すれば、共有フォルダ設定が有効になる。