「DockerでRELION」の版間の差分

提供: Eospedia
移動: 案内検索
(Dockerfile書く)
(追記)
 
(同じ利用者による、間の23版が非表示)
行8: 行8:
 
** yum installで入れているパッケージは https://web.chaperone.jp/w/index.php?Relion 様を参考にしています
 
** yum installで入れているパッケージは https://web.chaperone.jp/w/index.php?Relion 様を参考にしています
 
** Dockerfileのデバッグしんどい
 
** Dockerfileのデバッグしんどい
 +
  
 
* 以下の説明は上記Dockerfileのテンプレートを使用した場合について書きます。
 
* 以下の説明は上記Dockerfileのテンプレートを使用した場合について書きます。
行41: 行42:
 
</pre>
 
</pre>
  
特にユーザーを作らずにDockerコンテナを立ち上げると、rootユーザーしか存在しません。Dockerコンテナ内でのrootユーザーはホストマシンにおいてもrootユーザーと認識されるため、ホストマシンのディレクトリをコンテナにマウントした時にファイル所有権の関係で鬱陶しいことになります。コンテナにsshする時にも問題になります。
+
特にユーザーを作らずにDockerコンテナを立ち上げると、rootユーザーしか存在しません。Dockerコンテナ内でのrootユーザーはホストマシンにおいてもrootユーザーと認識されるため、ホストマシン内のユーザー所有ディレクトリをコンテナにマウントした時にファイル所有権の関係で鬱陶しいことになります。コンテナにsshする時にも問題になります。
  
ということで、上記の様にDockerfileの冒頭で、ホストマシンのユーザーと同じユーザー名、UID、GIDを持つユーザーを作成しています。こうするとファイル共有もsshも楽になります。
+
ということで、上記の様にDockerfileの冒頭でホストマシンのユーザーと同じユーザー名、UID、GIDを設定し、Dockefileの後の方で当該ユーザーを作成しています。こうするとファイル共有もsshも楽になります。
  
UIDとGIDは以下コマンドで調べてください。Ubuntuだと4桁の数字になると思います。
+
UIDとGIDはホストマシンで以下コマンドで調べてください。
  
 
<pre>
 
<pre>
行53: 行54:
  
  
また、GCTFのsmも、ホストマシンのGPUのcompute capabilityを調べて適切なものに変更してください。
+
また、GCTFのsmも、ホストマシンのGPUのcompute capabilityを調べて適切なものに変更してください。([[Gctf]]を参照)
  
USER_SSH_PUBKEYには、ユーザーのssh公開鍵の中身をそのままコピペします。そうすることで、ホストマシンから鍵交換でコンテナ内にsshログインできます。
+
USER_SSH_PUBKEYには、ユーザーのssh公開鍵の中身をそのままコピペします。そうすることで、鍵交換でコンテナ内にsshログインできます。複数のマシンからsshログインしたい時は、それぞれのマシンの公開鍵を改行で繋げた文字列を入れれば良いです。(パスフレーズを設定している場合にどうなるかはよく分かりません。)
  
 
== Dockerイメージのビルド ==
 
== Dockerイメージのビルド ==
行66: 行67:
  
 
(コロンの前はリポジトリ名、コロンの後ろはタグ名と言います。リポジトリ名はスラッシュで階層化できます。タグ名を変えることで、同一のリポジトリ名に対し複数の異なるイメージを作れます。バージョン管理やバリエーションの管理に使います。)
 
(コロンの前はリポジトリ名、コロンの後ろはタグ名と言います。リポジトリ名はスラッシュで階層化できます。タグ名を変えることで、同一のリポジトリ名に対し複数の異なるイメージを作れます。バージョン管理やバリエーションの管理に使います。)
 +
 +
 +
== Dockerコンテナの起動 ==
 +
* '''超重要''':<u><b>コンテナは終了するとデータが全部消えます。</b></u> データを残す場合は、コンテナ起動時にホストマシンの適当なディレクトリをマウントする必要があります。マウントしたディレクトリに保存されたファイルは、コンテナが終了しても残ります。
 +
* というように、気をつけて使わないといけない面もあるので、公式のドキュメントをきちんと読んで使ってください。
 +
 +
 +
オブジェクト指向で例えるとDockerイメージはクラスに相当し、Dockerコンテナはインスタンスに相当します。実際に起動して色々作業を行う場所はDockerコンテナになります。
 +
 +
今回のDockerコンテナの起動コマンド例を以下に示します。一番最後のはコンテナの雛形となるイメージの名前で、それ以外は全部起動オプションです。
 +
 +
<pre>
 +
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>
 +
 +
 +
一度にいろんなことをやっているので表にして説明します。値はお好きなものに適当に変更してください。
 +
 +
{| class="wikitable" style="width:100%"
 +
|+Dockerコンテナ起動オプション
 +
! style="width:20%" | オプション
 +
! style="width:10%" | 値
 +
! 説明
 +
|-
 +
| --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は、一番最後に
 +
<pre>
 +
CMD [ "/usr/sbin/sshd", "-D" ]
 +
</pre>
 +
 +
と書いておきました。これによって起動したコンテナの中ではすでにsshdが動いていますんで、sshログイン可能(なはず)です。
 +
 +
== Dockerコンテナの仮想端末にアクセス ==
 +
すでに稼働中(run)のコンテナの仮想端末にアクセスしてbashシェルを起動します。
 +
<pre>
 +
$ docker exec -it relion-docker bash
 +
</pre>
 +
 +
以下の様にコンテナのシェルプロンプトが表示されます。
 +
<pre>
 +
[root@relion-docker softwares]#
 +
</pre>
 +
 +
初期ディレクトリがsoftwaresになってますが、イメージをビルドした時の最後のディレクトリだからですかね。。
 +
 +
 +
ユーザー指定でログインするには以下の様にします。
 +
<pre>
 +
$ docker exec -u kttn -w /home/kttn -it relion-docker bash
 +
</pre>
 +
 +
-w はログイン後の初期ディレクトリを指定しています。
 +
<pre>
 +
[kttn@relion-docker ~]$ ls
 +
</pre>
 +
 +
== Dockerコンテナにsshログインする ==
 +
ホストマシンからコンテナにログインする手順です。
 +
 +
まず確認
 +
<pre>
 +
$ 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
 +
</pre>
 +
 +
relion-dockerコンテナが立ち上がっていて、コマンド"/usr/sbin/sshd -D"が実行済みであること等が確認できます。
 +
 +
 +
ホストの29290番ポートがコンテナの22番ポートにマッピングされてるので、以下でsshログインできます。
 +
<pre>
 +
$ 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 ~]$
 +
</pre>
 +
 +
 +
コンテナにはipアドレスが割り振られているので、それを探してip指定でログインすることもできます。
 +
 +
ipを確認するには、
 +
<pre>
 +
$ 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,
 +
</pre>
 +
 +
ipアドレスは172.17.0.2であると分かります。
 +
 +
 +
で、
 +
<pre>
 +
$ 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 ~]$
 +
</pre>
 +
 +
入れます。
 +
 +
== リモートの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時点における最新版

下準備


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


一度にいろんなことをやっているので表にして説明します。値はお好きなものに適当に変更してください。

Dockerコンテナ起動オプション
オプション 説明
--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

docker-relion.png


お疲れ様でした


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ログインできます。