LoginSignup
1
6

More than 3 years have passed since last update.

僕がAnsibleを学ぶためにVagrant upできるようになるまで

Last updated at Posted at 2019-05-14

はじめに

数年前から環境構築を自動で整えたいと思っていて、
ようやくVagrant + Ansible の勉強をはじめました。
本記事の範囲は

  1. とりあえず仮想マシンを2台立ち上げ
  2. Ansibleで操作できるようになる土台が整うまで

を目指し、
vagrant upが満足に立ち上がる様にまでの手順と
自分が躓いた箇所とその対応を記録したものです。

勉強の元ネタ

@hidekuro 様の記事を手始めに勉強させてもらいました。
Vagrant + Ansibleで環境構築をコード化する(1)導入
Vagrantfile はココを元ネタにしております。

環境

母艦:Ubuntu 18.04.2 LTS
仮想マシンの制御用ソフト:libvirtd (libvirt) 4.0.0、Vagrant 2.0.2
子1:Ubuntu 18.04.2 LTS (ホスト名:controller)
子2:Ubuntu 18.04.2 LTS (ホスト名:remote)

操作は可能な限りTerminalからコマンドで行っています。

libvirtのインストール

ubuntu 18.04 上でkvm仮想マシンを動作させるまでの最低限の手順 を参考にインストールしました。

$ sudo apt install libvirt-clients
$ sudo apt install qemu-utils
$ sudo apt install qemu-kvm
$ sudo apt install virtinst
$ sudo apt install libvirt-bin

vagrantの環境設定

~/.vagrant 配下が大容量必要になるとのことなので
Vagrantのホームディレクトリを変更しました。

$ sudo mkdir -p /srv/vagrant/home
$ sudo chown -R user:user /srv/vagrant
$ echo "VAGRANT_HOME=/srv/vagrant/home" >> ~/.bashrc
$ source ~/.bashrc

 出来上がったVagrantfile

Vagrant.configure(2) do |config|

  # remote-VM
  config.vm.define "remote" do |remote|
    remote.vm.box = "generic/ubuntu1804"
    remote.vm.hostname = "ansible-remote"
    remote.vm.network "private_network", ip: "172.16.97.102"
    remote.vm.synced_folder './remote/', '/vagrant', type: '9p', :mount_options => ['dmode=775', 'fmode=664']

    remote.vm.provider "virtualbox" do |vb|
      vb.memory = 1024
      vb.cpus = 2
    end

    remote.vm.provision "shell", inline: <<-SHELL
      # DNS config
      sed -i.bak -e "s/^DNS=.*$/DNS=8.8.8.8 192.168.122.1/g" /etc/systemd/resolved.conf
      systemctl restart systemd-resolved.service
    SHELL
  end

  # control-VM
  config.vm.define "control" do |control|
    control.vm.box = "generic/ubuntu1804"
    control.vm.hostname = "ansible-control"
    control.vm.network "private_network", ip: "172.16.97.101"
    control.vm.synced_folder './control/', '/vagrant', type: '9p', :mount_options => ['dmode=775', 'fmode=664']

    control.vm.provider "virtualbox" do |vb|
      vb.memory = 512
      vb.cpus = 2
    end

    control.vm.provision "shell", inline: <<-SHELL
      # DNS config
      sed -i.bak -e "s/^DNS=.*$/DNS=8.8.8.8 192.168.122.1/g" /etc/systemd/resolved.conf
      systemctl restart systemd-resolved.service

      apt update 
      # expect
      apt -y install expect

      # ansible 
      apt -y install software-properties-common
      apt-add-repository --yes --update ppa:ansible/ansible
      apt -y install ansible
      apt -y autoremove

    SHELL

    control.vm.provision "shell", privileged: false, inline: <<-SHELL
      # ssh
      mkdir -p ~/.ssh
      ssh-keygen -N "" -t ed25519 -f ~/.ssh/id_ed25519
      rm -f ~/.ssh/known_hosts

      # ssh-copy-id
      cp -f /vagrant/expect_sendkey.expect ~/expect_sendkey.expect
      chmod 774 ~/expect_sendkey.expect
      ~/expect_sendkey.expect vagrant@172.16.97.102
    SHELL
  end

end

エラー

その1

$ vagrant up
A Vagrant environment or target machine is required to run this
command. Run `vagrant init` to create a new Vagrant environment. Or,
get an ID of a target machine from `vagrant global-status` to run
this command on. A final option is to change to a directory with a
Vagrantfile and to try again.

カレントディレクトリにVagrantfileが無いだけでした。
カレントディレクトリを移動します。
$ cd ~/.vagrant.d

その2

母艦
$ vagrant up
Bringing machine 'remote' up with 'libvirt' provider...
Bringing machine 'control' up with 'libvirt' provider...
==> remote: An error occurred. The error will be shown after all tasks complete.
==> control: An error occurred. The error will be shown after all tasks complete.
An error occurred while executing multiple actions in parallel.
Any errors that occurred are shown below.

An error occurred while executing the action on the 'remote'
machine. Please handle this error then try again:

Name `vagrant_remote` of domain about to create is already taken. Please try to run
`vagrant up` command again.

An error occurred while executing the action on the 'control'
machine. Please handle this error then try again:

Name `vagrant_control` of domain about to create is already taken. Please try to run
`vagrant up` command again.

VAGRANT_HOME の場所をデフォルトから別の場所へ変更したので、
思い切って~/.vagrantディレクトリを削除(rm -rf)してしまいました。
ついでに1からやり直したくなったので、Vagrantfileを残して
仮想マシン等(boxes,data,gems,等...)すべて物理削除(rm -rf)してしまった後、
vagrant upした時に出たエラーです。

libvert側に名前が残っていたので、名前衝突によってエラーがでていました。

母艦
$ virsh list --all
 Id    Name                           State
----------------------------------------------------
 -     vagrant_control                shut off
 -     vagrant_remote                 shut off

$ virsh undefine vagrant_control
Domain vagrant_control has been undefined

$ virsh undefine vagrant_remote
Domain vagrant_remote has been undefined

上記のように、libvirt側も名前を消したら、解消しました。

その3

母艦
$ vagrant up
:
:
    control: Running: inline script
    control: /tmp/vagrant-shell: line 10: unexpected EOF while looking for matching `''
    control: /tmp/vagrant-shell: line 14: syntax error: unexpected end of file
==> control: An error occurred. The error will be shown after all tasks complete.
An error occurred while executing multiple actions in parallel.
Any errors that occurred are shown below.

An error occurred while executing the action on the 'control'
machine. Please handle this error then try again:

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.

「`」の数が合わないとのエラー。
実際にcontrolにログインして/tmp/vagrantファイルを見てみると、、、、

control
$ cat /tmp/vagrant-shell 
:
      mkdir -p ~/.ssh
      echo -e  'y
' | ssh-keygen -N "" -f ~/.ssh/id_rsa
:

たしかに数が合ってない。。。。
Vagrantfileを確認してみると、、、

母艦のVagrantfile抜粋
:
    control.vm.provision "shell", inline: <<-SHELL
:
      mkdir -p ~/.ssh
      echo -e  'y\n' | ssh-keygen -N "" -f ~/.ssh/id_rsa
:
    SHELL
:

ぱっと見おかしいところが無さそうですが、
echo -e 'y\n' | ssh-keygenの\n が改行として解釈されてしまったようです。
エスケープ処理(\を重ねる)で対応しました。

母艦のVagrantfile抜粋
:
    control.vm.provision "shell", inline: <<-SHELL
:
      mkdir -p ~/.ssh
      echo -e  'y\\n' | ssh-keygen -N "" -f ~/.ssh/id_rsa
:
    SHELL

うまく行きました。

その4

母艦
$ vagrant up
:
==> control: Installing NFS client...

==> control: An error occurred. The error will be shown after all tasks complete.
An error occurred while executing multiple actions in parallel.
Any errors that occurred are shown below.

An error occurred while executing the action on the 'control'
machine. Please handle this error then try again:

The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!

apt-get -yqq update
apt-get -yqq install nfs-common portmap
exit $?

Stdout from the command:

Stderr from the command:
E: Failed to fetch http://us.archive.ubuntu.com/ubuntu/pool/main/k/keyutils/keyutils_1.5.9-9.2ubuntu2_amd64.deb  Temporary failure resolving 'us.archive.ubuntu.com'
E: Failed to fetch http://us.archive.ubuntu.com/ubuntu/pool/main/libn/libnfsidmap/libnfsidmap2_0.25-5.1_amd64.deb  Temporary failure resolving 'us.archive.ubuntu.com'
E: Failed to fetch http://security.ubuntu.com/ubuntu/pool/main/libt/libtirpc/libtirpc1_0.2.5-1.2ubuntu0.1_amd64.deb  Temporary failure resolving 'us.archive.ubuntu.com'
E: Failed to fetch http://us.archive.ubuntu.com/ubuntu/pool/main/r/rpcbind/rpcbind_0.2.3-0.6_amd64.deb  Temporary failure resolving 'us.archive.ubuntu.com'
E: Failed to fetch http://us.archive.ubuntu.com/ubuntu/pool/main/n/nfs-utils/nfs-common_1.3.4-2.1ubuntu5.1_amd64.deb  Temporary failure resolving 'us.archive.ubuntu.com'
E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?

NFSのインストール〜設定まわりで失敗したようです。

母艦のVagrantfile(抜粋)
:
control.vm.synced_folder ".", "/vagrant", :mount_options => ['dmode=775', 'fmode=664']
:

Vagrant provider for libvirt. #Synced_Folders を見てみると若干書式が違っていました。
以下の様に修正してみると、、、、

母艦のVagrantfile(抜粋)
control.vm.synced_folder './', '/vagrant', type: '9p', :mount_options => ['dmode=775', 'fmode=664']

無事起動できました!

母艦
$ vagrant up
:
==> control: Configuring and enabling network interfaces...
==> control: mounting p9 share in guest
==> control: Running provisioner: shell...
    control: Running: inline script
:

その5

日本語化
Ubuntuの日本語環境 を参考にaptのリポジトリの更新を行いました

母艦のVagrantfile(抜粋)
    control.vm.provision "shell", inline: <<-SHELL
      # Japanese
      cd /tmp
      wget -nv https://www.ubuntulinux.jp/ubuntu-ja-archive-keyring.gpg
      apt-key add /tmp/ubuntu-ja-archive-keyring.gpg

      cd /tmp
      wget -nv https://www.ubuntulinux.jp/ubuntu-jp-ppa-keyring.gpg
      apt-key add /tmp/ubuntu-jp-ppa-keyring.gpg

      mkdir -p /etc/apt/sources.list.d
      cd /etc/apt/sources.list.d
      wget -nv https://www.ubuntulinux.jp/sources.list.d/bionic.list
      mv bionic.list ubuntu-ja.list

      apt update
    SHELL

オプションの -q はエラーも黙らせてしまうようなので-nvオプションに変更してます。
あと問題の切り分けのためにwgetapt-key を分割しました。

==> control: Running provisioner: shell...
    control: Running: inline script
    control: wget: unable to resolve host address 'www.ubuntulinux.jp'
    control: Warning: apt-key output should not be parsed (stdout is not a terminal)
    control: gpg: can't open '/tmp/ubuntu-ja-archive-keyring.gpg': No such file or directory

調べてみるとwgetでファイルが取得できていませんでした。
vagrant sshでログインした後、確認するとIPアドレスではpingが通りますが、
ホスト名だと迷子になってました。どうやらDNSの名前解決に失敗しているようです。

nsswitch.conf弄ったり、--natdnshostresolver1 onにしたり、offにしたり、
色々やってみましたが、destroy -> up を繰り返すたびに挙動が不安定です。
で、やっと見つけましたresolve.confを修正しました。

ほんと探しまくりました(2週間くらい。。。)

母艦のVagrantfile(抜粋)
    control.vm.provision "shell", inline: <<-SHELL
      # DNS config
      sed -i.bak -e "s/^DNS=.*$/DNS=8.8.8.8 192.168.122.1/g" /etc/systemd/resolved.conf
      systemctl restart systemd-resolved.service

    SHELL

DNSの接続先を8.8.8.8(GoogleのDNS)、母艦のvirbr0インタフェースに指定しています。

その他、調べていく中で、たくさんの方々の記事を参考にさせて頂きました。

1
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
6