[自動化系列]一、使用Packer自動化構建模版—CentOS7.x

[自動化系列]一、使用Packer自動化構建模版—CentOS7.x


最近在與客戶探討DevOps轉型的相關規劃和設計,當我們統計現有虛擬化管理員工作量的時候,發現大部分時間用在為應用部門準備各種虛擬機,由於每個應用對虛擬機的要求不同(CPU、內存、硬盤、硬盤分區、系統參數配置等),最後管理員不得不每次都全新安裝虛擬機,這就產生了大量重複性工作,無法學習新技術和業務創建。

很多時候管理員會直接通過歷史模版克隆,再進行調整,雖然時間上節約了一些,但是依然存在以下的挑戰:

  1. 虛擬機磁盤分區的調整難,這會導致大量的磁盤資源浪費;
  2. 模版補丁更新不及時,管理員很難做到每週/月更新一次模版,導致模版克隆出來的機器存在大量漏洞;
  3. 模版包含大量無用組件,為適應多種應用的環境,一般模版中會包含大量各應用無關的組件,帶來潛在的風險;
  4. 二次修改帶來的不穩定性,如果在克隆後的模版中再進行修改,穩定性會產生影響;
  5. 在“自動化”的背景下,CI/CD會基於模版進行自動化部署或伸縮,模版的更新不僅僅包含操作系統,還包含應用在內。

基於以上的分析,企業需要具備一個“自動化”的模版管理工具,實現模版自動化構建和聲明式定義,以釋放管理員的重複性工作,同時,也是企業向DevOps轉型的儲備,進而加速企業信息化建設步伐。

本系列一共分為四部分:

[自動化系列]一、使用Packer自動化構建模版—CentOS7.x

「自動化系列」二、使用Packer自動化構建模版—WindowsServer2016

[自動化系列]三、使用Terraform結合Packer批量部署虛擬機

[自動化系列]四、使用GitLab CI/CD實現虛擬機聲明式管理和自動化集成

相關

  • Packer是一個開源的自動化虛擬機模版構建工具,支持私有云和公有云,幾乎涵蓋所有的環境。

http://www.packer.io/

  • vSphere是VMware企業級虛擬化軟件,被企業客戶廣泛使用,具備穩定性高、性能好、安全性高和易使用的特點。

https://www.vmware.com/cn/products/vsphere.html

  • 示例代碼中包含Packer所需的json文件和CentOS7的kickstart文件

https://github.com/6547709/packer-vsphere/tree/master/CentOS7

  • kickstart語法參考中詳細說明了kickstart的語法

https://access.redhat.com/documentation/zh-cn/red_hat_enterprise_linux/7/html/installation_guide/sect-kickstart-syntax

  • VMware虛擬機硬件版本中詳細列出了vSphere對虛擬機硬件版本的支持

https://kb.vmware.com/s/article/2007240

使用時請根據實際環境進行修改

環境需求:

  1. 一臺Windows/Linux/MacOS電腦,能夠連接vCenter Server;
  2. Packer程序:https://packer.io/downloads.html
  3. CentOS 7.x ISO:https://wiki.centos.org/Download

Packer安裝

Packer採用GO語言編寫,安裝非常簡單,只需要將解壓後的packer文件拷貝到系統bin目錄下即可,下面是在Linux下的安裝方式:

<code>

wget

https://releases.hashicorp.com/packer/1.5.4/packer_1.5.4_linux_amd64.zip unzip packer_1.

5

.4_linux_amd64.zip cp packer /usr/loca/bin chmod +x /usr/local/bin/packer packer version/<code>

CentOS 7的Packer模版

我們需要兩個基礎文件,用於使用Packer在vSphere環境中構建CentOS 7.x模版:

  1. centos-vsphere.json文件(Packer模版);
  2. ks.cfg文件(無人值守配置文件)

推薦下載倉庫的文件,避免拷貝粘貼可能造成的字符問題;

https://github.com/6547709/packer-vsphere/tree/master/CentOS7

centos-vsphere.json文件說明

variables段落,用於定義vCenter的相關信息和虛擬機配置,其會在Builders段落引用,注意虛擬機文件夾需要預先創建好。

  1. vm-name:定義虛擬機模版基礎名稱,在build階段會自己增加日期後綴,以方便卻別版本;
  2. vm-version:定義虛擬機使用什麼硬件版本,當前vSphere6.7U3使用15,其他版本請查詢相關工具中心的VMware虛擬機硬件版本;
  3. vm-folder:定義虛擬機模版保存在哪個文件夾中;
  4. vm-cpu-num:定義虛擬機模版配置的CPU數量,通過模版再進行部署時可以修改;
  5. vm-mem-size:定義虛擬機模版配置的內存容量(MB單位),通過模版再進行部署時可以修改;
  6. vm-disk-size:定義虛擬機磁盤容量(MB單位),後續的kickstart會基於此容量進行分區,/boot、swap、/var/log、/分區是固定的配置(通過修改ks.cfg更改),/app-date用於存放應用,會使用所有剩餘空間;
  7. iso_url:指定系統安裝光盤位置,本示例使用vSphere環境構建,所以指定共享存儲的路徑;

提示1:為保證ISO文件有效,可以通過參數(iso_checksum、iso_checksum_type和iso_checksum_url)驗證ISO是否完成;

提示2:變量部分可以獨立為var.json文件,在build時單獨指定;

<code>  

"variables"

: {

"vsphere-server"

:

"vcenter.corp.local"

,

"vsphere-user"

:

"[email protected]"

,

"vsphere-password"

:

"VMware1!"

,

"vsphere-datacenter"

:

"Labs-DC02"

,

"vsphere-cluster"

:

"DC02-Cluster"

,

"vsphere-network"

:

"vlan100"

,

"vsphere-datastore"

:

"SSD_DATASTORE"

,

"vm-name"

:

"CentOS7-T"

,

"vm-version"

:

"15"

,

"vm-folder"

:

"Templates"

,

"vm-cpu-num"

:

"1"

,

"vm-mem-size"

:

"1024"

,

"vm-disk-size"

:

"81920"

,

"iso_url"

:

"[SSD_DATASTORE] 0-ISO/CentOS-7-x86_64-DVD-1908.iso"

,

"magic_reference_date"

:

"2006-01-02 15-04-05+0800"

},/<code>

builders段落,用於真正的構建配置,本示例中將經常需要改變的部分通過variables定義,並在此階段引用。

  1. vm_name:我們採用variables中的名字和日期進行組合,isotime會獲取當前日期;
  2. notes:顯示在虛擬機的備註屬性中,用於查看模版具體的構建時間;
  3. guest_os_type:定義虛擬機客戶機操作系統,可以通VMware官方文檔或者創建虛擬機後查詢.vmx文件獲得正確的客戶機操作系統代碼;
  4. ssh_username:定義provisioners階段連接模版虛擬機的口令,此口令來自ks.cfg中的配置;
  5. disk_controller_type:定義虛擬機的SCSI控制器類型,這裡採用更高性能的VMware準虛擬;
  6. disk_thin_provisioned:定義虛擬機是否使用精簡磁盤;
  7. network_card:網卡類型,這裡選擇了性能最好的vmxnet3;
  8. convert_to_template:定義是否自動轉換成模版,請根據需要選擇,如果虛擬機部署編排工具不支持從模版克隆,就需要配置為false;
  9. floppy_files:定義CentOS無人值守安裝的kickstart文件;
<code>  

"builders"

: [ {

"type"

:

"vsphere-iso"

,

"vcenter_server"

:

"{{user `vsphere-server`}}"

,

"username"

:

"{{user `vsphere-user`}}"

,

"password"

:

"{{user `vsphere-password`}}"

,

"insecure_connection"

:

"true"

,

"datacenter"

:

"{{user `vsphere-datacenter`}}"

,

"cluster"

:

"{{user `vsphere-cluster`}}"

,

"network"

:

"{{user `vsphere-network`}}"

,

"datastore"

:

"{{user `vsphere-datastore`}}"

,

"vm_name"

:

"{{user `vm-name`}}-{{isotime "2006-01-02"}}"

,

"vm_version"

:

"{{user `vm-version`}}"

,

"folder"

:

"{{user `vm-folder`}}"

,

"notes"

:

"Build via Packer in {{ (isotime | (user `magic_reference_date`)) }}"

,

"boot_wait"

:

"10s"

,

"boot_order"

:

"disk,cdrom,floppy"

,

"guest_os_type"

:

"centos7_64Guest"

,

"ssh_username"

:

"root"

,

"ssh_password"

:

"VMware1!"

,

"CPUs"

:

"{{user `vm-cpu-num`}}"

,

"RAM"

:

"{{user `vm-mem-size`}}"

,

"RAM_reserve_all"

:

false

,

"disk_controller_type"

:

"pvscsi"

,

"disk_size"

:

"{{user `vm-disk-size`}}"

,

"disk_thin_provisioned"

:

true

,

"network_card"

:

"vmxnet3"

,

"convert_to_template"

:

true

,

"iso_paths"

: [

"{{user `iso_url`}}"

],

"floppy_files"

: [

"ks.cfg"

],

"boot_command"

: [

""

,

"linux ks=hd:fd0:/ks.cfg"

] } ],/<code>

provissioners段落,用於系統自動化安全完成後的自定義操作,例如:更新系統補丁,清理模版等,本示例中進行了系統更新。

<code>  

"provisioners"

: [ {

"type"

:

"shell"

,

"inline"

: [

"rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7"

,

"yum install deltarpm -y"

,

"yum update -y"

,

"yum clean all"

] } ] }/<code>


ks.cfg文件說明

kickstart文件的介紹很多,這裡不進行詳細介紹,可以參考官方文檔說明,下面僅針對我定製化的內容進行說明;

  1. 第9行rootpw,定義root密碼,—plainetext參數表示不會在部署目標系統中記錄密碼;
  2. 第20行bootloader,更改默認網卡名為eth0,禁用ipv6;
  3. 第26行network,設定虛擬機網絡和主機名,本示例採用dhcp,如果使用靜態IP地址請參考上一行;
  4. 第33行lang,設定語言支持,添加簡體中文;
  5. 第39行timezone,設定亞洲/上海時區;
  6. 第47-63行,定義磁盤分區,按照企業生產規範進行分區,採用xfs文件系統,採用lvm以便後期擴展;
  7. 第145-151行,刪除系統無用用戶,減少風險;
  8. 第158-160行,創建本地用戶ops,用於應用用戶登陸,請根據實際情況定義;
  9. 第166-169行,授權ops用戶sudo權限,請根據實際情況定義;
  10. 第176-197行,更新ntp;
  11. 第202-205行,優化SSH登錄速度;
  12. 第210-229行,優化系統最大打開文件參數;請根據實際情況定義;
  13. 第235-246行,清理模版中的網卡UUID和更改ifcfg-eth0參數;此示例採用DHCP;
  14. 第252-291行,用於靜態IP地址配置和禁用NetworkManager管理DNS;
  15. 第334-403行,更改系統默認yum源為aliyun;請根據企業環境進行修改,一般內網使用yum私服(例如:nexus3);

本示例中的密碼均為VMware1!,請注意自行修改。

<code> 

firewall --disabled
selinux --disabled

 
 
 
rootpw --plaintext VMware1!


 
 
 
 
 
 
 
 
bootloader --location=mbr --append=

"elevator=noop pci=bfsort net.ifnames=0 biosdevname=0 ipv6.disable=1"

network --bootproto=dhcp --device=eth0 --noipv6 --onboot=yes --device=eth0 --hostname=CentOS7Template --activate authconfig --enableshadow --passalgo=sha512 keyboard --vckeymap=us --xlayouts=

'us'

lang en_US.UTF-8 --addsupport=zh_CN.UTF-8 skipx install timezone Asia/Shanghai --ntpservers=3.centos.pool.ntp.org,0.centos.pool.ntp.org eula --agreed services --enabled=NetworkManager,sshd zerombr ignoredisk --only-use=sda clearpart --all --drives=sda part /boot --fstype=xfs --size=512 part pv.01 --grow --size=1 volgroup sys_vg pv.01 logvol / --fstype=xfs --name=root --vgname=sys_vg --size=10240 logvol swap --name=swap --vgname=sys_vg --size=4096 logvol /tmp --fstype=xfs --name=tmp --vgname=sys_vg --size=4096 logvol /usr --fstype=xfs --name=usr --vgname=sys_vg --size=3072 logvol /var --fstype=xfs --name=var --vgname=sys_vg --size=2048 logvol /var/

log

--fstype=xfs --name=var_log --vgname=sys_vg --size=4096 logvol /app-data --fstype=xfs --name=app-data --vgname=sys_vg --size=1 --grow %packages --ignoremissing Require @Base @Base @core biosdevname sed perl less dmidecode bzip2 iproute iputils sysfsutils rsync nano mdadm setserial man-pages.noarch findutils tar net-tools tmpwatch lsof python screen lvm2 curl ypbind yp-tools smartmontools openssh-clients acpid irqbalance

which

bind

-utils ntsysv ntp man open-vm-tools vim lrzsz wget tree screen tcpdump chkconfig gzip %end %post --

log

=/root/ks-post.log (

set

-x /bin/sed -i -e

's/ rhgb//'

-e

's/ quiet//'

/boot/grub2/grub.cfg /bin/sed -i -e

's/ rhgb//'

-e

's/ quiet//'

/etc/grub2.cfg /bin/sed -i -e

's/ rhgb//'

-e

's/ quiet//'

/etc/default/grub plymouth-set-default-theme text /usr/libexec/plymouth/plymouth-update-initrd /usr/sbin/userdel operator /usr/sbin/userdel games /usr/sbin/userdel lp /usr/sbin/userdel sync /usr/sbin/userdel shutdown /usr/sbin/userdel halt /usr/sbin/groupdel games /usr/sbin/useradd ops;

echo

'VMware1!'

| passwd --stdin ops /usr/sbin/usermod -a -G wheel ops /usr/bin/chage -M -1 -E -1 ops /bin/cat

'EOF'

>> /etc/sudoers Defaults:ops !requiretty ops ALL=(ALL) NOPASSWD: ALL EOF /usr/sbin/ntpdate 192.168.10.1 /sbin/hwclock --systohc --utc /bin/cat

'EOF'

> /etc/ntp.conf restrict default ignore restrict 127.0.0.1 driftfile /var/lib/ntp/drift logfile /var/

log

/ntpd broadcastdelay 0.008 server 192.168.10.1 restrict 192.168.10.1 mask 255.255.255.255 nomodify notrap noquery EOF /bin/cat

'EOF'

> /etc/ntp/step-tickers 192.168.10.1 EOF /bin/touch /var/

log

/ntpd /bin/sed -i /etc/ssh/sshd_config \ -e

's/^#UseDNS yes$/UseDNS no/'

\ -e

's/^GSSAPIAuthentication yes$/GSSAPIAuthentication no/'

\ /bin/cat

'EOF'

>> /etc/sysctl.conf fs.file-max = 65536 EOF /bin/cat

'EOF'

>> /etc/security/limits.conf EOF /bin/cat

'EOF'

> /etc/security/limits.d/10-nofile.conf * soft nofile 65535 * hard nofile 65535 EOF /bin/cat

'EOF'

> /etc/security/limits.d/11-stack.conf * soft stack 65535 * hard stack 65535 EOF /bin/sed -i

'/^DNS1*..*$/d'

/etc/sysconfig/network-scripts/ifcfg

-e

* /bin/sed -i

'/^DNS2*..*$/d'

/etc/sysconfig/network-scripts/ifcfg

-e

* /bin/sed -i

'/^GATEWAY*..*$/d'

/etc/sysconfig/network-scripts/ifcfg

-e

* /bin/sed -i

'/^HOSTNAME*..*$/d'

/etc/sysconfig/network-scripts/ifcfg

-e

* /bin/sed -i

'/^HWADDR*..*$/d'

/etc/sysconfig/network-scripts/ifcfg

-e

* /bin/sed -i

'/^NM_CONTROLLED*..*$/d'

/etc/sysconfig/network-scripts/ifcfg

-e

* /bin/sed -i

'/^UUID*..*$/d'

/etc/sysconfig/network-scripts/ifcfg

-e

* /bin/mv /etc/sysconfig/network-scripts/ifcfg

-e

* /etc/sysconfig/network-scripts/ifcfg-eth0 /bin/sed -i

's/ens192/eth0/g'

/etc/sysconfig/network-scripts/ifcfg-eth0 /bin/sed -i

"s\ONBOOT=no\ONBOOT=yes\g"

/etc/sysconfig/network-scripts/ifcfg-eth0 /bin/sed -i

"s\IPV6INIT=yes\IPV6INIT=no\g"

/etc/sysconfig/network-scripts/ifcfg-eth0 touch /root/.dir_colors /bin/cat

'EOF'

>> /root/.i18n LC_COLLATE=C EOF /bin/cat

'EOF'

> /etc/logrotate.conf monthly rotate 12 create compress include /etc/logrotate.d /var/

log

/wtmp { create 0664 root utmp } EOF /bin/rm -f /etc/yum.repos.d/CentOS-* /bin/cat

'EOF'

> /etc/yum.repos.d/CentOS-Base.repo [base] name=CentOS-

$releasever

- Base - mirrors.aliyun.com failovermethod=priority baseurl=http://mirrors.aliyun.com/centos/

$releasever

/os/

$basearch

/ gpgcheck=1 gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7 [updates] name=CentOS-

$releasever

- Updates - mirrors.aliyun.com failovermethod=priority baseurl=http://mirrors.aliyun.com/centos/

$releasever

/updates/

$basearch

/ gpgcheck=1 gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7 [extras] name=CentOS-

$releasever

- Extras - mirrors.aliyun.com failovermethod=priority baseurl=http://mirrors.aliyun.com/centos/

$releasever

/extras/

$basearch

/ gpgcheck=1 gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7 [centosplus] name=CentOS-

$releasever

- Plus - mirrors.aliyun.com failovermethod=priority baseurl=http://mirrors.aliyun.com/centos/

$releasever

/centosplus/

$basearch

/ gpgcheck=1 enabled=0 gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7 [contrib] name=CentOS-

$releasever

- Contrib - mirrors.aliyun.com failovermethod=priority baseurl=http://mirrors.aliyun.com/centos/

$releasever

/contrib/

$basearch

/ gpgcheck=1 enabled=0 gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7 EOF /bin/cat

'EOF'

> /etc/yum.repos.d/epel-7.repo [epel] name=Extra Packages

for

Enterprise Linux 7 -

$basearch

baseurl=http://mirrors.aliyun.com/epel/7/

$basearch

failovermethod=priority enabled=1 gpgcheck=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7 [epel-debuginfo] name=Extra Packages

for

Enterprise Linux 7 -

$basearch

- Debug baseurl=http://mirrors.aliyun.com/epel/7/

$basearch

/debug failovermethod=priority enabled=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7 gpgcheck=0 [epel-source] name=Extra Packages

for

Enterprise Linux 7 -

$basearch

- Source baseurl=http://mirrors.aliyun.com/epel/7/SRPMS failovermethod=priority enabled=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7 gpgcheck=0 EOF /bin/sed -i

"s/UUID*..*\/boot/\/dev\/sda1\t\t\/boot/"

/etc/fstab /bin/rm -rf /var/tmp /bin/ln -s /tmp /var/tmp /usr/bin/systemctl

enable

autofs /usr/bin/systemctl

enable

ntpd /usr/bin/systemctl

disable

firewalld.service /usr/bin/systemctl

disable

auditd /usr/bin/systemctl

disable

mdmonitor /usr/bin/systemctl

disable

postfix /usr/bin/systemctl

disable

abrt-ccpp.service /usr/bin/systemctl

disable

abrt-oops.service /usr/bin/systemctl

disable

abrt-vmcore.service /usr/bin/systemctl

disable

abrt-xorg.service /usr/bin/systemctl

disable

abrtd.service /usr/bin/systemctl

disable

iscsi.service /usr/bin/systemctl

disable

iscsid.socket /usr/bin/systemctl

disable

iscsiuio.socket /usr/bin/systemctl

disable

libstoragemgmt.service /usr/bin/systemctl

disable

multipathd.service /usr/bin/systemctl

disable

wpa_supplicant.service ) 2>&1 %end reboot --eject/<code>


Packer驗證配置

完成配置文件的準備後,我們需要驗證packer的配置文件是否正確,使用一下命令:

<code>

packer

validate

centos-vsphere

.json

/<code>

Packer執行構建

<code>

packer

build

centos-vsphere

.json

/<code>

如果第一次構建成功,並且虛擬機名稱是固定的(本示例是基於日期的)下一次構建時可以增加-force參數覆蓋上一次模版;

<code> 

packer

build

-froce

centos-vsphere

.json

/<code>

構建完成後,命令行如下提示;


令行如下提示;


[自動化系列]一、使用Packer自動化構建模版—CentOS7.x


[自動化系列]一、使用Packer自動化構建模版—CentOS7.x


登陸到vSpehre中可以看到模版:


[自動化系列]一、使用Packer自動化構建模版—CentOS7.x


完成

至此我們通過Packer實現了vSphere環境下虛擬機模版的自動構建,如果希望構建其他環境可以參考官方文檔。下一章我會帶來通過Packer構建Windows Server 2016虛擬機模版。


分享到:


相關文章: