使用ESXi为Vagrant创建CentOS8虚拟映像盒子

环境ESXi6.7 可以用中文翻译为 “ESXi 6.7″。

vm

CentOS8 ベースイメージ用VM
jumpserver Vagrant作業用VM

OS

どちらもCentOS8.2.2004 Minimalインストールです

首先在Vagrant Cloud上,CentOS的镜像都是以128GB的磁盘进行创建的。虽然我想在我的ESXi环境中启动多个虚拟机,但不能使用那么多的磁盘空间(虽然使用Thin Provisioning也是一个选择,但总觉得过度分配有点不舒服)……因此,我决定创建一个更小磁盘大小的box镜像。

操作步骤

在CentOS8.2上安装Vagrant。在使用ESXi上的Vagrant时,需要使用vagrant-vmware-esxi插件。
由于它可以免费使用,对于无法购买vCenter的人来说非常有帮助。
我们将在jumpserver上安装Vagrant。

    1. 以下是有关安装Vagrant的指令:

# dnf install wget -y
# wget https://releases.hashicorp.com/vagrant/2.2.9/vagrant_2.2.9_x86_64.rpm
# dnf install -y https://releases.hashicorp.com/vagrant/2.2.9/vagrant_2.2.9_x86_64.rpm

以下是确认安装成功的示例指令:

[root@jumpserver ~]# vagrant –version
Vagrant 2.2.9
[root@jumpserver ~]#

接下来是安装vagrant-vmware-vsphere的指令:

请参考:How to install

安装ovftool:

https://code.vmware.com/web/tool/4.4.0/ovf
从上述网站下载文件”VMware-ovftool-4.4.0-xxxxxxxx-lin.x86_64.bundle”
将下载的文件复制到jumpserver上

以下是ovftool的安装指令:

# dnf install libnsl -y
# chmod 755 VMware-ovftool-4.4.0-15722219-lin.x86_64.bundle
# ./VMware-ovftool-4.4.0-15722219-lin.x86_64.bundle
# rm VMware-ovftool-4.4.0-15722219-lin.x86_64.bundle

然后是安装插件的指令:

# vagrant plugin install vagrant-vmware-esxi

以下是安装插件的示例指令:

[root@jumpserver ~]# vagrant plugin install vagrant-vmware-esxi
Installing the ‘vagrant-vmware-esxi’ plugin. This can take a few minutes…
Fetching iniparse-1.5.0.gem
Fetching mini_portile2-2.4.0.gem
Fetching nokogiri-1.10.10.gem
Building native extensions. This could take a while…
Vagrant failed to properly resolve required dependencies…

[root@jumpserver ~]#

如果是CentOS 8的简化安装版本可能会缺少一些包。请按照提示检查日志文件,并尝试几次…

最后,需要安装以下包:

# dnf install -y gcc make

然后再次运行以下指令以安装vagrant-vmware-vsphere:

# vagrant plugin install vagrant-vmware-esxi
# vagrant plugin list
# vagrant version

以下是再次安装插件的示例指令:

[root@jumpserver ~]# vagrant plugin install vagrant-vmware-esxi
Installing the ‘vagrant-vmware-esxi’ plugin. This can take a few minutes…
Building native extensions. This could take a while…
Fetching vagrant-vmware-esxi-2.5.0.gem
Installed the plugin ‘vagrant-vmware-esxi (2.5.0)’!
[root@jumpserver ~]#
[root@jumpserver ~]# vagrant plugin list
vagrant-vmware-esxi (2.5.0, global)
[root@jumpserver ~]#
[root@jumpserver ~]# vagrant version
Installed Version: 2.2.9
Latest Version: 2.2.9

You’re running an up-to-date version of Vagrant!
[root@jumpserver ~]#

设置Vagrant box的镜像配置。

    1. 将ESXi6.7安装CentOS8.2 minimal版本。

由于想要将盒子的磁盘大小设置为30GB,所以将虚拟机的磁盘设置为30GB并进行安装。

更新操作系统的软件包。

# dnf update -y

按照Vagrant的默认用户设置创建用户。

参考:Default User Settings

创建vagrant用户。

# adduser vagrant

将密码设置为”vagrant”。

# password vagrant

在vagrant用户的.ssh目录中放置SSH的公钥。

将”这里”的vagrant.pub的内容写入到/home/vagrant/.ssh/authorized_keys中

实际操作
[root@localhost ~]# su vagrant
[vagrant@localhost root]$ cd
[vagrant@localhost ~]$ pwd
/home/vagrant
[vagrant@localhost ~]$
[vagrant@localhost ~]$ mkdir -m 700 /home/vagrant/.ssh
[vagrant@localhost ~]$ cd /home/vagrant/.ssh
[vagrant@localhost ~]$ vi authorized_keys
[vagrant@localhost ~]$ chmod 600 authorized_keys
[vagrant@localhost ~]$ exit

虽然不需要root的密码,但通常需要将其设置为”vagrant”。因为这是我自己的盒子,所以不会改变我在安装操作系统时设置的密码。
参考:Root Password: “vagrant”

使vagrant用户可以无密码使用sudo命令。

参考:Password-less Sudo

# visodo

在最后一行添加以下内容:
vagrant ALL=(ALL) NOPASSWD: ALL

将sshd的UseDNS设置为no,以加速SSH连接。

参考:SSH Tweaks

# vi /etc/ssh/sshd_config

有一行UseDNS no被注释掉了,将开头的#去掉。

删除不必要的缓存等,以减小盒子的大小。

参考:CentOS7的自制整洁的盒子

删除缓存(之前下载的rpm文件、头文件等)。

# sudo dnf clean all

不保存历史记录。

# export HISTSIZE=0

删除历史记录。

# rm -f /home/vagrant/.bash_history
# rm -f /root/.bash_history

删除日志。

# rm -rf /var/log/*
# rm -rf /tmp/*

将0写入虚拟磁盘的剩余空间(缩小盒子的大小)。

# dd if=/dev/zero of=/EMPTY bs=1M
# rm -f /EMPTY

关闭虚拟机。

# shutdown -h now

创建Vagrant box镜像
参考:将ESXi上的VM转换为box文件的方法

    1. 以下是对原文进行的中文翻译:

设置ESXi以启用SSH登录,

登录WebUI,点击”主机”->”管理”->”服务”,右键点击TSM-SSH并选择”启动”。

在Vagrant服务器(跳转服务器)上创建用于创建box的Vagrantfile。

[root@jumpserver ~]# mkdir create-baseos
[root@jumpserver ~]# cd create-baseos/
[root@jumpserver create-baseos]# vagrant init
[root@jumpserver create-baseos]# vi Vagrantfile
[root@jumpserver create-baseos]# vi config.yaml

将Vagrantfile编辑如下:

# -*- mode: ruby -*-
# vi: set ft=ruby :

require ‘yaml’

# 读取配置文件
settings = YAML.load_file(‘config.yaml’)

Vagrant.configure(“2”) do |config|

config.vm.define settings[‘node’][‘hostname’] do |node|
node.vm.hostname = settings[‘node’][‘hostname’]
end

config.vm.provider :vmware_esxi do |esxi|
# 设置源ESXi的信息
esxi.guest_name = settings[‘node’][‘hostname’]
esxi.esxi_hostname = settings[‘esxi’][‘hostname’]
esxi.esxi_username = settings[‘esxi’][‘username’]
esxi.esxi_password = settings[‘esxi’][‘password’]
esxi.esxi_hostport = settings[‘esxi’][‘hostport’]
end
end

创建以下config.yaml配置文件:

esxi:
hostname: “192.168.123.74” # ESXi的IP地址
username: “root” # ESXi的登录用户
password: “prompt:” # 登录密码(”prompt:” 表示在执行vagrant命令时输入ESXi的密码)
hostport: 22 # ESXi的SSH登录端口
node:
hostname: “CentOS8” # 已创建的用于基础镜像的VM的名称

获取VM的虚拟机ID,
通过SSH登录ESXi,并获取设置为box区域镜像的VM的信息。

# vim-cmd vmsvc/getallvms

示例执行:

[root@localhost:~] vim-cmd vmsvc/getallvms
Vmid Name File Guest OS Version Annotation
32 CentOS8 [datastore1] CentOS8/CentOS8.vmx centos8_64Guest vmx-14
[root@localhost:~]

将VM的虚拟机ID写入Vagrant的配置文件中。

写入以下文件:

.vagrant/machines/<ESXi的VM名称>/vmware_esxi/id

示例执行:

[root@jumpserver ~]# cd ~/create-baseos/
[root@jumpserver create-baseos]# mkdir -p .vagrant/machines/CentOS8/vmware_esxi
[root@jumpserver create-baseos]# vi .vagrant/machines/CentOS8/vmware_esxi/id
[root@jumpserver create-baseos]# cat .vagrant/machines/CentOS8/vmware_esxi/id
32
[root@jumpserver create-baseos]#

创建box文件。

如果ESXi的VM设置为挂载ISO文件,请编辑该设置并取消挂载。
→特别要注意已经安装,但忘记修改镜像文件设置的情况。

创建box文件:

在output参数中指定要输出的box文件名称。

# vagrant package –output centos8base

执行示例:

[root@jumpserver create-baseos]# vagrant package –output centos8base

==> CentOS8: — 正在尝试打包
==> CentOS8: — box名称:centos8base.box
VMware ovftool 4.4.0 (build-15722219)
Opening VI source: vi://[email protected]:443/
Opening VMX target: ZZZZ_tmpdir
Writing VMX file: ZZZZ_tmpdir/centos8base/centos8base.vmx
Transfer Completed
Completed successfully
==> CentOS8: 正在压缩centos8base.box
centos8base-disk1.vmdk
centos8base-file1.nvram
centos8base.vmx
metadata.json
==> CentOS8: 清理中。
[root@jumpserver create-baseos]# ls -lh
总用量 1.7G
-rw-r–r–. 1 root root 654 8月 7 22:02 Vagrantfile
-rw-r–r–. 1 root root 1.7G 8月 7 22:16 centos8base.box ←★已创建
-rw-r–r–. 1 root root 369 8月 7 21:52 config.yaml
[root@jumpserver create-baseos]#

将box文件添加到Vagrant。

通过name参数指定要添加的box的名称。

# vagrant box add centos8base.box –name centos8box

执行示例:

[root@jumpserver create-baseos]# vagrant box add centos8base.box –name centos8box

==> box: 未检测到箱文件作为元数据。直接添加…
==> box: 正在添加箱 ‘centos8box’(v0),供提供者使用:
box: 正在从:file:///root/create-baseos/centos8base.box 解压必要文件
==> box: 成功添加提供者“vmware”使用的箱“centos8box”(v0)!
[root@jumpserver create-baseos]# vagrant box list
centos8box (vmware, 0) ←★已添加
[root@jumpserver create-baseos]#

使用已创建的盒子来启动虚拟机(进行操作确认)。

    1. 创建Vagrant文件

 

    1. 创建工作文件夹

[root@jumpserver ~]# mkdir test-baseos/
[root@jumpserver ~]# cd test-baseos
[root@jumpserver test-baseos]#

创建Vagrantfile

[root@jumpserver test-baseos]# vagrant init
已在此目录中放置了 ‘Vagrantfile’ 文件。现在可以准备好运行您的第一个虚拟环境了!请阅读Vagrantfile中的注释以及有关使用Vagrant的文档 [`vagrantup.com`](https://www.vagrantup.com/) 以获取更多信息。
[root@jumpserver test-baseos]# vi Vagrantfile
[root@jumpserver test-baseos]# vi config.yaml
[root@jumpserver test-baseos]#

将Vagrantfile编辑如下

# -*- mode: ruby -*-
# vi: set ft=ruby :

require ‘yaml’

# 加载配置文件
settings = YAML.load_file(‘config.yaml’)

Vagrant.configure(“2”) do |config|

# 禁用共享文件夹
config.vm.synced_folder ‘.’, ‘/vagrant’, disabled: true

config.vm.define settings[‘node’][‘hostname’] do |node|
# 主机名
node.vm.hostname = settings[‘node’][‘hostname’]
# 指定节点的基础操作系统
node.vm.box = settings[‘os’]
end

config.vm.provider :vmware_esxi do |esxi|
# 构建目标ESXi的信息
esxi.esxi_hostname = settings[‘esxi’][‘hostname’]
esxi.esxi_username = settings[‘esxi’][‘username’]
esxi.esxi_password = settings[‘esxi’][‘password’]
esxi.esxi_hostport = settings[‘esxi’][‘hostport’]
esxi.esxi_disk_store = settings[‘esxi’][‘diskstore’]
esxi.guest_guestos = settings[‘os_type’]

# 设置要构建的虚拟机
esxi.guest_name = settings[‘node’][‘hostname’]
esxi.guest_username = settings[‘guest_user’]
esxi.guest_memsize = settings[‘node’][‘memory’]
esxi.guest_numvcpus = settings[‘node’][‘cpus’]
esxi.guest_disk_type = settings[‘node’][‘disk_type’]
end
end

创建config.yaml如下

esxi:
hostname: “192.168.123.74” # ESXi的IP地址
username: “root” # ESXi的登录用户
password: “prompt:” # 登录密码(”prompt:”表示在执行vagrant命令时输入ESXi的密码)
hostport: 22 # ESXi的SSH登录端口
diskstore: “datastore1” # 使用的数据存储名称

os: “centos8box” # 指定要使用的操作系统映像(box)
os_type: “centos8-64Guest” # 操作系统类型

guest_user: “vagrant” # 虚拟机的客户操作系统用户名

node:
hostname: “CentOS8-test” # 要创建的虚拟机的名称
cpus: 2 # CPU核心数
memory: 4096 # 内存(GB)
disk_type: “thin” # 磁盘类型(thin、thick、eagerzeroedthick)

启动虚拟机

# vagrant up

执行示例

[root@jumpserver test-baseos]# vagrant up

正在使用“vmware_esxi”提供程序启动虚拟机 ‘CentOS8-test’…
==> CentOS8-test: 将构建虚拟机。
VMware ovftool 4.4.0 (build-15722219)
==> CentOS8-test: — 警告 : 未设置 esxi_virtual_network[0],使用 VM Network
==> CentOS8-test: — 警告 : GuestOS: 不受支持,使用 box/ovftool 的默认值
==> CentOS8-test: — — ESXi 摘要 —
==> CentOS8-test: — ESXi 主机 : 192.168.123.74
==> CentOS8-test: — 虚拟网络 : [“VM Network”]
==> CentOS8-test: — 磁盘存储 : datastore1
==> CentOS8-test: — 资源池 : /
==> CentOS8-test: — — 客户摘要 —
==> CentOS8-test: — VM 名称 : CentOS8-test
==> CentOS8-test: — Box : centos8box
==> CentOS8-test: — Box 版本 : 0
==> CentOS8-test: — 内存大小 (MB) : 4096
==> CentOS8-test: — CPU核心数 : 2
==> CentOS8-test: — 磁盘类型 : thin
==> CentOS8-test: — 客户操作系统类型: centos8-64
==> CentOS8-test: — — 客户构建 —
正在打开 VMX 源:/root/.vagrant.d/boxes/centos8box/0/vmware/ZZZZ_CentOS8-test.vmx
正在打开 VI 目标:vi://root@192.168.123.74:443/
正在部署至 VI:vi://root@192.168.123.74:443/
传输已完成
成功完成
==> CentOS8-test: — VMID : 34
==> CentOS8-test: — 已启动 VM…
==> CentOS8-test: — 正在等待状态 “running”
==> CentOS8-test: — 已成功,状态现在是 “running”
==> CentOS8-test: 正在设置主机名…
CentOS8-test:
CentOS8-test: 检测到Vagrant的不安全密钥。Vagrant将自动生成新的密钥对以提高安全性。
CentOS8-test:
CentOS8-test: 正在将生成的公钥插入到客户系统中…
CentOS8-test: 如果存在不安全密钥,则从客户系统中删除…
CentOS8-test: 密钥已插入!正在使用新的SSH密钥断开连接并重新连接…
[root@jumpserver test-baseos]#

总结在进行测试和环境搭建时,重复安装操作系统到虚拟机上变得很麻烦,于是我开始尝试自动化处理。
由于无法使用昂贵的vCenter,我决定利用免费的ESXi来解决问题,感谢前辈们的智慧帮助我达到了目标。谢谢大家!
实际上,我原本尝试使用terraform来实现,但在创建自定义镜像的过程中遇到了问题,只完成了一部分。
最终我使用了Vagrant,这是一个有很多实例的工具。以后可能会考虑尝试使用terraform…

请参考以下网址Vagrant-VMware-ESXi插件
创建基础镜像
制作一个干净的CentOS7镜像
将ESXi上的虚拟机转换为box文件的方法

bannerAds