ホストWIndowsでVagrant + ansibleでLinuxをプロビジョニングしようとしたら盛大にハマった。
はじめに
vagrantのansible_local使って複数台のゲストOSをansibleでプロビジョニングしようとしたら盛大にはまった。
筆者環境
- ホスト:Windows10
- Vagrant:2.0.0
- virtualbox : 5.1.28
ちなみに自宅のMBPで同じことやってもちゃんと動いたので、 Windows特有の問題。
構成
複数台のVM立ち上げるのに、地道にプロビジョニングしていくと時間かかるので、 ansibleのコントロール用VMを1個作って、そこからプロビジョニングするようにする。
絵書くとこんな感じ
図には書いてないですが、ホストオンリーアダプタでホストOSとやり取りが可能で、 ゲストOSは同一のネットワークセグメントです。
コード
基本Vagrant公式のansible_localの下の方に書いてあるヤツ。
Ansible Local - Provisioning - Vagrant by HashiCorp
ソースの構成
/root
Vagrantfile
inventory
docker.yml
ansible.cfg
プロジェクトルートからフラットに並べてるだけ
Vagrantfile
Vagrant.configure("2") do |config| config.vm.box = "centos7.2" config.vm.define "node1" do |machine| machine.vm.network "private_network", ip: "172.17.177.21" end config.vm.define "node2" do |machine| machine.vm.network "private_network", ip: "172.17.177.22" end config.vm.define 'controller' do |machine| machine.vm.network "private_network", ip: "172.17.177.11" machine.vm.provision :ansible_local do |ansible| ansible.playbook = "docker.yml" ansible.verbose = true ansible.install = true ansible.limit = "all" # or only "nodes" group, etc. ansible.inventory_path = "inventory" end end end
inventory
controller ansible_connection=local node1 ansible_ssh_host=172.17.177.21 ansible_ssh_private_key_file=/home/vagrant/private_key.node1 node2 ansible_ssh_host=172.17.177.22 ansible_ssh_private_key_file=/home/vagrant/private_key.node2 [nodes] node[1:2]
playbook
--- - name: install docker hosts: nodes become: true tasks: - name: create docker group group: name=docker - name: add a docker user user: name=docker password=docker123 group=docker state=present - name: install required packages yum: name={{ item }} state=present with_items: - yum-utils - device-mapper-persistent-data - lvm2 - name: setup stable docker repository shell: "yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo" args: chdir: "/etc/yum.repos.d" creates: docker-ce.repo - name: install docker yum: name=docker-ce state=present - name: enable service docker systemd: name: docker enabled: yes state: started
ansible.cfg
[defaults] host_key_checking = no [ssh_connection] ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o UserKnownHostsFile=/dev/null -o IdentitiesOnly=yes
実行する
vagrant up
provisionが動くと盛大にエラーになる。
実行エラー
PLAY [install docker] ******************************************************** TASK [Gathering Facts] ********************************************************* fatal: [node1]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: Warning: Permanently added '172.17.177.21' (ECDSA) to the list of known hosts.\r\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r\n@ WARNING: UNPROTECTED PRIVATE KEY FILE! @\r\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r\nPermissions 0777 for '/vagrant/.vagrant/machines/node1/virtualbox/private_key' are too open.\r\nIt is required that your private key files are NOT accessible by others.\r\nThis private key will be ignored.\r\nbad permissions: ignore key: /vagrant/.vagrant/machines/node1/virtualbox/private_key\r\nPermission denied (publickey,gssapi-keyex,gssapi-with-mic,password).\r\n", "unreachable": true} to retry, use: --limit @/vagrant/docker.retry PLAY RECAP ********************************************************************* node1 : ok=0 changed=0 unreachable=1 failed=0 Ansible failed to complete successfully. Any error output should be visible above. Please fix these errors and try again.
エラーのざっくりした内容
sshで使用するkeyのパーミッションが悪くてsshが失敗している。 めんどくさいからホストOS上からフルコントロール付ける。
再チャレンジ
vagrant provision
これでいけるだろうと思ったら盛大にエラーが出る
実行エラー
==> controller: Running provisioner: ansible_local... Vagrant has automatically selected the compatibility mode '2.0' according to the Ansible version installed (2.4.2.0). Alternatively, the compatibility mode can be specified in your Vagrantfile: https://www.vagrantup.com/docs/provisioning/ansible_common.html#compatibility_mode controller: Running ansible-playbook... cd /vagrant && PYTHONUNBUFFERED=1 ANSIBLE_NOCOLOR=true ansible-playbook --limit="all" --inventory-file=inventory -v docker.yml Using /vagrant/ansible.cfg as config file PLAY [install docker] ******************************************************** TASK [Gathering Facts] ********************************************************* fatal: [node1]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: Warning: Permanently added '172.17.177.21' (ECDSA) to the list of known hosts.\r\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r\n@ WARNING: UNPROTECTED PRIVATE KEY FILE! @\r\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r\nPermissions 0777 for '/vagrant/.vagrant/machines/node1/virtualbox/private_key' are too open.\r\nIt is required that your private key files are NOT accessible by others.\r\nThis private key will be ignored.\r\nbad permissions: ignore key: /vagrant/.vagrant/machines/node1/virtualbox/private_key\r\nPermission denied (publickey,gssapi-keyex,gssapi-with-mic,password).\r\n", "unreachable": true} fatal: [node2]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: Warning: Permanently added '172.17.177.22' (ECDSA) to the list of known hosts.\r\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r\n@ WARNING: UNPROTECTED PRIVATE KEY FILE! @\r\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r\nPermissions 0777 for '/vagrant/.vagrant/machines/node2/virtualbox/private_key' are too open.\r\nIt is required that your private key files are NOT accessible by others.\r\nThis private key will be ignored.\r\nbad permissions: ignore key: /vagrant/.vagrant/machines/node2/virtualbox/private_key\r\nPermission denied (publickey,gssapi-keyex,gssapi-with-mic,password).\r\n", "unreachable": true} to retry, use: --limit @/vagrant/docker.retry PLAY RECAP ********************************************************************* node1 : ok=0 changed=0 unreachable=1 failed=0 node2 : ok=0 changed=0 unreachable=1 failed=0 Ansible failed to complete successfully. Any error output should be
エラーのざっくりした内容
権限与えすぎなんだよ!って怒られてる。 ~/.ssh/known_hostに何かする場合、権限与えすぎてもダメということらしい。 (はじめて知った)
調べてみたら、 所有者以外の書込み権を設定してあるとだめとのこと。 Windows上から何したら600とかになるのか判らんから、とりあえずkeyファイルをコピーして権限を与えることに。
vagrant ssh controller cp -p /vagrant/.vagrant/machines/node1/virtualbox/private_key private_key.node1 cp -p /vagrant/.vagrant/machines/node2/virtualbox/private_key private_key.node2 chmod 600 private_key* exit vagrant provision
(略) 最後まで動いて、各ゲストにログインしてdockerコマンド打ってもちゃんと入った。
教訓
ゲストとホストをマウントした先の何かを参照して何かさせるの、ほんとにろくなことが起きない。
— shougo (@kroyeeg) 2018年2月28日
ファイルシステムが違うものをマウントして、参照することの難しさを再認識したのであった。
まとめ
Vagrant(WindowsをホストOS)を使って、コントロールマシン経由で各VMをプロビジョニングしたい場合は、 private_keyをコントロールマシン上にコピーしてパーミッションを600に変更してあげると、 WindowsだのMacだのLinuxだのでエラーは起きない。 Vagrant使うときはGNU系の何かが使う処理をホスト側に置いたまま処理しない方が無用な問題を避けられるなーと感じた。
弊社はLaravel + Vagrantで開発環境を作るので、この辺の知見は仕事にも活かしたい。
私、k8sの環境を会社のPC内に作りたかっただけなのに、これだけで3日分の昼休みを浪費した。。つらい。