当前位置: 首页 > 虚拟化 > GitOps—通过CI/CD自动化构建虚拟机模版

GitOps—通过CI/CD自动化构建虚拟机模版

虚拟化 3条评论 2020-10-11 3,168 views

概述:

从2月份开始的[模版自动化系列],已通过一系列的文章熟悉多种虚拟机模版的自动化构建,但在企业实际环境中模版的数量会远远超过这些,此时单一通过shell进行管理和更新,依然非常复杂和繁琐的(虽然相比以前已经又了很大的提高)。现在把自己基于GitOps的方式来管理模版分享出来,进一步提高模版的构建和管理效率,本篇文章将介绍如何通过GitLab CI/CD对模版进行自动化管理。

对于模版保存还存在一个重要的难题需要解决,那就是当云平台或其他自动调用的时候,并不是通过模版名称进行识别,那仅仅通过名称更新模版,就会导致其他系统无法正确识别新模版。vCenter 6.5开始支持模版更新,此特性正解决了我们遇到的问题,并且Packer也是在8月底的版本支持此特性(OVF模版)。使用vCenter内容库还有一个好处,内容库支持订阅,在企业内部如果包含多个vCenter环境的情况下,只需构建一次即可。

通过之前的文章大家对模版构建已经很熟悉了,为了提高移动设备的阅读体验,本手册不再介绍详细的模版配置,您可以通过访问https://github.com/6547709/gitops-packer直接查看代码和配置。

基于GitOps自动化构建vSphere模版特性:

  1. 使用Gitlab存储模版配置文件;
  2. 基于Gitlab CI/CD实现自动化模版构建;
  3. 基于Git提交记录进行语义版本管理(feet、fix),版本号自增,并存储到模版的Notes中;
  4. 定时执行CI/CD任务实现模版变异;
  5. 采用vCenter内容库存储模版,并以-latest为后缀;
  6. 每次构建自动更新vCenter内容库模版,保持ID不变,以保证vRA云平台或其他工具调用最新模版;
  7. 所有密码和配置,通过.gitlab-ci.yml进行定义;
  8. 提供Windows2016/2019、Ubuntu1804/1910/2004、CentOS7/8等多种模版;
  9. 所有模版进行基础优化(可参考对应模版的自动应答文件)
  10. Windows模版使用ISO镜像已集成最新补丁,缩短了部署时间。

相关工具:

Packer是一个开源的自动化虚拟机模版构建工具,支持私有云和公有云,几乎涵盖所有的环境。

vSphere是VMware企业级虚拟化软件,被企业客户广泛使用,具备稳定性高、性能好、安全性高和易使用的特点。

govc是一个基于govmomi的cli工具,实现对vSphere的远程管理。

packer-provisioner-windows-updateWindows Update for packer插件。

Gitlab CI/CD是一个CI/CD工具,与代码集成在一起工作。

semantic-delivery-gitlab镜像用于实现语义版本管理。

Harbor是私有Docker镜像仓库,用于存储用于执行Packer、Govc和Genisoimage的Docker镜像。

相关代码中包含了Gitlab CI/CD所需的所有文件。

针对模版的配置请参考历史的文章。 CI/CD可以根据情况选择不同工具,原理都相同。


环境需求

  • Gitlab服务器和Gitlab-Runner服务器,其中Runner运行在Docker模式;
  • 一台Windows/Linux/MacOS电脑,能够连接vCenter Server;
  • Packer程序、Govc程序、Windows Update for Packer程序;
  • 各操作系统安装镜像;
  • VMware Tools、Windows pvscsi驱动;
  • vCenter内容库;
  • Semantic-delivery-gitlab镜像;

步骤概要

  1. 搭建Harbor镜像仓库,用于存储本地镜像;
  2. 搭建Gitlab和Gitlab CI/CD相关环境,使用Docker Runner模式;
  3. 在Gitlab中创建项目,并上传相关代码、修改相关配置;
  4. 执行自动构建测试;
  5. 在Gitlab CI/CD中添加定时任务;
  6. 完成。

构建用于执行Packer命令的DockerIamge

需要先下载packer、govc和windows update for packer三个执行文件,存储到与Dockerfile相同的目录中,Dockerfile如下:

FROM centos:8
LABEL maintainer="Alex Li <guoqiangli@vmware.com>"
ENV PACKER_VERSION=1.6.4
ENV GOVC_VERSION=v0.23.0
ENV GOVC_INSECURE=true
ENV TIME_ZONE Asia/Shanghai
RUN ln -sf /usr/share/zoneinfo/${TIME_ZONE} /etc/localtime
ADD ./govc /usr/bin/
ADD ./packer /usr/bin/
ADD ./packer-provisioner-windows-update /usr/bin
RUN chmod a+x /usr/bin/govc /usr/bin/packer /usr/bin/packer-provisioner-windows-update && yum install -y  genisoimage
WORKDIR /tmp
CMD ["/bin/bash"]

开始构建Docker Image,并上传到私有仓库中:

docker build -t harbor.corp.local/library/gitops-packer:v1.0 .
docker push login harbor.corp.local
docker login -u admin harbor.corp.local
docker push harbor.corp.local/library/gitops-packer:v1.0

上传semantic-devlivery-gitlab镜像到Harbor

docker pull hutson/semantic-delivery-gitlab:9.1.0
docker tag hutson/semantic-delivery-gitlab:9.1.0 harbor.corp.local/library/semantic-delivery-gitlab:9.1.0
docker push harbor.corp.local/library/semantic-delivery-gitlab:9.1.0

在Gitlab中创建Access Token

  1. 使用个人账户登录Gitlab;
  2. 进入到用户设置->访问令牌;
  3. 填写令牌名称、到期日期和选择权限->创建个人访问令牌;
  4. 保存Token备用;

创建项目,并提交所有代码到仓库中

这里不进行详细操作说明,下面是最终仓库内容的截图:

修改.gitlab-ci.yml配置文件

此文件是Gitlab CI/CD的主配置文件,已将常用配置参数在此文件中定义,无需修改packer和操作系统自动应答文件。

提示1:本手册为了易读,所有敏感信息也在此配置文件中声明,强烈建议使用Gitlab项目变量进行定义,避免敏感信息泄漏。 提示2:以下代码示例已经过删减,完成代码请从Github获取。

# 环境变量定义,生产环境不建议在此配置敏感定义(例如:密码)
variables:
  DOCKER_DRIVER: "overlay2"
  GITLAB_TOKEN: "xxxxxxxxxxxxx"
# 定义用于执行packer、govc和genisoimage的Docker镜像,需要提前构建
  PACKER_DOCKER_IMAGE: "harbor.corp.local/library/packer-gitops:v1.0"
# 定义用于创建模板的vCenter相关信息,密码部分推荐在Gitlab的项目变量定义,以提高安全性。
  VC_SERVER: "vcenter.corp.local"
  VC_USERNAME: "Administrator@vsphere.local"
  VC_PASSWORD: "VMware1!"
  VC_DATACENTER: "Labs-DC02"
  VC_CLUSTER: "DC02-Cluster"
  VC_CONTENT_LIBRARY: "DC02-VM-Templates"
  VC_FOLDER: "Templates"
  VC_DATASTORE: "SSD_DATASTORE"
# 定义VM相关配置
  VM_NETWORK: "vlan100"
  VM_CPU: 2
  VM_MEM: 4096
  VM_DISK: 81920
  VM_VIDEO_RAM: 16384
  VM_HW_VERSION: 17
# 定义安装光盘的存储路径,Winodws系统需要根据安装光盘的不同调整自动应答文件。
# -----此处省略部分代码,从github中获取完整代码------ 
  OS_CENTOS8_ISO: "[SSD_DATASTORE 0-ISO/CentOS-8.2.2004-x86_64-dvd1.iso"
  OS_WINDOWS2016_ISO: "[SSD_DATASTORE] 0-ISO/cn_windows_server_2016_vl_x64_dvd.iso"
# 定义CentOS8自动应答光盘的存储路径,每次编译会自动覆盖之前版本。
  OS_CENTOS8_KS_ISO: "[SSD_DATASTORE] 0-ISO/centos8-ks.iso"
  OS_CENTOS8_GUI_KS_ISO: "[SSD_DATASTORE] 0-ISO/centos8-gui-ks.iso"
# 定义VMware Tools安装路径
  OS_WINDOWS_VMTOOLS: "[SSD_DATASTORE] 0-ISO/VMware-tools-windows-11.1.5.iso"
# 定义Windows系统使用pvscsi驱动的路径,此文件只能同时被一个VM挂载,需要为每个Windows系统配置一个文件。
  OS_WIN2016_DRIVER: "[SSD_DATASTORE] 0-ISO/win2016-pvscsi-Windows8.flp"
# 定义GOVC环境变量,用于上传CentOS8自动应答的ISO(ks.cfg)
  GOVC_URL: ${VC_SERVER}
  GOVC_USERNAME: ${VC_USERNAME}
  GOVC_PASSWORD: ${VC_PASSWORD}
# 此配置用于定义Linux root和ops用户、Windows Administrator和ops用户的密码,密码推荐在Gitlab的项目变量定义,以提高安全性。
  LINUX_SSH_PASSWORD: "VMware1!"
  WINDOWS_PASSWORD: "VMware1!"
# 此变量用于定义虚拟机名称,最终会以-latest作为后缀存储到vCenter内容库中。
  CENTOS8_VM_NAME: "CentOS8"
  WIN2016_VM_NAME: "Win2016"

# 定义Windows安装KEY,根据不同的安装版本配置。
  WIN2016_KEY: "XXXXX-XXXXX-XXXXX-XXXXX-XXXX-XXXX"
  WIN2019_KEY: "XXXXX-XXXXX-XXXXX-XXXXX-XXXX-XXXX"
#定义CI/CD的阶段,devliver阶段用于生成版本号,validate阶段用于验证packer配置文件是否正确,build-iso阶段用于CentOS8的ISO制作,并自动上传到共享存储中,,build阶段用于模版构建,list-library阶段用于列出内容库模版。
stages:
  - deliver
  - validate
  - build-iso
  - build
  - list-library

#采用语义版本管理,基于commit消息增加版本号和生成Release文档,此阶段不会进行打包和部署,仅仅是添加版本tag。
deliver:
  image:
    name: harbor.corp.local/library/sematic-delivery-gitlab:9.1.0
    entrypoint: [""]
  stage: deliver
  only:
    - master
  script:
    - semantic-delivery-gitlab --token ${GITLAB_TOKEN}

#此阶段用于验证packer配置文件是否正确。
packer-validate:
  image:
    name: ${PACKER_DOCKER_IMAGE}
  stage: validate
  script:
    - packer validate ./CentOS8/centos-vsphere.json
    - packer validate ./Win2016/win2016-vsphere.json
  only:
    - tags
  dependencies:
    - deliver
#此阶段用于构建CentOS8所需的ISO文件,并上传到vSphere存储中(自动覆盖之前版本)。
#for CentOS8。
CentOS8-ks-iso-build:
  image:
    name: ${PACKER_DOCKER_IMAGE}
  stage: build-iso
  script:
    - cd CentOS8
    - sed -i 's/__PASSWORD__/'"${LINUX_SSH_PASSWORD}"'/g' ./ks.cfg
    - genisoimage -o centos8-ks.iso -V "OEMDRV" ./ks.cfg
    - govc datastore.upload -ds ${VC_DATASTORE} centos8-ks.iso 0-ISO/centos8-ks.iso
  only:
    changes:
      - CentOS8/ks.cfg
# -----此处省略部分代码,从github中获取完整代码------ 
#此阶段用于生成虚拟机模板,模板名基于job中变量定义,最终模板使用-latest最为后缀。
#for CentOS8。
packer-build-CentOS8:
  image:
    name: ${PACKER_DOCKER_IMAGE}
  stage: build
  variables:
    VM_NAME: ${CENTOS8_VM_NAME}
  script: 
    - cd CentOS8
    - packer build --force centos-vsphere.json
  only:
    - tags
  dependencies:
    - packer-validate
# -----此处省略部分代码,从github中获取完整代码------ 
#for Windows Server 2016。
packer-build-Win2016:
  image:
    name: ${PACKER_DOCKER_IMAGE}
  stage: build
  variables:
    VM_NAME: ${WIN2016_VM_NAME}
    OS_WINDOWS_DRIVER: ${OS_WIN2016_DRIVER}
  script: 
    - cd Win2016
    - sed -i 's/__PASSWORD__/'"${WINDOWS_PASSWORD}"'/g' ./Autounattend.xml
    - sed -i 's/__LICENSEKEY__/'"${WIN2016_KEY}"'/g' ./Autounattend.xml
    - packer build --force win2016-vsphere.json
  timeout: 120m
  only:
    - tags
  dependencies:
    - packer-validate
# -----此处省略部分代码,从github中获取完整代码------ 
#list vcenter content library。
list-content-library:
  image:
    name: ${PACKER_DOCKER_IMAGE}
  stage: list-library
  script: 
    - govc library.info -json ${VC_CONTENT_LIBRARY}/*
  only:
    - tags

标准git commit消息格式

标准且规范的commit消息不仅可以保证版本历史的可读性,还可以了解每次变更的内容和影响范围,并会自动在Release页面生成文档,所以,强烈建议采用标准的commit消息格式和内容。

规范说明示例版本号变化
fix:当修复代码问题时,使用此标记。fix: 修复Windows模版ISO文件错误。1.0.0->1.0.1
feat:当新增功能或模版时,使用此标记feat: 增加Photon模版。1.0.0->1.1.0
[skip ci]当不希望自动执行CI/CD时,使用此标记。fix: 更新ReadME。[skip ci]无变化

验证执行过程和结果

当提交变更后,Gilab CI/CD会基于.gitlab-ci.yml中的配置自动执行流水线,整个过程分为2组5个步骤:

  1. 执行语义版本管理,为代码增加tag标记;
  2. 执行packer配置文件验证、CentOS8自动应答ISO构建、镜像构建和列出内容库内容;

流水线执行过程如下图所示,共花费25分钟时间,完成8个模版的自动化构建:

登录vCenter内容库查看模版更新:

添加定时任务

在Gitlab CI/CD的计划中,添加一个每周/月的定时执行计划,添加完成后入下图所示。

[可选]Windows镜像集成最新补丁

在模版构建过程中,Windows的构建时间最长,某些情况下长达2个小时,可能会触发Gitlab CI/CD的超时和Packer的超时,通过分析执行过程,更新补丁时间最长,为提高模版构建效率和降低出错率,建议自行封装带有最新补丁的模版,下面是大致的制作过程。

  1. 下载DISM++工具(国人制作,图形化操作);
  2. 解压缩系统安装光盘到目录中(d:\win2016-iso),并提取\sources\install.wim文件,拷贝到另一目录中(d:\win2016-iso);
  3. 打开DISM++工具,载入install.wim文件,挂载路径需提前创建(d:\win2016-iso\mnt);
  4. 选中载入的install.wim系统,打开会话;
  5. 使用系统安装光盘安装系统,并执行系统更新,更新完成后在已安装系统更新中(添加/删除程序)找到安装的补丁版本号;
  6. 登录到https://www.catalog.update.microsoft.com/网站,基于版本好下载补丁的msu格式文件,保存到目录中(d:\win2016-iso\msu);
  7. 在DISM++工具页面,控制面板->更新管理->添加(d:\win2016-iso\msu),并执行安装,等待安装完成(时间较长);
  8. 补丁安装完成后,DISM++->文件->另存为映像(d:\win2016-iso\new.wim)存储新的映像;
  9. 使用new.wim替换系统安装盘解压缩目录的install.wim(名称必须是install.wim);
  10. DISM++->常用工具->工具箱->ISO生成器,源选择替换install.wim文件的系统安装盘加压缩目录,目标选择d:\win2016-iso\目录,并指定新光盘名称和添加标签;
  11. DISM++->文件->卸载映像;
  12. 包含指定补丁的系统安装光盘制作完成;
  13. 上传新的ISO到共享存储中,并修改.gitlab-ci.yml文件使用新的ISO镜像路径。

提示:通过DISM工具还可以讲pvscsi的驱动添加到安装光盘中,这样就无需额外添加pvscsi驱动。

完成

至此通过Gitlab CI/CD、Govc和Packer实现了vSphere环境下的模版GitOps,以后只要修改了相关配置文件,就会自动执行模版构建,由于此构建是并发执行的,效率非常高,祝大家可以轻松工作和快乐生活。


3 条评论 “GitOps—通过CI/CD自动化构建虚拟机模版”

  1. Tim说道:

    赞。博主是否可以出一篇Jenkins版的?

    1. liguoqiang说道:

      整个过程都是标准的Shell,所以你可以直接转移到Jenkins上,没有太大的难度。

      1. Tim说道:

        了解。感谢博主。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注