布景

公司现在用到的公有云有腾讯云金山云阿里云华为云,最近想把作业平台的agent内置进镜像里边,发现运维同事仍是在手动操作,由于曾经学习terraform的时分,了解过packer,觉得这些作业可以用packer来做自动化打包,通过了解现在的镜像制作进程如下

用Packer自动构建公有云系统镜像
这仅仅一个镜像的制作进程,现在的镜像制作是,依据不同的用户,创立多个镜像,比方给数据库管理用的,里边要有一个dba用户,给业务运维的要有一个sa用户,IDC运维要有一个sre用户

用Packer自动构建公有云系统镜像

也就是说,假设我要制作 4 个云的镜像,图1的流程最少要履行 12 次, 交互时刻严重不确定

自动打包镜像

source "tencentcloud-cvm" "root" {
  region                      = "ap-guangzhou"
  zone                        = "ap-guangzhou-7"
  source_image_id             = "img-l8og963d"
  secret_id                   = var.TENCENT_AK
  secret_key                  = var.TENCENT_SK
  instance_type               = "S6.MEDIUM2"
  ssh_username                = "root"
  ssh_port                    = 22
  force_poweroff              = true
  associate_public_ip_address = true
  internet_max_bandwidth_out  = 10
  security_group_name         = "sg-${local.USER}-${var.JOB_ID}"
  vpc_name                    = "vpc-${local.USER}-${var.JOB_ID}"
  subnet_name                 = "subnet-${local.USER}-${var.JOB_ID}"
  image_name                  = "centos79-${local.USER}"
  instance_name               = "centos79-${local.USER}-${var.JOB_ID}"
  image_copy_regions          = ["ap-beijing", "ap-shanghai"]
}
build {
  sources = [
    "source.tencentcloud-cvm.root"
  ]
  provisioner "file" {
    source      = "../scripts.tar.gz"
    destination = "/opt/"
  }
  provisioner "shell" {
    script = "../setup.sh"
    env    = {
      "SERVER_USER" : var.SERVER_USER
    }
  }
}

只需履行 packer build . ,大概10分钟左右就可以构建出一个镜像,并仿制到 上海北京

依据用户配置打包多个镜像

上述打包仅仅打包了一个用户,如果要打包多个用户,咱们只需一起运转多个 packer build . 就好了,这里可以用 GitLab动态流水线功用

用Packer自动构建公有云系统镜像

将用户信息写到一个配置文件中,用 python 生成多个 job,然后用 trigger 指令触发

用Packer自动构建公有云系统镜像

这些作业都是并行履行的,所以时刻不会累加

build.pkr.hcl 文件有几个问题点要提一下,为什么 instance_namevpc, subnet, security_group都加了一些变量,在测验的时分发现,并行履行多个构建的时分,packer 有的时分会同享一台主机,原因还没查

镜像跨区域仿制

有人会问了,腾讯云不是有 image_copy_regions 吗,怎样还要 BB 一下镜像仿制呢?

跨区域仿制不是标配,腾讯云是有,金山云没有,所以金山云的仿制功用,要自己用金山云的SDK来完成

用Packer自动构建公有云系统镜像

镜像同享

镜像功用也是,腾讯云虽然有 image_share_accounts ,假设你是在广州构建的,把镜像仿制到上海北京,这个账号同享,仅仅同享了广州的镜像给用户,上海北京的没有,所以这个要用腾讯去的SDK自己完成,遍历区域,依据镜像名查找镜像ID,然后调用镜像同享接口,金山云同理

腾讯云

用Packer自动构建公有云系统镜像

金山云

用Packer自动构建公有云系统镜像

全自动化履行

上面这个功用都做完后,假设镜像称号在云厂商不存在,第一次履行应该是没有问题的,可是第二次履行,你会发现,流水报错了

==> tencentcloud-cvm.root: Image name centos79-user1 has exists

腾讯云的镜像不允许称号重复,金山云没这个问题

所以为了整个进程的自动化,你可能会想,把镜像名重命名一下就好了,这是个好主意

可是你履行个4次左右,你又会发现报错了,腾讯云某个区域下,镜像最多只可以是10

所以仍是删去镜像吧,金山云的也删了,多个同名的镜像,在创立主机的时分,也简单把自己整蒙

镜像删去流程

用Packer自动构建公有云系统镜像

腾讯云

用Packer自动构建公有云系统镜像

金山云

用Packer自动构建公有云系统镜像

构建环境清除

在实际履行进程中,发现腾讯云的安全组有可能会删去失利

==> tencentcloud-cvm.root: Failed to delete securitygroup(sg-jf5bd2ar), please delete it manually: retry count exhausted. Last err: [TencentCloudSDKError] Code=ResourceInUse, Message=The specified resource `sg-jf5bd2ar` is already in use., RequestId=

为了确保构建环境的洁净,最终调用了腾讯云的SDK,删去安全组

$ python3 clear.py
detect security group: sg-packer-gitlab-user1-26063
remove security group: sg-packer-gitlab-user1-26063

遇到的一些问题

  1. 金山云 public_ip_charge_type 不可以用 DailyTrafficMonthly

会报这个错

Error creating new eip: PackageNotExists: You do not have the approprivate permissions

DailyPaidByTransfer, 别问我为什么,我也不知道

  1. 金山云 system_disk_typeinstance_type 有一定的依靠,一开始 instance_type 用的是 S3.2Asystem_disk_typeSSD3.0,老是报
SystemDiskTypeInvalid: An invalid or out-of-range value was supplied for the "SystemDisk.DiskType" parameter.

找了半响不知道原因,后边在网页上创立资源,才发现 S3.2A 不可以选 SSD3.0,把 instance_type 换成 C5.2B 就好了

自动化流程

用Packer自动构建公有云系统镜像

思考

packer + terraform 感觉就像 Docker + Kubernetes

packer 像是 Docker

docker build出来的是 docker镜像

packer build出来的是 虚拟机镜像

terraform 像是 Kubernetesdeployment

如果咱们把JDK打包到镜像上,是不是就像一个PaaS了,是不是JAVA使用的运转环境就有了

如果咱们再激进一点,把使用程序代码也打包进去,是不是就是一个SaaS,镜像即代码,使用启动代码放到开机启动,合作云厂商的弹性伸缩,是不是也能做到像 Kubernetes 一样了,使用的更新,只需重装一个系统就好了

对于一些用不了Kubernetes 的使用,或许 terraform + packer 会是一个不错的方案,比方:一些依靠 windows 运转环境使用,或许依靠GPU的使用