Server Build Exercises on AWS (Amazon Web Services) 2022 edition

nginx

おもちゃシステムばかりでなく、今度は nginx を起動してみましょう

docker run --rm -it nginx
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2021/12/05 04:57:07 [notice] 1#1: using the "epoll" event method
2021/12/05 04:57:07 [notice] 1#1: nginx/1.21.4
    ... 10行ほど省略 ...
2021/12/05 04:57:09 [notice] 32#32: signal 28 (SIGWINCH) received

あれれ、ログインできません … そういうコンテナもあります。 まずは、Ctrl-C を押してコンテナを殺してください

2021/12/05 04:59:45 [notice] 1#1: signal 17 (SIGCHLD) received from 33
2021/12/05 04:59:45 [notice] 1#1: worker process 33 exited with code 0
    ... 5行ほど省略 ...
2021/12/05 04:59:45 [notice] 1#1: worker process 34 exited with code 0
2021/12/05 04:59:45 [notice] 1#1: exit

サーバプロセス(daemon として)実行

docker run -itをつけるのはログインしたいからなのですが、 必ずしもログインできるわけではありません(そのようにコンテナが作られていません)

サーバプロセスは

docker run -d nginx

と実行します。 -ddaemond、ログインなど考えていない(ターミナルを切りはなしてOK)という意思表示です 一行なぞの数字(16進数)が表示されますが、それは生成されたコンテナのIDです

2cb33eff6c2d2ddce617ed7342ab9a7aab14463682ac69b2d9115c65297f6f34

動作を確認

docker ps

を実行すれば

docker ps
CONTAINER ID   IMAGE           COMMAND                  CREATED         STATUS         PORTS                                 NAMES
2cb33eff6c2d   nginx           "/docker-entrypoint.…"   3 minutes ago   Up 3 minutes   80/tcp                                quirky_margulis

のように表示されるはずです。 一番左にコンテナIDの先頭が見えていて、イメージ名が nginx なのが確認できます。

コンテナにログインする

dockerコンテナ内でUnixコマンドを実行するdocker exec ...という呪文があります。 これを使い、コンテナ内の/bin/bashを実行することでユーザrootでログインしましょう

docker exec -it コンテナID /bin/bash

コンテナIDは、上のdocker psで表示されているものをコピー&ペーストしてください。 このIDは十分ランダムなはずで、先頭の数文字でも、どのコンテナか特定できるため、 コンテナIDは先頭の数文字でも大丈夫です(ふつうは docker ps の表示からコピーするでしょうけど)。

docker exec -it 192e128251 /bin/bash
root@2cb33eff6c2d:/# 

のようにプロンプトが表示されログインできたはずです。

さてコンテナに入れはしたのですが、 サーバの様子を調査するコマンドが入っていないので何していいかわからないですね;-)

コンテナを改変

ちなみにコンテナを改変しても再起動すると元に戻ります。 だからコンテナを壊しても全然大丈夫です。 気がねなく、いじりたおしてください。

そんなわけで、OSを調べるコマンドがないと始まりません。 しかたないから ps コマンドをいれましょう。

でもOSのパッケージ管理システムが分かりません。 そもそも、このコンテナの大元の distro は何でしょうね? そういうとき、まずは雑な探し方をします(w) だいたい、 /etc ディレクトリには、 OSのバージョン情報をもつほげほげ_versionとかふがふが_releaseという名前のファイルがあると予想されるので、 シェルパターン*(どんな文字にでもマッチするという意味)を使い、 それらしい文字列のファイルを表示してみましょう。 なおcatコマンドではファイル名が分からないので、 headコマンドで各ファイルの先頭最大10行だけを表示させます

head /etc/*ver* /etc/*rel*

(注: /etc/*ver*は /etc の下でファイル名に ver という文字を含むファイルすべて、 /etc/*rel*は同様にファイル名に rel を含むファイルすべてという意味)

次のように表示されました。debian のようです。 では apt コマンドを使いましょう

==> /etc/debian_version <==
11.1

==> /etc/os-release <==
PRETTY_NAME="Debian GNU/Linux 11 (bullseye)"
NAME="Debian GNU/Linux"
VERSION_ID="11"
VERSION="11 (bullseye)"
VERSION_CODENAME=bullseye
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

ちなみに ps コマンドは procps パッケージです。 (詳細は略しますが)コンテナ内で次のコマンドを実行すると ps コマンドが入ります

apt update
apt install procps

ps auxww コマンドを実行すると、次のように表示されました。 たしかに nginx サーバが走っています

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.2   8688  5484 ?        Ss   05:08   0:00 nginx: master process nginx -g daemon off;
nginx       32  0.0  0.1   9092  2368 ?        S    05:08   0:00 nginx: worker process
nginx       33  0.0  0.1   9092  2368 ?        S    05:08   0:00 nginx: worker process
nginx       34  0.0  0.1   9092  2368 ?        S    05:08   0:00 nginx: worker process
root        35  0.0  0.1   4096  3324 pts/0    Ss   05:09   0:00 /bin/bash
root       907  0.0  0.1   6696  2816 pts/0    R+   05:26   0:00 ps auxwww

exit でコンテナから抜けます

コンテナを止める

docker psしてみると、 nginx コンテナが走り続けています。 サーバプロセスなので走りつづけていて当たり前です。

docker stop コンテナID

で停止させてください

【補足】 このガイドの実行例では docker run にデバッグのため –rmオプションをつけていることが多いですが、 本番のサーバプロセスでは –rm は不要です。 ちなみに –rm をつけて実行すると、 コンテナに一回ログインして exit するだけでコンテナが終了し、 イメージのゴミも残りません。便利

コンテナIDが面倒ですよね?

–name オプションでコンテナに名前をつければ名前で操作できます

docker run -d --name=mynginx nginx

これなら

docker exec -it mynginx /bin/bash
docker stop mynginx

などと操作できます

コラム

ps auxwwを実行したさいに、 nginx のマスタープロセスがプロセス番号 1 番であることに気づきましたか? docker は普通の意味で Unix を実行する気はさらさらなく、 デフォルトでは init プロセスを使いません。 そういう設計思想(docker とは隔離されたアプリ一つだけを実行する環境と言えば正確かな?)なんですね

それで不具合とかないのか?というと、あるんですけども…

まぁ、 コンテナを起動、短時間実行、コンテナ終了という使い方なら問題になりません。 たぶん gmail の裏側(gmail は Google borg で動いていると思います。いずれにせよ docker ではない)とか Amazon Lambda の裏側(これも docker かどうかは知らないけど、いずれにせよコンテナでしょ)は、 そういう動作をしていて、そういう使い方ならOKです。

nginx コンテナのように長時間実行する場合も、 プロセス番号1番の挙動次第では大丈夫ですが、 一般的には問題になります。 これを説明するには Unix プロセスの詳細に立ち入らないといけないので、 そうとう長い話が始まります… (以下、略)

リファレンス

Last updated on 7 Dec 2021
Published on 7 Dec 2021
Copyright (C) 2021-2022 Ken'ichi Fukamachi, All rights reserved. CC BY-NC-SA 4.0
We appreciate AWS Academy Japan for the offer of the learning environment.

Powered by Hugo. Theme by TechDoc. Designed by Thingsym.