简介
ParallelCluster是由亚马逊云科技提供支持的开源集群管理工具,可以帮助客户快速创建并管理HPC集群。在一些场景下,客户会需要使用ParallelCluster部署多个Slurm集群,此外,还希望能做到集中管理多个集群的用户,并在多个集群间共享用户数据。
通过本文,您可以了解如何使用SimpleAD实现多个ParallelCluster集群的用户集中管理;并将共享存储Amazon Elastic File System (Amazon EFS) 作为用户的家目录,实现用户在多个集群间的数据共享。
Simple Active Directory (Simple AD)是亚马逊云科技提供的一个托管的目录服务,与Samba 4 目录服务兼容,并提供了不同规模的版本,满足不同用户的需求。Amazon EFS是亚马逊云科技提供的即用式无服务器弹性文件系统,它可以随着您添加和删除文件自动增大或收缩存储空间,无需管理或预置。
本文会包含个五个章节:环境要求,创建VPC、EFS及SimpleAD,创建ParallelCluster集群,集群用户管理,资源清理。
环境要求
在开始之前,我们首先需要了解下环境要求,避免出现意外的错误。
版本
- 本文在Ubuntu 20.04进行了测试,并建议您也使用此OS版本 。
- 本文撰写时,ParallelCluster的版本号为2.11.1,如果您的版本不同,请以官网文档给出的配置方法为准。
Amazon VPC
- Amazon VPC 需要包含至少1个公有
- 子网、2个分处不同可用区(Availability Zone, AZ)的私有子网;
- 公有子网放置ParallelCluster的Head节点,或者说是Slurm集群的登录(Login)节点;
- 其中一个私有子网与公有子网同处一个AZ,并放置Compute节点,以减少跨AZ数据传输带来的流量费。
- 私有子网,需要确保存在NAT 网关,以满足ParallelCluster访问外网的需求。否则,会导致集群创建失败。
- NAT网关需要放在公有子网。
- 启用DNS 主机名
- 启用DNS 解析
Amazon EFS文件系统
- 建议手动创建EFS,防止集群终止的时候,文件系统被一起删除。
- Simple AD会使用两个AZ的子网,需要保证EFS在这两个AZ都有挂载点(Mount Target)。
- EFS绑定的安全组需要允许Head及Compute节点访问。没有特殊要求的话,可以将安全组的source指定为 VPC CDIR。Region(区域)
- 确保以下服务/资源都是在同一个Region创建
准备工作
在部署ParallelCluster集群之前,我们需要先创建VPC网络、EFS及Simple AD等基础依赖项。
创建VPC
如果已有VPC,请按照 环境要求章节检查是否满足要求。如果没有VPC,可以使用[1]中的链接,通过CloudFormation服务,快速创建包含公有子网和 私有子网及对应NAT网关的VPC。
创建EFS
我们建议您手动创建EFS,在VPC中所有的AZ中都创建挂载点。防止集群终止的时候,文件系统被一起删除。
您也可以选择让ParallelCluster帮您自动完成EFS文件系统的创建,但您需要手动在其他AZ添加挂载点。
注意,EFS挂载点上绑定的安全组需要允许Head及Compute节点访问。
创建Simple AD
Simple AD的默认管理员是Administrator,以下参数请根据您的实际需要调整。
Directory DNS name: awsabc.cn
Directory NetBIOS name: TEST
Administrator password: <Your DOMAIN password>
第三步中的VPC选择之前创建的VPC,并选择两个私有子网,注意,其中一个子网的AZ需要和Head节点的相同。
等待约10分钟,完成创建,信息如下:
更新VPC DHCP选项集
这里,我们使用Simple AD管理DNS解析,因此需要使用自定义的VPC的DHCP选项集(DHCP Options Set)。
获取Simple AD的信息
从Simple AD的截图获取如下信息:
- DNS地址:10.45.230,10.0.0.4
- Domain Name:awsabc.cn ap-southeast-1.internal
注意:ap-southeast-1需要和您选择的Region一致。
创建DHCP选项集
在VPC控制台,点击创建DHCP选项集。
填入如下信息:
- 名称(可选):pcluster-u20-simplead
- 域名:awsabc.cn ap-southeast-1.internal
- 域名服务器:0.0.4,10.0.45.230
这里,需要注意域名服务器的IP顺序,请将与您Head节点或者Compute节点同一个CIDR的IP放在第一个。
DHCP选项集创建完成:
绑定DHCP选项集到VPC
创建ParallelCluster集群
自定义AMI
可以将必要的软件包提前打包到AMI里,减少Compute节点的初始化时间。打包方式参考官方doc[2] 。以下步骤,使用的是新加坡区域(ap-southeast-1),ParallelCluster 版本号为 2.11.1 ,OS及版本为Ubuntu 20.04 的。注意,pcluster每个版本的base image不同。您需要根据当前所用的pcluster版本,选择对应的base image。
ParallelCluster版本的查看命令是 pcluster version,输出为2.11.1(以实际输出为准)。
在官方AMI的基础上,构建定制化AMI的步骤如下:
- 从https://github.com/aws/aws-parallelcluster/blob/v2.11.1/amis.txt 找到base image,如ubuntu 20.04 为 ap-southeast-1: ami-0b0a1c6100fd9218d 。
- 根据此AMI启动机器,
- 安装自己的环境,
- 执行 sudo /usr/local/sbin/ami_cleanup.sh ,
- 关机,
- 创建AMI并得到新的AMI ID。
初始化ParallelCluster配置文件
建议您把ParallelCluster的Head节点放在公有子网,这样您就可以通过公网的方式直接访问Head节点。
同时,建议您选择与公有子网相同AZ的私有子网启动Compute节点,可以保证Head节点与Compute节点之间的延迟最小,且避免产生跨AZ的流量费。
export AWS_PROFILE=defalut
pcluster configure -c ~/.parallelcluster/config.sin.efs.u20
Allowed values for AWS Region ID:
1. ap-east-1
2. ap-northeast-1
3. ap-northeast-2
4. ap-south-1
5. ap-southeast-1
…
AWS Region ID [eu-central-1]: 5
Allowed values for EC2 Key Pair Name:
1. new-sing
2. …
EC2 Key Pair Name [new-sing]: 1
Allowed values for Scheduler:
1. sge
2. torque
3. slurm
4. awsbatch
Scheduler [slurm]: 3
Allowed values for Operating System:
1. alinux2
2. centos7
3. centos8
4. ubuntu1804
5. ubuntu2004
Operating System [alinux2]: 5
Minimum cluster size (instances) [0]: <ENTER>
Maximum cluster size (instances) [10]: <ENTER>
Head node instance type [t2.micro]: t3.large
Compute instance type [t2.micro]: c5.large
Automate VPC creation? (y/n) [n]: n
Allowed values for VPC ID:
# id name number_of_subnets
--- --------- --------------------------------- -------------------
3 vpc-xx ParallelClusterVPC-20210824092800 3
VPC ID [vpc-00cf21c92c6158040]: 3
Automate Subnet creation? (y/n) [y]: n
Allowed values for head node Subnet ID:
# id name size availability_zone
--- ------------------------ ------------------------------- ------ -------------------
1 subnet-08b5a8997039c523c ParallelClusterPublicSubnet 256 ap-southeast-1c
2 subnet-06a806ca4e7635b2a ParallelClusterPrivateSubnet-1c 4096 ap-southeast-1c
3 subnet-0bcaaff0386296d48 ParallelClusterPrivateSubnet-1b 4096 ap-southeast-1b
head node Subnet ID [subnet-08b5a8997039c523c]: 1
Allowed values for compute Subnet ID:
# id name size availability_zone
--- ------------------------ ------------------------------- ------ -------------------
1 subnet-08b5a8997039c523c ParallelClusterPublicSubnet 256 ap-southeast-1c
2 subnet-06a806ca4e7635b2a ParallelClusterPrivateSubnet-1c 4096 ap-southeast-1c
3 subnet-0bcaaff0386296d48 ParallelClusterPrivateSubnet-1b 4096 ap-southeast-1b
compute Subnet ID [subnet-06a806ca4e7635b2a]: 2
Configuration file written to /Users/binc/.parallelcluster/config.sin.u20
编辑PCluster配置文件
增加修改集群配置,使用Spot实例,增加pre/post install 脚本,
注意,请根据您的情况,调整文件内容。
cat ~/.parallelcluster/config.sin.efs.u20
[aws]
aws_region_name = ap-southeast-1
[aliases]
ssh = ssh {CFN_USER}@{MASTER_IP} {ARGS}
[global]
cluster_template = default
update_check = true
sanity_check = true
[cluster default]
key_name = <YOUR-KEY-PAIR>
scheduler = slurm
master_instance_type = t3.large
base_os = ubuntu2004
vpc_settings = default
queue_settings = spot
s3_read_resource = arn:aws:s3:::<YOUR-BUCKET>/*
pre_install = s3://<YOUR-BUCKET>/pcluster/scripts/ad/pre_install.sh
post_install = s3:// <YOUR-BUCKET>/pcluster/scripts/ad/post_install.sh
additional_iam_policies=arn:aws:iam::aws:policy/AmazonSSMDirectoryServiceAccess,arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore,arn:aws:iam::aws:policy/AWSLambda_FullAccess
efs_settings = customfs
[vpc default]
vpc_id = <YOUR-VPC-ID>
master_subnet_id = <YOUR-HEAD-SUBNET-ID>
compute_subnet_id = <YOUR_COMPUTE-SUBNET-ID>
[queue spot]
enable_efa = false
enable_efa_gdr = false
compute_resource_settings = default
compute_type=spot
[compute_resource default]
instance_type = c5.large
min_count = 0
max_count=300
[efs customfs]
shared_dir = efs
efs_fs_id = <YOUR-EFS-ID>
pre_install.sh
#!/bin/bash
set -x
exec > >(tee /var/log/pre-install.log|logger -t user-data -s 2>/dev/console) 2>&1
if ! command -v realm &> /dev/null
then
echo "<realm> could not be found, run install..."
# Install the required packages
export DEBIAN_FRONTEND=noninteractive
apt update && apt -y install sssd realmd krb5-user samba-common packagekit adcli sssd-tools
fi
instance_id=$(curl http://169.254.169.254/latest/meta-data/instance-id)
region=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone | sed 's/[a-z]$//')
# Lambda function to join the linux system in the domain
aws --region ${region} lambda invoke --function-name join-domain-function /tmp/out --payload '{"instance": "'${instance_id}'"}' --log-type None
output=""
while [ -z "$output" ]
do
sleep 5
output=$(realm list)
done
#This line allows the users to login without the domain name
sed -i 's/use_fully_qualified_names = True/use_fully_qualified_names = False/g' /etc/sssd/sssd.conf
#This line configure sssd to create the home directories in the shared folder
sed -i '/fallback_homedir/c\fallback_homedir = /efs/home/%u' /etc/sssd/sssd.conf
sleep 1
service sssd restart
# This line is required for AWS Parallel Cluster to understand correctly the custom domain
sed -i "s/--fail \${local_hostname_url}/--fail \${local_hostname_url} | awk '{print \$1}'/g" /opt/parallelcluster/scripts/compute_ready
echo "####pre install finished####"
post_install.sh
#!/bin/bash
set -x
exec > >(tee /var/log/post-install.log|logger -t user-data -s 2>/dev/console) 2>&1
if ! [ -d /efs/home ]; then
mkdir /efs/home
fi
sed -i 's/PasswordAuthentication no//g' /etc/ssh/sshd_config
echo "PasswordAuthentication yes" >> /etc/ssh/sshd_config
sleep 1
service sshd restart
echo "####post install finished####"
创建Lambda函数
此函数可以实现将head和compute节点加入到domain中。
环境
Lambda 控制台,点创建函数。
- Function name:join-domain-function
- Runtime:python 3.6
函数代码
填入如下代码(注意修改区域、用户名和密码),然后点击 部署(Deploy)。
import json
import boto3
import time
def lambda_handler(event, context):
json_message = json.dumps(event)
message = json.loads(json_message)
instance_id = message['instance']
ssm_client = boto3.client('ssm', region_name="ap-southeast-1") # 修改region_name为您所选区域
DomainName_value = "awsabc.cn" # 修改为您的域名
DomainPassword_value = "Yourpassword1234" # 修改为您的密码
response = ssm_client.send_command(
InstanceIds=[
"%s"%instance_id
],
DocumentName="AWS-RunShellScript",
Parameters={
'commands':[
'echo "%s" | realm join -U Administrator %s --verbose;rm -rf /var/lib/amazon/ssm/i-*/document/orchestration/*'%(DomainPassword_value, DomainName_value) ]
},
)
return {
'statusCode': 200,
'body': json.dumps('Command Executed!')
}
函数权限
点击角色名称,
点击附加策略,
筛选 AmazonSSMFullAccess ,勾选 AmazonSSMFullAccess,点击附加策略。
执行集群创建命令
pcluster create -nr -c ~/.parallelcluster/config.sin.efs.u20 u20-cluster
-nr参数,表示如果出现错误,不回滚CloudFormation,方便在集群创建出现问题的时候进行调试。
在确认集群功能正常之后,您可以采用同样的命令,快速创建出更多的集群。
测试集群功能
集群加入Domain成功
可以通过realm list命令查看状态。
root@ip-10-0-0-123:~# realm list
awsabc.cn
type: kerberos
realm-name: AWSABC.CN
domain-name: awsabc.cn
configured: kerberos-member
server-software: active-directory
client-software: sssd
required-package: sssd-tools
required-package: sssd
required-package: libnss-sss
required-package: libpam-sss
required-package: adcli
required-package: samba-common-bin
login-formats: %U
login-policy: allow-realm-logins
远程登录Head节点
通过 pcluster status -c ~/.parallelcluster/config.sin.u20 u20-cluster 命令,获取到公网IP。
binc@12345678b1fb ~ % pcluster status -c ~/.parallelcluster/config.sin.u20 u20-cluster
Status: CREATE_COMPLETE
MasterServer: RUNNING
MasterPublicIP: 13.214.17.226
ClusterUser: ubuntu
MasterPrivateIP: 10.0.0.123
ComputeFleetStatus: RUNNING
binc@12345678b1fb ~ % ssh awsabc.cn\\Administrator@13.214.17.226
awsabc.cn\Administrator@13.214.17.226's password:
Welcome to Ubuntu 20.04.2 LTS (GNU/Linux 5.8.0-1041-aws x86_64)
...
administrator@ip-10-0-0-123:/$ sinfo
PARTITION AVAIL TIMELIMIT NODES STATE NODELIST
spot* up infinite 300 idle~ spot-dy-c5large-[1-300]
提交作业
从命令的执行情况,我们可以看到:
- 使用pre_install script安装AD 相关软件包相对比较费时间,约为5分钟才能完成机器的初始化。这里,可以通过预先打包依赖软件的方式减少初始化时间;
- 作业是以当前登录用户提交到Slurm中。
集群用户管理
您可以使用亚马逊云科技建议的方法[3]来管理您的用户和组,也可以使用如下方法。
Kerberos登录
查看本地ticket
列出当前域中所有用户
net ads user -S awsabc.cn
添加用户
使用net命令:
net ads user ADD johndoe Password123! -C "John Doe" -S awsabc.cn
搜索用户
net ads search '(objectCategory=user)' -S awsabc.cn
设置密码并启用用户
新添加的用户默认处于禁用状态,此时userAccountControl的值为514,我们需要给用户设置登录密码,并调整 userAccountControl为512,以启用此用户。
修改过程如下:
首先,创建一个ldif文件,包含需要新增或修改的属性:
sudo vi uac.ldif
dn: CN=johndoe,CN=Users,DC=awsabc,DC=cn
changetype: modify
replace: userAccountControl
userAccountControl: 512
-
replace: userPassword
userPassword: yourPassword
其次,执行如下命令,完成userAccountControl以及userPassword的修改:
ldapmodify -h awsabc.cn -p 389 -D cn=Administrator,cn=Users,dc=awsabc,dc=cn -w YourAdminPassword -f uac.ldif
设置用户家目录
首先,我们创建一个ldif文件,包含增加homeDirectory属性的命令:
sudo vi uac-home.ldif
dn: CN=johndoe,CN=Users,DC=awsabc,DC=cn
changetype: modify
add: homeDirectory
homeDirectory: /efs/home/johndoe
其次,执行如下命令,完成homeDirectory属性的变更:
ldapmodify -h awsabc.cn -p 389 -D cn=Administrator,cn=Users,dc=awsabc,dc=cn -w YourAdminPassword -f uac-home.ldif
最后,我们通过如下命令,在homeDirectory指定的路径,创建文件夹。
sudo mkhomedir_helper johndoe@awsabc.cn
确认家目录正常
如上图所示,我们通过执行pwd、mount及id命令,确认用户家目录使用的是EFS。
完整命令
这里,我们通过Shell脚本,快速完成用户的增加及初始化工作。内容如下:
#!/bin/bash
set -x
if [ "$EUID" -ne 0 ]; then
echo "Please run as root"
exit
fi
if [ "$#" -lt 2 ]; then
echo "usage: $0 <username> <password> <display name>"
exit
fi
DCs=""
DNSDN=`dnsdomainname`
function parse_domain_name {
DCs=""
IFS=.
for item in $DNSDN;
do
DCs="${DCs},DC=${item}"
done
}
parse_domain_name
read -s adminPsw
echo "${adminPsw}" | kinit Administrator
net ads user ADD "$1" "$2" -C "$1" -S "$DNSDN"
cat <<EOF > /tmp/uac.ldif
dn: CN=$1,CN=Users${DCs}
changetype: modify
replace: userAccountControl
userAccountControl: 512
-
replace: userPassword
userPassword: $2
-
add: homeDirectory
homeDirectory: /efs/home/$1
EOF
ldapmodify -h "$DNSDN" -p 389 -D cn=Administrator,cn=Users"${DCs}" -w Mypassword1234 -f /tmp/uac.ldif
sleep 2
mkhomedir_helper $1@${DCs}
清理资源(可选)
您可以清理ParallelCluster集群、EFS及Simple AD,以防止产生额外费用。
清理ParallelCluster
pcluster delete -c ~/.parallelcluster/config.sin.u20 <cluster name>
清理EFS及Simple AD
对于EFS及Simple AD来说,您可以到对应的控制台,执行删除操作。
FAQ & 问题排查
DNS是如何管理的?
ParallelCluster会自动创建一个私有的Route53 托管域,在修改完VPC的DHCP选项集之后, Simple AD会自动将DNS请求转发给Amazon为您VPC提供的DNS服务器,这些服务器会解析私有Route53 托管域中的域名,详细见文档[4]。
如果堆栈创建失败怎么办?
可以通过EC2控制台或者Terminal,登陆到Head 节点,查看/var/log/中的log文件。
我们在pre/post install script中,插入了存档log的逻辑,对应pre-install.log 及 post-install.log,如:
exec > >(tee /var/log/post-install.log|logger -t user-data -s 2>/dev/console) 2>&1
cfn-init.log
查看当前CloudFormation执行到了哪一步,据此,分析应该查看的log文件。如:
2021-08-25 12:33:08,155 [INFO] Running config shellRunPreInstall
2021-08-25 12:33:08,155 [DEBUG] No packages specified
2021-08-25 12:33:08,155 [DEBUG] No groups specified
2021-08-25 12:33:08,155 [DEBUG] No users specified
2021-08-25 12:33:08,155 [DEBUG] No sources specified
2021-08-25 12:33:08,155 [DEBUG] No files specified
2021-08-25 12:33:08,156 [DEBUG] Running command runpreinstall
2021-08-25 12:33:08,156 [DEBUG] No test for command runpreinstall
2021-08-25 12:36:20,474 [INFO] Command runpreinstall succeeded
pre-install.log
如果已经进入到pre install阶段,可以查看此log,排查script执行情况。
post-install.log
如果已经进入post install 阶段,可以查看此log,排查script执行情况。
cloud-init-output.log
cloud-init-output日志文件 (/var/log/cloud-init-output.log) 会捕获控制台的输出,因此如果实例未按您预期的方式运行,则可以在实例启动后调试脚本。
EFS挂载失败
在/var/log/chef-client.log文件中,可以观察到类似 STDERR: mount.nfs4: Failed to resolve server fs-a100bfe1.efs.ap-southeast-1.amazonaws.com: No address associated with hostname的记录,表示EFS DNS解析失败了。
您可以排查下DHCP选项集中,DNS 服务器的IP顺序是否正确。可以尝试在Head节点中,依次执行nslookup来判断。如:
ubuntu@ip-10-0-0-210:~$ nslookup fs-bc45c1fc.efs.ap-southeast-1.amazonaws.com 10.0.45.230
Server: 10.0.45.230
Address: 10.0.45.230#53
Non-authoritative answer:
*** Can't find fs-bc45c1fc.efs.ap-southeast-1.amazonaws.com: No answer
ubuntu@ip-10-0-0-210:~$ nslookup fs-bc45c1fc.efs.ap-southeast-1.amazonaws.com 10.0.0.4
Server: 10.0.0.4
Address: 10.0.0.4#53
Non-authoritative answer:
Name: fs-bc45c1fc.efs.ap-southeast-1.amazonaws.com
Address: 10.0.0.106
可以看到第一个DNS IP未成功返回查询结果,第二个IP正常。则,您应把第二个IP放在DHCP选项集的首位。
或者,(不推荐,可能导致跨区域流量费)您也可以在Simple AD所使用的另一个AZ,为EFS创建挂载点:
aws efs create-mount-target --file-system-id fs-xxx--subnet-id subnet-xxx --region ap-southeast-1
然后,等待约5分钟,重新执行DNS查询。
[1] VPC快速创建模板 https://raw.githubusercontent.com/awslabs/aws-cloudformation-templates/master/aws/services/VPC/VPC_With_Managed_NAT_And_Private_Subnet.yaml
[2] Parallel Cluster 创建自定义AMI https://docs.thinkwithwp.com/parallelcluster/latest/ug/tutorials_02_ami_customization.html#modify-an-aws-parallelcluster-ami
[3] 管理 Simple AD用户和组https://docs.thinkwithwp.com/directoryservice/latest/admin-guide/simple_ad_manage_users_groups.html
[4] 配置Simple AD DNS https://docs.thinkwithwp.com/directoryservice/latest/admin-guide/simple_ad_dns.html
本篇作者