连接 Amazon EC2 Mac 实例
每 24 小时 22 美元
开发 Apple 系统(iPhone、iPad、Watch、TV 或 Vision Pro)应用程序时,在开发工作流的某些节点上,您必须使用 macOS 机器。这样,可以为远程开发人员或临时承包商提供托管的且安全的桌面计算机,或实现管道创建、测试、签名和发布的自动化(也称为持续集成和持续部署,即 CI/CD)。了解有关持续集成和持续部署的详细信息,请参见使用 CI/CD 管道快速构建 iOS 应用。
由于需要额外的采购、安装和配置过程,访问基于 macOS 的机器可能需要一些时间。为了方便起见,您可以选择通过 Amazon EC2 创建 macOS 实例。
本系列教程可以引导您在亚马逊云科技云中启动、连接和配置基于 macOS 的虚拟机。本系列中每个教程都是独立的,您不必按顺序学习。您只需选读那些与您想要完成的任务有关的教程。
在本系列教程中,我们假设您对 Amazon EC2 有一定的了解。您可以通过阅读 Amazon EC2 实例入门 来快速了解 Amazon EC2。本教程将重点介绍针对 EC2 Mac 机器的特性和特殊操作。
本文介绍了 EC2 Mac 实例和 macOS 上的高级 CLI 操作,包括构建、测试、签名、存档和部署。您也可以参见后续操作指导文章进行后续操作。
祝您快乐享受学习之旅!
远程连接 Amazon EC2 Mac 实例
- 启动 EC2 Mac 实例后,您可能希望远程连接该实例,安装您想要用构建和测试应用程序的工具、库和其他依赖项。
- 请注意,在某些情况下,实例在启动时就已配置好了(本文介绍如何配置实例)。这种情况下无需手动远程连接您的实例。如果是预配置的 EC2 Mac 实例,您无需手动连接就可以启动和使用。但本教程中,我们会根据一个亚马逊云科技提供的 Amazon 机器镜像 (AMI) 启动 EC2 Mac 实例。实例系统是新安装的不包含应用程序的 macOS。
- 您可以用以下方法连接您的 EC2 Mac 实例,且无需安装任何其他工具或驱动程序:SSH、SSM 和 ARD/VNC。其中两个方法(SSH 和 SSM)是用命令行连接。ARD/VNC 需要启动完整的图形用户界面。
CLI:使用 SSH 连接
使用 SSH 是最常见的方法。要建立与 EC2 Mac 实例的 SSH 连接,有三个前提条件:
在启动实例时,指定了用于用户身份验证的 SSH 密钥对。注意:SSH 密钥对只能在启动实例时指定。如果您在启动实例时没有指定密钥对,您可以终止实例并在同一台专用主机上启动新实例(在终止实例时,可能需要一段时间来清理数据,然后对应资源才能再次可用)。
实例必须部署在具有公网连接能力的 VPC 中(VPC 包含公共子网),并且实例具有公网 IP 地址。启动 EC2 实例时,相关参数的的默认值即指定开通实例的公网连接能力。
您已将一个安全组与您的 EC2 Mac 实例关联。安全组允许来自您的本地电脑 IP 地址或客户端网络 IP 范围的入站 TCP 22(SSH)流量访问该实例。
若满足这三个前提条件,则连接 macOS 实例与连接 Linux 实例的方法相同。本示例中,密钥对关联的用户名是 ec2-user。您需要使用 -i 选项来引用存储在本地电脑上的私钥。
您可以在亚马逊云科技控制台查看您的 EC2 实例的 IP 地址。或者,您可以在 CLI 中运行以下命令来查询实例的 IP 地址。本示例中,当前账户下只有一个 mac1.metal 实例在运行。命令返回该实例的 IP 地址是 1.0.0.0。
aws ec2 describe-instances \
--query "Reservations[].Instances[? InstanceType == 'mac1.metal'].NetworkInterfaces[][].Association.PublicIp"
# Response
[
1.0.0.0
]
使用 SSH 的 -i 选项引用私有密钥文件 pem,并在命令中指定亚马逊云科技为您的 macOS 机器创建的默认用户名。本示例中的用户名为:ec2-user。以下示例代码连接了 Big Sur 实例(请务必将 1.0.0.0 替换为您的实例的 IP 地址)。
ssh -i ./path_to/my_private_key.pem ec2-user@1.0.0.0
Last login: Fri Jul 1 12:07:28 2022 from 52.95.4.11
┌───┬──┐ __| __|_ )
│ ╷╭╯╷ │ _| ( /
│ └╮ │ ___|\___|___|
│ ╰─┼╯ │ Amazon EC2
└───┴──┘ macOS Big Sur 11.6.6
ec2-user@ip-172-31-44-83 ~ %
连接后,请查看您的实例的各项信息,了解该实例。检查 macOS 是否安装成功。
ec2-user 包含在 /etc/sudoers 文件中。您可以使用 sudo 命令将其权限提升为 root。该操作无需密码。
CLI:使用 Amazon SSM 连接
我们使用大家比较熟悉的 SSH 来连接实例。但是,从安全和管理的角度来看,SSH 有几个方面需要改进。
第一个需要改进的部分是网络。要使用 SSH,您的实例必须位于 VPC 的公共子网中,实例要有公共 IP 地址,并且要设置允许 TCP 流量通过端口 22 入站的安全组规则。由于 EC2 Mac 实例主要用于开发使用场景,例如持续集成和持续部署管道,因此所有这些网络限制都没有意义。大多数开发人员都希望在实例上进行的构建、测试和部署保留在私有子网中,不为实例分配公网 IP 地址,也不需要设置允许入站流量的安全组规则。
第二个需要改进的部分是访问控制。SSH 使用密钥对来对用户身份进行验证。您的密钥对的私钥存储在您的本地电脑上,而公钥作为 EC2 macOS Init 进程的一部分注入到实例的 macOS 文件系统上(macOS Init 会从实例元数据服务获取公钥)。根据安全实践,私钥需存储在安全位置并定期轮换密钥对。那么,怎样才能方便安全地连接和管理多个 EC2 实例呢?
为了提高 EC2 Mac 实例的安全性和优化管理,您可以使用 Amazon Systems Manager (SSM) 的 Session Manager 功能。Amazon SSM 是一项多功能服务。使用 Amazon SSM,您便能够通过 macOS 主机上运行的代理建立与实例的 shell 连接。亚马逊云科技提供的 AMI 上包含该代理。
与 SSH 相比,通过 SSM 进行连接有两个优点。1. 不需要来自本地网络的入站网络连接。SSM 代理轮询 SSM 服务,SSM 服务负责将信息(如键盘输入)转发到实例。这意味着 EC2 Mac 实例只需有一个位于私有 VPC 中的私有 IP 地址,并且不需要通过安全组规则允许入站流量。2. 不需要使用 SSH 密钥对来进行用户身份验证。您可以使用 IAM 管理实例的连接访问权限。您可以在 IAM 上设置允许或不允许某些亚马逊云科技用户或角色连接您的实例。
在实例上运行的代理必须具有调用 SSM API 的权限。为了授予相关权限,您可以创建一个 IAM 角色,为该角色添加权限,然后将该角色附到 EC2 实例上。您可以使用 IAM 控制台或 CLI 来完成此操作。
在本教程中,我将向您展示使用 CLI 的具体步骤。其中一个 CLI 命令需要您的 EC2 Mac 实例的 ID。系统可以根据实例的名称搜索实例。此示例中,我的实例名称为 macOS Monterey。请务必替换为您的实例信息。
首先,创建一个适用于 EC2 实例的角色:
# First create the trust policy file
cat<<EOF > ec2-role-trust-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": { "Service": "ec2.amazonaws.com"},
"Action": "sts:AssumeRole"
}
]
}
EOF
# Second, create role
aws iam create-role \
--role-name ssmAccess \
--assume-role-policy-document file://ec2-role-trust-policy.json
# Response
{
"Role": {
"Path": "/",
"RoleName": "ssmAccess",
"RoleId": "AROAXCTVZHOCU72YCLAQT",
"Arn": "arn:aws:iam::123456789012:role/ssmAccess",
"CreateDate": "2022-07-01T15:52:13+00:00",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
}
}
创建角色后,我们需要为其添加权限。您可以自定义权限策略,也可以使用亚马逊云科技提供的包含 SSM 完全权限的策略:arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore。此示例中,我们使用这个策略。
aws iam attach-role-policy \
--policy-arn arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore \
--role-name ssmAccess-Profile
接下来,我们将创建一个 EC2 实例配置文件,把角色附加到该配置文件,然后把该配置文件附加到 EC2 实例。
# Create an instance profile
aws iam create-instance-profile \
--instance-profile-name ssmAccess-Profile
# Response
{
"InstanceProfile": {
"Path": "/",
"InstanceProfileName": "ssmAccess-Profile",
"InstanceProfileId": "AIPAXCTVZHOC4QNUPTLZT",
"Arn": "arn:aws:iam::123456789012:instance-profile/ssmAccess-Profile",
"CreateDate": "2022-07-01T16:02:52+00:00",
"Roles": []
}
}
# Attach the role to the profile
aws iam add-role-to-instance-profile \
--instance-profile-name ssmAccess-Profile \
--role-name ssmAccess
# Search for my EC2 Mac Instance Id, search by name=macOS Monterey
INSTANCE_ID=$(aws ec2 describe-instances \
--filter "Name=tag:Name,Values=macOS Monterey" \
--query "Reservations[].Instances[?State.Name == 'running'].InstanceId[]" \
--output text)
# Associate the profile to the instance
aws ec2 associate-iam-instance-profile \
--instance-id $INSTANCE_ID \
--iam-instance-profile Name=" ssmAccess-Profile"
# Response
{
"IamInstanceProfileAssociation": {
"AssociationId": "iip-assoc-07d308386ff04f72d",
"InstanceId": "i-01e833b396e0cbf02",
"IamInstanceProfile": {
"Arn": "arn:aws:iam::123456789012:instance-profile/ssmAccess-Profile",
"Id": "AIPAXCTVZHOC4QNUPTLZT"
},
"State": "associating"
}
}
要签出示例项目,请前往 building-rust-applications-for-aws-graviton,然后使用以下命令克隆该存储库:
过程有点长,但操作完成后,该 EC2 实例就可以访问 SSM 了。您可以在启动实例时或实例启动后,将具有 SSM 访问权限的角色附加到 EC2 实例。将该角色附加到实例后,在这个 macOS 实例上运行的所有进程(包括 SSM 代理)都有权调用 SSM API。
初始设置已经完成。下一步,连接实例。您可以在亚马逊云科技控制台上或使用 CLI 来连接实例。
进入亚马逊云科技管理控制台,导航到 EC2 控制台,选择要连接的实例。然后点击 Connect(连接)按钮。
在弹出的页面上,确认当前实例满足连接的前提条件,然后点击 Connect(连接)。
当实例具有所需的权限时,浏览器中将打开一个黑色的界面。这是一个基于浏览器的 shell 连接,它连接的是您的实例。
或者,您可以使用 CLI 通过 SSM 进行连接。
您需要安装 Amazon CLI和相关插件。在本地计算机上,安装适用于 Amazon CLI 的 SSM 插件。
# Search for my EC2 Mac Instance Id, search by name=macOS Monterey
INSTANCE_ID=$(aws ec2 describe-instances \
--filter "Name=tag:Name,Values=macOS Monterey" \
--query "Reservations[].Instances[?State.Name == 'running'].InstanceId[]" \
--output text)
aws ssm start-session --target $INSTANCE_ID
然后,您就可以连接 Mac 实例。您可以运行下列命令来检查是否已连接实例:
Starting session with SessionId: sst-0a9c1047a20fdbd7c
sh-3.2$ uname -a
Darwin ip-172-31-32-67.us-east-2.compute.internal 21.4.0 Darwin Kernel Version 21.4.0: Fri Mar 18 00:45:05 PDT 2022; root:xnu-8020.101.4~15/RELEASE_X86_64 x86_64
sh-3.2$ diskutil list
/dev/disk0 (internal, physical):
#: TYPE NAME SIZE IDENTIFIER
0: GUID_partition_scheme *121.3 GB disk0
/dev/disk1 (external, physical):
#: TYPE NAME SIZE IDENTIFIER
0: GUID_partition_scheme *214.7 GB disk1
1: EFI EFI 209.7 MB disk1s1
2: Apple_APFS Container disk2 214.5 GB disk1s2
/dev/disk2 (synthesized):
#: TYPE NAME SIZE IDENTIFIER
0: APFS Container Scheme - +214.5 GB disk2
Physical Store disk1s2
1: APFS Volume Macintosh HD - Data 48.3 GB disk2s1
2: APFS Volume Preboot 267.0 MB disk2s2
3: APFS Volume Recovery 1.1 GB disk2s3
4: APFS Volume Macintosh HD 15.2 GB disk2s4
5: APFS Snapshot com.apple.os.update-... 15.2 GB disk2s4s1
6: APFS Volume VM 20.5 KB disk2s6
sh-3.2$ id
uid=502(ssm-user) gid=20(staff) groups=20(staff),12(everyone),61(localaccounts),701(com.apple.sharepoint.group.1),100(_lpoperator)
若要结束 SSH 会话,请运行 exit。
使用 SSM 时,您将以 ssm-user 身份(而不是 ec2-user)进行验证。这两个用户都包含在 /etc/sudoers 文件中。您可以使用 sudo 命令将用户权限提升为 root。该操作无需密码。
如果您不想耗费精力去记住这两个不同的命令,您可以配置您的本地 ssh,使用 aws ssm start-session 命令作为代理命令实现主机 SSH 连接。这个配置需要您有比较丰富的技术知识。相关详细信息,请参阅通过 Session Manager 允许和控制 SSH 连接的权限。
GUI:使用 Apple 远程桌面连接
当您有新环境,或想在新实例上安装工具,或想在 macOS 中使用您熟悉的图形用户界面 (GUI) 时,您可能希望使用传统的 macOS GUI 来连接您的 EC2 Mac 实例。
幸运的是,macOS 提供了所有必需的工具,您无需安装。但是,默认情况下,服务器端屏幕共享功能处于禁用状态,您必须先启用这个功能才能连接您的实例。您可以通过客户端上的 System Preferences(系统偏好设置)应用程序和 Sharing(共享)选项卡来启用此功能。但是,本教程中我们只介绍如何通过 CLI 启用此功能。让我们看看如何使用 CLI 启用屏幕共享。
第一步是使用 SSH 或 SSM 连接您的实例。
连接实例后,启用 Apple 远程桌面(ARD)。该过程需要两步。首先,为 ec2-user 设置密码,然后启动 Apple 远程桌面服务器组件。
# NB: These commands are when using SSH to connect, when connected with SSM, switch to ec2-user first with 'su -c ec2-user'
# set a password to ec2-user
sudo passwd ec2-user
# enable ARD
sudo /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart \
-activate -configure -access -on \
-restart -agent -privs -all
# Response
Starting...
Warning: macos 10.14 and later only allows control if Screen Sharing is enabled through System Preferences.
Activated Remote Management.
Stopped ARD Agent.
ec2-user: Set user remote control privileges.
ec2-user: Set user remote access.
ssm-user: Set user remote control privileges.
ssm-user: Set user remote access.
Done.
我们不建议通过公共网络连接 Apple 远程桌面。因为,这需要使用实例的公网 IP 地址,并需要添加安全组规则,允许流量通过 TCP 端口 5900(ARD 的默认端口)入站。ARD 基于密码进行用户身份验证。
我们建议您创建连接客户端和 EC2 Mac 实例的加密隧道。因为隧道是加密的,所以不需要使用用户名和密码来验证用户身份。
您可以使用 SSH 或 SSM 来创建隧道。我们先讲 SSH,然后在本文的末尾介绍 SSM 替代方案。
用 SSH 隧道连接 Apple 远程桌面
创建 SSH 隧道后,本地计算机上的 SSH 客户端将作为服务器,并开始接受 localhost 的入站连接。在此连接上接收的每条数据都经过加密和压缩,然后再发送到远程服务器:您的 EC2 Mac 实例。MacOS 上的 SSH 服务器对数据进行解密和解压缩,然后将数据发送到您在客户端上指定的目标。在本例中,流量将会被发送到实例上运行的 Apple 远程桌面服务器(localhost:5900)。
有关更多信息,请参阅 SSH 隧道。整个过程如下图所示:
要启动 SSH 隧道,请先为实例申请公网 IP 地址。然后,运行以下命令:
# We assume the EC2 Mac instance public IP address is 1.0.0.0
ssh -C -N -L 5900:localhost:5900 -i /path/my-key-pair.pem ec2-user@1.0.0.0
选项说明:
-i指定用于身份验证的密钥对的私钥部分。
-L 指 SSH 隧道选项。这个选项指示计算机上的 SSH 客户端开始侦听 TCP 端口 5900 (5900:) 上的入站连接,并将收到的所有流量转发到目标主机 (1.0.0.0)。流量到达目标主机后,再被发送到 ARD 服务器的地址:localhost:5900。
-C 指示 SSH 压缩隧道中的流量。
-N 指示 SSH 不要在客户端上启动交互式会话。该命令将一直阻止会话,直到您使用以下组合键中止命令: Ctrl-C
创建隧道后,在终端应用程序中打开另一个选项卡,然后打开 ARD 客户端。将其指向 localhost。SSH 隧道将充当服务器,将所有流量转发到隧道另一端的 EC2 Mac 实例上运行的实际 ARD 服务器。
open vnc://localhost
注意:该 URI 以 vnc:// 开头,因为 Apple 远程桌面客户端基于虚拟网络计算(VNC)协议。
此时将显示 ARD 身份验证界面。输入您在启用 ARD 时指定的用户名(ec2-user)和密码。
VNC 身份验证成功后,您会看到标准的 macOS 登录界面。再次输入您的凭据。
等待几秒钟后,macOS 桌面将会显示出来。
更改 EC2 Mac 实例屏幕的分辨率
连接成功后,您可以提高屏幕分辨率。
您可以使用 displayplacer。Displayplacer 是 Jake Hilborn 开发的命令行工具。
使用 SSH 会话或 GUI 会话上的终端应用程序安装该工具。然后,查看可用的显示模式和分辨率,选择所需的分辨率。
# install the displaylist command line tool
brew tap jakehilborn/jakehilborn && brew install displayplacer
# then list available resolutions
displayplacer list
Persistent screen id: 69784AF1-CD7D-B79B-E5D4-60D937407F68
Contextual screen id: 1020887298
Type: 24 inch external screen
Resolution: 1024x768
Hertz: 60
Color Depth: 8
Scaling:off
Origin: (0,0) - main display
Rotation: 0
Resolutions for rotation 0:
mode 0: res:1024x768 hz:60 color_depth:4
mode 1: res:1024x768 hz:60 color_depth:8 <-- current mode
mode 2: res:640x480 hz:60 color_depth:4
mode 3: res:640x480 hz:60 color_depth:8
mode 4: res:720x480 hz:60 color_depth:4
mode 5: res:720x480 hz:60 color_depth:8
mode 6: res:640x480 hz:60 color_depth:4
mode 7: res:640x480 hz:60 color_depth:8
mode 8: res:800x600 hz:60 color_depth:4
mode 9: res:800x600 hz:60 color_depth:8
mode 10: res:1280x720 hz:60 color_depth:4
mode 11: res:1280x720 hz:60 color_depth:8
mode 12: res:1440x900 hz:60 color_depth:4
mode 13: res:1440x900 hz:60 color_depth:8
mode 14: res:1680x1050 hz:60 color_depth:4
mode 15: res:1680x1050 hz:60 color_depth:8
mode 16: res:1920x1080 hz:60 color_depth:4
mode 17: res:1920x1080 hz:60 color_depth:8
mode 18: res:1920x1200 hz:60 color_depth:4
mode 19: res:1920x1200 hz:60 color_depth:8
mode 20: res:2560x1440 hz:60 color_depth:4
mode 21: res:2560x1440 hz:60 color_depth:8
mode 22: res:2560x1600 hz:60 color_depth:4
mode 23: res:2560x1600 hz:60 color_depth:8
mode 24: res:1024x576 hz:60 color_depth:4
mode 25: res:1024x576 hz:60 color_depth:8
Execute the command below to set your screens to the current arrangement:
displayplacer "id:69784AF1-CD7D-B79B-E5D4-60D937407F68 res:1024x768 hz:60 color_depth:8 scaling:off origin:(0,0) degree:0"
# Lastly, set the display resolution. We will choose 1440x900
displayplacer "id:69784AF1-CD7D-B79B-E5D4-60D937407F68 res:1440x900 origin:(0,0) degree:0"
您不需要重启 VNC 客户端,它会自动调整。
用 SSM 隧道连接 Apple 远程桌面
如前所述,SSH 连接和隧道要求您的实例开放 Internet 连接。此外,还需您还需创建、安全存储和轮换密钥对。
为避免这些操作,您可以选择使用 SSM 连接您的实例。SSM 也支持隧道。
SSM 隧道启动后,打开客户端、连接服务器以及调整显示大小等操作与 SSH 隧道的操作方法类似。
在为 Apple 远程桌面启动 SSM 隧道之前,请确认已为 EC2 Mac 实例添加具有 SSM API 权限的 IAM 角色。
运行以下命令启动隧道:
# first, select the instance ID of the machine you want to connect
# the below command search for a machine named "macOS Monterey"
INSTANCE_ID=$(aws ec2 describe-instances \
--filter "Name=tag:Name,Values=macOS Monterey" \
--query "Reservations[].Instances[?State.Name == 'running'].InstanceId[]" \
--output text)
# second, start the SSM tunnel
aws ssm start-session --target $INSTANCE_ID \
--document-name AWS-StartPortForwardingSession \
--parameters '{"portNumber":["5900"],"localPortNumber":["5900"]}'
Starting session with SessionId: sst-0f3b970f24182795d
Port 5900 opened for sessionId sst-0f3b970f24182795d.
Waiting for connections...
隧道打开后,运行以下命令连接实例:
open vnc://localhost
其余所有步骤都与 SSH 隧道操作类似。
完成后,按下 Ctrl-C,中断 aws ssm 命令,关闭隧道。
总结
恭喜 。您已使用 SSH 或 SSM 安全地连接您的 EC2 Mac 实例。您可以继续学习下一个教程,了解如何调整启动卷的大小分配更多存储空间。