[ Docker & CI/CD ] SSHポートフォワードを利用してDBとの接続を行う
はじめに
ローカル環境でdockerを使用してアプリケーションコンテナを構築した際に、コンテナ内からリモートサーバーのDBに接続するということがありました。
その際に、sshのポートフォワードについて色々と調べた上で試行錯誤を行なったので記事にまとめます。
早速リモートサーバーとローカル環境を繋いでみよう
踏み台サーバーを経由して、その先にあるリモートサーバーとローカル環境とでsshを接続する際には以下のコマンドを実行します。(多段ssh ポートフォワード)
$ ssh -f -N -L 29017:localhost:29017 -i ~/.ssh/id_rsa -4 root@11:11:11:11 -o ProxyCommand='ssh user@222.222.222.222 -W %h:%p' -A
このコマンドで設定されるのは、 localhostの 29017ポートへのアクセスを 222.222.222.222サーバーを経由して11.11.11.11サーバーのlocalhostの29017ポートへと転送する。
configファイルを使ってssh ポートフォワード
上記のコマンドを毎回打つのは非常に煩わしいので、configファイルに諸々の設定を行なっていると、以下のようにHost名を指定するだけでポートフォワードを繋ぐことができる。
CI上でsshポートフォワードを行う際には、-tオプションが必要であるようだ。
gitlab-runnerを使用した際には、不思議なことに -t
オプションが2つ必要であった。
ssh -t -t tep_overseas_db -f -N
以下のconfigファイルの設定をもとに上のsshコマンドを実行すると、はじめに解説したsshポートフォワード と同様の設定ができる。
ssh -t tep_overseas_db -f -N
以下、configファイルの設定
Host step_server
HostName 222.222.222.222
User deployer
LocalForward 29017 localhost:29017
ForwardAgent yes
IdentityFile ~/.ssh/id_rsa
Host target_db
HostName 11.11.11.11
User root
LocalForward 29017 localhost:29017
ProxyCommand ssh -W %h:%p step_server
ForwardAgent yes
IdentityFile ~/.ssh/id_rsa
AddressFamily inet
CI上ではどうする
CI/CDパイプラインを構築して、CI上で自動テストを行いたいということがあると思います。
私の開発現場ではCIのdockerコンテナ上からsshのポートフォワードを開発環境のDBに直接、接続してテストを実行していました。
※注意
CI上でsshポートフォワードを行う際には、-tオプションが必要であるようです。
私の開発現場では gitlab-runner
を使用してCI/CDパイプラインを構築したのですが、なんと不思議なことに -t
オプションが2つ必要でした。。
(これは、結構ハマってしまいましたね。。。)
ssh -t -t tep_overseas_db -f -N
上記のコマンドをCIの処理の中に含めることで、CIのdockerコンテナ上からもsshのポートフォワードを接続することができるようになり、自動でテストを実行することが可能となりました。
そもそも自動テストってDBとの接続はどうするんだろうか
私の開発現場では上記のsshポートフォワードでクラウドサーバー上の開発DBに直接接続して自動テストを回していましたが、
本来は、DBのdockerコンテナを同時に立ち上げて、モックデータとかを投げ込んでからテストを回すのが理想、という気もしますよね。
sshコマンドのオプション
一応、sshポートフォワードで頻繁に使用するオプションをまとめておきます。
オプション | 意味 |
---|---|
-L | ローカルのポートを指定するときに必要 |
-f | ssh 先でコマンドを実行したあとに, バックグラウンドへと潜るオプション |
-N | ssh 先でなんのコマンドも実行しないオプション |
-t | 仮想端末を割り当てるオプション(CIでsshを実行する際などに必要) |
-i | 秘密鍵のパスを指定するオプション |
-A | ssh接続する際に、リモートサーバーに秘密鍵を転送する |
-4 | ipv4だけを使用する際に必要 |
その他のオプションは以下を参照
最後に
今回は、dockerを使用してローカル開発環境を構築する場合と、CI/CDパイプラインを構築してCI上から自動テストを回す場合とで、sshポートフォワードを使用しました。
他のCIサービスなどを利用する時にもsshポートフォワードを使用することがあるかどうかは分かりませんが、もしその際には今回キャッチアップした内容を基にしてCI/CDパイプラインを構築したいと思います。
Discussion