AWS AMI 二三事

AWS AMI 全称是 Amazon Machine Image, 就是启动 EC2 节点时指定的操作系统的镜像, 可以简单理解为 AWS 上的 Ghost 镜像(什么是 Ghost? 嗯, 少年你知道什么是 XP 么). 打个比方, AWS AMI 就是重量级的 Docker: 你可以按照 Docker 的方式使用 AMI, 只不过 AMI 不能跑在你本机和 Kubernetes 上. 总结几个关于 AWS AMI 的事儿.

为什么要 Build 自己的 AMI

AWS 官方提供了很多现成的 AMI, 就跟 Docker Registry 提供了很多 Base Image 一样, 为了一些定制的需求(比如跨墙安装一些依赖), 提前 Build 好 AMI 可以提升很多效率, 当然, 你也可以像使用 Docker 一样, 每次发布时将自己的代码打包到一个最新的 AMI 中直接部署

如何 Build 一个自己的 AMI

鼠标流

最简单的方式是在 AWS Console 上面点击鼠标, 这个可以查看 AWS 官方的文档, 但是如果你是个鼠标流, 你用 AWS 干啥呢?

AWS cli/API

还有一个办法就是使用 AWS Cli 中的 aws ec2 create-image 命令或者 boto 中相关的 API, 这种方法在"鄙视链"中更上了一层楼, 但跟鼠标流一样, 这个仅仅能满足的场景是你已经在一个 running 的 EC2 instance 上 setup 好了所有的东西的场景, 就好比你使用 docker commit 的方式 Build 了一个 docker image. 平时玩玩儿可以, 但对于一个成熟的技术团队来说, 需要打造一个标准化的 CI/CD Pipeline 来 Build AMI 才行.

Hashicorp 公司出品的 packer

这时候就不得不提到 Hashicorp 出品的 packer. packer 核心是如下几个组件:

  • Builder: 就是实际启动虚拟机并执行你的业务逻辑的一层. 支持 AWS, GoogleCloud Aliyun VirtualBox 等很多种方式
  • Provisioner: 初始化的脚本. 可以是 shell, 也可以是 ansible/chef 等其他工具
  • Post-Processors: build 完成后的钩子任务, 例如可以使用 VirtualBox builder build 任务, 然后再 Post-Processors 中将 VirtualBox 的虚拟机镜像 Export 成 OVF 在使用 Amazon Import 功能直接导入到 AWS

例如下面这个 packer 官方的例子:

{
    "variables": {
        "aws_access_key": "{{env `AWS_ACCESS_KEY_ID`}}",
        "aws_secret_key": "{{env `AWS_SECRET_ACCESS_KEY`}}",
        "region":         "us-east-1"
    },
    "builders": [
        {
            "access_key": "{{user `aws_access_key`}}",
            "ami_name": "packer-linux-aws-demo-{{timestamp}}",
            "instance_type": "t2.micro",
            "region": "us-east-1",
            "secret_key": "{{user `aws_secret_key`}}",
            "source_ami_filter": {
              "filters": {
              "virtualization-type": "hvm",
              "name": "ubuntu/images/*ubuntu-xenial-16.04-amd64-server-*",
              "root-device-type": "ebs"
              },
              "owners": ["099720109477"],
              "most_recent": true
            },
            "ssh_username": "ubuntu",
            "type": "amazon-ebs"
        }
    ],
    "provisioners": [
        {
            "type": "file",
            "source": "./welcome.txt",
            "destination": "/home/ubuntu/"
        },
        {
            "type": "shell",
            "inline":[
                "ls -al /home/ubuntu",
                "cat /home/ubuntu/welcome.txt"
            ]
        },
        {
            "type": "shell",
            "script": "./example.sh"
        }
    ]
}

"正规军"方式 build AMI

回到我们 Build AMI 的问题上来, 作为一个"专业"的技术团队, 那么方案就变成:

  • 一律使用 packer 构建 AMI
  • 通过 gitlab 进行 code review
  • CI 过程中可以使用 packer validate 方法检验 packer 构建文件语法
# .gitlab-ci.yml 示例
# 使用 `packer validate` 验证文件语法

image:
  hashicorp/packer:latest

stages:
  - config_check

packer-config-check:
  tags:
    - docker
  stage: config_check
  retry: 2

  script:
   - packer validate java-ami.json

We can be Better

即便使用了 packer, 依旧有几个问题没有解决:

  • 开发过程中如何测试 AMI
  • 多个环境如何共享 AMI

开发过程如何测试 AMI

开发过程中一定是要测试 AMI 是否符合需求的, 如果简单的使用 AWS builder 来构建 AMI, 那么流程就变成了:

  1. 开发 packer 配置, build 一个新的 AMI
  2. 使用新的 AMI 启动一个 instance, 上去查看该版本的 AMI 是否符合需求
    • 如何符合需求, 就提交代码进行 code review, 并不要忘记 terminate 刚刚的测试 instance
    • 如果不符合需求, 跳到第一步继续修改 packer 文件

能否在本地测试 AMI, 省的 AMI 开发人员需要各种 AWS 账号的权限?

还真有, 一种方法是使用 VirtualBox 的 Builder 在开发过程中构建 Image, 如果符合需求再提交代码, 将 Builder 修改成 AWS, 或者依旧使用 VirtualBox 的 builder, 但 post-processor 使用 Amazon-import 将 OVF 导入到 AWS

多个环境如何共享 AMI

通常情况下, 我们都是使用多个环境(开发测试和生产环境), 为了隔离性也会分别使用不同的 AWS Account, 如何确保构建的 AMI 能够在多个环境/AWS Account 中使用? 其实也简单, 使用 ami_users 指定需要共享的 AWS Account ID.

AMI 使用注意事项

AMI 就是用来在 AWS 上启动虚拟机 EC2 的, 无论是自己手动启动还是使用 Autoscaling Group 启动. 需要注意的是在使用 Autoscaling Group 时, 如果 Autoscaling Group 的 Launch Configuration 中指定的 AMI 被你误删了, Autoscaling Group 启动 EC2 instance 会失败, 这个问题根源其实是 AWS 在做 AMI 删除时没有检查 AMI 是否正在被其他服务依赖. 避免的办法也不难:

  1. 添加 Autoscaling Group 的告警, 在启动 instance 失败时尽快告知开发人员
  2. 构建 AMI 时使用 tags 标记好 AMI, 避免在别人不知道的情况下误删
  3. 自动化清理过期的 AMI, 并添加上述依赖检查的逻辑, 避免误删

总结

构建 AMI 也不是什么高科技, 但这种简单的事情往往能看出一个技术团队的"工艺水平". 当然, Hashicorp 这种公司就更上了一层楼: 不爽的东西写一个工具让你爽, 而且还做了多平台支持, 方便大家随时跑路换云服务商(当然, 跑路也不是那么容易的事情).

-- EOF --

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,198评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,663评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,985评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,673评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,994评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,399评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,717评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,407评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,112评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,371评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,891评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,255评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,881评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,010评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,764评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,412评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,299评论 2 260

推荐阅读更多精彩内容

  • 情感性攻击、猎食性攻击、防御性攻击 神经生物学因素 脑结构:下丘脑 杏仁核 前额皮层 生物化学方面: 动物方面的...
    桦子语阅读 1,070评论 0 1
  • 文/小菩提 躺在松软的床 感受着毛细孔 用力呼吸着的四月天 有种奇妙 不可言喻 忽如端坐校园石凳 等一忘却但又流连...
    小菩提X阅读 143评论 0 2
  • 17年广东移动面试 作为一个应届毕业生,秋招的时候就开始找工作,很多时候面试经验得益于网络上师兄师姐们分享的经验,...
    晕啊yun阅读 6,383评论 3 2
  • 情谊这玩意,放心里自己暖着也就够了。
    老驴三儿阅读 195评论 3 1