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 --

你可能感兴趣的:(AWS AMI 二三事)