vagrant 做測試環境的一點總結(上)
既然還在幸運的活著,當然要全力以赴的快樂。
“Vagrant uses Oracle’s VirtualBox to build configurable, lightweight, and portable virtual machines dynamically.”
Vagrant 是 Mitchell Hashimoto 用 ruby 寫的,去年11月份,Mitchell 專門成立了一個公司 HashiCorp 來更好的開發 Vagrant, 并且申明,Vagrant會一直開源。Announcing HashiCorp感興趣的還可以看下作者在就HashiCorp成立在Hacker News上發的一個 topic。
vagrant 是什么
Vagrant 提供了基于企業級標準技術的易配置、可重復、可移植的工作環境,從而最大化團隊的生產力和靈活性。
Vagrant 可構建在由 VirtualBox,VMware,AWS 以及其他提供商提供的機器上,并且可以使用 shell 腳本,Chef,Puppet 等配置管理工具。
vagrant 的特點:
- 將配置和依賴隔離在一次性和一致性的環境中
- 使用簡單,只需 Vagrantfile 和 vagrant up,適用人群廣(開發者,運維人員,設計師)
vagrant 其實就是封裝了的 Virtualbox 的 API 的 ruby DSL,抽象和簡化了某些操作,用一個命令以及配置文件,而不是一堆命令去管理和使用 vm。
更多關于 vagrant 的介紹,網上比較多,這里就不在闡述,有興趣的可以讀一下 Go實戰開發 這本書里關于 vagrant 的介紹,已經很詳細了,我就簡單的介紹點常用的即可
基礎
1、基本命令
- # 查看幫助
- $ vagrant list-commands
- -v, --version
- -h, --help
- # 把鏡像加入到 vagrant 中
- $ vagrant box add "centos-6.6-x86_64 py27" vagrantbox/centos-6.6-x86_64.box
- # 查看 vagrant 環境
- $ vagrant box list
- centos-6.6-x86_64 py27 (virtualbox, 0)
- # 初始化一個新的倉庫
- $ cd test_env
- $ vagrant init "centos-6.6-x86_64 py27"
- A `Vagrantfile` has been placed in this directory. You are now
- ready to `vagrant up` your first virtual environment! Please read
- the comments in the Vagrantfile as well as documentation on
- `vagrantup.com` for more information on using Vagrant.
- 會在當前目錄下生成一個 Vagrantfile 這個配置文件
2、下面貼個常見配置,修改 Vagrantfile 文件
- config.vm.box= "centos-6.6-x86_64 py27"
- config.vm.network "forwarded_port", guest: 8000, host: 8000
- config.vm.network "forwarded_port", guest: 3306, host: 9999
- config.vm.synced_folder".", "/vagrant" # 將當前目錄映射到虛擬機上的/vagrant 目錄
- config.vm.hostname = "devops-node1"
- config.vm.provider "virtualbox" do |vb|
- # Display the VirtualBox GUI when booting the machine
- # vb.gui = true
- # Customize the amount of memory on the VM:
- vb.memory = "1024"
- vb.cpus = 1
- end
3、服務管理
- #啟動,重載,關機
- $vagrant up
- $vagrant reload
- 重新讀取配置
- $vagrant halt
- 將虛擬機關閉,虛擬機內存釋放,下次啟動要慢一點。
- $vagrant suspend
- 將虛擬機掛起,虛擬機內存都保存到硬盤上,下次可以快速恢復
- $vagrant destroy
- 將虛擬機刪除,所有變更都丟失,下次啟動要重新克隆一個 Vagrant box。
- $vagrant status
- 查看虛擬機的狀態
更多命令行: https://www.vagrantup.com/docs/cli/index.html
制作模板
當做好基礎的環境后,方便打包發送給其他人和方便以此為模板衍生其他環境,所以需要對這個環境進行打包,形成模板
- $ VBoxManage list vms
- "win10" {f0fa02e2-48ca-439f-bfca-0e4ddb138485}
- "centos6.5-node1" {57e5500f-e91b-469e-86c9-f0b90b2a01a8}
- "env_default_1488966927566_38686" {16817773-c844-4412-af8d-df89bae489ca}
1、打包基礎環境
- $ vagrant package --base env_default_1488966927566_38686 --output centos66-base.box
- /opt/vagrant/embedded/gems/gems/vagrant-1.9.2/lib/vagrant/util/platform.rb:24: warning: Insecure world writable dir /usr/local in PATH, mode 040777
- ==> env_default_1488966927566_38686: Attempting graceful shutdown of VM...
- env_default_1488966927566_38686: Guest communication could not be established! This is usually because
- env_default_1488966927566_38686: SSH is not running, the authentication information was changed,
- env_default_1488966927566_38686: or some other networking issue. Vagrant will force halt, if
- env_default_1488966927566_38686: capable.
- ==> env_default_1488966927566_38686: Forcing shutdown of VM...
- ==> env_default_1488966927566_38686: Clearing any previously set forwarded ports...
- ==> env_default_1488966927566_38686: Exporting VM...
- ==> env_default_1488966927566_38686: Compressing package to: /Users/song/Downloads/vagrant/env/centos66-base.box
2、還原基礎環境
到此打包到封裝好的環境就在當前目錄下生成了,下次用這個模板重新開始初始化新環境就非常容易了
- # 拷貝打包好的鏡像到其他小伙伴的機器,或者共享目錄
- # 在本地導入并重新啟動一個環境
- $ vagrant box add "template_centos66" centos66-base.box
- /opt/vagrant/embedded/gems/gems/vagrant-1.9.2/lib/vagrant/util/platform.rb:24: warning: Insecure world writable dir /usr/local in PATH, mode 040777
- ==> box: Box file was not detected as metadata. Adding it directly...
- ==> box: Adding box 'template_centos66' (v0) for provider:
- box: Unpacking necessary files from: file:///Users/song/Downloads/vagrant/centos66-base.box
- ==> box: Successfully added box 'template_centos66' (v0) for 'virtualbox'!
- $ vagrant box list
- centos-6.6-x86_64 py27 (virtualbox, 0)
- template_centos66 (virtualbox, 0)
- $ mkdir test_env
- $ cd test_env
- $ rm -rf Vagrantfile
- $ vagrant init template_centos66
- A `Vagrantfile` has been placed in this directory. You are now
- ready to `vagrant up` your first virtual environment! Please read
- the comments in the Vagrantfile as well as documentation on
- `vagrantup.com` for more information on using Vagrant.
- $ vagrant up
- /opt/vagrant/embedded/gems/gems/vagrant-1.9.2/lib/vagrant/util/platform.rb:24: warning: Insecure world writable dir /usr/local in PATH, mode 040777
- Bringing machine 'default' up with 'virtualbox' provider...
- ==> default: Importing base box 'template_centos66'...
- ==> default: Matching MAC address for NAT networking...
- ==> default: Setting the name of the VM: test_env_default_1489043027159_6542
- ==> default: Clearing any previously set network interfaces...
- ==> default: Preparing network interfaces based on configuration...
- default: Adapter 1: nat
- ==> default: Forwarding ports...
- default: 22 (guest) => 2222 (host) (adapter 1)
- ==> default: Booting VM...
- ==> default: Waiting for machine to boot. This may take a few minutes...
3、測試完畢,銷毀測試環境
- $ vagrant destroy
- /opt/vagrant/embedded/gems/gems/vagrant-1.9.2/lib/vagrant/util/platform.rb:24: warning: Insecure world writable dir /usr/local in PATH, mode 040777
- default: Are you sure you want to destroy the 'default' VM? [y/N] y
- ==> default: Destroying VM and associated drives...
出現的錯誤
這里出現的錯誤主要在遷移的過程中,如果只是安裝部署中出現錯誤,多數應該是配置文件 Vagrantfile 的語法錯誤,我這里先描述下錯誤出現的背景
– default: Warning: Authentication failure. Retrying…
1、當我打包一個系統鏡像為模板的時候,想根據這個模板生成新的 vagrant 系統,所以有如下操作
- $vagrant package --base env_default_1488966927566_38686 --output centos66-base.box
- $vagrant box add "template_centos66" centos66-base.box
- $mkdir test_env
- $cd test_env
- $vagrant init template_centos66
- 適當修改 Vagrantfile,然后啟動
- $vagrant up
如果一切正常,則會產生一個新的 vagrant 虛擬環境,但這里會報錯
- $ vagrant up
- /opt/vagrant/embedded/gems/gems/vagrant-1.9.2/lib/vagrant/util/platform.rb:24: warning: Insecure world writable dir /usr/local in PATH, mode 040777
- Bringing machine 'default' up with 'virtualbox' provider...
- ==> default: Clearing any previously set forwarded ports...
- ==> default: Fixed port collision for 22 => 2222. Now on port 2200.
- ==> default: Clearing any previously set network interfaces...
- ==> default: Preparing network interfaces based on configuration...
- default: Adapter 1: nat
- ==> default: Forwarding ports...
- default: 22 (guest) => 2200 (host) (adapter 1)
- ==> default: Running 'pre-boot' VM customizations...
- ==> default: Booting VM...
- ==> default: Waiting for machine to boot. This may take a few minutes...
- default: SSH address: 127.0.0.1:2200
- default: SSH username: vagrant
- default: SSH auth method: private key
- default: Warning: Authentication failure. Retrying...
- default: Warning: Connection refused. Retrying...
- default: Warning: Authentication failure. Retrying...
一直卡在這里無法過去,然后根據錯誤 google 找了下,在 vagrant 的 github 的 issue 里找到了有人提出了這個問題,根據里面的回答,我做了如下嘗試
1、升級 vagrant 和 vbox ,確保都是最新版,怕有人提到的因為版本不匹配導致的原因,報錯依舊
2、根據 @kikitux 這個哥們在 5 Mar 2015 的回答
- Adding here my impressions for people that find this issue from google/internet:
- This is my point of view here.
- The source box use the insecure key
- by default the actual version of vagrant will remove it, to make it secure
- the new box, use a generated pair key.. that is not being used anymore
- vagrant can’t connect to the new box.
- You have 3 options here.
- A. Tell vagrant in the middle box to NOT create a new safe/secure pair.
- B. Run an Script before packaging to delete 70-persistent-net.rules
- and put back the insecure pair key
- C. Copy the new now secure pair to /vagrant and include it in the
- package box plus Vagrantifle conf to use it
- I will say, if this is for prototyping, just use A, just remember
- delete 70-persistent-net.rules
- On the first box, add:
- config.ssh.insert_key = false
我在 Vagrantfile 里新增了 config.ssh.insert_key = false 這個配置,發覺無果,報錯依舊
3、issue 上 @mtchavez 的回答得到了多數人的支持,很多人用了他的方法解決了問題
I had found a solution to this and haven’t had time to update this issue. I did something similar to what @dylanschoenmakers described.
The main thing which fixed it for me was adding the vagrant.pub to the authorized_keys with
wget https://raw.githubusercontent.com/mitchellh/vagrant/master/keys/vagrant.pub -O .ssh/authorized_keys
chmod 700 .ssh
chmod 600 .ssh/authorized_keys
chown -R vagrant:vagrant .ssh
Then when building the base box I think you need to add the config.ssh.insert_key = false to your Vagrantfile. If you built a new version of the box you can simply do a vagrant box update otherwise you can do what @dylanschoenmakers already mentioned to remove and re-add the box to get the newest box.
This all makes sense, but I am not clear on if this is something that needs to be documented or if there was indeed a change in Vagrant that used to do this transparently for previous versions which is broken now.
他其實做的方法和 @dylanschoenmakers 類似
- a、首先在 Vagrantfile 中增加了這段
- config.ssh.insert_key = false
- b、其次在連接 vagrant 的 ssh-config 配置
- $ vagrant ssh-config
- /opt/vagrant/embedded/gems/gems/vagrant-1.9.2/lib/vagrant/util/platform.rb:24: warning: Insecure world writable dir /usr/local in PATH, mode 040777
- Host default
- HostName 127.0.0.1
- User vagrant
- Port 2200
- UserKnownHostsFile /dev/null
- StrictHostKeyChecking no
- PasswordAuthentication no
- IdentityFile /Users/song/.vagrant.d/insecure_private_key
- IdentitiesOnly yes
- LogLevel FATAL
- 這里的 IdentityFile 在基于模板創建新的 vagrant 虛機環境的時候 ssh 連接使用的 key,所以 @dylanschoenmakers 用了一個新的內容替換原有的內容
- ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key
- c、再次重新打包環境
而我的解決方案并不和上述一樣,我查看了下 ssh-config 配置
- # 第一個正常連接的 vagrant 環境的配置
- $ vagrant ssh-config
- Host default
- ......
- IdentityFile /Users/song/Downloads/vagrant/env_django/.vagrant/machines/default/virtualbox/private_key
- ......
- # 登錄異常的基于模板產生的 vagrant 環境
- $ vagrant ssh-config
- Host default
- ......
- IdentityFile /Users/song/.vagrant.d/insecure_private_key
- ......
這里只貼出了不同的部分,所以我的想法就是把這個連接秘鑰用正常環境的那個秘鑰是否可以解決,所以在問題環境的 Vagrantfile 里增加如下配置
config.ssh.private_key_path = “/Users/song/Downloads/vagrant/env_django/.vagrant/machines/default/virtualbox/private_key”
再次啟動虛擬環境,發覺再無報錯,至此問題解決
另外好像還有個解決辦法, 就是不指定用 key 連接,而是直接使用密碼連接,雖然暴力,但是的確提供了一種思路
- config.ssh.username = "vagrant"
- config.ssh.password = "vagrant"
–warning: Insecure world writable dir /usr/local in PATH, mode 040777
曾經為了方便,改過 osx 下這個目錄權限,現在操作 vagrant 都會報這個警告,修改權限如下即可
- $sudo chmod go-w /usr/local/