Windows Server已经EOL(End of Life)的许多版本其实还是有不少应用场景需要用到的, 但是AWS官方的AMI中已经停止了对这些版本的支持, 本文以Windows Server 2008 R2为例, 提供一个在本地创建虚机并导入至EC2进行使用的方法.

本地创建Windows Server 2008 R2虚拟机

这里使用了Microsoft自家的Hyper-V作为本地虚拟化环境, 当然使用VirtualBox/Vmware理论上也是相同的. 具体的安装步骤就不展开介绍了, 主要说明几点:

  1. 虚拟机创建的时候使用单个磁盘, 只用来安装操作系统, 我们的目的是制作AMI, 越简单越好
  2. 安装好系统后一定要检查一下远程桌面服务是否开启, Server2008里面默认是禁用的, 切记一定要保证RDP服务是自动启动的, 否则后面到EC2中以后会连不上, 别问我怎么知道的🤣
  3. 系统安装完成后通过sysprep进行封装, 清理操作使用OOBE, 注意勾选上通用, 关机选项使用关机, 这样封装操作结束后虚拟机会自动关闭
  4. Hyper-V中删除掉当前虚拟机自动创建的检查点, 然后导出至本地磁盘. 导出的数据其实只需要用到Virtual Hard Disks文件夹中的.vhdx文件

上传vhdx文件至S3存储桶

将上面导出的vhdx磁盘文件上传到自己账号下的S3存储桶中, 做这次记录的时候我导出的vhdx文件有7.3G, 上传用时会视网速决定, 耐心等待上传成功后复制一下对象的键备用

创建IAM角色进行授权

选择可信实体

自定义信任策略

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "vmie.amazonaws.com"
            },
            "Action": "sts:AssumeRole",
            "Condition": {
                "StringEquals": {
                    "sts:Externalid": "vmimport"
                }
            }
        }
    ]
}

vm可以导入镜像文件么_vm可以导入镜像文件么

添加权限

需要先创建策略, 切换到JSON编辑模式, 注意将对应位置的ARN修改为自己S3里面的实际路径. 随后在创建角色的向导中刷新一下策略列表, 搜索选中.

vm可以导入镜像文件么_BYOL_02

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetBucketLocation",
                "s3:GetObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws-cn:s3:::lpwm",
                "arn:aws-cn:s3:::lpwm/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetBucketLocation",
                "s3:GetObject",
                "s3:ListBucket",
                "s3:PutObject",
                "s3:GetBucketAcl"
            ],
            "Resource": [
                "arn:aws-cn:s3:::lpwm",
                "arn:aws-cn:s3:::lpwm/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2:ModifySnapshotAttribute",
                "ec2:CopySnapshot",
                "ec2:RegisterImage",
                "ec2:Describe*"
            ],
            "Resource": "*"
        }
    ]
}

命名, 查看和创建

注意: Role 名称必须用 vmimport

安装AWS CLI

这一步参考官方文档即可:
https://docs.aws.amazon.com/zh_cn/cli/latest/userguide/install-cliv2.html

命令导入过程

完整的官方文档:
https://docs.aws.amazon.com/vm-import/latest/userguide/vmimport-image-import.html

首先创建配置S3中vhdx文件位置信息的json文件, 这里lpwm是Bucket桶的名字, S3Key是具体文件存放的相对路径, 注意开头不需要写/, 我是放在名为vm的文件夹中了, 如下例子:

[
  {
    "Description": "Windows Server 2008 R2 BYOL",
    "Format": "vhdx",
    "UserBucket": {
        "S3Bucket": "lpwm",
        "S3Key": "vm/Server08.vhdx"
    }
  }
]

接下来执行import-image命令进行导入, 注意如果不添加--license-type的话会自动根据上传的虚拟机镜像进行识别, 可能会判断有误, 建议对BYOL的手动加上:

aws ec2 import-image --description "Windows Server 2008 R2 BYOL" --disk-containers "file:///home/lpwm/containers.json"  --license-type "BYOL"

注意如果是在Windows中执行, 后面的文件路径中应当用\, 例如file://D:\containers.json

命令执行后会输出json格式的操作结果:

{
    "Description": "Windows Server 2008 R2 BYOL",
    "ImportTaskId": "import-ami-06808337bdc598cd2",
    "LicenseType": "BYOL",
    "Progress": "1",
    "SnapshotDetails": [
        {
            "Description": "Windows Server 2008 R2 BYOL",
            "DiskImageSize": 0.0,
            "Format": "VHDX",
            "UserBucket": {
                "S3Bucket": "lpwm",
                "S3Key": "vm/Server08.vhdx"
            }
        }
    ],
    "Status": "active",
    "StatusMessage": "pending"
}

监控当前导入任务可以复制上面的ImportTaskId后执行下面的命令:

aws ec2 describe-import-image-tasks --import-task-ids import-ami-06808337bdc598cd2

输出json格式的状态信息:

{
    "ImportImageTasks": [
        {
            "Description": "Windows Server 2008 R2 BYOL",
            "ImportTaskId": "import-ami-06808337bdc598cd2",
            "LicenseType": "BYOL",
            "Progress": "19",
            "SnapshotDetails": [
                {
                    "Description": "Windows Server 2008 R2 BYOL",
                    "DiskImageSize": 7788822528.0,
                    "Format": "VHDX",
                    "Status": "active",
                    "UserBucket": {
                        "S3Bucket": "lpwm",
                        "S3Key": "vm/Server08.vhdx"
                    }
                }
            ],
            "Status": "active",
            "StatusMessage": "converting",
            "Tags": []
        }
    ]
}

可以看到Progress, Status , StatusMessage这些主要的进度信息. 其中StatusMessage会经历pending>converting>booting>preparing ami>completed, (中间的阶段可能有没看到的遗漏, 大致就是这么几个阶段)

当然也可以用watch命令来定时刷新监控信息进行跟踪:

watch -n 3 aws ec2 describe-import-image-tasks --import-task-ids import-ami-06808337bdc598cd2

如果想要取消当前导入的任务, 需要执行下面命令:

aws ec2 cancel-import-task --import-task-id import-ami-06808337bdc598cd2

使用AMI启动实例

上一步 import 成功后, 会生成名称为 import-ami-xxxxx 的 AMI 和一个快照, 这个时侯就可以直接使用AMI启动实例了