Chapter 09

2部: コンテナに接続する

ほげさん
ほげさん
2022.03.21に更新

コンテナを活用したりトラブルシューティングに必要になったりする、とても大事な container exec コマンドについて学びます。

このページで初登場するコマンドとオプション

コンテナ内でコマンドを実行する - container exec

新コマンド
$ docker container exec [option] <container> command
旧コマンド
$ docker exec [option] <container> command
オプション 意味 用途
-i, --interactive コンテナの標準入力に接続する コンテナを対話操作する
-t, --tty 擬似ターミナルを割り当てる コンテナを対話操作する

起動中のコンテナ内でコマンドを実行する

container exec は、起動中のコンテナに命令を送るコマンドです。

命令を送ると言っても container stop のような コンテナを操作する命令ではなく、コンテナ内で ls /etc をせよといった コンテナ内で実行する Linux コマンド を命令します。

たとえば Ubuntu コンテナをデフォルト命令 ( bash ) で起動し、適当な ~/hello.txt を作成します。

Host Machine
$ docker container run \
    --name ubuntu1     \
    --rm               \
    --interactive      \
    --tty              \
    ubuntu:20.04

# echo 'hello world' > ~/hello.txt

この bashexit で終了せずに、ターミナルの別のタブでコンテナに cat コマンドの実行を命令します。

Host Machine
$ docker container exec \
    ubuntu1             \
    cat ~/hello.txt
    
hello world

cat ~/hello.txt の結果で ~/hello.txt の存在を確認できました。

作ったファイルを確認できるのは当然だと思うかもしれませんが、次のほとんど同じコマンドとは 決定的に違う点 を理解していないと、この先いろいろと回り道をすることになります。

Host Machine
$ docker container run \
    ubuntu:20.04       \
    cat ~/hello.txt

cat: ~/hello.txt: No such file or directory

container run を2回実行したら 同じイメージから2つめのコンテナが起動してしまいます

image

container execcontainer run も Linux コマンドを指定できる点が似ていますが、起動中のコンテナに命令をするコマンドイメージからコンテナを起動するコマンド なので、結果は 決定的に違います

ubuntu1 コンテナはまだ停止しないでください。

コンテナに接続する

実際に構築やデバッグを行うときは、ls などを一回ずつ実行するより起動しているコンテナの bash を直接使いたくなります。

bashcatls と同じ Linux の1プロセスなので、container exec を使って命令すれば起動できます。

次のコマンドで ubuntu1 コンテナに bash を命令します。
対話操作には container run と同様のオプションが必要です。

Host Machine
$ docker container exec  \
    --interactive        \
    --tty                \
    ubuntu1              \
    bash

#

プロンプトが # に切り替わったので、Ubuntu コンテナの bash に切り替わっています。
普段と同じように操作することができます。

Container
# pwd
/

# date
Tue Feb 15 15:18:23 UTC 2022

# whoami
root

# cat ~/hello.txt
hello world

# exit

container exec は次のような場面で大変役に立つので、是非とも正しく理解して使いこなせるようになりましょう。

  • コンテナの中にあるログを調べたい
  • Dockerfile を書く前にbash でインストールコマンドを試し打ちしたい
  • MySQL データベースサーバのクライアント mysql を直接操作したい

ubuntu1 コンテナはもう終了して大丈夫です。

Host Machine
$ docker container stop \
    ubuntu1

( 余談 ) コンテナに SSH するという誤解について

コンテナや container exec について正しく理解できていないと、Docker コンテナ SSH のような検索をしてしまうことは珍しくありません。

これで調べると本当にコンテナに sshd という SSH を待ち受ける常駐プロセスを立てて... という手順も見つかりますが、コンテナへの SSH は次のような観点から 推奨できません

  • SSH のための拡張をしたイメージを作る必要がある
  • イメージや Dockerfile とは別に鍵やパスフレーズなどの管理が必要になったり、脆弱性対応などのコストが増える
  • SSH の対応が含まれるイメージをそのままデプロイすると、本来は存在しなかった脆弱性が増える可能性がある

SSH をしたくなるという考えは、イメージを仮想サーバのようなものだと捉えていたり、container execcontainer run の違いが理解できていないと発生しやすいと思います。
僕自身も初めは Docker コンテナ SSH で Google 検索をした覚えがあります。

( 再掲 )
image

( 再掲 )
image

コンテナ内で操作を行いたい場合は container execbash を命令すればよいだけです。

まとめ

簡潔にまとめます。

  • container exec で起動中のコンテナに命令ができる
  • container runcontainer exec を混同しない
  • SSH 接続は基本的にはせず、bash を命じれば良い

混乱してしまったときは立ち返ってみてください。