Alicloud Image Builder是阿里云推出的一款镜像构建工具,旨在通过简易的方式自动化构建镜像。利用Alicloud Image Builder构建出的操作系统镜像,再结合ACK集群节点池的自定义镜像功能,可以快速地扩容节点。本文介绍如何在ACK集群中利用Alicloud Image Builder通过Job的方式构建自定义操作系统镜像。
前提条件
已创建ACK集群。具体操作,请参见创建ACK托管集群。
已通过kubectl工具连接集群。具体操作,请参见获取集群KubeConfig并通过kubectl工具连接集群。
为什么需要弹性优化的自定义镜像
ACK集群的节点池支持ACK集群节点的弹性伸缩,默认创建节点池时,提供的操作系统镜像包括Alibaba Cloud Linux、CentOS等操作系统镜像,已经能够满足绝大多数场景的使用。但是在一些预安装或者高性能场景下,原有的基础镜像并不能满足我们的需求。阿里云提供的Alicloud Image Builder,可以帮助您构建属于自己的自定义操作系统镜像,从而提高复杂场景下弹性伸缩的便捷性。
使用Alicloud Image Builder创建自定义镜像时,您可以通过Job或CronJob将镜像构建任务下发到集群完成构建。
使用ACK Job快速构建自定义操作系统镜像
本文通过创建名为build-config的配置项和名为build的Job工作负载为例,说明如何使用Alicloud Image Builder快速构建自定义操作系统镜像。
1、配置构建操作系统镜像的参数
您可以创建名为build-config的配置项,以配置构建操作系统镜像的参数。
使用以下YAML内容创建名为build-config.yaml的文件。
上述YAML中涉及参数解释如下。
表 1. Alicloud Image Builder配置文件的参数解释
参数
示例值
描述
variables{"<variable1>":"<value>"}
variables{"access_key":"{{env ALICLOUD_ACCESS_KEY}}"}
定义了Alicloud Image Builder中会用到的变量(
variables
)。说明如果将重要信息,例如AccessKey(包括
access_key
和secret_key
)写入配置文件的话,存在信息泄露的风险,但是将其设置成变量后可防止意外,变量的值来源于运行时的输入值。builders{"type":"<value>"}
builders{"type":"alicloud-ecs"}
镜像生成器(
builders
)。当设置type为aliyun-ecs时,表示构建镜像时,会临时创建一个ECS实例来完成镜像构建。构建完成后,ECS实例会自动销毁。provisioners{"type":"<value>"}
provisioners{"type":"shell"}
镜像配置器(
provisioners
),用以定义需要在临时实例内执行的操作。当设置type为shell时,说明使用的是Shell Provisioner,表示在连接Linux实例后自动执行一段Shell命令。例如,执行Shell命令yum install redis.x86_64 -y
安装Redis。关于Provisioner配置的更多信息,请参见下文的Provisioner配置介绍。
表 2. 镜像构建涉及的参数解释
参数
示例值
描述
是否必填
access_key
LTAInPyXXXXQ****
您的AccessKey ID。更多详情,请参见获取AccessKey。
必填
secret_key
CM1ycKrrCekQ0dhXXXXXXXXXl7y****
您的AccessKey Secret。
必填
region
cn-beijing
目标自定义镜像的所属地域。
必填
image_name
ack-custom_image
目标自定义镜像的名称。不允许与已有镜像重名。
必填
source_image
aliyun_2_1903_x64_20G_alibase_20200904.vhd
具有相同操作系统的阿里云公共镜像ID。详细信息,请参见容器服务Kubernetes版支持的操作系统镜像。
必填
instance_type
ecs.c6.xlarge
以source_image为镜像生成实例运行指定的预安装任务然后生成自定义镜像。如需要GPU类型镜像此处需要填写GPU类型的实例。
必填
RUNTIME
containerd
容器运行时,Docker或者containerd。
必填
RUNTIME_VERSION
1.6.28
容器运行时为Docker时,默认RUNTIME_VERSION为19.03.15。
容器运行时为containerd时,默认RUNTIME_VERSION为1.6.20。
选填
SKIP_SECURITY_FIX
true
跳过安全更新。
必填
KUBE_VERSION
1.30.1-aliyun.1
集群版本号。
必填
PRESET_GPU
true
预置安装GPU,加速启动。
选填
NVIDIA_DRIVER_VERSION
460.91.03
预置GPU版本,不填默认为460.91.03。
选填
OS_ARCH
amd64
CPU架构,amd64或者arm64。
必填
MOUNT_RUNTIME_DATADISK
true
自定义镜像缓存了业务镜像后,如需在使用过程中为ECS实例挂数据盘,则配置为true。
选填
重要为节点池配置自定义镜像前,请确认节点池的相关配置(集群版本、容器运行时、GPU版本适配机型)与构建自定义镜像时的相关配置一致,否则会导致节点无法加入集群。
自定义镜像验证阶段使用和所选参数匹配的普通节点池验证即可,成功加入节点池后在业务上验证是否正常。
执行以下命令部署Alicloud Image Builder到集群。
kubectl apply -f build-config.yaml
2、创建Job以完成自定义操作系统镜像的构建
使用以下YAML内容为AK、SK授予相关权限。
使用以下命令生成AK、SK加密字符串。
echo -n "AKxxxxxxxxxxxxxxx" | base64 echo -n "SKxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" | base64
使用以下YAML内容创建my-secret。
apiVersion: v1 kind: Secret metadata: name: my-secret namespace: default type: Opaque data: ALICLOUD_ACCESS_KEY: TFRxxxxxxxxxxxxxRTkx // 上一步经过base64加密后的字符串 ALICLOUD_SECRET_KEY: a0zxxxxxxxxxxxxxx2UThl
使用以下YAML内容创建名为build.yaml的文件。
根据需求配置变量运行Job,过程中会用的source_image在AK、SK所在账号下生成instance_type类型的ECS,然后运行provisioners的配置,运行完成后会将ECS生成镜像推送到AK、SK所在账号下指定REGION的自定义镜像。
执行以下命令部署Job到集群开始构建操作系统镜像。
kubectl apply -f build.yaml
3、(可选)查看自定义镜像构建日志
构建镜像时会产生操作日志。日志给出了构建过程中执行的每一个步骤,包括校验参数、创建临时资源、预安装软件、创建目标资源和释放临时资源等。您可以执行以下步骤查看镜像构建日志。
登录容器服务管理控制台,在左侧导航栏选择集群。
在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择 。
在任务列表中,找到上步创建的任务(Job),并单击其右侧操作列下的详情。
在目标任务详情页,单击日志页签,然后查看镜像构建日志。
Provisioner配置介绍
Provisioner是在转换为静态操作系统镜像之前,在正在运行的机器中用于安装和配置软件的组件。常用来被执行安装软件到镜像中的主要工作场景包括:
安装软件包。
修补内核。
创建用户。
下载应用程序代码。
制作Alibaba Cloud Linux 3自定义镜像。
执行Shell脚本
"provisioners": [{
"type": "shell",
"script": "script.sh"
}]
使用Ansible执行编排脚本
"provisioners": [
{
"type": "ansible",
"playbook_file": "./playbook.yml"
}
]
安装CPFS客户端
由于CPFS需要安装的包较多,且一部分安装包涉及现场编译流程,安装过程比较费时。在客户端节点数量较大时,使用自定义镜像可以极大减少批量安装CPFS客户端节点的成本。示例配置如下。
定制Arm架构镜像
定制GPU节点系统镜像,加速启动
自定义GPU镜像和自定义CPU镜像暂不支持混用。
将业务镜像缓存到系统镜像中
挂载了数据盘的ECS实例在加入节点池的过程中会经历磁盘初始化,预先缓存的业务镜像会被清理。如果您使用自定义镜像生成ECS时有挂载数据盘的需求,可以选择在制作自定义镜像的过程中生成数据盘快照,确保业务镜像不会被清理。
{
"variables": {
"image_name": "ack-custom_image",
"source_image": "aliyun_3_x64_20G_alibase_20240528.vhd",
"instance_type": "ecs.c6.xlarge",
"access_key": "{{env `ALICLOUD_ACCESS_KEY`}}",
"region": "{{env `ALICLOUD_REGION`}}",
"secret_key": "{{env `ALICLOUD_SECRET_KEY`}}"
},
"builders": [
{
"type": "alicloud-ecs",
"system_disk_mapping": {
"disk_size": 120,
"disk_category": "cloud_essd"
},
"image_disk_mappings": {
"disk_size": 40,
"disk_category": "cloud_auto"
}, # 制作自定义镜像时配置数据盘,镜像制作完成后将自动生成数据盘的快照。
"access_key": "{{user `access_key`}}",
"secret_key": "{{user `secret_key`}}",
"region": "{{user `region`}}",
"image_name": "{{user `image_name`}}",
"source_image": "{{user `source_image`}}",
"instance_type": "{{user `instance_type`}}",
"ssh_username": "root",
"skip_image_validation": "true",
"io_optimized": "true"
}
],
"provisioners": [
{
"type": "file",
"source": "scripts/ack-optimized-os-linux3-all.sh",
"destination": "/root/"
},
{
"type": "shell",
"inline": [
"export RUNTIME=containerd",
"export SKIP_SECURITY_FIX=true",
"export KUBE_VERSION=1.30.1-aliyun.1",
"export OS_ARCH=amd64",
"export MOUNT_RUNTIME_DATADISK=true", # 将容器运行时的文件路径挂载到数据盘
"bash /root/ack-optimized-os-linux3-all.sh",
"ctr -n k8s.io i pull registry-cn-hangzhou-vpc.ack.aliyuncs.com/acs/pause:3.9", # 将业务镜像固化到系统镜像中。
"mv /var/lib/containerd /var/lib/container/containerd" # 将镜像文件移动到数据盘
]
}
]
}
配置节点池时,您可以配置包含数据盘快照的自定义镜像,系统会自动关联对应的数据盘快照。
Runtime为Docker时拉取私有仓库镜像
docker login <镜像地址> -u user -p password
docker pull nginx
Runtime为containerd时拉取私有仓库镜像
ctr -n k8s.io i pull --user=username:password nginx
自定义镜像构建拉取私有仓库镜像
在已安装完成Docker的Linux机器上,执行如下
docker login
命令,生成证书。docker login --username=zhongwei.***@aliyun-test.com --password xxxxxxxxxx registry.cn-beijing.aliyuncs.com
docker login
成功后,会在/root/.docker
下生成证书config.json。将生成的config.json文件制作成ConfigMap。
apiVersion: v1 kind: ConfigMap metadata: name: docker-config data: config.json: |- { "auths": { "registry.cn-beijing.aliyuncs.com": { "auth": "xxxxxxxxxxxxxx" } }, "HttpHeaders": { "User-Agent": "Docker-Client/19.03.15 (linux)" } }
修改Job的YAML,将Configmap挂载到Pod中。
修改build-config,增加图中所示内容。
执行Job。
设置镜像上传、下载并发数
登录容器服务管理控制台,在左侧导航栏单击集群。
在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择
。单击目标节点池名称,然后单击基本信息页签,在节点池信息区域,单击弹性伸缩 ESS 伸缩组 的链接。
单击实例配置来源页签,然后在操作列单击目标伸缩配置右侧的修改,单击确定。
在修改伸缩配置页面,修改相关配置项并展开高级设置,记录实例自定义数据区域的内容。使用Base64编码方式解密实例自定义数据框中的数据。
解密完成后,将以下代码加入解密后代码的后面。
yum install -y jq echo "$jq '. += {"max-concurrent-downloads": 20,"max-concurrent-uploads": 20}' /etc/docker/daemon.json" > /etc/docker/daemon.json service docker restart
使用Base64编码方式加密合成的代码,用加密后的代码替换原来实例自定义数据框中的代码,单击修改,然后单击确认修改。
制作Alibaba Cloud Linux 3自定义镜像
制作Red Hat Enterprise Linux 9自定义镜像
相关操作
使用Alicloud Image Builder创建好自定义镜像后,您就可以使用自定义的镜像创建弹性伸缩节点池以实现快速扩容节点。关于如何创建弹性节点池,请参见启用节点自动伸缩。
创建好自定义镜像后,您可以使用自定义镜像创建集群,请参见如何基于创建好的ECS实例创建自定义镜像,并使用该镜像创建节点?。