Dockerの生態系に迫る!第2回:DockerイメージをDIY、Dockerfileの活用

スポンサーリンク
tech系(Linux)
スポンサーリンク

オープニング

ジャッカル
ジャッカル

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

ジェシー
ジェシー

ジェシーよ~♪

インターネットという大海に生息する高度な精度を誇るOSSにクローズアップし、どんなものなのかを触れ合うことで理解するシリーズ。

本シリーズは鯨さんがトレードマークのDockerにクローズアップしその生態系に迫ります。第2回目はDockerfileです。

Dockerの特徴の一つに環境で使用する実行ファイルやアプリケーションのパッケージ化の手順を自動化できることが挙げられます。そこにはDocker独自の概念、Dockerfileの存在があります。今回はそのDockerfileにフォーカスし、実際に手を動かしてみていこうと思います。

以下の記事でわからない用語などがあれば前回の記事(以下)も参考にしてください。

https://apao-m-appare99999.com/?p=466

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をインストールしてます。

httpdはHTTPサーバを構築するためのOSS(オープンソースソフトウェア)です。
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シリーズ」

タイトルとURLをコピーしました