みなさんこんにちは。早いもので今年ももう終わりです。この1年間、有意義に過ごすことができたでしょうか? 私は先日発売されたRyzen 3950Xを入手してホクホクです。今回からは心機一転、Ryzenマシン上に環境構築をして記事を書いていきます。
TEXT_痴山紘史 / Hiroshi Chiyama(日本CGサービス)
EDIT_尾形美幸 / Miyuki Ogata(CGWORLD)
ローカル環境とクラウド環境で連携して処理を行う
前回まででHTCondor Annexを使用したクラウド環境の構築、AWSのS3を使用したファイルサーバの構築、そしてAWS SFTPサーバを使用したファイルの転送という、クラウド上で処理を行うために必要な3つの環境構築が一通りできました。今回は、この環境とローカル環境を連携させて各種ジョブを実行できるようにしていきます。
社内インフラとクラウド環境を連携させて使用するためには、社内のデータのクラウド上へのアップロードと、クラウド上で作成されたデータのダウンロードが必要となります。まずはここを考えてみます。
よくある要望として、社内のファイルサーバとクラウド上のサーバとが自動的に同期をとり、常に両方の環境に最新のデータが全て用意されるようにしてほしいというものがあります。これは、プロダクションでクラウド環境をつくる場合に、まずまちがいなく上がってくる要望です。ユーザーからすれば、最近は計算機もネットワークも速いし、それくらいチョチョイッとできるでしょ? という感じの軽い気持ちでの要望だったりするのですが、まずまちがいなくまともに実現できないと考えた方がよいです。以前、実証実験を行なった際には3TBのデータを転送するために約1週間を要し、その上システムに負荷がかかることでほかの問題を引き起こし、通常業務にも少なからぬ影響をおよぼすことになりました(※)。
※ 平成25年度 我が国経済社会の情報化・サービス化に係る基盤整備 (CG・VFX産業クラウド活用・高連携実証事業)P. 38
www.dcaj.or.jp/project/report/pdf/2013/dc_13_01.pdf
これでは気軽にクラウド環境を使うのは難しいです。そこで最近のクラウドレンダリングサービスでは、レンダリングジョブを投げるためのツールを用意し、その中でシーンで使用しているファイルを自動的に集めて転送する機能が用意されています。この方法はとてもお手軽で、個人で使用するには効果的です。
本連載ではもう一歩進んで、チームの誰かが一度でもファイルをアップロードしたら、ほかのメンバーはアップロード済みのデータを流用できるようなしくみをつくっていきます。
しくみをつくるためには、いくつかルールを決める必要があります。今回は、あまり開発に負荷をかけずに実現できる方法を探っていきます。
構築したシステムの微調整
本題に入る前に、記事を書き進める中で、これまで構築した環境にいくつか問題が見つかったので、微調整します。
・s3fsのマウント方法修正
s3fsは、Roleの指定方法によっては/etc/fstabにマウントポイントを記述する方法では正常にマウントができないようです。その場合、/etc/rc.localでマウントします。また、このときにhtcondorプロセスを実行しているのと同じuid, gid(condor, condor)でマウントしておきます。
[ec2-user@ip-172-31-89-155 condor]$ cat /etc/rc.local
#!/bin/bash
# THIS FILE IS ADDED FOR COMPATIBILITY PURPOSES
#
# It is highly advisable to create own systemd services or udev rules
# to run scripts during boot instead of using this file.
#
# In contrast to previous versions due to parallel execution during boot
# this script will NOT be run after all other services.
#
# Please note that you must run 'chmod +x /etc/rc.d/rc.local' to ensure
# that this script will be executed during boot.
touch /var/lock/subsys/local
/usr/bin/s3fs condorannexdata /gs -o passwd_file=/etc/passwd-s3fs,rw,allow_other,uid=996,gid=993
[ec2-user@ip-172-31-89-155 condor]$
この場合、コメントに書かれているようにchmod +x /etc/rc.d/rc.localを実行することを忘れないようにします。
・condor_annexのオプション調整
condor_annexで起動したインスタンスで実行できるジョブは、ユーザー名によって制限をかけることができます。複数人でクラウド環境を使用する場合に必要な機能ですが、現時点ではユーザー管理関連の設定を省略してしまっている関係で都合が悪いので調整が必要です。今回はcondor_annexに-no-ownerオプションをつけることで制限を撤廃しました。
・計算ノードで実行するプロセスのオーナーを変更
ユーザー情報がきちんと管理されていれば、計算ノード上で実行するプロセスはジョブのオーナーと同じアカウントで実行されます。しかし、今のところわれわれはユーザー情報の管理を行なっていないため、condor_annexのデフォルトで指定されている、slot1~slot32というユーザーで各スロットのジョブが実行されてしまいます。これはアクセス権の問題などで困ったことになってしまうため、ジョブも全てcondorアカウントで実行するようにします。
そのために、セントラルマネージャで用意している計算ノード用の設定を追加します。
-bash-4.1$ cat condor-8.8.5/etc/condor.aws/01slot-users.config
SLOT1_USER = condor
SLOT2_USER = condor
SLOT3_USER = condor
SLOT4_USER = condor
SLOT5_USER = condor
SLOT6_USER = condor
SLOT7_USER = condor
SLOT8_USER = condor
SLOT9_USER = condor
SLOT10_USER = condor
SLOT11_USER = condor
SLOT12_USER = condor
SLOT13_USER = condor
SLOT14_USER = condor
SLOT15_USER = condor
SLOT16_USER = condor
SLOT17_USER = condor
SLOT18_USER = condor
SLOT19_USER = condor
SLOT20_USER = condor
SLOT21_USER = condor
SLOT22_USER = condor
SLOT23_USER = condor
SLOT24_USER = condor
SLOT25_USER = condor
SLOT26_USER = condor
SLOT27_USER = condor
SLOT28_USER = condor
SLOT29_USER = condor
SLOT30_USER = condor
SLOT31_USER = condor
SLOT32_USER = condor
STARTER_ALLOW_RUNAS_OWNER = TRUE
DEDICATED_EXECUTE_ACCOUNT_REGEXP = slot[0-9]+
-bash-4.1$
以上三点を修正します。
ファイル管理ルールを決める
ローカルとクラウドのディレクトリ構成を決めます。
ローカルの作業環境とAWS上のインスタンスの両方に/gsディレクトリを用意します。ローカル環境の場合は/gsはローカルのファイルサーバを参照し、インスタンスではS3上のデータをs3fsでマウントします。
また、ローカル環境ではS3上のデータをs3fsで/s3fsディレクトリにマウントします。
環境構築
環境構築は、これまでやってきた方法を組み合わせるだけで実現できます。PublicなIPアドレスをもった環境にセントラルマネージャを置き、クラウド上の計算ノードとローカルの計算ノードの両方を参加させます。以下では、AWS上の計算ノードが2つ、ローカルの計算ノードが1つ、同じプール上に登録されています。
ローカル環境では、前述の通り/gsと/s3fsを用意します。
[neo@matrix ~]$ ls /gs
[neo@matrix ~]$ ls /s3fs
foobar Kitchen_set test2 test3 WinSCP
[neo@matrix ~]$ mount
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
(中略)
s3fs on /s3fs type fuse.s3fs (rw,relatime,user_id=0,group_id=0,allow_other)
[neo@matrix ~]$
AWS上のインスタンスでは/gsのみを用意します。
[ec2-user@ip-172-31-86-188 ~]$ ls /gs
foobar Kitchen_set test2 test3 WinSCP
[ec2-user@ip-172-31-86-188 ~]$ mount
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
(中略)
s3fs on /gs type fuse.s3fs (rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other)
[ec2-user@ip-172-31-86-188 ~]$
[[SplitPage]]
aws cliのセットアップ
前回、AWS Transfer for SFTPを使用してファイルを転送するしくみをつくりました。単に手動でファイルをアップロードするだけならこれでも十分なのですが、自動化しようとすると色々と問題があったのでaws cliを使用することにします。
aws cliをインストールします。aws cliはpythonのpipでインストールできます。
[neo@matrix Downloads]$ pip install awscli --upgrade --user
DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won't be maintained after that date. A future version of pip will drop support for Python 2.7. More details about Python 2 support in pip, can be found at https://pip.pypa.io/en/latest/dev
インストールが終わったら、パスを通します。
[neo@matrix Downloads]$ export PATH=~/.local/bin:$PATH
aws cliのインストールができたので、Access Keyの設定を行います。
[neo@matrix Downloads]$ aws configure
AWS Access Key ID [None]: (AWS Access Key)
AWS Secret Access Key [None]: (AWS Secret Access Key)
Default region name [None]: us-east-1
Default output format [None]: json
[neo@matrix Downloads]$
これで準備が完了です。早速試してみましょう。
[neo@matrix cloudTest]$ mkdir -p /s3fs/work/neo/cloudTest
[neo@matrix cloudTest]$ aws s3 sync render s3://condorannexdata/work/neo/cloudTest/render
upload: render/layout_Arnold.0000.exr to s3://condorannexdata/work/neo/cloudTest/render/layout_Arnold.0000.exr
upload: render/layout_Arnold.0001.exr to s3://condorannexdata/work/neo/cloudTest/render/layout_Arnold.0001.exr
upload: render/layout_Arnold.0002.exr to s3://condorannexdata/work/neo/cloudTest/render/layout_Arnold.0002.exr
upload: render/layout_Arnold.0003.exr to s3://condorannexdata/work/neo/cloudTest/render/layout_Arnold.0003.exr
upload: render/layout_Arnold.0004.exr to s3://condorannexdata/work/neo/cloudTest/render/layout_Arnold.0004.exr
upload: render/layout_Arnold.0006.exr to s3://condorannexdata/work/neo/cloudTest/render/layout_Arnold.0006.exr
upload: render/layout_Arnold.0005.exr to s3://condorannexdata/work/neo/cloudTest/render/layout_Arnold.0005.exr
upload: render/layout_Arnold.0007.exr to s3://condorannexdata/work/neo/cloudTest/render/layout_Arnold.0007.exr
upload: render/layout_Arnold.0009.exr to s3://condorannexdata/work/neo/cloudTest/render/layout_Arnold.0009.exr
upload: render/layout_Arnold.0008.exr to s3://condorannexdata/work/neo/cloudTest/render/layout_Arnold.0008.exr
[neo@matrix cloudTest]$ ls -la /s3fs/work/neo/cloudTest/render
total 249041
drwxrwxrwx 1 neo neo 0 Jan 1 1970 .
drwxrwxrwx 1 neo neo 0 Dec 24 15:32 ..
-rw-r----- 1 neo neo 25496058 Dec 24 23:03 layout_Arnold.0000.exr
-rw-r----- 1 neo neo 25504371 Dec 24 23:04 layout_Arnold.0001.exr
-rw-r----- 1 neo neo 25505110 Dec 24 23:04 layout_Arnold.0002.exr
-rw-r----- 1 neo neo 25499350 Dec 24 23:04 layout_Arnold.0003.exr
-rw-r----- 1 neo neo 25494908 Dec 24 23:04 layout_Arnold.0004.exr
-rw-r----- 1 neo neo 25502157 Dec 24 23:04 layout_Arnold.0005.exr
-rw-r----- 1 neo neo 25496158 Dec 24 23:04 layout_Arnold.0006.exr
-rw-r----- 1 neo neo 25501568 Dec 24 23:04 layout_Arnold.0007.exr
-rw-r----- 1 neo neo 25503468 Dec 24 23:04 layout_Arnold.0008.exr
-rw-r----- 1 neo neo 25511207 Dec 24 23:04 layout_Arnold.0009.exr
[neo@matrix cloudTest]$
正常に転送できました。
ファイルアップロード
続いて、ファイルのアップロードをHTCondorに行わせてみましょう。
[neo@matrix cloudTest]$ cat sendFile.sh
#!/bin/sh
export PATH=/home/neo/.local/bin:$PATH
mkdir -p /s3fs/work/neo/cloudTest/log
aws s3 sync render s3://condorannexdata/work/neo/cloudTest/render
[neo@matrix cloudTest]$
HTCondorの.sdfファイルも作成します。
[neo@matrix cloudTest]$ cat sendFile.sdf
executable = /bin/sh
output = /gs/work/neo/cloudTest/log/send_file.out
error = /gs/work/neo/cloudTest/log/send_file.err
log = /gs/work/neo/cloudTest/log/send_file.log
arguments = sendFile.sh
initialdir = /gs/work/neo/cloudTest
requirements = TARGET.OpSys == "LINUX" && TARGET.FileSystemDomain == "intra.jcgs.co.jp" && TARGET.UidDomain == "intra.jcgs.co.jp"
should_transfer_files = no
queue
[neo@matrix cloudTest]$
ジョブを投入します。
[neo@matrix cloudTest]$ condor_submit sendFile.sdf
Submitting job(s).
1 job(s) submitted to cluster 39.
[neo@matrix cloudTest]$
ジョブが完了したら、実行結果を確認します。
[neo@matrix cloudTest]$ ls /s3fs/work/neo/cloudTest/render
layout_Arnold.0000.exr layout_Arnold.0002.exr layout_Arnold.0004.exr layout_Arnold.0006.exr layout_Arnold.0008.exr
layout_Arnold.0001.exr layout_Arnold.0003.exr layout_Arnold.0005.exr layout_Arnold.0007.exr layout_Arnold.0009.exr
[neo@matrix cloudTest]$
計算ノード側からも確認します。
[ec2-user@ip-172-31-95-187 cloudTest]$ ls /gs/work/neo/cloudTest/render
layout_Arnold.0000.exr layout_Arnold.0003.exr layout_Arnold.0006.exr layout_Arnold.0009.exr
layout_Arnold.0001.exr layout_Arnold.0004.exr layout_Arnold.0007.exr
layout_Arnold.0002.exr layout_Arnold.0005.exr layout_Arnold.0008.exr
[ec2-user@ip-172-31-95-187 cloudTest]$
無事に転送されています。
[[SplitPage]]クラウド上での処理
続いて、転送したファイルを使用してクラウド上で処理をするためのジョブを作成します。今回は、転送したexrファイルを別名ファイルとしてコピーします。まず、変換用のPythonスクリプトを用意します。
[neo@matrix cloudTest]$ cat rename.py
#!/usr/bin/python
import os
import shutil
if not os.path.exists('renamed'):
os.mkdir('renamed')
for f in os.listdir('render'):
new_name = f.replace('layout_Arnold', 'renamed')
src = os.path.join('render', f)
dst = os.path.join('renamed', new_name)
shutil.copyfile(src, dst)
[neo@matrix cloudTest]$
rename.pyをクラウド側にアップロードする必要があるので、sendFile.shに追記します。rename.pyはそれほど大きくないので、手抜きをしてs3fs経由でファイルコピーをしています。
[neo@matrix cloudTest]$ cat sendFile.sh
#!/bin/sh
export PATH=/home/neo/.local/bin:$PATH
mkdir -p /s3fs/work/neo/cloudTest/log
aws s3 sync render s3://condorannexdata/work/neo/cloudTest/render
cp rename.py /s3fs/work/neo/cloudTest/
[neo@matrix cloudTest]$
ジョブを投入するためのSDFも用意します。
[neo@matrix cloudTest]$ cat rename.sdf
executable = /usr/bin/python
output = /gs/work/neo/cloudTest/log/rename.out
error = /gs/work/neo/cloudTest/log/rename.err
log = /gs/work/neo/cloudTest/log/rename.log
arguments = rename.py
initialdir = /gs/work/neo/cloudTest
requirements = TARGET.OpSys == "LINUX" && TARGET.FileSystemDomain == "aws.jcgs.co.jp" && TARGET.UidDomain == "aws.jcgs.co.jp"
should_transfer_files = NO
+MayUseAWS = True
queue
[neo@matrix cloudTest]$
AWS上で実行するための指定をしています。
ジョブを投入します。
[neo@matrix cloudTest]$ condor_submit rename.sdf
Submitting job(s).
1 job(s) submitted to cluster 63.
[neo@matrix cloudTest]$
少し待って、ジョブが完了したら結果を確認します。クラウド環境では/gs、ローカル環境では/s3fs以下にファイルが生成されます。
[neo@matrix cloudTest]$ ls /s3fs/work/neo/cloudTest/renamed/
renamed.0000.exr renamed.0002.exr renamed.0004.exr renamed.0006.exr renamed.0008.exr
renamed.0001.exr renamed.0003.exr renamed.0005.exr renamed.0007.exr renamed.0009.exr
[neo@matrix cloudTest]$
できました。
続いて、生成されたファイルをローカル環境にダウンロードします。これはアップロードの逆を行えばよいです。
[neo@matrix cloudTest]$ cat getFile.sh
#!/bin/sh
export PATH=/home/neo/.local/bin:$PATH
aws s3 sync s3://condorannexdata/work/neo/cloudTest/renamed renamed
[neo@matrix cloudTest]$ cat getFile.sdf
executable = /bin/sh
output = /gs/work/neo/cloudTest/log/get_file.out
error = /gs/work/neo/cloudTest/log/get_file.err
log = /gs/work/neo/cloudTest/log/get_file.log
arguments = getFile.sh
initialdir = /gs/work/neo/cloudTest
requirements = TARGET.OpSys == "LINUX" && TARGET.FileSystemDomain == "intra.jcgs.co.jp" && TARGET.UidDomain == "intra.jcgs.co.jp"
should_transfer_files = no
queue
[neo@matrix cloudTest]$ condor_submit getFile.sdf
Submitting job(s).
1 job(s) submitted to cluster 73.
ジョブ完了後に確認します。
[neo@matrix cloudTest]$ ls renamed/
renamed.0000.exr renamed.0002.exr renamed.0004.exr renamed.0006.exr renamed.0008.exr
renamed.0001.exr renamed.0003.exr renamed.0005.exr renamed.0007.exr renamed.0009.exr
[neo@matrix cloudTest]$
無事にファイルがダウンロードできています。
これで、
- ローカル環境からファイルやプログラムをアップロードする
- クラウド環境で処理を行う
- 生成されたデータをローカル環境にダウンロードする
というそれぞれの処理をHTCondor上で行うことができるようになりました。
ジョブの依存関係を定義する
ファイルのアップロード、変換、ダウンロードという処理は並行して行うことができず、必ず前の処理が終わってから実行する必要があるため、手動で管理しているとひとつのジョブが完了するまで待って次のジョブを投入するということをしなければいけなくなります。そんなことはとてもではないですがやってられないです。そこで、ひとつのコマンドでこれらの処理を投入・実行できるようにします。このような場合、ジョブの間に依存関係を設定します。
HTCondorにはDAGManという、ジョブの依存関係を管理するためのしくみがあります。まずは定義ファイルを見てみます。
[neo@matrix cloudTest]$ cat clodTest.dag
JOB sendFile sendFile.sdf
JOB rename rename.sdf
JOB getFile getFile.sdf
PARENT sendFile CHILD rename
PARENT rename CHILD getFile
[neo@matrix cloudTest]$
JOBでジョブ名と、使用するSDFを定義し、PARENTでジョブの親子関係を指定します。この場合、sendFile - rename - getFileというジョブの依存関係が定義されています。PARENTやCHILDには複数のジョブを指定することもできるため、もっと複雑な依存関係も定義することができます。
ジョブ投入前に一度データを全て削除しておきます。
[neo@matrix cloudTest]$ rm -rf renamed
[neo@matrix cloudTest]$ rm -rf /s3fs/work/neo/cloudTest
作成したDAGファイルを使ってジョブを投入します。依存関係つきでジョブを投入する場合はcondor_submit_dagコマンドを使用します。
[neo@matrix cloudTest]$ condor_submit_dag clodTest.dag
Can't open directory "/home/neo/condor-8.8.5/local/config" as PRIV_UNKNOWN, errno: 2 (No such file or directory)
Cannot open /home/neo/condor-8.8.5/local/config: No such file or directory
-----------------------------------------------------------------------
File for submitting this DAG to HTCondor : clodTest.dag.condor.sub
Log of DAGMan debugging messages : clodTest.dag.dagman.out
Log of HTCondor library output : clodTest.dag.lib.out
Log of HTCondor library error messages : clodTest.dag.lib.err
Log of the life of condor_dagman itself : clodTest.dag.dagman.log
Submitting job(s).
1 job(s) submitted to cluster 82.
-----------------------------------------------------------------------
[neo@matrix cloudTest]$ condor_q
-- Schedd: matrix.intra.jcgs.co.jp : <192.168.0.31:9618?... @ 12/24/19 23:49:09
OWNER BATCH_NAME SUBMITTED DONE RUN IDLE TOTAL JOB_IDS
neo clodTest.dag+82 12/24 23:48 _ _ 1 1 83.0
Total for query: 1 jobs; 0 completed, 0 removed, 1 idle, 0 running, 0 held, 0 suspended
Total for all users: 1 jobs; 0 completed, 0 removed, 1 idle, 0 running, 0 held, 0 suspended
[neo@matrix cloudTest]$ condor_q -nobatch
-- Schedd: matrix.intra.jcgs.co.jp : <192.168.0.31:9618?... @ 12/24/19 23:49:15
ID OWNER SUBMITTED RUN_TIME ST PRI SIZE CMD
82.0 neo 12/24 23:48 0+00:00:16 R 0 0.3 condor_dagman -p 0 -f -l . -Lockfile clodTest.dag.lock -AutoRescue 1 -DoRescueFrom 0 -Dag clod
83.0 neo 12/24 23:49 0+00:00:00 I 0 1.0 sh sendFile.sh
Total for query: 1 jobs; 0 completed, 0 removed, 1 idle, 0 running, 0 held, 0 suspended
Total for all users: 1 jobs; 0 completed, 0 removed, 1 idle, 0 running, 0 held, 0 suspended
[neo@matrix cloudTest]$
condor_qの表示がこれまでと随分ちがう感じになりました。
ジョブが全て完了したら、最後に結果の確認です。
[neo@matrix cloudTest]$ ls -la renamed/
total 249060
drwxr-xr-x 2 neo neo 246 Dec 24 23:59 .
drwxrwxr-x 5 neo neo 4096 Dec 24 23:59 ..
-rw-r--r-- 1 neo neo 25496058 Dec 24 23:50 renamed.0000.exr
-rw-r--r-- 1 neo neo 25504371 Dec 24 23:50 renamed.0001.exr
-rw-r--r-- 1 neo neo 25505110 Dec 24 23:50 renamed.0002.exr
-rw-r--r-- 1 neo neo 25499350 Dec 24 23:51 renamed.0003.exr
-rw-r--r-- 1 neo neo 25494908 Dec 24 23:51 renamed.0004.exr
-rw-r--r-- 1 neo neo 25502157 Dec 24 23:51 renamed.0005.exr
-rw-r--r-- 1 neo neo 25496158 Dec 24 23:51 renamed.0006.exr
-rw-r--r-- 1 neo neo 25501568 Dec 24 23:51 renamed.0007.exr
-rw-r--r-- 1 neo neo 25503468 Dec 24 23:51 renamed.0008.exr
-rw-r--r-- 1 neo neo 25511207 Dec 24 23:51 renamed.0009.exr
[neo@matrix cloudTest]$
できました!! これで、ファイルのアップロードとダウンロードはローカル環境にある計算ノードが行い、本体の処理はクラウド上の計算ノードが行うというそれぞれの処理を完全に統合して管理できるようになりました。これは簡単な例ですが、たとえばショットシーンのビルドをローカル環境で行なって、レンダリングをクラウド上で行なった後にローカル環境でコンポジットを行うということもできるということです。
次回予告
6月から続けてきたクラウド環境構築編も今回で一定の成果を上げることができてホッとしています。次回以降は引き続きクラウドに関係したトピックをいくつかご紹介します。
第20回の公開は、2020年1月を予定しております。
プロフィール