根据我的经验,AWS EC2 实例越小,它冻结/完全锁定的频率就越高。 AWS 基础设施内部出了点问题,噗,无法使用 SSH 或对其执行任何操作。这与系统负载、内存状态、应用程序类型等无关。崩溃的频率与实例大小成反比。
- t3.micro -> 每月 1-8 次(免费层级实例)
- t3.medium -> 每月 1-3 次(在我维护的商业 Django 产品上)
- t2.xlarge -> 如果有的话,可能每年一次(我的另一个客户运行着一个高流量的网站)
一种“解决方案”是登录 AWS 控制台并停止/启动实例。这很痛苦,因为 1) 我有 MFA 设置,2) AWS 控制台很难导航。实例停止也可能需要一些时间(最坏情况需要 15 分钟)或需要强制停止,然后才能重新启动。
所以我决定弄清楚如何使用 AWS CLI 查询服务器状态,并在需要时从命令行停止/启动它。这个过程被锁定到我的 IP,所以即使 IAM 用户凭证泄露,它也必须来自我的机器。我对这种易用性和安全性的平衡感到非常满意。如果您的 EBS 卷已加密(它应该是),则在您继续配置时需要注意一些重要但模糊的事情。
在本指南中,我将向您展示如何使用 AWS cli 从命令行使用具有正确权限的 IAM 用户停止/启动 EC2 实例,包括对加密卷的支持。
1)安装AWS CLI 工具(如果尚未安装)。
2)在 AWS 控制台的 IAM 下,创建一个 IAM 用户,将其命名为类似ec2-stop-start
名称。获取新用户的凭据(访问密钥 ID 和秘密访问密钥)并将它们保存在安全的地方。
如果您的 EBS 卷已加密,请在 EC2 -> EBS 卷配置下找到它使用的密钥。如果这是客户管理的密钥,请在 AWS KMS 控制台下,将新的 IAM 用户添加到密钥用户下的密钥。
3)在 AWS 控制台中,在 IAM 下创建一个允许查询 EC2 状态和停止/启动实例的策略。
此策略将锁定到您的本地 IP!对我来说这很好,因为我的 ISP 每两年更改一次我的 IP。如果我的 wifi 路由器上的 MAC 地址发生变化,IP 也会发生变化(这是强制分配新 IP 的技巧)。
IAM 政策大纲:
{ "版本": "2012-10-17", “陈述”: [ { “希德”:“0”, "效果": "允许", “行动”: [ “ec2:启动实例”, “ec2:停止实例” ], “资源”:“arn:aws:ec2:*:*:实例/*”, “健康)状况”: { “IP地址”: { “aws:SourceIp”:“xyz.0.0.1/32” } } }, { “希德”:“1”, "效果": "允许", “行动”: [ “ec2:描述实例”, “ec2:DescribeInstanceStatus” ], “资源”:“*”, “健康)状况”: { “IP地址”: { “aws:SourceIp”:“xyz.0.0.1/32” } } }, { “锡德”:“2”, "效果": "允许", “行动”: [ “公里数:加密”, “公里:解密”, “公里数:重新加密*”, “公里数:描述键”, “公里:生成数据密钥*”, “公里:获取公钥”, “kms:GetKeyPolicy” ], “资源”:“arn:aws:kms:us-west-2:0000:/xyz”, “健康)状况”: { “字符串等于”:{ “公里数:ViaService”:[ “ec2.us-west-2.amazonaws.com” ] } } } ] }
每个块的摘要:
Sid 0 -> EC2 允许从您的 IP 停止/启动
Sid 1 -> EC2 允许从您的 IP 描述实例
Sid 2 -> 授予用户通过 EC2 访问加密密钥的权限
确保更改以下内容:
- 将
aws:SourceIP
更改为您的公共 IP,它位于两个位置。 - 如果您的 EBS 卷已加密,请将
kms:ViaService
块下的区域更改为您的 EC2 实例实际所在的区域。同时将 `arn:aws:kms:us-west-2:0000:/xyz` 值更改为与 EBS 卷一起使用的实际密钥的 ARN。 - 注意 – 如果您的 EBS 卷未加密,则不需要带有
"SiD": "2"
。此部分使 IAM 用户能够在代表其他服务请求时使用加密密钥(这就是 kms:ViaService 标签的作用)。 - 注意——此策略允许访问帐户下的所有 EC2 实例,但也许这太多了?根据您的情况需要自定义资源块。
4)在 IAM 控制面板中将您刚刚创建的策略与您的 ec2-stop-start 用户相关联。
5)使用名为
aws_ec2_stop_start:
[aws_ec2_stop_start] aws_access_key_id = ****** aws_secret_access_key = ******
6)在 EC2 控制面板中找到您服务器的实例 ID(类似于 i-00000)。
7)尝试查询实例状态:
$ aws ec2 describe-instances --region us-west-2 --profile aws_ec2_stop_start --output 文本 $ aws ec2 describe-instance-status --instance-ids i-00000 --region us-west-2 --profile aws_ec2_stop_start --输出文本
(根据您的情况更改区域和实例 ID 参数,输出可以是文本、表格或 json)
8)尝试使用空运行参数运行 stop start:
$ aws ec2 stop-instances --instance-ids i-00000 --region us-west-2 --profile aws_ec2_stop_start --dry-run $ aws ec2 start-instances --instance-ids i-00000 --region us-west-2 --profile aws_ec2_stop_start --dry-run
(同样,根据您的情况更改区域和实例 ID 参数)
9)实际上,没有 -dry-run 参数:
# 真正停止实例 - 确保您知道自己在做什么!! $ aws ec2 停止实例 --instance-ids i-00000 --region us-west-2 --profile aws_ec2_stop_start # 如果你需要强制它 $ aws ec2 停止实例 --instance-ids i-00000 --region us-west-2 --profile aws_ec2_stop_start --force #此时可以查询状态 $ aws ec2 描述实例 \ --region us-west-2 --output text --profile aws_ec2_stop_start \ --query 'Reservations[*].Instances[*].{Instance:InstanceId,Instance:State}' # 真正开始 $ aws ec2 start-instances --instance-ids i-00000 --region us-west-2 --profile aws_ec2_stop_start --输出文本
故障排除:
如果实例未启动(停留在待定状态),则 describe-instance-status 显示:
“状态原因”:{ "Message": "Client.InternalError: 客户端启动时出错", “代码”:“Client.InternalError” },
这可能是因为 EBS 卷已加密。在这种情况下,请仔细检查上面 IAM 配置文件中的 Sid 2 块,并查看此 AWS 帖子以了解有关修复该问题的详细信息,以及有关密钥的 IAM 策略和kms:ViaService 配置设置的更多信息。上面的注释对我有用,但您可能需要摆弄设置才能使其正常工作。同样,如果您的卷使用客户管理的密钥加密,请在 AWS KMS 控制台下,将您在步骤 2 中创建的 IAM 用户添加到密钥用户下的密钥中。
AWS CLI EC2 命令文档的链接:
AWS CLI 有许多您可能想要熟悉的额外命令行选项。请参阅此处的文档:
如何使用 AWS CLI 命令行停止/启动 AWS EC2 实例一文首次出现在Laurence Gellert 的博客上。