新型コロナウイルス感染症に罹患された皆さまおよび関係者の皆さまに、心よりお見舞い申し上げます。一日も早い収束と、皆さまのご健康を心からお祈り申し上げます。
さて、ご覧の皆様は、新型コロナウイルスを解析するプロジェクトがあるのをご存知でしょうか。
有名なところですと「Folding@Home」などがあります。
こちらのサイトからアプリケーションプログラムをダウンロードして、ちょこちょこっと設定を行うと、コンピュータの余剰リソースを利用して解析を実施してくれるのです!
というわけで、この Folding@Home による新型コロナウイルス解析プロジェクトへの参加環境を自動構築する CloudFormation テンプレートを作成しましたので共有します。
こんな方におすすめです
- COVID-19(SARS-CoV-2)の解析に貢献したい AWS を利用している方
- AWS のアカウント作成から1年以内で無料枠が残っている方!
- Reserved Instance の前払いを行っているが余剰リソースがある企業の皆様!!
- イベントなどで獲得した AWS クレジットが残っており、有効活用したい方!!!
このテンプレートを元に解析プロジェクトに貢献してみてはいかがでしょうか。
事前準備
アクセス元 IP アドレスの確認
自分のパソコンなどのみからのアクセスに絞るため、現在の自分の IP アドレスを確認します。
お手軽な方法は、 AWS マネージメントコンソールで セキュリティグループの作成画面を使うことです。
流れは以下の通りです。
- AWS マネージメントコンソールで EC2 の画面を表示する
- セキュリティグループの一覧を表示し、セキュリティグループの作成画面を呼び出す
- インバウンドルール、アウトバウンドルールどちらでもかまわないので送信元もしくは送信先のプルダウンから「マイ IP」を選択する。
- そうすると、自分の IP アドレスが表示されるので CIDR 表記(末尾の/32)を含めて コピーする。
キーペアがなければキーペアを作成
EC2 インスタンスを作成する際にキーペアが必要になります。未作成であれば、事前に作成します。
- AWS マネージメントコンソールで EC2 の画面を表示する
- キーペアの一覧を表示し、キーペアの作成画面を表示する
- 任意の名称をつけて、pem もしくは ppk タイプの鍵を生成します。
※本環境では SSM Agentによる操作を可能にするために EC2 インスタンスへ埋め込むのみで SSH 接続などには利用しません。
テンプレート
ちょっと長いので折りたたんでいます。
CloudFormation テンプレートを見る
---
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
AmaLin2ID:
Type: AWS::SSM::Parameter::Value<String>
Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2
InstanceType:
Type: String
Default: t2.micro
MyIP:
Type: String
Description: 'Your Public IP Address'
MinLength: 9
MaxLength: 18
AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
ConstraintDescription: "Must be a valid IP CIDR range of the form x.x.x.x/xx"
KeyPair:
Type: "AWS::EC2::KeyPair::KeyName"
CPUPower:
Type: String
Description: "CPU power settings"
Default: full
AllowedValues:
- full
- medium
- light
UserName:
Type: String
Description: "Folding@Home UserName"
Default: Anonymous
MinLength: 1
TeamId:
Type: String
Description: "Folding@Home TeamId. The ID '222' is team Japan."
Default: 222
Conditions:
isT2Micro: !Equals [!Ref InstanceType, "t2.micro"]
Resources:
# Network
VPC:
Type: "AWS::EC2::VPC"
Properties:
CidrBlock: 10.0.0.0/16
InstanceTenancy: default
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: vpc_kaiseki
SubnetA:
DependsOn: VPC
Type: "AWS::EC2::Subnet"
Properties:
CidrBlock: 10.0.0.0/24
AvailabilityZone: "ap-northeast-1a"
VpcId:
Ref: VPC
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: subnet_kaiseki_az-a
IGW:
Type: "AWS::EC2::InternetGateway"
Properties:
Tags:
- Key: Name
Value: igw_kaiseki
AttachIGW:
DependsOn: VPC
Type: "AWS::EC2::VPCGatewayAttachment"
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref IGW
RouteTable:
DependsOn: VPC
Type: "AWS::EC2::RouteTable"
Properties:
VpcId:
Ref: VPC
Tags:
- Key: Name
Value: rtb_kaiseki
AttachRouteTableA:
DependsOn: SubnetA
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
RouteTableId: !Ref RouteTable
SubnetId: !Ref SubnetA
AddRouteRtbIGW:
DependsOn: IGW
Type: "AWS::EC2::Route"
Properties:
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref IGW
RouteTableId: !Ref RouteTable
SecurityGroup:
Type: "AWS::EC2::SecurityGroup"
Properties:
GroupName: sg_kaiseki
GroupDescription: sg_kaiseki
VpcId: !Ref VPC
Tags:
- Key: Name
Value: sg_kaiseki
## Inbound Rule ########################################################
SecurityGroupIngress:
- CidrIp: !Sub ${MyIP}
IpProtocol: tcp
FromPort: 7396
ToPort: 7396
Description: "Folding@Home Web UI"
# IAM Role
IAMRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
-
Effect: "Allow"
Principal:
Service:
- "ec2.amazonaws.com"
Action:
- "sts:AssumeRole"
ManagedPolicyArns:
- "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
Path: "/"
RoleName: role-kaiseki-ssm
InstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Path: "/"
Roles:
- !Ref IAMRole
# EC2
Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref AmaLin2ID
InstanceType: !Ref InstanceType
KeyName: !Sub ${KeyPair}
IamInstanceProfile: !Ref InstanceProfile
InstanceInitiatedShutdownBehavior: stop
Monitoring: false
BlockDeviceMappings:
- DeviceName: /dev/xvda
Ebs:
VolumeSize: 30
VolumeType: gp2
NetworkInterfaces:
- DeviceIndex: 0
GroupSet:
- !Ref SecurityGroup
SubnetId: !Ref SubnetA
DeleteOnTermination: true
Tags:
- Key: Name
Value: ec2-kaiseki
UserData:
Fn::Base64: !Sub |
#!/bin/bash
# Configure Timezone
timedatectl set-timezone Asia/Tokyo
localectl set-locale LANG=ja_JP.UTF-8
# Install SSMAgent
yum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm
# Install fahclient
rpm -i --nodeps https://download.foldingathome.org/releases/public/release/fahclient/centos-6.7-64bit/v7.5/fahclient-7.5.1-1.x86_64.rpm
# backup fahclient
cp -p /etc/fahclient/config.xml /etc/fahclient/config.xml.org
sleep 5
# Stop fahclient
/etc/init.d/FAHClient stop
sed -i -e 's/light/${CPUPower}/g' /etc/fahclient/config.xml
sed -i -e 's/anonymous/${UserName}/g' /etc/fahclient/config.xml
sed -i -e '$d' /etc/fahclient/config.xml
echo " <team v='${TeamId}'/>">>/etc/fahclient/config.xml
echo " <allow>127.0.0.1 0.0.0.0/0</allow>">>/etc/fahclient/config.xml
echo " <web-allow>127.0.0.1 0.0.0.0/0</web-allow>">>/etc/fahclient/config.xml
echo "</config>">>/etc/fahclient/config.xml
# Start fahclient
/etc/init.d/FAHClient start
# Delete keys
shred -u /etc/ssh/*_key /etc/ssh/*_key.pub
sed -i -e '$!d' /home/ec2-user/.ssh/authorized_keys
sed -i -e '$!d' /root/.ssh/authorized_keys
AutoStartRole:
Type: "AWS::IAM::Role"
Condition: isT2Micro
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
-
Effect: "Allow"
Principal:
Service:
- "events.amazonaws.com"
- "ssm.amazonaws.com"
- "ec2.amazonaws.com"
Action:
- "sts:AssumeRole"
ManagedPolicyArns:
- "arn:aws:iam::aws:policy/service-role/AmazonSSMAutomationRole"
Path: "/"
RoleName: role-kaiseki-auto-start
AutoStartEC2Event:
Type: AWS::Events::Rule
Condition: isT2Micro
Properties:
EventPattern:
source:
- "aws.ec2"
detail-type:
- "EC2 Instance State-change Notification"
detail:
instance-id:
- !Ref Instance
state:
- "stopped"
State: "ENABLED"
Name: AutoStartEC2Event
RoleArn: !Sub "arn:aws:iam::${AWS::AccountId}:role/role-kaiseki-auto-start"
Targets:
- Id: AutoStartEC2EventTarget
Arn: !Sub "arn:aws:ssm:${AWS::Region}::automation-definition/AWS-StartEC2Instance:$DEFAULT"
RoleArn: !Sub "arn:aws:iam::${AWS::AccountId}:role/role-kaiseki-auto-start"
Input:
!Join
- ''
- - !Sub "{\"InstanceId\":[\""
- !Ref Instance
- !Sub "\"]}"
AutoStopEC2Event:
Type: AWS::CloudWatch::Alarm
Condition: isT2Micro
Properties:
AlarmName: AutoStopEC2Alarm
MetricName: CPUCreditBalance
Namespace: AWS/EC2
Statistic: Maximum
Period: 60
EvaluationPeriods: 1
Threshold: 1
ComparisonOperator: LessThanOrEqualToThreshold
Dimensions:
- Name: InstanceId
Value: !Ref Instance
AlarmActions:
- !Sub arn:aws:automate:${AWS::Region}:ec2:stop
EIP:
Type: AWS::EC2::EIP
Properties:
Domain: VPC
InstanceId: !Ref Instance
このテンプレートで作成されるもの
- VPC(10.0.0.0/16)
- Subnet(10.0.0.0/24, ap-northeast-1a)※いわゆるパブリックサブネット
- Internet Gateway
- RouteTable
- Internet Gateway に対するルートを設定
- セキュリティグループ
- インバウンドは Folding@Home の状況確認ができる画面に対するポート(7396)のみ。SSH などは未開封
- アウトバウンドは 0.0.0.0/0 のデフォルト設定
- IAMRole
- SSM Agent 経由で EC2 インスタンスに接続するための IAMRole
- EC2 インスタンス
- 最新の AmazonLinux2 AMI から起動し、 Folding@Home Client をインストールし初期セットアップ
- インスタンスタイプが 無料枠の対象である t2.micro の場合
- CPU クレジットが 0 になった際に EC2 インスタンスを停止する CloudWatch Alarm
- 停止した EC2 を起動する CloudWatch Events
- この CloudWatch Events を動かすための IAMRole
使い方
環境構築
CloudFormation テンプレートを使って CloudFormation スタックを作成します。
その際、以下のパラメータが指定可能ですので、適宜設定を行ってください。
- CPUPower
- CPU をどれだけ利用するかを指定できます、デフォルトでは full です。 middle, light も選択できます。
- InstanceType
- デフォルトでは無料枠対象の t2.micro としています。GPUインスタンスやコンピュート最適化インスタンスなどを指定すると良いでしょう。 t2.micro の場合は前述の通り CPU クレジットが 0 になると自動的に停止、起動するようになり、自動的に CPU クレジットを回復できるようになっています。
- KeyPair
- 作成済みのキーペアから使用するものを選択してください。
- MyIP
- 事前準備で確認した IP アドレスを 10.11.12.13/32 のような CIDR 表記で指定します。
- TeamId
- デフォルトではチーム名が Japan である 222 を設定しています。
- UserName
- デフォルトでは初期値である Anonymous(匿名の意) にしてあります。任意のユーザー名をご指定ください。
動作確認
EC2 のパブリックDNS(IPv4)の値を確認します。
起動した EC2 インスタンスを選択して、赤枠で囲んである箇所に表示されています。
確認したパブリックDNS名にポート番号7396を指定してWebブラウザからアクセスします。
例えば、パブリックDNS名が ec2-111-222-333-444.ap-northeast-1.compute.amazonaws.com であれば、以下のようになります。
http://ec2-111-222-333-444.ap-northeast-1.compute.amazonaws.com:7396/
※ありえない URL です。
インスタンスタイプが t2.micro であれば、起動から概ね30分~35分後に自動で停止して起動します。
注意点
vCPU 数が多すぎても動作に支障がでるようです。
検証した範囲では vCPU 数が16より多い(例えば g4dn.8xlarge のように vCPU 数が32個など)と解析がうまく動きませんでした。
同様に GPU についても、Tesla ドライバではうまく動かず、 GRID ドライバを利用する必要がありました。そのため、 g系インスタンスを使うか、p3インスタンスに GRID ドライバインスト済み AMI を導入する必要があります。。
※わたしの環境だけかもしれませんが、ご注意ください。
※本作例の CFn で利用している AMI では GPU ドライバ未適用ですので利用の際は適宜改造してください。
あなたがもし石油王であっても GPU インスタンスの一番強力なインスタンスを大量利用するのではなく、ほどほどのインスタンスを超大量に利用するのがよいでしょう。
成果
コンピューティング最適化インスタンス
インスタンスタイプ:c5n.4xlarge
vCPU数:16
メモリ:42GiB
動作期間:約3日程度
GPUインスタンス
インスタンスタイプ:g4dn.4xlarge
vCPU数:16
メモリ:64GiB
動作期間:約3時間程度
まとめ
この貢献により1日も早く新型コロナによる被害の鎮静化、特効薬の創出などに繋がることを祈念しております。
その他
スポットインスタンスを利用することで廉価に解析に貢献することも可能です!
参考資料
https://qiita.com/deflatSOCO/items/965208e74168f6e0d984
https://dev.classmethod.jp/articles/foldingathome_covid-19/
https://pc.watch.impress.co.jp/docs/news/1243458.html
https://ascii.jp/elem/000/004/008/4008887/