LoginSignup
14
12

More than 3 years have passed since last update.

簡単にFargateのコンテナにSSH接続する(本番でSSHできるようにするのは非推奨)

Last updated at Posted at 2020-06-05

追記 ーーーーーーーーーーーーーーーーー
一般論として、そもそもコンテナにssh接続するのは邪道なので、基本的にやらない方がいいです。
下記リンク先を読んでいただければ納得できるかと思います。
https://jpetazzo.github.io/2014/06/23/docker-ssh-considered-evil/

とは言っても開発中にデバッグするためにどうしてもsshしたくなる時もあるかと思うので、そういう時は参考にしてください。
本番リリースの時にsshできる状態になっているのは良くないので、検証が終わったらsshは削除することをオススメします。
ーーーーーーーーーーーーーーーーーーーー

Fargateでコンテナ開発をしていると、問題の切り分けとかする時にコンテナにsshできたらいいなと思うこともあるかと思います。

fargateのコンテナにsshするのにはいくつか条件があります。
例えば、同一VPCからでないと、fargateのコンテナにはsshできません。

sshトンネルというやり方もあるようですが、それよりも簡単なやり方を発見したのでメモとして残します。

やり方を3行で

sshのpublic keyをParameter Storeに登録
そのpublic keyをTask Definitionで読み込む設定をしてコンテナに渡す
シェルスクリプトを使ってコンテナ内でそのpublic keyを~/.ssh/authorized_keyに登録して同一VPCにあるEC2からそのコンテナにssh

実現方法の流れ

  1. Dockerfileにopensshをインストールするコマンドを加える
  2. Parameter Storeにpublic keyを登録
  3. 環境変数として受け取ったpublic keyをauthorized_keyに登録するシェルスクリプトを用意してENTRYPOINTで実行
  4. Task DefinitionにParameter Storeの値の読み込み設定
  5. Taskを実行してTaskのIPアドレスにssh

ざっとこんな感じです。これで良さそうだなと思ったら読み進めていただければと。

Dockerfileにopensshをインストールするコマンドを加える

まずはDockerfileにopenssh-serverをインストールするよう記載。

RUN apt-get update && apt-get install -y openssh-server && apt-get clean all

Parameter Storeにpublic keyを登録

sshするなら必要になるのが秘密鍵と公開鍵。接続元のサーバでssh-keygenを実行してください。

$ ssh-keygen -t rsa -b 4096

とりあえず今回は~/.sshにid_rsa.pubができるのでそれをコピーしてAWSのParameter Storeに登録します。

AWS Systems Manager > Parameter Store

Create Parameterを押下し、任意のキーと共に公開鍵をペーストして保存します。

ここの記事ではキーをPUB_KEYとします。

環境変数として受け取ったpublic keyをauthorized_keyに登録するシェルスクリプトを用意

以下のようなシェルスクリプトを用意。接続元の公開鍵を認証サーバに登録して、sshdを動かしてssh接続を受け付ける準備をします。

#!/bin/sh

[ ! -d "$USER_SSH_KEYS_FOLDER" ] && mkdir -p $USER_SSH_KEYS_FOLDER

echo $PUB_KEY > ~/.ssh/authorized_keys

unset PUB_KEY

/usr/sbin/sshd -D

他にも動かすプロセスがあるはずなので、このスクリプトはsupervisorを使って実行します。

supervisord.conf
[program:sshd]
command=/usr/local/bin/docker-entrypoint.sh

Dockerfileに下記の内容を追記。

Dockerfile
RUN apt-get update \
    && apt-get install -y openssh-server \
    && mkdir -p /var/run/sshd

COPY docker-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/docker-entrypoint.sh

CMD supervisord -c /etc/supervisord.conf

EXPOSE 80 22

Task DefinitionにParameter Storeの値の読み込み設定

Terraformを使っているなら、aws_ecs_task_definitionのcontainer_definitionsの中にParameter Storeに登録した値を参照する設定をします。

      "Secrets": [
        {
          "ValueFrom": "arn:aws:ssm:your-region:your-aws-id:parameter/PUB_KEY",
          "Name": "PUB_KEY"
        }
      ],

それに併せてIAMも。

 {
          "Effect": "Allow",
          "Action": [
              "ssm:GetParameters",
              "ssm:GetParameter"
          ],
          "Resource": "arn:aws:ssm:your-region:your-aws-id:parameter/PUB_KEY"
 }

これによりコンテナ内で環境変数として値をParameter Storeから渡すことが可能になりました。

Taskを実行してTaskのIPアドレスにssh

これで準備は整いました。全ての処理がうまくいっていればコンテナにsshできるでしょう。

Clusters > Your cluster > Task

と進んで、Network欄のPrivate IPに、fargateと同一VPCにあり、かつセキュリティグループで許可されているインスタンスからsshしてみてください。

$ ssh root@private-ipaddress

上手くいかない場合

もし、すぐに接続が切れてしまう場合は何らかの原因でTaskが終了してしまい、起動と停止を繰り返していることが考えられますのでStopped Taskを見てその原因を調査してみてください。

まずはローカルできちんとコンテナが動くか、healthcheckのパスにGETリクエストを送って200が返ってくるようになっているかあたりを見てみると良いかと思います。

そもそも接続できない場合は、セキュリティグループの見直しをしてみてください。sshの22番ポートを許可するのをお忘れなく。
冒頭でも言いましたが、同一VPCからでないとsshできません。

もし上手くいかない場合はコメントで教えていただければお答えします。

これでこの記事は以上です。

参考

https://docs.aws.amazon.com/AmazonECS/latest/developerguide/instance-connect.html
https://medium.com/ci-t/9-steps-to-ssh-into-an-aws-fargate-managed-container-46c1d5f834e2

14
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
12