在 亚马逊云科技 ParallelCluster 中使用 NICE DCV 弹性可视化

作者:肖恩·史密斯 |

许多 HPC 工作负载都需要图形化桌面,包括为 CFD 模型布局网格、检查分子动力学仿真的输出或仅运行西门子 StarCCM+ 或 Ansys Fluent 等桌面软件等情况。

在这篇博客文章中,我们将介绍一种解决方案,该解决方案将 亚马逊云科技 ParallelCluster 的计算 与 NICE DCV 的远程桌面功能相结合,提供对连接到 HPC 用户期望的相同文件系统、用户身份和调度程序的远程桌面的访问权限。

背景

DCV 是一个高性能桌面可视化包,为访问远程桌面提供安全、低延迟和高性能的解决方案。这是亚马逊 Appstream 2.0 和 亚马逊云科技 Nimble Studio 之下的直播协议。

我们已经将 DCV 包含在 ParallelCluster 中了。它允许单用户使用与集群连接时相同的 SSH 密钥对直观地连接到头节点。对于用户希望无需额外设置即可进行远程桌面会话的单用户环境来说,这是一个很好的解决方案。

但是,对于有多个用户想要进行可视化的环境,我们需要进一步自定义 ParallelCluster。这篇文章中描述的解决方案在 计算队列 中的实例 上 设置 DCV 会话。与默认 DCV 配置相比,这有几个优点:

  1. 您可以运行多用户会话(即多个用户共享的实例) 专用于个人的 多个实例
  2. 您可以按使用量付费的方式在针对远程桌面应用程序(如 GPU 加速的 G4/G5 实例)进行了优化的硬件上运行,而无需向一直运行的头节点增加成本。
  3. 在不需要图形会话时,您可以缩小图形会话的规模,以控制成本。

使用 DCV 队列设置的 亚马逊云科技 ParallelCluster 架构

Figure 1 – AWS ParallelCluster Architecture with DCV Queue in a public subnet.

图 1 — 在公有子网中使用 DCV 队列的 亚马逊云科技 ParallelCluster 架构。

设置

在这篇文章中,我们假设你在使用 3.4.0 或更高版本之前已经设置了 亚马逊云科技 ParallelCluster。如果您还没有,请按照我们的 亚马逊云科技 HPC 研讨会 中的说明进行操作。我们将使用指定多个子网的功能,这是 3.4.0 中的一项新功能。如果你的版本较旧,你仍然可以使用下面的 “ No-Ingress DCV ” 部分

在这种情况下,我们将使用安全组设置一个公有子网, 该 安全组 允许用户通过端口 8443 连接到 DCV 实例。如果您希望保持子网私有,请参阅下面标题为 “No-Ingress DCV” 的部分。

步骤 1: 创建允许您连接到端口 8443 上的计算节点的安全组。我们将在下面队列的 Addition alSecurityGro u ps 参数中使用此参数(图 2 显示了此配置的屏幕截图):

  • 转到 EC2 安全组 > 创建
  • 名称: DCV
  • 添加入口规则,自定义 TCP,端口 8443,0.0.0 /0
Figure 2 - Creating a security group that allows connections to the compute nodes on port 8443.

图 2 — 创建允许连接端口 8443 上的计算节点的安全组。

步骤 2: 接下来,确保您在 分配公有 IP = True 的情况下在同一个可用区中有一个子网 。这将允许用户解析计算节点的 IP 地址。另一种选择是设置 点对点 VPN 亚马逊云科技 Direct Connect , 这样用户就可以解析计算节点的私有 IP 地址。

步骤 3: 使用名为 DCV 的队列 和经过图形优化的实例类型(如 g4dn.xlarge) 创建集群

下表描述了密钥设置。

Parameters Explanation
InstanceType An instance type like a g4dn.xlarge optimized for the graphics workload.
AdditionalSecurityGroups Allows users to connect on port 8443.
AdditionalIamPolicies AmazonS3ReadOnlyAccess allows the compute nodes to fetch the DCV license . AmazonSSMManagedInstanceCore is needed for the No-Ingress DCV setup.
SubnetIds This is a public subnet, i.e. one that assigns a public ipv4 address.

你应该有一个类似于这样的集群定义:

Region: us-east-2
Image:
  Os: alinux2
HeadNode:
  InstanceType: c5.xlarge
  Networking:
    SubnetId: subnet-123456789
  Ssh:
    KeyName: blah
  Iam:
    AdditionalIamPolicies:
      - Policy:arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
Scheduling:
  Scheduler: slurm
  SlurmQueues:
    - Name: dcv
      ComputeResources:
        - Name: dcv-g4dnxlarge
          InstanceType: g4dn.xlarge
          MinCount: 0
          MaxCount: 4
      Networking:
        SubnetIds:
       - subnet-123456789
        AdditionalSecurityGroups:
          - sg-031b9cd973e8f62b0 # security group you created above
      Iam:
        AdditionalIamPolicies:
          - Policy: arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
          - Policy: 
        S3Access: arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess # needed for license access

步骤 4: 接下来, 使用下面的列表创建作业脚本 d esktop.sbat ch。这个脚本:

  • DCV 队列中启动,该队列具有正确的网络设置和实例类型
  • 设置 12 小时的超时时间,使实例在 12 小时后自动关闭
  • 启动 DCV 服务器
  • 使用作业 ID 作为唯一标识符创建 DCV 会话
  • 创建用户可以用来连接的临时密码(有关详细信息,请参阅多用户部分)
  • 为用户提供一个他们可以连接的 URL。
#!/bin/bash
#SBATCH -p dcv
#SBATCH -t 12:00:00
#SBATCH -J desktop
#SBATCH -o "%x-%j.out"
#SBATCH --exclusive

# magic command to disable lock screen
dbus-launch gsettings set org.gnome.desktop.session idle-delay 0 > /dev/null
# Set a password
password=$(openssl rand -base64 32)
echo $password | sudo passwd $USER --stdin > /dev/null
# start DCV server and create session
sudo systemctl start dcvserver
dcv create-session $SLURM_JOBID


TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
instance_id=$(curl -sH "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/public-ipv4)
printf "\e[32mClick the following URL to connect:\e[0m"
printf "\n=> \e[34mhttps://$ip:8443?username=$USER&password=$password\e[0m\n"

while true; do
   sleep 1
done;

现在提交任务以启动 DCV 实例:

$ sbatch desktop.sbatch # take note of the job id

步骤 5: 作业开始运行 后,请查看 desktop-[job-id] .out 中引用的文件以了解连接详细信息。尽管大多数终端应用程序也允许您按住 Ctrl 单击进行连接,但您可以在浏览器中输入 URL 进行连接。

Figure 3 - The file desktop-[job-id].out contains the connection details you need to connect to the virtual desktop.

图 3 — 文件 desktop-[job-id] .out 包含连接到虚拟桌面所需的连接详细信息。

为禁止进入 DCV 进行设置

除了打开我们的安全组以允许来自端口 8443 的流量外,还有其他选择。这涉及 使用 亚马逊云科技 SS M 对会话进行 端口转发 。这使我们能够锁定安全组并且无法进入。

但是,它确实要求用户在其桌面 上安装 会话管理器插件 ,并在每次连接时在本地运行该插件(如图 4 所示)。为了简化此过程,我们将修改 d esktop.sbatch 脚本以输出它们需要运行的命令。

Figure 4 - An architecture for permitting access to DCV's port 8443 without needing to open that port in a security group. This uses AWS SSM to tunnel traffic to this port via SSH.

图 4 — 允许访问 DCV 的 8443 端口而无需在安全组中打开该端口的架构。这使用 亚马逊云科技 SSM 通过 SSH 将流量传输到此端口。

首先 ,在用户的本地计算机 上安装 会话管理器插件 。按照说明选择正确的操作系统。你可以在微软 Windows、macOS、Linux 和 Ubuntu 的支持版本上安装该插件。

接下来, 使用下面的提交脚本提交作业。这个脚本:

  • 在 DCV 队列中启动
  • 启动 DCV 服务器
  • 使用作业 ID 作为唯一标识符创建 DCV 会话
  • 获取运行它的 Amazon EC2 实例的实例 ID,并创建包含该实例的 SSM 命令。
  • 为用户提供一个本地 URL,他们可以在运行端口转发会话后连接到该网址。
#!/bin/bash
#SBATCH -p desktop
#SBATCH -t 12:00:00
#SBATCH -J desktop
#SBATCH -o "%x-%j.out"

# magic command to disable lock screen
dbus-launch gsettings set org.gnome.desktop.session idle-delay 0 > /dev/null
# Set a password
password=$(openssl rand -base64 32)
echo $password | sudo passwd $USER --stdin > /dev/null
# start DCV server and create session
sudo systemctl start dcvserver
dcv create-session $SLURM_JOBID

TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
instance_id=$(curl -sH "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/instance-id)
printf "\e[32mFor a no-ingress cluster, you'll need to run the following command (on your local machine):\e[0m"
printf "\n=> \e[37m\taws ssm start-session --target $instance_id --document-name AWS-StartPortForwardingSession --parameters '{\"portNumber\":[\"8443\"],\"localPortNumber\":[\"8443\"]}'\e[0m\n"

printf "\n\n\e[32mThen click the following URL to connect:\e[0m"
printf "\n=> \e[34mhttps://localhost:8443?username=$USER&password=$password\e[0m\n"

while true; do
   sleep 1
done;

现在, 在桌面上本地 运行输出端口转发命令,如图 5 所示。

Running output port-forwarding command locally on your desktop.

图 5 — 在桌面上本地运行输出端口转发命令。

最后, 连接到 本地主机 URL 以安全访问您的 DCV 桌面。

DCV 客户端

DCV 为 macOS、Windows 和 Linux 提供了原生客户端。与浏览器相比,该客户端可以提供更好的体验,因为允许它使用工作站或笔记本电脑的更多硬件功能。

在以下步骤中,我们将向您展示如何修改 DCV 队列以创建和上传 DCV 连接文件 , 以便您的用户可以使用本机客户端进行连接。

首先 ,从 NICE DCV 客户端下载页面下载客户端。

接下来, 您需要在 您的 DCV 队列中设置另外两个 IAM 策略才能启用瘦客户端。 AWScloudformationReadonlyAcces s 用于描述使用集群创建的存储桶,我们使用 Amazons3Full Access 来允许将连接文件上传到该存储桶。

使用以下文本修改集群配置文件的 IAM 部分:

      Iam:
        AdditionalIamPolicies:
          - Policy: arn:aws:iam::aws:policy/AWSCloudFormationReadOnlyAccess
          - Policy: arn:aws:iam::aws:policy/AmazonS3FullAccess

更新集群以使这些策略生效。

现在 使用以下 脚本创建一个名为 d esktop.sbatch 的文件:

#!/bin/bash
#SBATCH -p dcv
#SBATCH -t 12:00:00
#SBATCH -J desktop
#SBATCH -o "%x-%j.out"

# magic command to disable lock screen
dbus-launch gsettings set org.gnome.desktop.session idle-delay 0 > /dev/null
# Set a password
password=$(openssl rand -base64 32)
echo $password | sudo passwd $USER --stdin > /dev/null
# start DCV server and create session
sudo systemctl start dcvserver
dcv create-session $SLURM_JOBID

# params
source /etc/parallelcluster/cfnconfig
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
ip=$(curl -sH "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/public-ipv4)


port=8443
bucket=$(aws cloudformation describe-stacks --region $cfn_region --stack-name $stack_name --query "Stacks[0].Parameters[?ParameterKey=='ResourcesS3Bucket'].ParameterValue" --output text)

cat <<EOT > connect-$SLURM_JOB_ID.dcv
[version]
format=1.0

[connect]
host=$ip
port=$port
user=$USER
password=$password
sessionid=$SLURM_JOB_ID
EOT

aws s3 cp --region $cfn_region connect-$SLURM_JOB_ID.dcv s3://$bucket/
url=$(aws s3 presign --region $cfn_region s3://$bucket/connect-$SLURM_JOB_ID.dcv)
echo "$url"

printf "Connect using the DCV Client with the following file:\n"
printf "\e[34m=> %s \e[0m\n" "$url"

while true; do
   sleep 1
done;

像其他脚本一样,这个脚本:

  • 启动 DCV 服务器
  • 使用作 业 ID 作为唯一标识符创建 DCV 会话
  • 创建包含 IP、端口、用户名和会话 ID 的 DCV 连接文件
  • 将此 DCV 会话文件上传到与集群关联的 S3 存储桶,并创建 预签名 URL 来共享 此文件

此脚本运行后,您将看到如下输出:

The output you'd expect from running the batch submission script when using the local client configuration.

图 6 — 使用本地客户端配置时运行批量提交脚本所需的输出。

最后 ,将这个长网址复制并粘贴到浏览器中以下载会话文件。双击会话文件以通过客户端进行连接。

多用户 DCV

我们已经举了一个示例,该示例侧重于单个用户,即提交 d esktop.sbatc h 文件的用户。要处理多个用户,我们必须首先将 集群 重新配置为使用 Active Directory 或其他用户管理系统。

完成此操作后,您可以 删除 在执行 d esktop.sbatc h 文件期间设置本地密码的两行:

password=$(openssl rand -base64 32)
echo $password | sudo passwd $USER --stdin > /dev/null

从现在起,当用户使用该文件提交作业时,他们仍然会获得一个用于连接的网址,但需要他们使用自己的 Active Directory 密码进行身份验证。

每个亚马逊 EC2 实例有多个 DCV 会话

在上面的示例中,我们设置了 —exclusiv e 标志,它告诉 Slurm 只在计算机上安排一项作业。如果我们删除该标志,则默认情况下,Slurm 将在 1 个 vCPU 上安排每个会话。

这意味着我们的 g4dn.xlarge 实例类型 (有 4 个 vCPU)可以为其安排四个会话。 例如,如果我们提交了 d esktop.sbatch 文件四次,我们会看到所有作业都在同一个主机 dcv-st-dcvg4dnxlarge-1 上运行:

Figure 7 - Four jobs being run on the same DCV host.

图 7 — 在同一 DCV 主机上运行四个作业。

要控制每台计算机安排的会话数量,可以在 desktop.sbatch 脚本的顶部添加一个标志来指定所需的资源。如果每个会话需要 2 个 vCPU:

#SBATCH -n 2

要为每个用户提供自己的 GPU,只需指定:

#SBATCH –-gpus 1

要为每位用户提供一 台 整台机器 ,请指定独占标志:

#SBATCH --exclusive

停止会话

要在时间限制之前取消正在运行的会话,用户只需要找到作业 ID 并运行 slur m scancel 命令即可:

$ scancel [job-id]

您也可以在 亚马逊云科技 ParallelCluster 用户界面中通过单击 “ 停止任务 ” 按钮来完成此操作,如图 8 所示。

Figure 8 - Using the AWS ParallelCluster UI to stop a job, thus cancelling a DCV session.

图 8 — 使用 亚马逊云科技 ParallelCluster 用户界面停止任务,从而取消 DCV 会话。

结论

这篇博客文章向您展示了如何利用 亚马逊云科技 ParallelCluster 和 Slurm 调度程序为使用 NICE DCV 的用户创建按需图形会话。这可确保 DCV 会话在正确的硬件上运行,并且可以 根据用户需求向上 和向下 扩展。

这将使您能够节省成本,同时为用户的需求提供出色的性能。请通过 ask-hpc@amazon.com 联系我们,告诉我们你是如何使用它的。

Sean Smith

肖恩·史密斯

肖恩·史密斯是 亚马逊云科技 的 HPC 专家解决方案架构师。在此之前,肖恩曾在亚马逊云科技 Batch和CfnCluster上担任软件工程师,成为创建亚马逊云科技 ParallelCluster的团队中第一位工程师。


*前述特定亚马逊云科技生成式人工智能相关的服务仅在亚马逊云科技海外区域可用,亚马逊云科技中国仅为帮助您发展海外业务和/或了解行业前沿技术选择推荐该服务。