从凭据到工作环境

三种方式连上你的 M4

命令行用 SSH,交互操作用图形桌面,自动构建用 CI runner。三种入口指向同一台独享物理节点,不是三个不同环境。

已租用户:在控制台打开订单对应的实例详情,查看主机地址、SSH 端口、用户名与交付说明。本文的主机变量均需替换为该实例的真实值。

SSH验证主机、同步文件、运行构建命令
图形桌面操作 Xcode、模拟器与 macOS 界面
CI runner把项目任务调度到自己的物理节点
先建立可验证的连接

SSH:生成密钥,再登记节点别名

先连通命令行,再配置桌面和流水线。SSH 也是检查节点是否可达、定位认证问题的最短路径。

  1. 01

    在本地生成密钥

    在自己的电脑上执行,不是在云端节点上执行。为密钥设置口令;已有专用密钥时可复用,不要覆盖仍在使用的文件。私钥始终留在本地,交付给节点的只有以 .pub 结尾的公钥。

    ssh-keygen -t ed25519 -f ~/.ssh/xcnode_ed25519 -C "xcnode-workstation"
    ssh-add ~/.ssh/xcnode_ed25519

    如果 ssh-add 提示未连接认证代理,先确认本机的 SSH agent 已启动。密钥口令与远程用户密码不是同一个东西。

  2. 02

    安装公钥并验证主机

    按实例说明设置三个变量。只有交付说明允许初次密码认证时,才使用 ssh-copy-id;若已登记公钥,直接测试登录。首次连接时核对主机指纹,不能仅因看到确认提示就接受未知主机。

    read -r -p "Host: " NODE_HOST
    read -r -p "SSH port: " NODE_PORT
    read -r -p "User: " NODE_USER
    ssh-copy-id -i ~/.ssh/xcnode_ed25519.pub -p "$NODE_PORT" "$NODE_USER@$NODE_HOST"
    ssh -i ~/.ssh/xcnode_ed25519 -p "$NODE_PORT" "$NODE_USER@$NODE_HOST"

    以上变量输入命令适用于 Bash。macOS 的 zsh 可先执行 bash 再运行。若初次公钥安装受阻,使用控制台提供的凭据管理路径或提交工单,不要反复尝试密码。

  3. 03

    保存别名并检查环境

    在本地 ~/.ssh/config 中写入别名。下面的尖括号字段需替换成实例值,不保留尖括号。Windows OpenSSH 同样读取用户目录下的 .ssh/config。

    Host xcnode-work
      HostName <INSTANCE_HOST>
      Port <SSH_PORT>
      User <INSTANCE_USER>
      IdentityFile ~/.ssh/xcnode_ed25519
      IdentitiesOnly yes
      ServerAliveInterval 30
      ServerAliveCountMax 3
    ssh xcnode-work
    uname -m
    sysctl -n machdep.cpu.brand_string
    xcode-select -p
    xcodebuild -version

    uname -m 应返回 arm64。芯片名称应与订单机型一致;Xcode 版本以节点实际安装结果为准。保持连接参数不等于自动续跑任务,长构建应交给 runner 或持久会话管理工具。

三个客户端系统,关注点不同

先确认本地能执行 ssh -V。缺少某个辅助命令,不代表节点不支持 SSH。

本地客户端准备与公钥安装方式
本地系统SSH 客户端公钥安装注意事项
macOS终端自带 OpenSSHssh-copy-id 通常需要另行安装,也可按交付说明登记公钥。默认 shell 常为 zsh;不要直接照搬 Bash 专用的输入语法。
WindowsPowerShell 中使用 OpenSSH Client可在 WSL 中使用 ssh-copy-id,或在控制台登记公钥。PowerShell 与 WSL 的用户目录和密钥文件各自独立。
Linux发行版的 OpenSSH 客户端包通常提供 ssh-copy-id;没有时先安装客户端工具。私钥权限设为 600,~/.ssh 目录权限设为 700。
需要操作界面时

图形桌面:优先走 SSH 隧道

SSH 通畅之后,再检查屏幕共享服务与图形会话。不要把“能连上端口”当作“桌面已经准备好”。

macOS 屏幕共享

本地 Mac 可使用系统自带的“屏幕共享”客户端。VNC 常用服务端口是 TCP 5900;实际端口、认证方式以及是否已启用,均以实例交付说明为准。

确认远端使用 5900 后,在本地终端建立隧道,保持该终端运行。这里使用本地 15900,避免与本机服务冲突。

ssh -N -L 127.0.0.1:15900:127.0.0.1:5900 \
  -o ExitOnForwardFailure=yes xcnode-work

然后在另一终端打开客户端:

open "vnc://127.0.0.1:15900"
隧道只监听本机回环地址

Windows / Linux VNC 客户端

选择支持实例认证方式的 VNC 客户端,例如 TigerVNC。先建立同样的 SSH 隧道,再将客户端目标填写为 127.0.0.1,端口填写为 15900。

不同客户端对端口的写法不同:有的单独提供端口字段,有的使用双冒号表示完整端口。按客户端说明输入,不要把端口误当作显示编号。

macOS 屏幕共享的认证与通用 VNC 并不总是兼容。认证失败时先核对客户端能力与交付说明,不要为兼容客户端而随意降低节点的访问保护。

桌面凭据与 SSH 密钥分开管理

画质调低一点,先把交互跑顺

首次连接先选自动或较低画质,只使用一个显示器,避免同时传输大文件与全屏动态画面。文字清楚、点击稳定后,再逐步提高分辨率与色彩质量。SSH 文件传输快,不代表图形桌面的往返延迟也低。

黑屏时,按顺序检查:隧道是否仍在运行、目标端口是否正确、屏幕共享是否启用、远端是否存在可用图形会话。遇到会话冲突先协调团队使用时间,不要直接强制注销正在构建的用户。

让任务自动到达节点

CI 接入:注册一次,验证自启

runner 在云端 Mac 上执行,而不是在你的本地电脑上执行。先用交互式任务验证工具链,再把它变成服务。

GitHub Actions self-hosted runner

进入项目或组织的 runner 设置,选择 macOS ARM64。按页面当前提供的下载和校验命令准备程序;注册 URL 与短期令牌都从该设置页领取。

cd ~/actions-runner
read -r -p "Registration URL: " RUNNER_URL
read -r -s -p "Registration token: " RUNNER_TOKEN
printf '\n'
./config.sh --url "$RUNNER_URL" --token "$RUNNER_TOKEN" \
  --name xcnode-work --labels xcnode,arm64
unset RUNNER_TOKEN
./run.sh

以上输入命令在 Bash 中运行。提交测试任务,确认 runner 在线并完成构建,再停止前台进程、安装服务:

./svc.sh install
./svc.sh start
./svc.sh status

工作流使用明确标签,避免派到另一种架构的机器:

runs-on: [self-hosted, macOS, ARM64, xcnode]
steps:
  - run: xcodebuild -version

注册令牌不是长期项目密钥。不要把它写入仓库、构建输出或工单附件。

GitLab Runner

在项目或组中创建 runner,按当前平台说明取得 runner 认证令牌。安装 macOS ARM64 版本后,在目标运行用户的图形会话终端中登记;不要以 root 身份运行工程构建。

gitlab-runner register

交互输入实例 URL 与认证令牌,选择 shell 执行器。为 runner 配置 xcnode 与 arm64 标签,并限制到可信项目。

gitlab-runner install
gitlab-runner start
gitlab-runner status

最小测试任务先检查环境,之后再加入签名与归档:

build-check:
  tags: [xcnode, arm64]
  script:
    - uname -m
    - xcode-select -p
    - xcodebuild -version

Shell 执行器可以访问运行用户的文件。独享机器并不替你隔离同一账户下的不可信任务。

自启与交互能力,要分开验证

macOS 上的用户级服务通常由 launchd 管理,可能依赖用户会话。安装服务后检查进程、日志与队列状态;在团队允许的时间测试重启后的恢复行为。需要模拟器或图形操作的任务,还应验证登录会话是否满足要求,不能只看 runner 显示在线。

先从单任务开始,记录工程实际峰值内存,再增加并行度。缓存按项目和 Xcode 版本划分;构建产物单独归档。使用系统钥匙串中的签名材料时,还需单独验证服务用户的访问权限,不能假定终端构建成功就代表后台构建也成功。

按真实网络选位置

四个节点,先测常用办公网络

新加坡、东京、首尔、香港均提供两档机型。可用性以控制台实时返回为准;地理距离只是起点,运营商路由和团队工作时段同样重要。

新加坡

东南亚团队可优先评估。使用实际办公网络测试桌面交互,再检查工程拉取与产物上传路径。

sg · UTC+8

东京

日本及东亚团队可优先评估。时区接近不代表网络必然更快,仍需比较忙时与闲时的连接表现。

jp · UTC+9

首尔

韩国及东北亚团队可优先评估。常驻 runner 更应关注访问代码仓库和依赖源的稳定性。

kr · UTC+9

香港

华南与东南亚团队可优先评估。跨时区共享桌面时,提前约定图形会话的使用与退出时间。

hk · UTC+8

自测记录三件事:往返、波动、实际任务

对已分配实例的真实主机地址执行检查,不要对网站域名测速来代替节点测速。下面命令在已设置节点变量的本地 Bash 终端执行。

ping -c 20 "$NODE_HOST"
ssh -p "$NODE_PORT" "$NODE_USER@$NODE_HOST" 'uptime'

Windows PowerShell 使用 ping -n 20 <INSTANCE_HOST>。记录丢包与往返时间范围,再进行一次真实 Git 拉取或构建产物传输。ICMP 可能被网络策略过滤:ping 无回应时,仍要单独测试实际 SSH 端口。

把测试放在团队常用网络和常用工作时段重复进行。本文不提供统一延迟承诺;测试结果只代表该网络路径当时的表现。尚未租用时,可通过支持邮箱咨询测试方式,不使用猜测出来的节点地址。

把概念放到同一张表上

八个连接术语,一次说清

先分清资源边界、连接协议与任务调度,排查问题时才不会把不同层级混在一起。

物理节点
实际运行 macOS 的 Apple Silicon 机器;订单分配的是整台设备,不是共享宿主中的虚拟机。
独享
租期内该物理机分配给一个租户,CPU、GPU 与统一内存不与其他租户分摊。
VNC
传输远程屏幕画面和键鼠输入的协议;它的服务状态、端口与认证需要单独检查。
Screen Sharing
macOS 的屏幕共享能力与客户端,用于访问远端图形会话,不能替代 SSH 的命令行连接。
SSH 密钥
由公钥和私钥构成的身份凭据;公钥可登记到节点,私钥只保留在受保护的客户端。
self-hosted runner
在自有节点执行 CI 任务的代理程序,使用节点本身的工具链、权限和缓存。
Thunderbolt 5 并联
按台选择的节点连接附加项,不会把多台设备自动变成单一共享内存系统,软件仍需适配分布式任务。
统一内存
Apple Silicon 中 CPU 与 GPU 使用同一内存池,因此构建、模拟器和模型任务需要共同预算内存占用。
连得上,也要收得住

确认密钥可用,再收紧访问

不要在唯一连接尚未验证时修改认证。保留当前会话,用第二个终端确认新的密钥登录成功后,再调整节点策略。

关闭密码认证

按当前 macOS 版本检查 sshd 配置及其包含文件。目标是启用公钥认证,并关闭密码与键盘交互认证;不要只修改一个可能被其他文件覆盖的字段。

PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication no

应用配置前使用 sudo /usr/sbin/sshd -t 检查语法,并按实例说明生效。

只开放必要端口

SSH 按交付端口连接。图形桌面优先通过本地隧道访问,不把 5900 直接暴露到公共网络。临时测试服务用完就关闭,监听地址和防火墙规则一起检查。

lsof -nP -iTCP -sTCP:LISTEN

runner 通常主动连接 CI 服务,不要因此额外开放入站管理端口。

按人员和任务管理凭据

每个成员使用独立公钥,人员离开时移除对应授权。runner 只接收可信仓库任务,项目密钥使用 CI 平台的受保护变量,不写进脚本或工程文件。

出现主机指纹变更时先核实实例是否重装,不直接删除本地记录后继续连接。

工单只附脱敏日志、订单号和失败步骤,不发送私钥、密码或注册令牌。

把本地步骤,变成可重复的远程工位

先选机型和租期,再领取实例凭据。从 SSH 验证开始,逐项接通图形桌面与构建队列;已有实例遇到阻塞,就在控制台提交脱敏排查记录。