Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >vagrant学习笔记 - provision

vagrant学习笔记 - provision

作者头像
pollyduan
发布于 2019-11-04 05:43:47
发布于 2019-11-04 05:43:47
1.4K00
代码可运行
举报
运行总次数:0
代码可运行

从字面上来看,provision是准备,实现的功能是在原生镜像的基础上,进行一些附加的操作,以改变虚拟机的环境,比如安装应用,发布程序等。

1 helloword

在vagrant的 Vagrant.configure(2) do |config| 节点内,加入如下代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  config.vm.provision "shell", inline: "echo hello provisio."

还有一种格式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  config.vm.provision "shell" do |s|
    s.inline = "echo hello provision."
  end

测试一下:

如果vm已经启动,直接运行

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
vagrant provision

就可以看到控制台显示的信息了。或者:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
vagrant reload --provision

重启vm,并自动执行provision操作。

Tips: 运行后可能会提示:default: stdin: is not a tty 错误,不影响执行效果,想要去除,在配置文件增加一行即可。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
config.ssh.shell = "bash -c 'BASH_ENV=/etc/profile exec bash'"

什么是provision任务

provision任务是预先设置的一些操作指令,格式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
config.vm.provision 命令字 json格式参数
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
config.vm.provion 命令字 do |s|
    s.参数名 = 参数值
end

每一个 config.vm.provision 命令字 代码段,我们称之为一个provisioner。

根据任务操作的对象,provisioner可以分为:

  • Shell
  • File
  • Ansible
  • CFEngine
  • Chef
  • Docker
  • Puppet
  • Salt

根据vagrantfile的层次,分为:

  • configure级:它定义在 Vagrant.configure("2") 的下一层次,形如: config.vm.provision ...
  • vm级:它定义在 config.vm.define "web" do |web| 的下一层次,web.vm.provision ...

执行的顺序是先执行configure级任务,再执行vm级任务,即便configure级任务在vm定义的下面才定义。例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Vagrant.configure("2") do |config|
  config.vm.provision "shell", inline: "echo foo"

  config.vm.define "web" do |web|
    web.vm.provision "shell", inline: "echo bar"
  end

  config.vm.provision "shell", inline: "echo baz"
end

输出结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
==> default: "foo"
==> default: "baz"
==> default: "bar"

2 如何执行provision任务

尝试了helloword,我们来了解一下provision任务是怎么运行的。

  • 启动时自动执行,缺省地,任务只执行一次,第二次启动就不会自动运行了。如果需要每次都自动运行,需要为provision指定run:"always"属性
  • 启动时运行,在启动命令加 --provision 参数,适用于 vagrant upvagrant reload
  • vm启动状态时,执行 vagrant provision 命令。

在编写provision任务时,可能同时存在几种类型的任务,但执行时可能只执行一种,如,我只执行shell类型的任务。可以如下操作:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
vagrant provision --provision-with shell

3 shell

3.1 基本使用

3.1.1 数据类型

类型名

范例

string

"arg1"

hash

{key1:value1,key2:value2}

array

["arg1","arg2"]

boolean

true,false

3.1.2 参数:

必选:inline 或者 path

可选:

参数名

类型

说明

args

string or array

传递给shell或path的参数

env

hash

传递给脚本的环境变量

binary

boolean

是否替换windows的行结束符,这个参数名有点奇怪

privileged

boolean

是否提权运行,如sudo执行,缺省为true

upload_path

boolean

上传到vm中的路径,缺省是/tmp/vagrant-shell

keep_color

boolean

设置是否脚本自身控制颜色,缺省为false,表示使用绿色和红色来显示输出到stdout和stderr的消息

name

string

给当前执行的脚本命名,与provisioner名称无关

powershell_args

string

windows相关,略

powershell_elevated_interactive

boolean

windows相关,略

在有些情况下,vagrant会帮你处理引号,但建议,都匹配好双引号,可读性也好一些。

3.1.3 使用规则
3.1.3.1 单行脚本

helloword只是一个开始,对于inline模式,命令只能在写在一行中。一个以上的命令,可以写在同一行,用分号分隔,这属于shell编程的范畴,在这里不多解释。

单行脚本使用的基本格式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
config.vm.provision "shell", inline: "echo foo"

shell命令的参数还可以写入do ... end代码块中,如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
config.vm.provision "shell" do |s|
  s.inline = "echo hello provision."
end

其他,如后面提到的path参数也是一样的。

一个shell代码段,在1.7.0+版本,这个provisioner是可以命名的,如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
config.vm.provision "myshell,type:"shell" do |s|
  s.inline = "echo hello provision."
end

Tips: provisioner命名块如果重名,会有覆盖问题。

一个shell节点内,如果连续写一条以上s.inline,则只有最后一条有效,前面的会被后面的覆盖掉。

3.1.3.2 内联脚本

如果要执行脚本较多,可以在Vagrantfile中指定内联脚本,在Vagrant.configure节点外面,写入命名内联脚本:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$script = <<SCRIPT
echo I am provisioning...
echo hello provision.
SCRIPT

然后,inline调用如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  config.vm.provision "shell", inline: $script
3.1.3.3 外部脚本

也可以把代码写入代码文件,并保存在一个shell里,进行调用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  config.vm.provision "shell", path: "script.sh"

script.sh的内容:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
echo hello provision.

效果是一样的。

Tips:path可以使用http/https来访问远程脚本,这个在部署时访问一个脚本仓库来做一些通用的操作,比较方便。如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  config.vm.provision "shell", path: "https://example.com/provisioner.sh"

Tips: 脚本文件在host机器上,而脚本实际上是在vm里运行的,做个测试验证一下,在Vagrant.configure节点外面,写入命名内联脚本:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$script = <<SCRIPT
echo I am provisioning...
date > /etc/vagrant_provisioned_at
SCRIPT

检查结果, /etc/vagrant_provisioned_at 这个文件不在host主机里,而是在vm虚机里。

3.2 脚本参数

如果要执行的脚本需要参数,那么使用args属性进行传递:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  config.vm.provision "shell" do |s|
    s.inline = "echo $1"
    s.args   = "'hello, world!'"
  end

Tips: 这两args有两层引号,如果去掉一层,字符串中的逗号会让shell以为是两个参数,那么后面的world会被丢掉。 你也可以使用方括号作为外层分隔符,而内层分隔符使用单引号或双引号都可以,只要前后匹配即可,如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
s.args   = ["hello, world!"]

Tips: 多个参数,你可以把args理解为一个json 数组,只要在inline里用 $x 进行引用即可。

2.3 环境变量

为命令行指定环境变量,env的格式为hash,是一个hash对象的列表,多个环境变量,多次配置env。 如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  config.vm.provision "shell" do |s|
    s.inline = "echo $1 $JAVA_HOME"
    s.env = {JAVA_HOME:"/opt/java"}
    s.args   = ["java_home is "]
  end

执行结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
==> default: java_home is /opt/java

多个环境变量的例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  config.vm.provision "shell" do |s|
    s.inline = "echo $1 $JAVA_HOME $2 $PATH"
    s.env = {JAVA_HOME:"/opt/java",PATH:"$JAVA_HOME/bin:$PATH"}
    s.args   = ["java_home is ",";PATH ="]
  end

执行结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
==> default: java_home is /opt/java ;PATH = /opt/java/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

Tips: 环境变量可以引用已经存在的环境变量,如 PATH:"/opt/java/bin:$PATH",结果是在原有的PATH环境变量前面增加了一个路径。

Tips: env新增的环境变量,是顺序执行赋值操作的,实例中JAVA_HOME,系统中原来是没有的,如果JAVA_HOME和PATH这两个参数顺序换一下,把JAVA_HOME放在后面,PATH在拼接JAVA_HOME的时候取到的是系统原来的值,这里是null。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  config.vm.provision "shell" do |s|
    s.inline = "echo $1 $JAVA_HOME $2 $PATH"
    s.env = {PATH:"$JAVA_HOME/bin:$PATH",JAVA_HOME:"/opt/java"}
    s.args   = ["java_home is ",";PATH ="]
  end

结果是: ==> default: java_home is /opt/java ;PATH = /bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

这里出错了,本来应该是/opt/java/bin,结果变成了/bin

同样,如果在系统的/etc/profile中加入:export JAVA_HOME=/usr/local/jdk

那么上面例子的执行结果将是:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
==> default: java_home is /usr/local/jdk ;PATH = /usr/local/jdk/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

Tips: provision里设置的环境变量,只对provision自身操作有效,vagrant ssh 登录vm,里边的变量值是不会变的。

4 文件操作

file 操作有两个参数:

  • source : 源文件或文件夹
  • destination : 目标文件或文件
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  config.vm.provision "file", source: "./Vagrantfile", destination: "Vagrantfile"

将host主机的 "./Vagrantfile" 上传到 vm虚拟机的目标文件 "./Vagrantfile" 。

Tips: 文件是通过scp上传到vm的,使用的是缺省用户,可使用vagrant ssh-config 查看缺省用户的名称,一般为vagrant。所以,目的路径需要让默认用户拥有写权限。

5 扩展操作

vagrant可以集成其他服务器运维工具,来增强服务器管理能力。在使用这些技术之前,需要系统地学习这些技术。而每一套系统都有很多内容学习。本文只简单介绍,不做详细展开。

5.1 集群管理,自动化配置等系统

ansible,cfengine,Chef,puppet 每一套系统都可以写本书了,所以这里不详细说明。

简单来说 Ansible 是一个极简化的应用和系统部署工具,类似 Puppet、Chef、SaltStack。由于默认使用 ssh 管理服务器(集群),配置文件采用 yaml 而不是某一种特定语言制定。 cfengine是一个Linux的自动化配置系统。 Chef 是一套Linux的配置管理系统。

5.2 Docker 面向容器的虚拟解决方案

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上。docker不会虚拟guest os系统,几乎没有性能开销,最重要的是,他们不依赖于任何语言、框架包括系统。

Docker自身提供了很多优秀的工具和客户端,目前vagant支持的操作并不方便,建议直接使用docker的客户端工具学习和使用docker。

###5.3 Salt

Salt 是一个强大的远程执行管理器,用于快速和高效的服务器管理。

更多,请参考:https://www.vagrantup.com/docs/provisioning/

Final

vagrant对于一个开发人员来说,搭建测试开发环境很方便,而且官网也说了——是为了搭建测试环境。所以一些复杂的操作,像本章的provision,了解一下就好,生产环境无法使用,至少现阶段没必要花太多力气把运维工具跟vagrant整合。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Vagrant入门
Vagrant是一个基于Ruby的工具,用于创建和部署虚拟化开发环境。它 使用Oracle的开源VirtualBox虚拟化系统,使用 Chef创建自动化虚拟环境。
用户2131907
2019/02/27
9210
Vagrant快速入门教程
之前学习Docker的时候,发现了Vagrant,感觉这也是一个挺方便的技术,但是我下载安装完Vagrant的时候,发现恰好VirtualBox发了新版本,Vagrant还没兼容,所以这篇文章一直拖到了现在。昨天正好Vagrant更新了版本,修复了这个问题,所以不说了,我们直接开始吧。
乐百川
2020/02/18
1.3K0
Vagrant快速入门教程
k8s 系列教程-Vagrant
vagrant是开源的虚拟机技术,相对于 vmware 而言更轻量级,操作更简便移植性更强,如果我们需要学习k8s或者搭建一些集群的话建议使用 Virtualbox+Vagrant。Vagrant 是创建虚拟机的工具,Virtualbox 是vagrant 管理工具,而且这两个软件是开源的,不需要我去付费或者破解。掌握 Vagrant技术对我们后续学习k8s会有很大的帮助
六个核弹
2022/12/23
8160
Vagrant 中高效的 Puppet 模块管理
到现在我还记得首次尝试使用vagrant和puppet这两个工具来准备本地开发环境时候的场景。找出适当的方式来捆绑puppet模块与项目后一切都是很容易做到。基本上它可以通过三步阶段来实现。
星哥玩云
2022/07/01
3710
Vagrant 基本使用操作
Vagrant 是一款支持自动化虚拟机暗转、可配置流程的用于管理虚拟机的软件. 主要的优势在于可以提供一个可配置、可移植和复用的虚拟机环境 (通过定义 Vagrantfile , 类似 Dockerfile ), 并且可以使用 shell、chef、puppet 等工具进行部署. 这里要注意, Vagrant 并不能单独使用, 必须要在自己的电脑里安装额外的虚拟机软件, 比如常见的虚拟机软件有: VirtualBox、VMWare 等.
全栈程序员站长
2022/11/17
7830
Vagrant 基本使用操作
使用vagrant搭建验证环境
这周的工作需要在一个独立的kubernetes环境调试功能,自然而然地想到在本机装个虚拟机搭建这个环境。不过有同事推荐我试一下vagrant,久闻Vagrant大名,之前也经常在一些开源项目中看到它,今天花了些时间了解下这个新东西。
jeremyxu
2019/05/06
9020
Vagrant使用技巧
在使用Vagrant过程中,难免会出现一些不稳定的因素而造成一些使用上的bug,因此,Vagrant提供了Debug日志的方式用于调试,可以方便的查找错误的原因,以便快速解决问题。
用户2131907
2019/02/27
1.1K0
Vagrant入门
简单地说,Vagrant让我们可以通过代码的方式快速地、可重复地创建针对不同虚拟环境的虚拟机,包括Virtualbox、AWS、Docker等。它使得我们可以一次性地、自动创建多个环境相同的虚拟机,对于软件开发和测试尤其有用。本文我们将以Virtualbox为例,看看Vagrant的基本使用。
全栈程序员站长
2021/11/10
4720
vagrant provision 典型应用场景
将如下配置添加到Vagrantfile的"config.vm.synced_folder" 下面即可。
pollyduan
2019/11/04
4340
☀️手把手教你Camel 环境搭建☀️《❤️记得收藏❤️》
Vagrant是一款用来构建虚拟开发环境的工具,它底层支持 VirtualBox、VMware 甚至 AWS 作为虚拟机系统,提供易于配置,重复性好,便携式的工作环境。也可以和 puppet,chef 结合,实现虚拟机管理的自动化。
苏州程序大白
2021/08/18
2.6K0
☀️手把手教你Camel 环境搭建☀️《❤️记得收藏❤️》
手把手教你打造 SDN 网路 (二) (安装准备)
在安装完 Vagrant 和 Virtualbox 就可以开始进行,如果用的是 Windows 建议可以下载 Cmder 这个 Console Emulator 来下指令,使用的是 ubuntu 16.04 我们将会先製做出一个 VM 在这个 VM 裡面安装 OVS 和 Docker
腾讯云TStack
2019/05/16
8650
手把手教你打造 SDN 网路 (二) (安装准备)
Vagrant搭建集群环境
平时大家可能需要在多机集群中做一些部署测试,下面介绍如何通过vagrant配置一个测试用的集群环境 1. 安装vagrant和virtualbox 自行解决 2. 安装box文件 根据需要下载centos或者ubuntu的vbox镜像,并添加到系统中,例如: vagrant box add alpha xxx.box vagrant box add centos centos.box vagrant box add xxx.box 3. 创建目录并初始化vagrant vagrant init <!-- m
高木工
2019/05/06
1.1K0
关于vagrant一个虚拟机搭建多个项目配置(总结)
问题1:执行vagrant status命令,报错,没有找到命令,翻译;“vargrant bash命令没有找到。”
全栈程序员站长
2022/07/08
2600
关于vagrant一个虚拟机搭建多个项目配置(总结)
vagrant + virtualbox搭建一个可移动的开发环境
vagrant+virtualbox 的出现,成功的解决了搭建开发环境耗时且不一致的问题
崔哥
2022/05/25
3580
Windows 10 使用 Hyper-V 和 Vagrant 创建虚拟机环境
以前我都是用 Vagrant + VirtualBox 快速创建虚拟机环境。通过 Vagrant 配置文件,我们可以快速初始化多个关联的虚拟机,并省去了设置网络和存储的时间。还可以将 Vagrant 项目直接转给别人,让别人快速搭建类似的环境。用了 Kubernetes Desktop 后,需要开启 Windows 的 Hyper-V,这样就无法使用 VirtualBox 了。所以,为了同时使用 Kubernetes 和虚拟化,使用 Hyper-V 代替 VirtualBox会是一个自然的选择。不过目前 Vagrant 还不支持 Hyper-V 网络初始化,所以要有需要自定义的步骤。
云云众生s
2024/03/27
6050
『中级篇』docker之虚拟机创建vagrant技巧(番外篇)(81)
PS:这个很类似docker的镜像,需要什么找什么镜像,这个是找对应的虚拟机,我选择的virtualbox,等于别人在特定的系统版本下预装了你需要的软件。对于学习开发很好用。
IT架构圈
2018/12/10
3640
使用Vagrant在你的电脑上构建独立的虚拟开发环境
Techeek
2018/01/08
1.2K0
『中级篇』docker网络(23)
PS:本机基本上docker的多虚拟机网络已经完成了,比较简单,毕竟是演示环境,可能有老铁说,为啥设置成了自动获得IP,而不是静态IP,毕竟是学习的环境,我也尝试改成过静态IP但是ping不通,其实我的思路就是先让计算机帮我设置一个自动获取的IP,我可以在他的基础上设置自己的静态ip,这样保证可以用,对于静态IP如何设置我也写一份静态IP的配置吧,跟上边差距不太大。 还有老铁说 我不太习惯用vagrant 我喜欢用docker-machine,这个都无所谓了,其实重点是吧环境搭建起来。
IT架构圈
2018/08/01
3230
『中级篇』docker网络(23)
『中级篇』docker网络(23)
PS:本机基本上docker的多虚拟机网络已经完成了,比较简单,毕竟是演示环境,可能有老铁说,为啥设置成了自动获得IP,而不是静态IP,毕竟是学习的环境,我也尝试改成过静态IP但是ping不通,其实我的思路就是先让计算机帮我设置一个自动获取的IP,我可以在他的基础上设置自己的静态ip,这样保证可以用,对于静态IP如何设置我也写一份静态IP的配置吧,跟上边差距不太大。
IT架构圈
2018/06/28
3520
『中级篇』docker网络(23)
ansible自动化运维工具环境准备
我们使用 Vagrant+ VirtualBox 创建虚拟机 这里对于Vagrant以及VirtualBox的安装使用就不再过多介绍,有需要小伙伴请移步到以下文章参考了解学习。 vagrantfile创建多个Host Mac上下载安装Vagrant、配置打包属于自己的开发环境(使用Homestead后续也会更新出来) kong接入网关的准备工作部分 (Vagrant和VirtualBox 版本兼容问题在这篇有提及到) 目录介绍 ansible-code[1-4]为宿主机与虚拟机之间的共享目录 ├─ans
友儿
2022/09/13
4420
相关推荐
Vagrant入门
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验