「DockerでRELION」の版間の差分
(→Dockerfile書く) |
(→追記) |
||
(同じ利用者による、間の7版が非表示) | |||
行56: | 行56: | ||
また、GCTFのsmも、ホストマシンのGPUのcompute capabilityを調べて適切なものに変更してください。([[Gctf]]を参照) | また、GCTFのsmも、ホストマシンのGPUのcompute capabilityを調べて適切なものに変更してください。([[Gctf]]を参照) | ||
− | + | USER_SSH_PUBKEYには、ユーザーのssh公開鍵の中身をそのままコピペします。そうすることで、鍵交換でコンテナ内にsshログインできます。複数のマシンからsshログインしたい時は、それぞれのマシンの公開鍵を改行で繋げた文字列を入れれば良いです。(パスフレーズを設定している場合にどうなるかはよく分かりません。) | |
== Dockerイメージのビルド == | == Dockerイメージのビルド == | ||
行79: | 行79: | ||
<pre> | <pre> | ||
− | docker run --runtime=nvidia -i -t -d --expose 22 -p 127.0.0.1:29290:22 --hostname relion-docker --name relion-docker -v / | + | docker run --runtime=nvidia -i -t -d --expose 22 -p 127.0.0.1:29290:22 --hostname relion-docker --name relion-docker -v /data/kttn:/data/kttn kttn8769/cryoem/relion:3.0.5-cuda9.2-gctf |
</pre> | </pre> | ||
行124: | 行124: | ||
|- | |- | ||
| -v | | -v | ||
− | | / | + | | /data/kttn:/data/kttn |
− | | ホストの/ | + | | ホストの/data/kttnディレクトリを、コンテナの/data/kttnにマウントしています。/data/kttnなんていうディレクトリはコンテナの中に本来存在しませんが、-vで指定するとdockerが親ディレクトリも含めて作ってくれます。ホストとコンテナでパスを変えることもできますが、絶対パスでファイル管理するソフトなどがあると問題が発生するため、同じパスにしてマウントすることを推奨します。 |
|} | |} | ||
− | + | また、今回書いたDockerfileは、一番最後に | |
<pre> | <pre> | ||
CMD [ "/usr/sbin/sshd", "-D" ] | CMD [ "/usr/sbin/sshd", "-D" ] | ||
行223: | 行223: | ||
== リモートのDockerコンテナにローカルからsshログインする == | == リモートのDockerコンテナにローカルからsshログインする == | ||
+ | <pre> | ||
+ | ローカル(Mac Mini) → リモート(Ubuntu, Dockerのホストマシン) → リモート内のDockerコンテナ(CentOS) | ||
+ | </pre> | ||
+ | という図式です。 | ||
+ | |||
+ | まずsshのローカルフォーワードを設定します。 | ||
+ | <pre> | ||
+ | (local)$ ssh -fNL 29290:localhost:29290 <リモートのipアドレス> | ||
+ | </pre> | ||
+ | |||
+ | -fによりバックグラウンド動作、-Nはリモートで何のコマンドも実行させないためのオプション、-Lがローカルフォーワードを指定するためのオプションです。 | ||
+ | |||
+ | 上記により、ローカルの29290番ポートが、リモートのlocalhost:29290番ポートにフォーワードされます。 | ||
+ | |||
+ | で、 | ||
+ | <pre> | ||
+ | (local)$ ssh kttn@localhost -p 29290 | ||
+ | Last login: Sat May 18 05:52:23 2019 from gateway | ||
+ | [kttn@relion-docker ~]$ | ||
+ | </pre> | ||
+ | |||
+ | 入れます。 | ||
+ | |||
+ | ssh -X すればx forwardingもできます。(ローカルにxサーバー入ってれば) | ||
+ | <pre> | ||
+ | (local)$ ssh -X kttn@localhost -p 29290 | ||
+ | |||
+ | [kttn@relion-docker ~]$ relion | ||
+ | Only run the relion GUI from your ProjectDirectory. Do you want to start a new project here [y/n]? y | ||
+ | </pre> | ||
+ | |||
+ | [[File:docker-relion.png|x500px]] | ||
+ | |||
+ | |||
+ | お疲れ様でした | ||
+ | |||
+ | |||
+ | == WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! == | ||
+ | 同一のDockerイメージからコンテナを生成して使ってるうちはいいんですが、Dockerfileを更新するなりしてイメージが書き変わると、コンテナのECDSA鍵が書き変わるためにsshログイン時にエラーが生じます。 | ||
+ | |||
+ | <pre> | ||
+ | > ssh -X kttn@localhost -p 29290 | ||
+ | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | ||
+ | @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ | ||
+ | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | ||
+ | IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY! | ||
+ | Someone could be eavesdropping on you right now (man-in-the-middle attack)! | ||
+ | It is also possible that a host key has just been changed. | ||
+ | The fingerprint for the ECDSA key sent by the remote host is | ||
+ | ... | ||
+ | Please contact your system administrator. | ||
+ | Add correct host key in /Users/kttn/.ssh/known_hosts to get rid of this message. | ||
+ | Offending ECDSA key in /Users/kttn/.ssh/known_hosts:5 | ||
+ | ECDSA host key for [localhost]:29290 has changed and you have requested strict checking. | ||
+ | Host key verification failed. | ||
+ | </pre> | ||
+ | |||
+ | |||
+ | ssh元のマシンのknown_hostsからlocalhost:29290の古いECDSA公開鍵を削除し、再度接続すれば入れる様になります。 | ||
+ | |||
+ | |||
+ | もしくは、古いECDSA公開鍵を削除した後、ホストマシンでコンテナの仮想端末に入り、 | ||
+ | <pre> | ||
+ | $ cat /etc/ssh/ssh_host_ecdsa_key.pub | ||
+ | </pre> | ||
+ | |||
+ | によりイメージのECDSA公開鍵を確認し、ssh元のマシンの~/.ssh/known_hostsに [localhost]:29290 <公開鍵> みたいな感じで書き足せば特に何も聞かれることなくsshログインできます。 |
2019年5月19日 (日) 10:09時点における最新版
目次
下準備
- DockerとNVIDIA Dockerをインストールする。→ DockerとNVIDIA_Dockerのインストール
Dockerfile書く
- 取り急ぎ書いたDockerfileのテンプレートを公開しておきます。
- https://github.com/kttn8769/cryoem-docker.git
- yum installで入れているパッケージは https://web.chaperone.jp/w/index.php?Relion 様を参考にしています
- Dockerfileのデバッグしんどい
- 以下の説明は上記Dockerfileのテンプレートを使用した場合について書きます。
- Dockerの使い方としてまともかどうかわからないので、もしかすると参考にしないほうがいいかもしれません。
$ git clone https://github.com/kttn8769/cryoem-docker.git $ cd cryoem-docker
cryoem-docker内のDockerfileの以下の部分について、適切に設定してください。
### Base image: DockerHub nvidia/cuda, CUDA v9.2, cuDNN v7, development package, CentOS7 FROM nvidia/cuda:9.2-cudnn7-devel-centos7 ### User account in Docker image # username ARG USER_NAME="" # UID ARG USER_ID="" # GID ARG GROUP_ID="" # SSH public key ARG USER_SSH_PUBKEY="" ### Software configs ARG RELION_VERSION="3.0.5" ARG RELION_BUILD_NUM_THREADS="12" ARG GCTF_BIN_URL="https://www.mrc-lmb.cam.ac.uk/kzhang/Gctf/Gctf_v1.18_b2/bin/Gctf_v1.18_b2_sm61_cu9.2" ARG GCTF_LIB_URL="https://www.mrc-lmb.cam.ac.uk/kzhang/Gctf/Gctf_v1.18_b2/lib/libEMcore_sm61_cu9.2.so"
特にユーザーを作らずにDockerコンテナを立ち上げると、rootユーザーしか存在しません。Dockerコンテナ内でのrootユーザーはホストマシンにおいてもrootユーザーと認識されるため、ホストマシン内のユーザー所有ディレクトリをコンテナにマウントした時にファイル所有権の関係で鬱陶しいことになります。コンテナにsshする時にも問題になります。
ということで、上記の様にDockerfileの冒頭でホストマシンのユーザーと同じユーザー名、UID、GIDを設定し、Dockefileの後の方で当該ユーザーを作成しています。こうするとファイル共有もsshも楽になります。
UIDとGIDはホストマシンで以下コマンドで調べてください。
$ id uid=1003(kttn) gid=1006(kttn) groups=1006(kttn),27(sudo),999(docker),2002(vglusers)
また、GCTFのsmも、ホストマシンのGPUのcompute capabilityを調べて適切なものに変更してください。(Gctfを参照)
USER_SSH_PUBKEYには、ユーザーのssh公開鍵の中身をそのままコピペします。そうすることで、鍵交換でコンテナ内にsshログインできます。複数のマシンからsshログインしたい時は、それぞれのマシンの公開鍵を改行で繋げた文字列を入れれば良いです。(パスフレーズを設定している場合にどうなるかはよく分かりません。)
Dockerイメージのビルド
Dockerfileがあるディレクトリで、Dockerイメージをビルドします。最後のピリオドを忘れない様に。
$ docker build -t <Dockerイメージにつけたい名前> .
私の場合は kttn8769/cryoem/relion:3.0.5-cuda9.2-gctf としました。
(コロンの前はリポジトリ名、コロンの後ろはタグ名と言います。リポジトリ名はスラッシュで階層化できます。タグ名を変えることで、同一のリポジトリ名に対し複数の異なるイメージを作れます。バージョン管理やバリエーションの管理に使います。)
Dockerコンテナの起動
- 超重要:コンテナは終了するとデータが全部消えます。 データを残す場合は、コンテナ起動時にホストマシンの適当なディレクトリをマウントする必要があります。マウントしたディレクトリに保存されたファイルは、コンテナが終了しても残ります。
- というように、気をつけて使わないといけない面もあるので、公式のドキュメントをきちんと読んで使ってください。
オブジェクト指向で例えるとDockerイメージはクラスに相当し、Dockerコンテナはインスタンスに相当します。実際に起動して色々作業を行う場所はDockerコンテナになります。
今回のDockerコンテナの起動コマンド例を以下に示します。一番最後のはコンテナの雛形となるイメージの名前で、それ以外は全部起動オプションです。
docker run --runtime=nvidia -i -t -d --expose 22 -p 127.0.0.1:29290:22 --hostname relion-docker --name relion-docker -v /data/kttn:/data/kttn kttn8769/cryoem/relion:3.0.5-cuda9.2-gctf
一度にいろんなことをやっているので表にして説明します。値はお好きなものに適当に変更してください。
オプション | 値 | 説明 |
---|---|---|
--runtime | nvidia | NVIDIA Dockerをランタイムとして用います。ホストマシンのGPUデバイスとドライバが使用できます。 |
-i | --interactiveの略。コンテナへの標準入力が開かれます。 | |
-t | --ttyの略。コンテナに仮想端末を割り当てます。-iと組み合わせることで、ちょうどsshログインでログイン先のシェルを使用するのと同じ様に、コンテナ内のシェルを使えます。-i, -tを指定しておかないと、コンテナは必要なプロセスを起動し終えたら即終了してしまいます。立ち上げっぱなしにするためには-i, -tが必要です。 | |
-d | --detachの略。コンテナをバックグランドで動かします。-itによりコンソール開きっぱなしだと鬱陶しい時はこれでバッググラウンドプロセス化します。 | |
--expose | 22 | コンテナが22番ポートをlistenする様にします。 |
-p | 127.0.0.1:29290:22 | コンテナの22番ポートをホスト(127.0.0.1)の29290番ポートへマッピングします。ホストの29290番ポートへ何か送るとコンテナの22番ポートに届きます。 |
--hostname | relion-docker | コンテナ内で立ち上がるマシンのホスト名をrelion-dockerとしています。 |
--name | relion-docker | コンテナ名をrelion-dockerとしています。 |
-v | /data/kttn:/data/kttn | ホストの/data/kttnディレクトリを、コンテナの/data/kttnにマウントしています。/data/kttnなんていうディレクトリはコンテナの中に本来存在しませんが、-vで指定するとdockerが親ディレクトリも含めて作ってくれます。ホストとコンテナでパスを変えることもできますが、絶対パスでファイル管理するソフトなどがあると問題が発生するため、同じパスにしてマウントすることを推奨します。 |
また、今回書いたDockerfileは、一番最後に
CMD [ "/usr/sbin/sshd", "-D" ]
と書いておきました。これによって起動したコンテナの中ではすでにsshdが動いていますんで、sshログイン可能(なはず)です。
Dockerコンテナの仮想端末にアクセス
すでに稼働中(run)のコンテナの仮想端末にアクセスしてbashシェルを起動します。
$ docker exec -it relion-docker bash
以下の様にコンテナのシェルプロンプトが表示されます。
[root@relion-docker softwares]#
初期ディレクトリがsoftwaresになってますが、イメージをビルドした時の最後のディレクトリだからですかね。。
ユーザー指定でログインするには以下の様にします。
$ docker exec -u kttn -w /home/kttn -it relion-docker bash
-w はログイン後の初期ディレクトリを指定しています。
[kttn@relion-docker ~]$ ls
Dockerコンテナにsshログインする
ホストマシンからコンテナにログインする手順です。
まず確認
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f5c4ead0964f kttn8769/cryoem/relion:3.0.5-cuda9.2-gctf "/usr/sbin/sshd -D" 42 minutes ago Up 42 minutes 127.0.0.1:29290->22/tcp relion-docker
relion-dockerコンテナが立ち上がっていて、コマンド"/usr/sbin/sshd -D"が実行済みであること等が確認できます。
ホストの29290番ポートがコンテナの22番ポートにマッピングされてるので、以下でsshログインできます。
$ ssh kttn@localhost -p 29290 The authenticity of host '[localhost]:29290 ([127.0.0.1]:29290)' can't be established. ... Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '[localhost]:29290' (ECDSA) to the list of known hosts. Last login: Sat May 18 05:22:55 2019 from gateway [kttn@relion-docker ~]$
コンテナにはipアドレスが割り振られているので、それを探してip指定でログインすることもできます。
ipを確認するには、
$ docker inspect relion-docker | grep IP "LinkLocalIPv6Address": "", "LinkLocalIPv6PrefixLen": 0, "SecondaryIPAddresses": null, "SecondaryIPv6Addresses": null, "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAddress": "172.17.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "IPAMConfig": null, "IPAddress": "172.17.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0,
ipアドレスは172.17.0.2であると分かります。
で、
$ ssh kttn@172.17.0.2 The authenticity of host '172.17.0.2 (172.17.0.2)' can't be established. ... Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '172.17.0.2' (ECDSA) to the list of known hosts. [kttn@relion-docker ~]$
入れます。
リモートのDockerコンテナにローカルからsshログインする
ローカル(Mac Mini) → リモート(Ubuntu, Dockerのホストマシン) → リモート内のDockerコンテナ(CentOS)
という図式です。
まずsshのローカルフォーワードを設定します。
(local)$ ssh -fNL 29290:localhost:29290 <リモートのipアドレス>
-fによりバックグラウンド動作、-Nはリモートで何のコマンドも実行させないためのオプション、-Lがローカルフォーワードを指定するためのオプションです。
上記により、ローカルの29290番ポートが、リモートのlocalhost:29290番ポートにフォーワードされます。
で、
(local)$ ssh kttn@localhost -p 29290 Last login: Sat May 18 05:52:23 2019 from gateway [kttn@relion-docker ~]$
入れます。
ssh -X すればx forwardingもできます。(ローカルにxサーバー入ってれば)
(local)$ ssh -X kttn@localhost -p 29290 [kttn@relion-docker ~]$ relion Only run the relion GUI from your ProjectDirectory. Do you want to start a new project here [y/n]? y
お疲れ様でした
WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
同一のDockerイメージからコンテナを生成して使ってるうちはいいんですが、Dockerfileを更新するなりしてイメージが書き変わると、コンテナのECDSA鍵が書き変わるためにsshログイン時にエラーが生じます。
> ssh -X kttn@localhost -p 29290 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY! Someone could be eavesdropping on you right now (man-in-the-middle attack)! It is also possible that a host key has just been changed. The fingerprint for the ECDSA key sent by the remote host is ... Please contact your system administrator. Add correct host key in /Users/kttn/.ssh/known_hosts to get rid of this message. Offending ECDSA key in /Users/kttn/.ssh/known_hosts:5 ECDSA host key for [localhost]:29290 has changed and you have requested strict checking. Host key verification failed.
ssh元のマシンのknown_hostsからlocalhost:29290の古いECDSA公開鍵を削除し、再度接続すれば入れる様になります。
もしくは、古いECDSA公開鍵を削除した後、ホストマシンでコンテナの仮想端末に入り、
$ cat /etc/ssh/ssh_host_ecdsa_key.pub
によりイメージのECDSA公開鍵を確認し、ssh元のマシンの~/.ssh/known_hostsに [localhost]:29290 <公開鍵> みたいな感じで書き足せば特に何も聞かれることなくsshログインできます。