在AWS Marketplace上获取预配置的云服务器镜像(AMI)时,经常会遇到两个痛点:一是部分厂商的镜像定价过高,尤其是某些商业软件的授权费用可能占到实例成本的30%-50%;二是官方发布的原始镜像版本更新滞后,Marketplace上的版本往往比官网落后1-2个版本号。去年我在部署一套开源监控系统时,就发现Marketplace提供的镜像不仅额外收取每小时0.12美元的费用,集成的组件版本还停留在半年前的老旧版本。
更关键的是,当你需要定制化基础镜像时(比如预装特定安全补丁或优化内核参数),直接从官方渠道获取纯净镜像再自行构建,会比使用第三方打包的镜像更可靠。这就像装修房子时,直接采购毛坯房比买精装房更容易实现个性化改造。
以Ubuntu为例,官方提供三种格式的云镜像下载:
bash复制# 示例:下载Ubuntu 22.04 LTS的QCOW2镜像
wget https://cloud-images.ubuntu.com/releases/22.04/release/ubuntu-22.04-server-cloudimg-amd64.img
注意:不同发行版的镜像获取方式差异较大。CentOS Stream镜像需从https://cloud.centos.org获取,而Debian官方镜像则托管在https://cloud.debian.org/images/cloud/
HashiCorp Packer是跨平台镜像构建的神器,通过json配置文件可自动化完成镜像下载、软件安装等操作:
json复制{
"builders": [{
"type": "qemu",
"iso_url": "https://cloud-images.ubuntu.com/releases/22.04/release/ubuntu-22.04-server-cloudimg-amd64.img",
"output_directory": "output"
}],
"provisioners": [{
"type": "shell",
"inline": ["apt update", "apt install -y nginx"]
}]
}
如果你已经在阿里云、Azure等平台有现成镜像,可以通过以下流程迁移:
| 格式 | 适用平台 | 压缩率 | 转换工具 |
|---|---|---|---|
| QCOW2 | KVM/OpenStack | 高 | qemu-img |
| VMDK | VMware | 中 | ovftool |
| VHD/X | Hyper-V/Azure | 低 | StarWind V2V |
| RAW | 通用 | 无 | dd命令 |
将QCOW2转换为AWS支持的RAW格式:
bash复制# 安装qemu-utils工具包
sudo apt install qemu-utils -y
# 转换格式(注意预留足够磁盘空间)
qemu-img convert -f qcow2 -O raw ubuntu-22.04-server-cloudimg-amd64.img ubuntu-22.04.raw
# 检查转换结果
file ubuntu-22.04.raw # 应显示"DOS/MBR boot sector"
许多官方镜像采用动态分区,直接上传会导致EC2无法识别。需要先挂载镜像检查分区表:
bash复制# 安装必要工具
sudo apt install kpartx -y
# 挂载镜像
sudo kpartx -av ubuntu-22.04.raw
# 输出示例:add map loop0p1 (253:0): 0 1048576 linear 7:0 2048
# 检查挂载点
lsblk
# 应看到类似loop0p1的分区
# 卸载镜像(操作完成后)
sudo kpartx -dv ubuntu-22.04.raw
bash复制# 安装AWS CLI
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
# 配置凭证
aws configure
# 依次输入Access Key、Secret Key、默认区域(如us-east-1)
超过5GB的镜像需要采用分段上传:
bash复制# 创建S3存储桶
aws s3 mb s3://my-ami-storage
# 将RAW镜像分片上传
split -b 4G ubuntu-22.04.raw ubuntu-part-
aws s3 cp ubuntu-part-* s3://my-ami-storage/
# 合并分片(在AWS端自动完成)
创建import-role.json文件:
json复制{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": { "Service": "vmie.amazonaws.com" },
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals":{
"sts:Externalid": "vmimport"
}
}
}
]
}
执行导入命令:
bash复制aws ec2 import-image \
--architecture x86_64 \
--description "Ubuntu 22.04 Custom" \
--disk-containers \
"Format=raw,UserBucket={S3Bucket=my-ami-storage,S3Key=ubuntu-22.04.raw}"
官方云镜像通常依赖cloud-init进行初始化,但AWS使用EC2-specific数据源。需要修改配置:
bash复制sudo tee /etc/cloud/cloud.cfg.d/90_aws.cfg <<EOF
datasource_list: [ Ec2, None ]
datasource:
Ec2:
strict_id: false
EOF
# 清理缓存
sudo cloud-init clean
默认镜像的EBS配置可能未优化,建议调整:
bash复制# 查看当前调度器
cat /sys/block/nvme0n1/queue/scheduler
# 应改为none(NVMe)或deadline(普通EBS)
# 永久生效配置
sudo tee /etc/udev/rules.d/99-ebs-optimize.rules <<EOF
ACTION=="add|change", KERNEL=="nvme[0-9]*", ATTR{queue/scheduler}="none"
EOF
可能原因及解决方案:
file命令输出,确保是MBR/GPT分区表bash复制sudo apt install linux-aws -y
检查清单:
bash复制sudo cat /var/log/cloud-init-output.log
AWS控制台显示的存储大小可能与实际分区不符,需要手动扩展:
bash复制# 检查未分配空间
sudo growpart /dev/nvme0n1 1
sudo resize2fs /dev/nvme0n1p1
创建.github/workflows/build-ami.yml:
yaml复制name: Build AMI
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install tools
run: sudo apt-get install qemu-utils awscli -y
- name: Convert image
run: |
wget ${{ secrets.SOURCE_IMAGE_URL }}
qemu-img convert -f qcow2 -O raw input.img output.raw
- name: Upload to S3
run: |
aws s3 cp output.raw s3://${{ secrets.S3_BUCKET }}/
hcl复制resource "aws_ami_from_instance" "custom" {
name = "terraform-custom"
source_instance_id = "i-0123456789abcdef"
}
resource "aws_instance" "app" {
ami = aws_ami_from_instance.custom.id
instance_type = "t3.micro"
}
在实际操作中,我发现原始镜像的cloud-init配置是最容易出问题的环节。特别是在跨云平台迁移时,建议先在本地用KVM测试启动镜像,确认能正常完成初始化后再上传到AWS。另外,对于需要频繁更新的镜像,可以建立一个简单的版本控制系统,用S3对象标签管理不同版本的镜像,避免混乱。