「Vagrant」カテゴリーアーカイブ

Vagrant用のUbuntu 16.04 x64のBoxを作る

Vagrant用のUbuntu 16.04 x64のBoxを作りました。

こちらのサイトが参考になりました。ありがとうございます。

Ubuntu 16.04のVagrantで使うboxを作成する

何かあったときにXサーバーがあるといいので、Desktop版で作りました。容量は大きくなってしまいますけれど。

1つだけ注意があって、インストール時にvagrantユーザーを作ってしまえばスーパーユーザーになれます。しかし、別のアカウントを作って後からvagrantユーザーを作るときは、パスワードの設定とスーパーユーザーになれる権限を忘れずにしなければいけません。

$ sudo adduser vagrant
$ sudo passwd vagrant
$ sudo gpasswd -a vagrant sudo

この3つを忘れずにしないと、なんか動かないことになってしまいます。adduserはuseraddにするとホームディレクトリがつくられません。オプションuseradd -mが必要です。パスワードの設定を忘れると、ログインできません。sudoをできるようにしないと、Vagrantの設定ができないというエラーになります。

パスワードなしでスーパーユーザーにならないとネットワークの設定ができないと言われ、それってセキュリティ的にどうなの?と思ってしまいました。

作ってみて、容量が大きいと時間がかかって、エラーで何度も繰り返すのが大変でした。

Vagrantでprivate_networkを指定したときの仕組み

Vagrantでネットワークの設定は3つあります。このうち、private_networkを指定したときにVagrantは少し複雑な処理をしていました。

1つめのVagrantでpublic_networkを指定したときは、VirtualBoxのブリッジアダプターが使われ、外部のルーターなどからDHCPでIPアドレスをもらいます。

2つめのforwarded_portを指定したときは、VirtualBoxのNATが使われて、VirtualBox内蔵のネットワークからDHCPでIPアドレスをもらいます。

3つめのprivate_networkを指定したときは、VirtualBoxのホストオンリーアダプターという仮想ネットワークアダプターが使われます。この場合、上の2つとは少し違っていて、DHCPサーバーはデフォルトでは設定されていません。このことは、ホストの仮想ネットワークアダプターのプロパティからわかります。IPアドレスは、192.168.33.1というアドレスが設定されています。

このため、ゲストOSは192.168.33.x(xは2から254)というネットワークを自分で設定しないといけません。Vagrantではvagrant upのときに、ssh接続を使って/etc/network/interfacesに次のようなエントリーを書き込みます。

#VAGRANT-BEGIN
# The contents below are automatically generated by Vagrant. Do not modify.
auto enp0s8
iface enp0s8 inet static
      address 192.168.33.10
      netmask 255.255.255.0
#VAGRANT-END

これでIPアドレスが設定されて、ホストとゲストで通信ができるようになります。このような仕組みのため、vagrant upのときにvagrantというユーザーでSSHで接続できることと、ファイルに書き込む権限がいるためにスーパーユーザーになれることが条件になります。

Vagrantを使わずVirtualBoxのみでプライベートネットワークを組んだ時は、手作業でネットワークインターフェース、この場合はenp0s8の設定をする必要があります。

自分でvagrantboxを作ろうとして、わかったことでした。

VirtualBoxのCUIコンソールでクリップボードのコピーペースト

VirtualBoxのCUI(Character User Interface)コンソールでCtrl-Vでコピーペーストをしようとしたけど^Vが表示されるだけで困っている。コピーペーストはマウスを使わないといけないのかな。

そんな人の悩みに答えます。

この記事では、次のことがわかります。
1. Gnomeデスクトップの端末で、コピーペーストをする方法
2. Gnomeデスクトップが立ち上がる前のVirtualBoxのコンソールでコピーペーストをする方法
3. まとめ

1. Gnomeデスクトップの端末で、コピーペーストをする方法

Gnomeデスクトップが立ち上がっている場合、コピーペーストは端末アプリの編集に、コピーと貼り付けがあります。コピーしたいところをマウスで白黒反転させておいてから、コピーを選び、貼り付けたいところにカーソルを持っていって、貼り付けを選べばいいです。

なお、ゲストOSとホストOSの間でコピーペーストができない場合は、VirtualBoxのGuestAdditionsが動作しているかどうか確認してください。

このときに、キーボードショートカットのCtrl-C/Ctrl-Vを使おうとすると、画面に^Vと表示されてしまって貼り付けできません。

解決方法は、Ctrl-Shift-CとCtrl-Shift-Vを使えばよいです。

Ctrl-Cは、プロセスの終了に割り当てられているため、Gnomeデスクトップの設定でこうなっています。

2. Gnomeデスクトップが立ち上がる前のVirtualBoxのコンソールでコピーペーストをする方法

Gnomeデスクトップが立ち上がる前のVirtualBoxのコンソールでは、ショートカットキーは使えません。そこで、xselというコマンドを使います。

サーバーバージョンのCentOSを使っていて、Gnomeデスクトップがない場合などに相当します。

ここでは、CentOSについて説明します。

2-1. xselのインストールと動作の確認

コンソールでxselと打ち込んでコマンドがない場合は、xselをインストールします。このときに、Xvfbという画面のないXサーバーを使いますので、同時にインストールします。

sudo yum install xsel Xvfb

Xvfbを立ち上げます。

Xvfb -screen 0 1280x720x24 &
export DISPLAY=:0

もし、Xvfbが立ち上がっていなくてxselを使おうとすると、次のようなエラーが出ます。DISPLAY変数がexportされてないときも同様です。

xsel: Can't open display :(null)

準備の最後にVBoxClientを立ち上げます。

VBoxClient --clipboard

これで、ホストOSとゲストOS間でコピーペーストできます。準備は終わりです。

例えば、文字列aaaをクリップボードへにコピーするには、次のようにします。

echo aaa |xsel --input --clipboard

クリップボードからのペーストは次のようにします。

xsel --output --clipboard

これでクリップボードをコマンドで使うことができるようになりました。

2-2. pbcopy/pbpasteコマンドにまとめる

いちいちxselのコマンドを打ち込むのは手間がかかりますので、pbcopy/pbpasteというコマンドにまとめます。pbcopy/pbpasteは同名のMac OSのコマンドです。

ホームディレクトリの.bash_profileの最後にaliasで定義します。

.bash_profile

alias pbcopy="xsel --input --clipboard"
alias pbpaste="xsel --output --clipboard"

aliasを書いたあとは $ source .bash_profileで有効にします。

2-3. viで使う

コンソールの中でviを使ったとき、コピーペーストするにはもう一工夫必要でした。viの中では、:r! 外部コマンドを打つとコマンドの実行結果が入力されます。上で設定したpbpasteを実行しようとしてもエラー127のcommand not foundになってしまいます。

そのため、環境変数BASH_ENVの設定と、.bashenvの設定が必要でした。

.bashenvというファイルを作ります。
.bashenv

shopt -s expand_aliases
alias pbcopy="xsel --input --clipboard"
alias pbpaste="xsel --output --clipboard"

.bashrcの最後でこのファイルを有効にします。

export BASH_ENV=~/.bashenv

これで、viのコマンドモードで

:r!pbpaste

とすると、クリップボードにコピーされた内容を取り込むことができます。

コピーしたいときはビジュアルモードで範囲を選択して、次のようにします。

:!pbcopy;pbpaste

ちなみにpbcopyとpbpasteの間はセミコロンです。

pbopyの前のビックリマークが必要です。また、pbpasteがないと切り取りになってしまいます。

3. まとめ

VirtualBoxのCUI(Character User Interface)コンソールでコピーペーストを使えるようにしました。

CentOSのGnomeデスクトップが立ち上がる前のコピーペーストの方法について説明しました。

設定が完了するとviでクリップボードへのコピーペーストができるようになります。

Vagrant+Ansibleのデバッグ方法

VagrantとAnsibleを使っていると、たびたびエラーになります。

そのデバッグに役立ったことを紹介します。

Vagrantの場合

Vagrantでプロビジョニングをしてエラーになったときは、次のようにします。

VAGRANT_LOG=info vagrant provision

を実行する。

エラーになると次のような表示が確認できる。

ERROR vagrant: 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.

調べてみるとログの上の方にこんな情報がありました。

 INFO interface: info: Could not get lock /var/lib/dpkg/lock - open (11: Resource temporarily unavailable)
 INFO interface: info: ==> default: Could not get lock /var/lib/dpkg/lock - open (11: Resource temporarily unavailable)

apt-getのエラーのようで、vagrant sshでゲストOSにログインしてapt-getしてみても原因はつかめず。もう1度vagrant provisionしてみると成功しました。一時的にエラーになっただけのようでした。

Ansible単独の場合

AnsibleはSSHで接続できていないと動きません。そのためSSHのチェックが重要になります。
まず、次のコマンドで接続を確かめます。

ansible -vvvv all -m ping

を実行してみる。

表示色が濃い青色で読めないときは、ANSIBLE_NOCOLOR=1をつけます。

ANSIBLE_NOCOLOR=1 ansible -vvvv all -m ping

ログのポイントは次のところです。ESTABLISH SSH CONNECTION FOR USERでssh接続のユーザー名が間違っていないか。

SSH:EXEC sshのところで、この場合sshから192.168.33.10までがsshのコマンドラインになります。とりあえずこのIPアドレスまでをコピーしてペーストして単独で接続できるか見てみます。

<192.168.33.10> ESTABLISH SSH CONNECTION FOR USER: ubuntu
<192.168.33.10> SSH: EXEC ssh -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o 'IdentityFile=".vagrant/machines/default/virtualbox/private_key"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=ubuntu -o ConnectTimeout=10 -o ControlPath=/tmp 192.168.33.10 '/bin/sh -c '"'"'chmod u+x /home/ubuntu/.ansible/tmp/ansible-tmp-1496030041.85-156969875839371/ /home/ubuntu/.ansible/tmp/ansible-tmp-1496030041.85-156969875839371/ping.py && sleep 0'"'"''

sshからIPアドレスまでの部分だけをコピーペーストで新しく張り付けて実行してみます。

ssh -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o 'IdentityFile=".vagrant/machines/default/virtualbox/private_key"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=ubuntu -o ConnectTimeout=10 -o ControlPath=/tmp 192.168.33.10

これで接続できているかまず確認しましょう。

sshで接続できていれば、問題の切り分けができます。あとはpythonのスクリプトが実行できているかどうかです。

MSYS2のAnsibleを使ってVagrantでプロビジョニング

VagrantでゲストOSをセットアップするには、次の3通りがあります。

  1. Vagrantfileの中ではプロビジョニングを使わず、ゲストOSを立ち上げるだけにして、ansible単独でゲストOSを操作する方法
  2. Vagrantfileの中でconfig.vm.provision 'ansible_local'として、Vagrantのansible_localというプロビジョニングを使う方法
  3. Vagrantfileの中でconfig.vm.provision 'ansible'として、Vagrantのプロビジョニングを使う方法

今回は、3番目のVagrantのansibleプロビジョニングを使ってゲストOSをセットアップします。

AnsibleもVagrantも、ansibleプロビジョニングをWindowsホストではサポートしていないのでその点はご了承ください。

前回までに、MSYS2上でAnsibleが動くことがわかりました。

まず、これまでのように、ホストからansible-playbookでゲストOSが操作できることを確認します。

これで素直にVagrantのプロビジョニングのなかでansibleが使えるかというと、エラーが出て使えません。

そこで、Cygwinでの動作例を参考に次のようにしました。

ansble-play.batという次のようなファイルを作ってPATHの通ったところに置きます。

@echo off

REM MSYS2のインストール場所
set MSYS=C:\msys32

REM bash.exeからansible-playbookを起動します
set SH=%MSYS%\usr\bin\bash.exe

"%SH%" -c "/usr/bin/ansible-playbook %*"

これで、Vagrantからansible-playbookを呼び出すことができます。

Vagrantfileは次の通りです。ゲストOSはubuntu/xenial64にしたのですが、このイメージはpythonが含まれていません。そのため、shellプロビジョニングを使ってインストールしました。このとき、aptのソースファイルを書き換えて少し速くインストールするようにしました。

ansibleプロビジョニングでは、Playbookをsite.yml、コンフィグレーションファイルにansible.cfg、インベントリファイルにhostsを指定しました。

Vagrantfile

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "ubuntu/xenial64"

  config.vm.network "private_network", ip: "192.168.33.10"
  
  config.vm.provision "shell", inline: <<-SHELL
		# aptのソースファイルを書き換え
    sed -i s%archive.ubuntu.com/ubuntu%ftp.jaist.ac.jp/pub/Linux/ubuntu/%g /etc/apt/sources.list
    apt-get update
    apt-get -y install python aptitude
  SHELL

  config.vm.provision "ansible" do |ansible|
    ansible.playbook = "site.yml"
    ansible.config_file = "ansible.cfg"
    ansible.inventory_path = "hosts"
    ansible.limit = 'all'
  end
end

次にansible.cfgファイルです。vagrant ssh-configで表示される結果をもとに作ります。Userをremote_userに、IdentityFileをprivate_key_fileにします。

control_pathの設定は、CygwinやMSYS2を使ったときにエラーになるのを回避するためです。こちらの情報をもとにしました。

ansible.cfg

[defaults]
inventory = hosts
remote_user = ubuntu
host_key_checking = False
private_key_file = .vagrant/machines/default/virtualbox/private_key


[ssh_connection]
# for Cygwin, MSYS2
control_path = /tmp

インベントリファイルは、次の通りです。vagrantsというグループで、ubuntu01という名前にしました。IPアドレスはVagrantfileと合わせます。これが違っていてよくSSHのエラーになりました。

hosts

[vagrants]
ubuntu01 ansible_host=192.168.33.10

最後はPlaybookです。Apache2をインストールすることにしました。

vagrantsというグループにubuntuでアクセスします。aptでapache2の最新版ををインストールしてbecome: trueでスーパーユーザーで行います。

site.yml

---
- hosts: vagrants
  user: ubuntu
  tasks:
    - name: install packages Apache2
      apt: name=apache2 update_cache=yes
      become: true

4つのファイルがそろえば、vagrant upでサーバーが設定され、http://192.168.33.10/にアクセスするとApache2の画面を見ることができます。
使ってみて、VagrantのAnsibleプロビジョニングはVagrantと一緒に使うときは便利ですが、Ansible単独で設定したほうが自由度はあるのかなという感じがしました。

Vagrantで、ansible_localを使ってみる

VagrantでゲストOSをセットアップするには、次の3通りがあります。

  1. Vagrantfileの中ではプロビジョニングを使わず、ゲストOSを立ち上げるだけにして、ansible単独でゲストOSを操作する方法
  2. Vagrantfileの中でconfig.vm.provision 'ansible_local'として、Vagrantのansible_localというプロビジョニングを使う方法
  3. Vagrantfileの中でconfig.vm.provision 'ansible'として、Vagrantのプロビジョニングを使う方法

このうち、今回はansible_localを使う方法を試してみます。

Vagrantのプロビジョニングでansible_localを使う場合には、ホストOSにはansibleをインストールしてある必要はありません。

ゲストOSにansibleが自動的にインストールされ、そこでansible-playbookが実行されます。

ポイントは2つあります。1つは、Vagrantfileでprovisionにansible_localを設定します。2つめは、Playbookでconnection: localを使うことです。

ansible_localを指定すると、ゲストOSにansibleが自動的にインストールされます。

実際の例は以下の通りです。

Vagrantfileは次の通りです。プライベートアドレスに192.168.33.10を指定して、provisionにansible_localを指定します。Playbookにsite.ymlを指定し、インベントリファイルにhostsを指定しています。

Vagrantfile

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "ubuntu/xenial64"

  config.vm.network "private_network", ip: "192.168.33.10"
  
  config.vm.provision "ansible_local" do |ansible|
    ansible.playbook = "site.yml"
    ansible.inventory_path = "hosts"
    ansible.limit = 'all'
  end
end

インベントリファイルは次の通りです。vagrantsというグループにubuntu01というホスト名のサーバーがあり、アドレスは192.168.33.10としています。

hosts

[vagrants]
ubuntu01 ansible_host=192.168.33.10

Playbookは次の通りです。vagrantsというグループに、connection: localという設定で、ubuntuというユーザーにログインします。そこで、Apache2をインストールしています。

site.yml

---
- hosts: vagrants
  connection: local
  user: ubuntu
  tasks:
    - name: install packages Apache2
      apt: name=apache2 update_cache=yes
      become: yes

connection: localがないと、次のようなエラーになります。

TASK [Gathering Facts] *********************************************************
fatal: [ubuntu01]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: Host key verification failed.\r\n", "unreachable": true}
        to retry, use: --limit @/vagrant/site.retry

connection: localを使わないと、ゲストOSにansibleをインストールしてあるのに、わざわざ自分自身にsshでログインしてplaybookを実行しようとします。そのとき、SSHのエラーになります。

ansible_localを使うと、ansibleは自動的にインストールしてくれますので簡単ですね。

AnsibleでゲストOSをセットアップする

前々回でAnsibleをインストールし、前回でVagrantで作ったゲストOSにSSHで接続できることがわかりました。Ansibleを使う環境は整ったので、Ansible単独でゲストOSをセットアップします。

手順はまず、Vagrantでサーバーを用意します。次に、Ansibleの設定をansible.cfgにして、扱うサーバーの設定を書いたhostsという名前のインベントリファイルを用意して動作確認をします。それが出来たら、Playbookを作成して実行してみます。

なお、Windows上のAnsibleの設定ではこちらのCygwinの情報を参考にしました。

Vagrantfileファイル

用意したサーバーは、次のようなVagrantfileで作りました。

Vagrantfile

VAGRANTFILE_API_VERSION = &quot;2&quot;

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = &quot;ubuntu/xenial64&quot;

  config.vm.define 'ubuntu01' do |host|
    host.vm.hostname = 'ubuntu01'
    host.vm.network &quot;private_network&quot;, ip: &quot;192.168.33.10&quot;
  end

  config.vm.provision 'shell', inline: &lt;&lt;-SCRIPT
    # aptのソースファイルを書き換え
    sed -i s%archive.ubuntu.com/ubuntu%ftp.jaist.ac.jp/pub/Linux/ubuntu/%g /etc/apt/sources.list
    apt-get update
    apt-get -y install python aptitude
  SCRIPT

end

ゲストOSには、ubuntu/xenial64を選びました。ubuntu01という名前にして、IPアドレスは、192.168.33.10にしました。

ubuntu/xenial64にはPythonがインストールされていません。Ansibleは、PythonのコードをゲストOSに送り込んで実行します。そのため、あらかじめPythonをインストールしていおきます。ダウウンロードの時間を短縮するために、aptのソースファイルを編集してあります。

ansible.cfgファイル

次に、Ansibleの設定をするansible.cfgを作ります。vagrant ssh-configの結果をもとに次のようなファイルを作りました。

ansible.cfg

[defaults]
inventory = hosts
remote_user = ubuntu
host_key_checking = False
private_key_file = C:/msys32/home/kazu/ansible/intro/.vagrant/machines/ubuntu01/virtualbox/private_key

[ssh_connection]
# for Cygwin, MSYS2
control_path = /tmp

インベントリファイル名は、hostsにします。remote_userとprivate_key_fileは、vagrant ssh-configで表示されるユーザー名UserとプライベートキーIdentityFileの場所を設定します。

host_key_checking = Falseは、ゲストOSを作ったり壊したりしたときに公開鍵が変わってしまうのですが、それをチェックしないという意味です。

MSYS2やCygwinでansibleを動かすときのポイントは、control_path = /tmpをansible.cfgに設定することです。これがないとエラーになります。
こんなエラーが出ます。

ubuntu01 | UNREACHABLE! =&gt; {
    &quot;changed&quot;: false,
    &quot;msg&quot;: &quot;Failed to connect to the host via ssh: mm_send_fd: sendmsg(2): Connection reset by peer\r\nmux_client_request_session: send fds failed\r\n&quot;,
    &quot;unreachable&quot;: true
}

hostsファイル

次に、hostsという名前のインベントリファイルを作ります。

hosts

[webservers]
ubuntu01 ansible_host=192.168.33.10

webserversというグループに、ubuntu01という名前のサーバーを作り、そのIPアドレスは192.168.33.10です。これは、Vagrantと合わせます。

Ansibleで使うhostsファイルのホスト名(この場合はubuntu01)は、Vagrantで使うVagrantfileのhost.vm.nameで指定する名前とは無関係です。もっとも、同じにしておいた方が間違わなくて済むのでいいです。

動作確認

ファイルが出来たら、ansibleに続けて、すべてのマシン(all)にpingを打ってサーバーからの返事を見ます。-m pingというのはpingモジュールを使ってpingを打つという意味です。

ansible all -m ping

こういう返事が返ってくれば成功です。

ubuntu01 | SUCCESS =&gt; {
    &quot;changed&quot;: false,
    &quot;ping&quot;: &quot;pong&quot;
}

Playbookの実行

あとは、Playbookを作って実行するだけです。

Playbookは、インデントが重要なのでタブが入っているとエラーになります。気をつけましょう。

ここでは、site.ymlという名前のPlaybookを作りました。

hostsに実行するサーバー名を指定して、userにログインするユーザー名を入れます。tasksとして、Apache2をインストールします。nameには、このタスクのコメントをいれ、aptというモジュールを使ってapache2をインストールされた状態にします。このとき、スーパーユーザーで行います。

site.yml

---
- hosts: ubuntu01
  user: ubuntu
  tasks:
    - name: install Apache2
      apt: name=apache2 state=installed
      become: true

ansible-playbookの次にsite.ymlを指定して実行してみます。

ansible-playbook site.yml

これで、Apache2がインストールできたら成功です。

実際に、http://192.168.33.10/ にブラウザでアクセスするとApacheの画面が見れると思います。

Ansibleの使い方は、Ansible構成管理入門を参考にさせてもらいました。ありがとうございます。

VagrantでAnsibleを使うのはSSHの理解がカギ

VagrantでAnsibleを使うのは、SSHを使ってリモートホストを操作します。なので、SSHがつながらないと話になりません。

SSHのしくみ

SSHの接続には秘密鍵と公開鍵の2つを使います。

公開鍵は、秘密鍵から作ることができます。

クライアント側とサーバー側の双方で秘密鍵と公開鍵があります。このうち公開鍵をお互いに送って保管することで通信ができます。

サーバーに接続してみて.sshディレクトリにあるauthorized_keysが保管場所。自分のホームディレクトリの.sshディレクトリの中のknown_hostsというファイルが保管場所です。

接続される側(サーバー側)で使われるのがauthorized_keysで、接続する側(クライアント側)で使われるのがknown_hostsです。

SSHクライアントで接続しようとしている場合、まずパスワードで接続してクライアント側の公開鍵をサーバー側に送ります。接続されるサーバー側は、authorized_keysという中にクライアント側の公開鍵をいれます。

そのあとで、サーバー側からサーバー側の公開鍵をクライアント側に送ります。これをクライアント側でknown_hostsに登録することで鍵認証で通信する準備が整います。これは、初めてsshで接続しようとしたときに警告が出てyesと答えると自動でやってくれます。

一度設定が済むと、

ssh -i <秘密鍵> <リモートホスト名>

で接続できます。

Vagrantの場合

Vagrantで作ったゲストOSにSSHを使ってパスワードでログイン

まずは、ゲストOSにパスワードでログインしてみます。

まず、vagrant ssh-configでVagrantが使っているsshの設定を見てみます。

$ vagrant ssh-config

Host default
  HostName 127.0.0.1
  User ubuntu
  Port 2222
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile C:/msys32/home/vagrant/vm/ubuntu16.04/.vagrant/machines/default/virtualbox/private_key
  IdentitiesOnly yes
  LogLevel FATAL

HostNameが接続時に設定するホスト、Userがユーザー名、Portがポート番号です。-pでポート番号を指定して、ユーザー名とホスト名を@マークで区切って指定します。

$ ssh -p 2222 ubuntu@127.0.0.1

The authenticity of host '[127.0.0.1]:2222 ([127.0.0.1]:2222)' can't be established.
ECDSA key fingerprint is SHA256:h8pe0EpC3I5ocDrZ7PGUxjYMIs2Wh8lIsXG0R/C3S5A.
Are you sure you want to continue connecting (yes/no)?

なにやら表示が出ます。これは、サーバー側の公開鍵をホームディレクトリの.ssh/known_hostsに登録してもいいかという意味です。

yesと答えると、パスワードを聞かれます。

ubuntu@127.0.0.1's password:

Vagrantでubuntu/xenail64をゲストに使ったときは、ゲストのパスワードは、C:\ユーザー\自分の名前\.vagrant.dのなかのVagrantfileの中に書かれています。

ubuntu/xenial64の場合は以下のところです。

C:\Users\(your name)\.vagrant.d\boxes\ubuntu-VAGRANTSLASH-xenial64\20170423.0.0\virtualbox\Vagrantfile

これでログインできると思います。

公開鍵認証を使う場合

Vagrantの場合は、ホームディレクトリの.vagrant\machines\(host名)\virtualboxというフォルダの中にprivate_keyがつくられています。これを使って、ゲストOSに接続しています。
Vagrantが最初にvagrant upしたとき、ホストの公開鍵をコピーしてゲストOSのAuthorized_keysに登録しています。これで、パスワードなしでも鍵を使ってログインできるようになっています。

このauthorized_keysを確認してみます。

$ vagrant ssh

で接続して

(remote host) $ cat .ssh/authorized_keys

で、なかを見ると、

ssh-rsa AAAAB3NzaC----すごく長い------CBnRropmyAxL vagrant

みたいにssh-rsaで始まりvagrantで終わっているのがVagrantが送ったクライアント側の公開鍵です。

(remote host) $ exit

でログアウトします。

実際にsshを使って手動で接続してみようと思います。

まず、vagrant ssh-configでVagrantが使っているsshの設定を見てみます。

$ vagrant ssh-config

Host default
  HostName 127.0.0.1
  User ubuntu
  Port 2222
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile C:/msys32/home/vagrant/vm/ubuntu16.04/.vagrant/machines/default/virtualbox/private_key
  IdentitiesOnly yes
  LogLevel FATAL

HostNameが接続時に設定するホスト、Userがユーザー名、Portがポート番号、IdentityFileが接続時に使う秘密鍵です。

sshで-iで秘密鍵を、-pでポート番号を、ホストの前に@マークで名前を指定して接続してみます。

$ ssh -i .vagrant/machines/default/virtualbox/private_key -p 2222 ubuntu@127.0.0.1

最初に接続したときは、ゲストOS(接続先)の公開鍵が登録されていないため、次のような警告が出ます。

The authenticity of host '[127.0.0.1]:2222 ([127.0.0.1]:2222)' can't be established.
ECDSA key fingerprint is SHA256:+lHBujro5WLFzsFfFSFTQzWS/E35OvSwdr8t8OO/AFo.
Are you sure you want to continue connecting (yes/no)? 

yesと入力しリターンキーを押すとパスワードなしでログインしたと思います。この確認は2度目から出ません。

(remote host)$ exit

でログアウトして、自分のホームディレクトリの.ssh/known_hostsを確認してみます。

$ cat ~/.ssh/known_hosts

[127.0.0.1]:2222 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBE1rZpVqvH1jYQ2lEjm0zc0LORZh7aIH61qIS0msMbBvA0W1s+NTgiftffhTcnON903vw/pWt9tqNhR69wNJsI8=

ホスト127.0.0.1ポート番号2222としてリモートホストの公開鍵が登録されています。

なお、vagrant destroyしたあと、vagrant upでゲストOSを作り直し、sshで接続しようとすると、次のようなエラーになります。

$ ssh -i .vagrant/machines/default/virtualbox/private_key  -p 2222 ubuntu@127.0.0.1

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ECDSA key sent by the remote host is
SHA256:h8pe0EpC3I5ocDrZ7PGUxjYMIs2Wh8lIsXG0R/C3S5A.
Please contact your system administrator.
Add correct host key in /home/vagrant/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /home/vagrant/.ssh/known_hosts:3
ECDSA host key for [127.0.0.1]:2222 has changed and you have requested strict checking.
Host key verification failed.

これは、ゲストOSを作り直して公開鍵が変わってしまったために、ホームディレクトリで保存しているゲストOSの公開鍵と違っているためです。

このときは、エディタで~/.ssh/known_hostsの[127.0.0.1]:2222の行を削除すると接続することができます。

このようにvagrant ssh-configで確認した設定値を使って、sshで接続することができます。

AnsibleをMSYS2で使う

前回、VagrantとDockerで環境構築をしたので、Ansibleを使ってみることにしました。

Vagrantで作ったゲストOSに対してAnsibleで環境設定をするには、大きく分けると次の3つの方法があります。

  1. Vagrantfileの中ではプロビジョニングを使わず、ゲストOSを立ち上げるだけにして、ansible単独でゲストOSを操作する方法
  2. Vagrantfileの中でconfig.vm.provision 'ansible_local'として、Vagrantのansible_localというプロビジョニングを使う方法
  3. Vagrantfileの中でconfig.vm.provision 'ansible'として、Vagrantのプロビジョニングを使う方法

1番の方法は、WindowsホストではAnsibleからサポートされていません。

2番の方法は、AnsibleをゲストOSにインストールして、ゲストOS内でAnsibleを動かします。よって、Windowsホストでも使えます。

3番の方法は、WindowsホストではVagrantからは公式にはサポートされていません。そもそも1番の方法でansibleコマンドが動かないと、Vagrantでは動きようがありません。

このように、Windowsをホストにする場合、ansible_localしか方法はないのかと思いました。

実際、MSYS2のpipでパッケージを入れてみても、ansibleコマンドはエラーが出て動きません。

でも、Cygwinで動かしている人がいて、何とかならないかなとやってみることにしました。

最近はMSYS2をメインに使っています。そこでMSYS2で検索してみると、Ansibleを動かした人がいました。

[ansible] MSYS2 で ansible を使えるようにする手順

この通りやったらansibleが動き出しました。ありがとうございます。

ポイントは、32bitバージョンのMSYS2(msys2-i686-20161025.exe)を使うことです。64bitバージョンでは動きませんでした。

(2017/05/31)訂正
MSYS2のバージョンが問題ではなかったです。インストールするパッケージがmsysのpython2である必要がありました。

pacman -S python2

です。mingw-w64-x86_64-python2とかではだめでした。スタートメニューから起動するコンソールがMSYS2 MinGW 64bitやMSYS2 MinGW 32bitだと、MinGWのpythonがインストールしてある時はそちらが優先的に使われてしまうので気をつけてください。

インストールが終わったら、SSHでゲストOSにアクセスできることを確認して、ansibleが使えるようになります。

次回は、SSHについて書きます。

VagrantでDockerを使ってみて高速化のあれこれ

今までVirtualBoxは素のまま使っていたのですが、Vagrantを使うといいということを聞いて使ってみることにしました。

せっかくなのでDockerも使ってみようということで以下のサイトを参考にしてインストールしてみました。

VagrantとDockerについて名前しか知らなかったので試した

やってみた結果は、とてもすんなりできました。ありがとうございます。

でも、なんかインストールに時間がかかるのです。VagrantのゲストOSの元となるboxファイルは、自分のC:\Users\(your name)\.vagrant.d\boxesというフォルダに保存されます。ですので、一度ダウンロードしてしまえば2度目からはとても速くゲストOSが出来上がります。

でも、そのときにDockerをセットアップしようとprovisioningに加えると、ゲストOSを作り直すごとにインターネットからDockerが使うファイルをダウンロードします。速度が2Mbpsくらいしかでなくてプロビジョニングが終わるまで10分くらいかかります。DockerをDockerは速いということが言われていますが、Docker自身のセットアップは時間がかかるのですね。

これを解決するため、CocPxoryというプロキシサーバーをつかってみたりしました。でも、httpではなくhttpsでダウンロードしようとするのでなかなか難しいです。

結局、こちらを参考に、Ubuntuをインストールするときはaptのソースリストを変更して、日本のサーバーからダウンロードするように変更しました。

ただ、ソースのリスト先がus.archive.ubuntu.comではなく、archive.ubuntu.comでした。また、ubuntuをmirrorしているところから速いのを選びました。

また、vagrant-cachierというプラグインが少し速くしてくれました。これを使うときの注意点は、vagrant-cachierは、/var/cache/apt/archivesを/tmp/vagrant-cache/aptにシンボリックリンクすることで、ホストのフォルダC:\Users\(your name)\.vagrant.d\cache\(box名)を保存先にしています。そのため、vagrant-cachierを使ったままVagrantfileから設定を削除したり、プラグインをvagrant plugin uninstallで削除してしまうと、/var/cache/apt/archivesのリンクがそのままになってしまうため、apt-getが動かなくなってしまうことです。

Vagrantfileは、こんな感じ。

Vagrant.configure(&quot;2&quot;) do |config|
  config.vm.box = &quot;ubuntu/xenial64&quot;

  config.vm.provision &quot;shell&quot;, inline: &lt;&lt;-SHELL
    # aptのソースファイルを書き換え
    sed -i s%archive.ubuntu.com/ubuntu%ftp.jaist.ac.jp/pub/Linux/ubuntu/%g /etc/apt/sources.list
    apt-get update
  SHELL

  config.vm.provision &quot;docker&quot; do |d|
    # dockerに関する操作
    d.build_image &quot;/vagrant&quot;, args: &quot;-t kazu/my-bash&quot;
    d.run &quot;kazu/my-bash&quot;, args: &quot;-d -t -v /vagrant:/tmp/shared&quot;
  end

  if Vagrant.has_plugin?(&quot;vagrant-cachier&quot;)
    config.cache.scope = :box 
  end
end

Dockerfileは、次のようにしました。

FROM ubuntu:xenial

MAINTAINER kazu

CMD [&quot;/bin/bash&quot;]

これでvagrant upするとゲストOSが立ち上がります。その中で、Dockerが動いています。

一度Vagrantのboxがダウンロードされると、プロビジョニングは4分ほどで終わります。なんとか待っていられるかな。