AWS Systems Manager (SSM) 使用手册

简介

AWS Systems Manager (SSM) 是一个统一的管理服务,用于管理 AWS 云端以及本地环境中的服务器资源。

主要功能

  • Session Manager: 安全的远程连接,无需 SSH 密钥
  • Run Command: 批量执行命令
  • Patch Manager: 自动化补丁管理
  • Parameter Store: 安全存储配置和密钥
  • State Manager: 维护实例配置状态
  • Inventory: 收集实例元数据

前提条件

1. SSM Agent 安装

注意: 大多数 AWS 官方 AMI 已预装 SSM Agent

检查 Agent 状态:

# Linux
sudo systemctl status amazon-ssm-agent

# 启动 Agent
sudo systemctl start amazon-ssm-agent
sudo systemctl enable amazon-ssm-agent

# Windows (PowerShell)
Get-Service AmazonSSMAgent
Start-Service AmazonSSMAgent

手动安装 SSM Agent:

2. IAM 权限配置

方式一: Default Host Management (推荐)

# 启用自动管理
aws ssm update-service-setting \
  --setting-id arn:aws:ssm:region:account-id:servicesetting/ssm/managed-instance/default-ec2-instance-management-role \
  --setting-value service-role/AWSSystemsManagerDefaultEC2InstanceManagementRole

方式二: IAM 实例配置文件

创建 IAM 角色并附加策略:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

附加托管策略:

  • AmazonSSMManagedInstanceCore
  • CloudWatchAgentServerPolicy (可选)
# 创建角色
aws iam create-role \
  --role-name SSM-EC2-Role \
  --assume-role-policy-document file://trust-policy.json

# 附加策略
aws iam attach-role-policy \
  --role-name SSM-EC2-Role \
  --policy-arn arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore

# 创建实例配置文件
aws iam create-instance-profile --instance-profile-name SSM-EC2-Profile
aws iam add-role-to-instance-profile \
  --instance-profile-name SSM-EC2-Profile \
  --role-name SSM-EC2-Role

# 关联到 EC2 实例
aws ec2 associate-iam-instance-profile \
  --instance-id i-1234567890abcdef0 \
  --iam-instance-profile Name=SSM-EC2-Profile

3. 网络配置

公有子网实例:

  • 无需额外配置,实例可直接通过互联网访问 SSM 服务

私有子网实例 (2选1):

选项 1: NAT 网关 (更简单)

  • 在公有子网创建 NAT 网关
  • 私有子网路由表指向 NAT 网关
  • 实例通过 NAT 访问 SSM 公共端点

选项 2: VPC 端点 (更安全,流量不出 VPC)

需要创建 3 个 VPC 端点(SSM 服务需要):

  • com.amazonaws.region.ssm - 核心 SSM 服务
  • com.amazonaws.region.ssmmessages - Session Manager 消息
  • com.amazonaws.region.ec2messages - Run Command 消息
# 一键创建所有必需端点
for service in ssm ssmmessages ec2messages; do
  aws ec2 create-vpc-endpoint \
    --vpc-id vpc-xxxxx \
    --vpc-endpoint-type Interface \
    --service-name com.amazonaws.region.$service \
    --subnet-ids subnet-xxxxx \
    --security-group-ids sg-xxxxx
done

安全组要求:

  • VPC 端点安全组: 入站允许 HTTPS (443) 来自实例
  • 实例安全组: 出站允许 HTTPS (443) 到 VPC 端点

快速开始

验证实例是否被 SSM 管理

# 列出所有托管实例
aws ssm describe-instance-information

# 查看特定实例
aws ssm describe-instance-information \
  --filters "Key=InstanceIds,Values=i-1234567890abcdef0"

# 检查实例在线状态
aws ssm describe-instance-information \
  --filters "Key=PingStatus,Values=Online"

第一次测试

使用 Run Command 测试 (无需额外插件):

# 简单测试命令
aws ssm send-command \
  --instance-ids "i-1234567890abcdef0" \
  --document-name "AWS-RunShellScript" \
  --parameters 'commands=["echo Hello from SSM","hostname","uptime"]'

# 查看命令输出
aws ssm get-command-invocation \
  --command-id "命令ID" \
  --instance-id "i-1234567890abcdef0"

使用 Session Manager 连接 (需安装插件):

# 安装 Session Manager 插件后使用
aws ssm start-session --target i-1234567890abcdef0

插件安装: https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html


核心功能

1. Session Manager (高级连接)

端口转发 (访问远程服务):

# 本地 8080 -> 远程 80 (访问 Web 服务)
aws ssm start-session \
  --target i-1234567890abcdef0 \
  --document-name AWS-StartPortForwardingSession \
  --parameters '{"portNumber":["80"],"localPortNumber":["8080"]}'

# 访问远程数据库
aws ssm start-session \
  --target i-1234567890abcdef0 \
  --document-name AWS-StartPortForwardingSession \
  --parameters '{"portNumber":["3306"],"localPortNumber":["3306"]}'

SSH over Session Manager (免密钥登录):

编辑 ~/.ssh/config:

host i-* mi-*
    ProxyCommand sh -c "aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"

使用:

ssh ec2-user@i-1234567890abcdef0
scp file.txt ec2-user@i-1234567890abcdef0:/tmp/

2. Run Command (批量执行)

使用标签批量执行:

# 对所有生产环境实例执行
aws ssm send-command \
  --targets "Key=tag:Environment,Values=Production" \
  --document-name "AWS-RunShellScript" \
  --parameters 'commands=["systemctl restart nginx"]'

# 多个标签条件
aws ssm send-command \
  --targets "Key=tag:Environment,Values=Production" "Key=tag:Role,Values=WebServer" \
  --document-name "AWS-RunShellScript" \
  --parameters 'commands=["df -h"]'

查看命令结果:

# 查看命令状态
aws ssm list-command-invocations \
  --command-id "命令ID" \
  --details

# 获取特定实例的输出
aws ssm get-command-invocation \
  --command-id "命令ID" \
  --instance-id "实例ID"

保存输出到 S3:

aws ssm send-command \
  --instance-ids "i-1234567890abcdef0" \
  --document-name "AWS-RunShellScript" \
  --parameters 'commands=["ps aux"]' \
  --output-s3-bucket-name "my-ssm-logs" \
  --output-s3-key-prefix "outputs/"

3. Parameter Store (参数管理)

安全存储配置数据和密钥,支持加密、版本控制和细粒度访问控制

创建参数:

# 普通字符串
aws ssm put-parameter \
  --name "/myapp/db/host" \
  --value "db.example.com" \
  --type "String"

# 加密密钥
aws ssm put-parameter \
  --name "/myapp/db/password" \
  --value "MyPassword123" \
  --type "SecureString"

读取参数:

# 单个参数
aws ssm get-parameter \
  --name "/myapp/db/password" \
  --with-decryption

# 按路径批量获取
aws ssm get-parameters-by-path \
  --path "/myapp/" \
  --recursive \
  --with-decryption

在脚本中使用:

DB_HOST=$(aws ssm get-parameter --name "/myapp/db/host" --query "Parameter.Value" --output text)

4. State Manager (配置管理)

自动维护实例的期望配置状态,定期执行任务确保配置不漂移

定期执行脚本:

# 每周日凌晨 2 点执行清理任务
aws ssm create-association \
  --name "AWS-RunShellScript" \
  --targets "Key=tag:Environment,Values=Production" \
  --parameters 'commands=["find /tmp -mtime +7 -delete"]' \
  --schedule-expression "cron(0 2 ? * SUN *)"

自动安装/更新软件:

# 确保 CloudWatch Agent 始终安装
aws ssm create-association \
  --name "AWS-ConfigureAWSPackage" \
  --targets "Key=instanceids,Values=*" \
  --parameters 'action=Install,name=AmazonCloudWatchAgent'

查看关联状态:

aws ssm list-associations
aws ssm describe-association --association-id "关联ID"

5. Patch Manager (补丁管理)

扫描可用补丁:

aws ssm send-command \
  --targets "Key=tag:Environment,Values=Production" \
  --document-name "AWS-RunPatchBaseline" \
  --parameters 'Operation=Scan'

安装补丁:

aws ssm send-command \
  --targets "Key=tag:Environment,Values=Production" \
  --document-name "AWS-RunPatchBaseline" \
  --parameters 'Operation=Install'

创建维护窗口 (定期打补丁):

# 创建维护窗口
aws ssm create-maintenance-window \
  --name "Production-Patching" \
  --schedule "cron(0 2 ? * SUN *)" \
  --duration 4 \
  --cutoff 1

6. Inventory (清单管理)

配置清单收集:

aws ssm create-association \
  --name "AWS-GatherSoftwareInventory" \
  --targets "Key=instanceids,Values=*" \
  --schedule-expression "rate(30 minutes)" \
  --parameters 'applications=Enabled,awsComponents=Enabled,networkConfig=Enabled'

查询清单数据:

# 查看实例上安装的应用
aws ssm list-inventory-entries \
  --instance-id i-1234567890abcdef0 \
  --type-name "AWS:Application"

# 查看网络配置
aws ssm list-inventory-entries \
  --instance-id i-1234567890abcdef0 \
  --type-name "AWS:NetworkConfig"

最佳实践

1. 安全性

  • ✅ 使用 IAM 策略限制 SSM 权限
  • ✅ 启用 Session Manager 日志记录到 CloudWatch 和 S3
  • ✅ 使用 SecureString 存储敏感参数
  • ✅ 定期轮换 Parameter Store 中的密钥
  • ✅ 使用 VPC 端点避免公网流量

Session Manager 日志配置:

aws ssm update-document \
  --name "SSM-SessionManagerRunShell" \
  --content file://session-preferences.json \
  --document-version '$LATEST'

session-preferences.json:

{
  "schemaVersion": "1.0",
  "description": "Document to hold regional settings for Session Manager",
  "sessionType": "Standard_Stream",
  "inputs": {
    "s3BucketName": "my-session-logs-bucket",
    "s3KeyPrefix": "session-logs/",
    "s3EncryptionEnabled": true,
    "cloudWatchLogGroupName": "/aws/ssm/session-logs",
    "cloudWatchEncryptionEnabled": true
  }
}

审计和监控:

# 查看命令历史
aws ssm list-commands

# 查看会话历史
aws ssm describe-sessions \
  --state History \
  --filters "key=Target,value=i-1234567890abcdef0"

# 查看特定时间段的命令
aws ssm list-commands \
  --filters "key=InvokedAfter,value=2025-12-01T00:00:00Z"

2. 应急恢复方案

当 SSM 无法访问实例时的备用方案:

方案 1: EC2 Serial Console (推荐,适用所有场景)

# 提前启用 Serial Console
aws ec2 enable-serial-console-access --region us-east-1

# 通过控制台连接: EC2 Console -> 实例 -> 操作 -> EC2 Serial Console
# 连接后可重启 SSM Agent: sudo systemctl restart amazon-ssm-agent

方案 2: EC2 Instance Connect

公有子网实例:

# 直接通过公网 IP 连接
aws ec2-instance-connect send-ssh-public-key \
  --instance-id i-1234567890abcdef0 \
  --instance-os-user ec2-user \
  --ssh-public-key file://~/.ssh/id_rsa.pub

ssh ec2-user@<public-ip>

私有子网实例:

# 需要创建 EC2 Instance Connect Endpoint
aws ec2 create-instance-connect-endpoint \
  --subnet-id subnet-xxxxx \
  --security-group-ids sg-xxxxx

# 通过私有 IP 连接
aws ec2-instance-connect ssh \
  --instance-id i-1234567890abcdef0

方案 3: 传统 SSH (需提前配置密钥对)

ssh -i key.pem ec2-user@<public-ip>

方案 4: 救援实例 (最后手段)

# 1. 停止问题实例并分离根卷
# 2. 将根卷附加到救援实例
# 3. 挂载并修复配置
# 4. 重新附加到原实例

预防建议:

  • ✅ 提前启用 EC2 Serial Console
  • ✅ 保留 SSH 密钥对作为备用
  • ✅ 私有子网考虑创建 Instance Connect Endpoint
  • ✅ 配置 CloudWatch 告警监控 SSM Agent 状态

3. 运维效率

  • 创建自定义 SSM 文档用于常见任务
  • 使用 State Manager 自动化配置管理
  • 利用 Inventory 跟踪软件和配置

4. 混合环境

适用于本地数据中心的物理服务器,本地虚拟机 以及 其他云平台的虚拟机。

激活混合实例:

# 创建激活
aws ssm create-activation \
  --default-instance-name "OnPrem-Server" \
  --iam-role "service-role/AmazonSSMRoleForManagedInstances" \
  --registration-limit 10 \
  --region us-east-1

# 在本地服务器上注册
sudo amazon-ssm-agent -register \
  -code "activation-code" \
  -id "activation-id" \
  -region "us-east-1"

5. 成本优化

  • 使用标签管理实例
  • 定期清理未使用的参数
  • 使用 Parameter Store 标准层(免费)而非高级层

附录

快速参考卡

功能 命令
连接实例 aws ssm start-session --target INSTANCE_ID
执行命令 aws ssm send-command --instance-ids ID --document-name AWS-RunShellScript --parameters 'commands=["COMMAND"]'
获取参数 aws ssm get-parameter --name NAME --with-decryption
创建参数 aws ssm put-parameter --name NAME --value VALUE --type SecureString
列出实例 aws ssm describe-instance-information
查看命令输出 aws ssm get-command-invocation --command-id ID --instance-id ID

实例管理

# 列出所有在线实例
aws ssm describe-instance-information \
  --filters "Key=PingStatus,Values=Online" \
  --query "InstanceInformationList[*].[InstanceId,PlatformName,PlatformVersion]" \
  --output table

# 按标签筛选
aws ssm describe-instance-information \
  --filters "Key=tag:Environment,Values=Production"

# 查看实例详情
aws ssm describe-instance-information \
  --instance-information-filter-list key=InstanceIds,valueSet=i-1234567890abcdef0

禁用和卸载 SSM

停止 SSM Agent:

# Linux
sudo systemctl stop amazon-ssm-agent
sudo systemctl disable amazon-ssm-agent

# Windows (PowerShell)
Stop-Service AmazonSSMAgent
Set-Service AmazonSSMAgent -StartupType Disabled

卸载 SSM Agent:

# Amazon Linux / RHEL / CentOS
sudo yum remove -y amazon-ssm-agent

# Ubuntu / Debian
sudo apt-get remove -y amazon-ssm-agent

# Windows (PowerShell)
wmic product where name="Amazon SSM Agent" call uninstall

移除 IAM 实例配置文件:

# 解除实例关联
aws ec2 disassociate-iam-instance-profile \
  --association-id <association-id>

# 删除实例配置文件
aws iam remove-role-from-instance-profile \
  --instance-profile-name SSM-EC2-Profile \
  --role-name SSM-EC2-Role

aws iam delete-instance-profile \
  --instance-profile-name SSM-EC2-Profile

注销混合实例:

# 注销托管实例
aws ssm deregister-managed-instance \
  --instance-id mi-xxxxxxxxx

参考资源

Next Post Previous Post
No Comment
Add Comment
comment url