背景
公司现在用到的公有云有腾讯云
、金山云
、阿里云
、华为云
,最近想把作业平台的agent内置进镜像里面,发现运维同事还是在手动操作,因为以前学习terraform
的时候,了解过packer
,觉得这些工作可以用packer
来做自动化打包,通过了解现在的镜像制作过程如下
这只是一个镜像的制作过程,现在的镜像制作是,根据不同的用户,创建多个镜像,比如给数据库管理用的,里面要有一个dba
用户,给业务运维的要有一个sa
用户,IDC运维要有一个sre
用户
也就是说,假如我要制作 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
的动态流水线功能
将用户信息写到一个配置文件中,用 python
生成多个 job
,然后用 trigger
指令触发
这些作业都是并行执行的,所以时间不会累加
build.pkr.hcl
文件有几个问题点要提一下,为什么 instance_name
, vpc
, subnet
, security_group
都加了一些变量,在测试的时候发现,并行执行多个构建的时候,packer
有的时候会共享一台主机,原因还没查
镜像跨区域复制
有人会问了,腾讯云
不是有 image_copy_regions
吗,怎么还要 BB 一下镜像复制呢?
跨区域复制不是标配,腾讯云
是有,金山云
没有,所以金山云的复制功能,要自己用金山云的SDK
来实现
镜像共享
镜像功能也是,腾讯云虽然有 image_share_accounts
,假如你是在广州
构建的,把镜像复制到上海
和北京
,这个账号共享,只是共享了广州
的镜像给用户,上海
和北京
的没有,所以这个要用腾讯去的SDK自己实现,遍历地区,根据镜像名查找镜像ID,然后调用镜像共享接口,金山云同理
腾讯云
金山云
全自动化执行
上面这个功能都做完后,假如镜像名称在云厂商不存在,第一次执行应该是没有问题的,但是第二次执行,你会发现,流水报错了
==> tencentcloud-cvm.root: Image name centos79-user1 has exists
腾讯云的镜像不允许名称重复,金山云没这个问题
所以为了整个过程的自动化,你可能会想,把镜像名重命名一下就好了,这是个好想法
但是你执行个4
次左右,你又会发现报错了,腾讯云某个地区下,镜像最多只可以是10
个
所以还是删除镜像吧,金山云的也删了,多个同名的镜像,在创建主机的时候,也容易把自己整蒙
镜像删除流程
腾讯云
金山云
构建环境清除
在实际执行过程中,发现腾讯云的安全组有可能会删除失败
==> 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
遇到的一些问题
- 金山云
public_ip_charge_type
不可以用Daily
、TrafficMonthly
会报这个错
Error creating new eip: PackageNotExists: You do not have the approprivate permissions
用 DailyPaidByTransfer
, 别问我为什么,我也不知道
- 金山云
system_disk_type
跟instance_type
有一定的依赖,一开始instance_type
用的是S3.2A
,system_disk_type
是SSD3.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
+ terraform
感觉就像 Docker
+ Kubernetes
packer
像是 Docker
docker build
出来的是 docker
镜像
packer build
出来的是 虚拟机
镜像
terraform
像是 Kubernetes
的deployment
如果我们把JDK
打包到镜像上,是不是就像一个PaaS
了,是不是JAVA
应用的运行环境就有了
如果我们再激进一点,把应用程序代码也打包进去,是不是就是一个SaaS
,镜像即代码,应用启动代码放到开机启动,配合云厂商的弹性伸缩,是不是也能做到像 Kubernetes
一样了,应用的更新,只要重装一个系统就好了
对于一些用不了Kubernetes
的应用,或许 terraform
+ packer
会是一个不错的方案,比如:一些依赖 windows
运行环境应用,或者依赖GPU
的应用