Apache
docker
systemd

【学習メモ】 DockerのCentOS7にapache2.4をソースインストールしたけど時間がたつと終了している

More than 1 year has passed since last update.

はじめに

DockerのCentOS7にapache2.4をソースから入れてみました。
Docker runで起動しても、5分もしないうちにwebにアクセスできなくなっていて、execで入ってみると起動していたはずのapacheが落ちている。
解決策を探した一連の流れです。

apacheをコンテナ起動時に立ち上げるために、/sbin/initを引数にしているので、systemctlを使ってどうにか起動できるようにしたかったのでした。

結論:解決方法は2つ。

1.systemctlに追跡させないType=simpleで起動すること
2.mod_systemd.soを入れること

やったこと

環境
[apache]
OS:Centos:7.3.1611
インストール先:/opt/apache2.4.27/
httpd.conf :/opt/apache2.4.27/conf/httpd.conf
httpd.service :/usr/lib/systemd/system/httpd.service

apacheのログを確認

apacheのログレベルをwarnからdebugに変えてみる
### Dockerfile : イメージビルド時にログレベルを warn -> debug へ変更。
+ RUN sed -i -e 's/LogLevel\ warn/#LogLevel\ warn\nLogLevel\ debug/g' /opt/apache2.4.27/conf/httpd.conf

### httpd.conf
# LogLevel: Control the number of messages logged to the error_log.
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
#
- LogLevel warn
+ LogLevel debug
(後略)

結果、error_logに、apacheが終了したログは出なかった。

rsyslog.confで確認

Dockerfileのイメージビルド時にrsyslogをインストールしてログレベルをinfo->debugへ変更する。

修正内容
### Dockerfile
+RUN yum install -y rsyslog
+RUN sed -i -e 's/\.info/\.debug/g' /etc/rsyslog.conf

### /etc/rsyslog.conf
(前略)
-*.info;mail.none;authpriv.none;cron.none   /var/log/messages
+*.debug;mail.none;authpriv.none;cron.none  /var/log/messages
(後略)

結果、それっぽいのが出た。

rsyslog抜き出し
(前略)
Aug 15 19:18:16 localhost systemd: Starting The Apache HTTP Server...
(中略)
Aug 15 19:19:46 localhost systemd: httpd.service start operation timed out. Terminating.
Aug 15 19:21:16 localhost systemd: httpd.service stop-final-sigterm timed out. Killing.
Aug 15 19:21:16 localhost systemd: httpd.service: main process exited, code=killed, status=9/KILL
Aug 15 19:21:16 localhost systemd: Failed to start The Apache HTTP Server.
Aug 15 19:21:16 localhost systemd: Unit httpd.service entered failed state.
Aug 15 19:21:16 localhost systemd: httpd.service failed.
(後略)

KILLされていた。

The Apache HTTP Serverの文字列はどこから?
起動用に作った /usr/lib/systemd/system/httpd.service の
[Unit]
Description=The Apache HTTP Server
に記載。

apacheが終了する原因を調べる

出てきた。
Apache2.4 on CentOS7 でsystemctl start httpdで起動しない問題の対処法

どうやら mod_system.so が足りないようだけど、
そんなmoduleは入っていないので、

httpd.confにmoduleを追加しても
+LoadModule systemd_module modules/mod_systemd.so
当然起動しない。
httpd: Syntax error on line X of ./httpd.conf:
Cannot load modules/mod_systemd.so into server:
./modules/mod_systemd.so: cannot open shared object file: No such file or directory

mod_systemd.soを入れるのは面倒そうなので後回し。

systemdにpidを読ませる

systemdがTerminatingしてるのは間違いないのでsystemdの仕組みを調べる。
"fedora16でhttpd.serviceがsystemctl startで立ち上がらなかったマヌケな話"を読むと、どうやら/usr/lib/systemd/system/httpd.serviceにPIDファイルの指定ができる模様。
/opt/apache2.4.27/bin/httpd -Vでオプションを見ながら

httpd-Vを実行してオプションを確認
Server version: Apache/2.4.27 (Unix)
(中略)
Server compiled with....
(中略)
 -D DEFAULT_PIDLOG="logs/httpd.pid"
(後略)

/usr/lib/systemd/system/httpd.serviceにpidを追記してみた。

/usr/lib/systemd/system/httpd.serviceの中身抜粋
[Unit]
Description=The Apache HTTP Server
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=notify
ExecStart=/opt/apache2.4.27/bin/httpd  -DFOREGROUND
ExecReload=/opt/apache2.4.27/bin/httpd  -k graceful
ExecStop=/bin/kill -WINCH
KillSignal=SIGCONT
PrivateTmp=true
PIDFile=/opt/apache2.4.27/logs/httpd.pid

早速Dockerで起動して、
Apacheが動いているうちにsystemctl status httpdで状態を確認。

まずは動いている模様
[root@localhost /]# systemctl status httpd
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
   Active: activating (start) since Wed 2017-08-16 09:34:04 UTC; 25s ago
 Main PID: 52 (httpd)
   CGroup: /docker/2646b0d50d674a4cdd1a56e48c5f5e351513f4d0c3e02a2a697ccf6ebb1cda51/system.slice/httpd.service
           ├─52 /opt/apache2.4.27/bin/httpd -DFOREGROUND
           ├─63 /opt/apache2.4.27/bin/httpd -DFOREGROUND
           ├─64 /opt/apache2.4.27/bin/httpd -DFOREGROUND
           └─65 /opt/apache2.4.27/bin/httpd -DFOREGROUND
           ‣ 52 /opt/apache2.4.27/bin/httpd -DFOREGROUND

Aug 16 09:34:04 localhost systemd[1]: Starting The Apache HTTP Server...
Aug 16 09:34:04 localhost httpd[52]: AH00558: httpd: Could not reliably determine the server's fully qualifi...ssage
Hint: Some lines were ellipsized, use -l to show in full.

しかし時間が経つと

終了。
[root@localhost /]# systemctl status httpd
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
   Active: failed (Result: signal) since Wed 2017-08-16 09:37:04 UTC; 3min 12s ago
  Process: 52 ExecStart=/opt/apache2.4.27/bin/httpd -DFOREGROUND (code=killed, signal=KILL)
 Main PID: 52 (code=killed, signal=KILL)
   CGroup: /docker/2646b0d50d674a4cdd1a56e48c5f5e351513f4d0c3e02a2a697ccf6ebb1cda51/system.slice/httpd.service

Aug 16 09:34:04 localhost systemd[1]: Starting The Apache HTTP Server...
Aug 16 09:34:04 localhost httpd[52]: AH00558: httpd: Could not reliably determine the server's fully qualifi...ssage
Aug 16 09:35:34 localhost systemd[1]: httpd.service start operation timed out. Terminating.
Aug 16 09:37:04 localhost systemd[1]: httpd.service stop-final-sigterm timed out. Killing.
Aug 16 09:37:04 localhost systemd[1]: httpd.service: main process exited, code=killed, status=9/KILL
Aug 16 09:37:04 localhost systemd[1]: Failed to start The Apache HTTP Server.
Aug 16 09:37:04 localhost systemd[1]: Unit httpd.service entered failed state.
Aug 16 09:37:04 localhost systemd[1]: httpd.service failed.
Hint: Some lines were ellipsized, use -l to show in full.

終了している模様。

Type=forkingしてみる

systemdの動きの流れをなんとなく理解して、"Systemd入門(4) - serviceタイプUnitの設定ファイル"を見ながらhttpd.serviceの設定ファイルを再確認する。
PIDFileはfork型サービスのメインプロセスのPIDファイルとあるけど、

httpd.service抜粋
[Service]
Type=notify

なんとnotify。PIDFileは効いてないのか。
httpd.serviceは"[CentOS7]初めてsystemdを使ってみたときのメモ"を参考にしていた。参考記事の参照元を見ると、Type=forkingでないとPIDを見に行かないらしい。
参考にした記事では、systemctl status httpdの結果がStart ed だから、問題なく起動している。同じCentOSでも何が違うのか…(→yum install httpdはmod_systemd.soが入る)

systemctlの結果の差
(成功)
localhost systemd[1]: Started The Apache HTTP Server...
(失敗)
localhost systemd[1]: Starting The Apache HTTP Server...

とりあえず、PIDFileはType=forkingでないと機能しない模様なので

notifyからforkingへ
[Service]
Type=forking

変更してやってみるけど、結局Apacheは時間とともに終了してしまう。
ログは一緒。pidが違うくらい。

さらに調べるとこんな記事が。
"Systemd メモ書き#tyepforking"にsystemdのサービスではType=notifyが推奨されるとあり、apacheでmod_systemdが利用できる(知ってた)
現在はmod_systemdは使わない方向で解決策を探してるのだよ…

ServerNameを指定する

ダメもとで。
ServerNameのエラーが出てるのでhttpd.confのSeverNameを設定。
Type=forikingのままやってみたけど、AH00558のエラーが消えただけで終了してしまう。(当然)

Typeをsimpleでやってみる

いろいろ試すしかない。
httpd.serviceのTypeが問題そうなのは分かったので
まずはType=simpleに変えてみる。

Type=simple
[Service]
Type=simple

終了しないみたい。ログも変わった。

systemctl
[root@localhost /]# 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 Wed 2017-08-16 10:45:32 UTC; 3min 46s ago
 Main PID: 53 (httpd)
   CGroup: /docker/5933466f5ea9ea58e4f51153eff4e2703741aa01177f75533c95796f11536363/system.slice/httpd.service
           ├─53 /opt/apache2.4.27/bin/httpd -DFOREGROUND
           ├─63 /opt/apache2.4.27/bin/httpd -DFOREGROUND
           ├─64 /opt/apache2.4.27/bin/httpd -DFOREGROUND
           └─66 /opt/apache2.4.27/bin/httpd -DFOREGROUND
           ‣ 53 /opt/apache2.4.27/bin/httpd -DFOREGROUND

Aug 16 10:45:32 localhost systemd[1]: Started The Apache HTTP Server.
Aug 16 10:45:32 localhost systemd[1]: Starting The Apache HTTP Server...

Startingのログが前後しているようだけど、
Startupが終了する前に、httpdに関するログは出ていない。

/var/log/messages
(前略)
Aug 16 10:45:32 localhost systemd: Started The Apache HTTP Server.
Aug 16 10:45:32 localhost systemd: Starting The Apache HTTP Server...
(中略)
Aug 16 10:45:32 localhost systemd: Started Cleanup of Temporary Directories.
Aug 16 10:45:32 localhost systemd: Startup finished in 17h 40.036s (kernel) + 458ms (userspace) = 17h 40.495s.

起動させるだけなら、Type=simpleで動作した。
落ちたときのために、ServiceにRestartを設定すると良い模様

mod_systemdを入れる

Type=simpleで起動はできたので
面倒そうなmod_systemdを入れて対応することを考える。
mod_system.soを調べても、apache2.5のリファレンスしか出てこない。
まだ最新って2.4だと思ったんだけど…2.5ってどこからDLするの?
yum install httpdで動いているようなので、その中にmod_systemd.soがあるか確認する。

httpd-2.4*el7.centos*x86_64.rpm
yum install --downloadonly --downloaddir=/tmp httpd
  • 投稿検証当時2017年08月16日はhttpd-2.4.6-45.el7.centos.4.x86_64.rpm

rpmの中身を確認してみる。

検索してみる
rpm -pql /tmp/httpd-2.4*el7.centos*x86_64.rpm | grep mod_systemd.so
/usr/lib64/httpd/modules/mod_systemd.so

あったーーーーーーーー
取り出す

取り出す
cd /tmp
rpm2cpio /tmp/httpd-2.4*el7.centos*x86_64.rpm | cpio -id  ./usr/lib64/httpd/modules/mod_systemd.so

モジュールはコンパイル時に指定って聞いたような覚えがあるから、展開したソースファイルのmodulesフォルダに入れようとした。
modules以下にフォルダがありすぎて、どこに入れれば良いかわからない。
諦めてインストール後のmodulesフォルダに入れて、httpd.confでIncludeしてみる。

Dockerfile
RUN cp /tmp/usr/lib64/httpd/modules/mod_systemd.so /opt/apache2.4.27/modules
RUN sed -i -e 's/<IfModule\ unixd_module>/LoadModule\ systemd_module\ modules\/mod_systemd.so\n<IfModule\ unixd_module>/g' /opt/apache2.4.27/conf/httpd.conf

起動してみるとsystemctlを見ると…startedになっている!!

インストール後のmodulesフォルダに入れてIncludeしたとき
[root@localhost /]# 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 Wed 2017-08-16 17:55:17 UTC; 53s ago
 Main PID: 60 (httpd)
   Status: "Total requests: 2; Current requests/sec: 0; Current traffic:   0 B/sec"
   CGroup: /docker/dbdb7456c17c8f6972f66d619508f97673c4962c4a85186049189deb3b928c0c/system.slice/httpd.service
           ├─60 /opt/apache2.4.27/bin/httpd -DFOREGROUND
           ├─66 /opt/apache2.4.27/bin/httpd -DFOREGROUND
           ├─67 /opt/apache2.4.27/bin/httpd -DFOREGROUND
           └─68 /opt/apache2.4.27/bin/httpd -DFOREGROUND
           ‣ 60 /opt/apache2.4.27/bin/httpd -DFOREGROUND

Aug 16 17:55:17 localhost systemd[1]: Starting The Apache HTTP Server...
Aug 16 17:55:17 localhost systemd[1]: Started The Apache HTTP Server.

読み込まれているモジュールも確認。

httpd-Mで確認
/opt/apache2.4.27/bin/httpd -M | grep systemd
 systemd_module (shared)

コンパイルしなくても、フォルダに入れれば動いた。
(∩´∀`)∩