美文网首页
AWS AMI 二三事

AWS AMI 二三事

作者: haitaoyao | 来源:发表于2018-03-12 23:28 被阅读858次

    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 二三事

          本文链接:https://www.haomeiwen.com/subject/uncafftx.html