オープニング

ディスカバリーチャンネル「インターネッツ!大海原!!」MCを務めるのは毎度おなじみジャッカルと、

ジェシーよ~♪
インターネットという大海に生息する高度な精度を誇るOSSにクローズアップし、どんなものなのかを触れ合うことで理解するシリーズ。
本シリーズは鯨さんがトレードマークのDockerにクローズアップしその生態系に迫ります。第2回目はDockerfileです。
Dockerの特徴の一つに環境で使用する実行ファイルやアプリケーションのパッケージ化の手順を自動化できることが挙げられます。そこにはDocker独自の概念、Dockerfileの存在があります。今回はそのDockerfileにフォーカスし、実際に手を動かしてみていこうと思います。
以下の記事でわからない用語などがあれば前回の記事(以下)も参考にしてください。
Dockerfileとは
Dockerfileはアプリケーションのインストールなどの手順などを記載するものです。このDockerfileを元にDockerイメージを作成することができます。
これの何がいいかというと、よりコンテナの環境を複雑かつ自分の求めているような環境にしようとするとき便利になります。Dockerfileによってベースイメージの入手であったり、アプリケーションのインストールであったりができるので求めている環境を構築できるようになります。

オーマイゴッシュ!!
これは、斬新で革新的ね!きっと他のコンテナツールも真っ青になるわ
Dockerfileを書いてみる
今回は簡易的なweb serverとしてのコンテナをDockerfileから作成してみようと思います。
まず適当な作業するディレクトリを作成してそこに入ってDockerfileを作成します。今回はdockerっていうディレクトリを作業ディレクトリとして作成します。以下を実行していきます。
$ mkdir docker
$ cd docker/
$ vi Dockerfile
Dockerfileの中身は以下のように記載します。
FROM centos:7
RUN yum install -y httpd iproute && yum clean all
RUN echo "Hello World, this is Apache site" > /var/www/html/index.html
RUN systemctl enable httpd
「FROM centos:7」で使用するDockerイメージ名を指定しています。
2行目ではhttpd, iprouteをインストールしてます。
iprouteはipコマンドできるようになるためのパッケージです。後ほどの処理でipコマンドを使用するためにインストールしています。
3行目では今回コンテナ内に立ち上げる仮のWebサイトのページのためのファイルを配置してます。
4行目はコンテナ起動時にhttpdが起動するように設定してます。
上記の例では4行なのでわざわざDockerfileを使用せず、イメージをpullしてきた方がいいのかもしれませんが、実際に用意したい環境が複雑になっていき、自分でその環境をカスタマイズして用意したい場合にDockerfileの真価が発揮されます。
※本来はproxyを設定するようなのですが、ラズパイ内でcentosコンテナを動かす際のproxyの設定がうまくいかず、今回は設定しておりません。すいません。
Dockerfileからイメージを作成する
Dockerfileからイメージを作成するにはビルドという操作を行います。以下コマンドでビルドができます。
$ sudo docker image build -f ./Dockerfile -t centos:apache-test .
イメージからコンテナを起動する
以下コマンドを実行します
$ sudo docker container run \
-itd \
--tmpfs /tmp \
--tmpfs /run \
-v /sys/fs/cgroup:/sys/fs/cgroup:ro \
--stop-signal SIGRTMIN+3 \
--name apache-test \
-h apache-test \
-p 8081:80 \
centos:apache-test /sbin/init
オプションについて
「centos:apache-test /sbin/init」
CentOS 7~ではサービスの起動にsystemdが使用されます。
そしてsystemdが使用されるOSのコンテナを起動させるためには/sbin/initで起動を行う必要があります。ここで/sbin/initは/lib/systemd/systemdへのシンボリックリンクになっているのでコンテナ起動時に/lib/systemd/systemdが起動します。最後の行の「centos:apache-test /sbin/init」はそのためのものです。
「–tmpfs /tmp」、「–tmpfs /run」、「-v /sys/fs/cgroup:/sys/fs/cgroup:ro」、「–stop-signal SIGRTMIN+3」
「–tmpfs /tmp」、「–tmpfs /run」、「-v /sys/fs/cgroup:/sys/fs/cgroup:ro」、「–stop-signal SIGRTMIN+3」の部分についての説明です。systemdが正常に稼働するための条件を満たすためにこの3つの部分が必要になります。
systemdが正常に稼働するための条件として「/tmpディレクトリがtmpfsにマウントされていること」と「/tmpディレクトリがtmpfsにマウントされていること」があるので「–tmpfs /tmp」、「–tmpfs /run」のオプションはそれを実現させています。
また、systemdが正常に稼働するための条件として「/sys/fs/cgroupが読込み権限付きでマウントされていること」があり、「-v /sys/fs/cgroup:/sys/fs/cgroup:ro」は/sys/fs/cgroupが読込み権限付きでマウントされていることを実現するためのオプションです。
最後にsystemdが正常に稼働するための条件として「シャットダウンシグナルがSIGRTMIN+3として定義されていること」があるので「–stop-signal SIGRTMIN+3」というオプションでそれを実現させてます。
「-p 8081:80」
クライアントからDockerコンテナの8081番ポートにアクセスすると、コンテナ内部の80番ポートにポートフォワーディングを行うようになっております。
コンテナにアクセスする
コンテナ内からの確認
まずラズベリーパイからコンテナに入ってみます。以下のコマンドで入ります。今回はコンテナの名前がapache-testなのでapache-testを指定して入ります。
$ sudo docker container exec -it apache-test /bin/bash
[root@apache-test /]#
Dockerfileの4行目でapacheを起動しています。実際にコンテナ内のapacheが起動しているかを見てみます。「active (running)」になっていることが確認できました。
[root@apache-test /]# systemctl status httpd
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
Active: active (running) since Sat 2021-02-06 02:43:38 UTC; 3h 21min ago
Docs: man:httpd(8)
man:apachectl(8)
Main PID: 30 (httpd)
Status: "Total requests: 0; Current requests/sec: 0; Current traffic: 0 B/sec"
CGroup: /docker/fa271539f7ee69d6c1dee9437c1aa8cd5e330cbcbf1e886632ff21f70afe7fbd/system.slice/httpd.service
tq30 /usr/sbin/httpd -DFOREGROUND
tq35 /usr/sbin/httpd -DFOREGROUND
tq36 /usr/sbin/httpd -DFOREGROUND
tq37 /usr/sbin/httpd -DFOREGROUND
tq38 /usr/sbin/httpd -DFOREGROUND
mq39 /usr/sbin/httpd -DFOREGROUND
Feb 06 02:43:38 apache-test systemd[1]: Starting The Apache HTTP Server...
Feb 06 02:43:38 apache-test httpd[30]: AH00558: httpd: Could not reliably determine the server's fully qualified d...essage
Feb 06 02:43:38 apache-test systemd[1]: Started The Apache HTTP Server.
Hint: Some lines were ellipsized, use -l to show in full.
コンテナ内でコンテナに割り振られたIPを確認しましょう。
[root@apache-test /]# ip a s eth0 | grep inet
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
ipを確認出来たら「exit」を打ってコンテナから出ましょう。
ラズベリーパイ側から(コンテナ外側から)の確認
ラズベリーパイの中からコンテナに対してcurlを打ってみます。以下のように設定したhtmlファイルにアクセスができることが確認できました。
$ curl http://172.17.0.2/index.html
Hello World, this is Apache site
まとめ

今回はDockerfileを取り上げて実際に動かしてみたけど、どうだったかな。

It’s soooo good !
こんな便利なものがあるなんて目から鱗だったわ!!明日から使ってみようと思う。
...
どうだったでしょうか。
今回はDockerfileを使用しました。どんな感じのものか理解の一助となれば幸いです。ラズベリーパイ内でdocker使うって人あんまいないかもしれないですが、、、。
というか、ジェシーとジャッカルを無理やり入れ込もうとして不自然さがにじみ出ていますね。。。
彼らにはいろいろな場面で相づちを打ってほしかったんですが。。。うまくキャラが立たないな。。。
はい、今日はここまで、以上。読んでいただきありがとうございました。
参考:「Docker実践ガイド 第2版 impress top gearシリーズ」
