出来心でこのblogをホストしているubuntuをアプリ込みでupdateしたら、Wordpressがすっかり動かなくなってしまい、色々やり直した話。

このblogをホストしているubuntuにloginしたら色々updateが溜まっていたようなので、気楽にupdateしてみた。するとここのwordpressが動かなくなった。どうも無理やりroutedで動かしていたのが動かなくなっていた。

今まではNATをしないためにiptablesをdisableにして、host側にrouting設定を入れておけばcontainerに対してもL3 routingしてくれてたのだが、どう設定してもそれがうまくいかなくなっていた。NATしない時はiptableやめちゃえって書いてあったはずの公式ドキュメントもない。いつの頃からかよく見るとiptablesのchain項目に’DOCKER xxx’というのが増えている。ここに設定している内容はiptables -Fとかでは全部消えないようで、iptables=falseとかしてもうまく動かない。chatgptが

どうやら新たに独自にrouted typeのbridge(network)を作ると、iptables他の設定はいじらずに通常のL3 networkはしてくれるっぽい。ただ、現在動いているコンテナのネットワーク設定は変えられないので、改めてcontainerを作るところから始めなきゃ行けないようだ。

とりあえず現在稼働中のやつのimageをとっておかねばというところで、mysql、wordpressのimageをcommitしておく

$ sudo docker commit momose-wordpress miscmemo-wordpress-latest:20240818
sha256:495adc56fa9dbd1cda8c969f7ab82d6f474d2871698e1d426f99523dd25efa04
$ sudo docker commit wp-mysql mysql:5.7.21-my20240818
sha256:4fb2a23c3b0016c3087e39be1453c01ce81a18df897a517a253d54a7f6f87bca

routedになるnetworkを作る。v6 prefixも指定し、gateway_mode_ipv4をroutedにし enable_ip_masqueradeをfalseにするのがポイント。

$ sudo docker network create --driver bridge --subnet 172.18.0.0/16 --ipv6 --subnet 2001:2c0:cc17:c302::/64  --opt com.docker.network.bridge.gateway_mode_ipv4=routed   --opt com.docker.network.bridge.enable_ip_masquerade=false   routed-net
e8df9d66c9e9b68d22eddd0464451b1e955f14df0d51fc14d24bfee383c1a30b

退避させた(というかcommitした)imageを使ってこのnetwork上にcontainerを作る。前のやつは止めたままにしておく。今までアドレスはhost起動直後に各コンテナを手動で起動させることでIP address固定にするという原始的とも言えないほど原始的なことをしていたが、今回からは専用bridgeを作ってそこでIPアドレスを固定にする。

$ sudo docker run -d --name miscmemo-wp-mysql --network routed-net --ip 172.18.0.2 -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=mysql -e MYSQL_USER=wordpress -e MYSQL_PASSWORD=wordpress -p 3306:3306   mysql:5.7.21-my20240818
3abb3d2c34be91cbf8f0d48bee9491d84117713efaef12b371376e8502c02893
sudo docker run --network routed-net --ip 172.18.0.3 -v /var/www/html/:/var/www/html --name miscmemo-wordpress -d miscmemo-wordpress-latest:20240818
31ee2c1176cc7258b09fdf82b3c61d95e4762b6040c32b62c3c309ff743b4c17

ごちゃごちゃいじりすぎたので、docker本体をrestart。miscmemo-wordpress (wordpress本体; 172.18.0.3からmiscmemo-wp-mysql (wordpress用のmysql; 172.18.0.2)へのpingは通る。が、外(10.0.0.1とか)からは通らない。もちろん10.0.0.1には172.16.0.0/14宛のrouteはこのubuntu本体がnexthopになるようなrouteを設定してある。

これは例によってiptablesの設定が足りていなかろうということで、miscmemo-wordpress tcp:80宛は通るようにしておく。port限定しなくてもip全部通せばいいんじゃないかとも思うが、どうせ80以外は空いていないからとりあえずこれで。

$ sudo iptables -L
[sudo] momose のパスワード: 
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy DROP)
target     prot opt source               destination         
DOCKER-USER  all  --  anywhere             anywhere            
DOCKER-FORWARD  all  --  anywhere             anywhere            

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain DOCKER (2 references)
target     prot opt source               destination         
ACCEPT     tcp  --  anywhere             172.18.0.2           tcp dpt:mysql
ACCEPT     icmp --  anywhere             anywhere            
DROP       all  --  anywhere             anywhere            
DROP       all  --  anywhere             anywhere            

Chain DOCKER-BRIDGE (1 references)
target     prot opt source               destination         
DOCKER     all  --  anywhere             anywhere            
DOCKER     all  --  anywhere             anywhere            

Chain DOCKER-CT (1 references)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED

Chain DOCKER-FORWARD (1 references)
target     prot opt source               destination         
DOCKER-CT  all  --  anywhere             anywhere            
DOCKER-ISOLATION-STAGE-1  all  --  anywhere             anywhere            
DOCKER-BRIDGE  all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
RETURN     all  --  anywhere             anywhere            
DOCKER-ISOLATION-STAGE-2  all  --  anywhere             anywhere            
DOCKER-ISOLATION-STAGE-2  all  --  anywhere             anywhere            

Chain DOCKER-ISOLATION-STAGE-2 (2 references)
target     prot opt source               destination         
DROP       all  --  anywhere             anywhere            
DROP       all  --  anywhere             anywhere            

Chain DOCKER-USER (1 references)
target     prot opt source               destination         
momose@peso:~$ sudo iptables -I DOCKER 1 -d 172.18.0.3 -p tcp --dport 80 -j ACCEPT
momose@peso:~$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy DROP)
target     prot opt source               destination         
DOCKER-USER  all  --  anywhere             anywhere            
DOCKER-FORWARD  all  --  anywhere             anywhere            

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain DOCKER (2 references)
target     prot opt source               destination         
ACCEPT     tcp  --  anywhere             172.18.0.3           tcp dpt:http
ACCEPT     tcp  --  anywhere             172.18.0.2           tcp dpt:mysql
ACCEPT     icmp --  anywhere             anywhere            
DROP       all  --  anywhere             anywhere            
DROP       all  --  anywhere             anywhere            

Chain DOCKER-BRIDGE (1 references)
target     prot opt source               destination         
DOCKER     all  --  anywhere             anywhere            
DOCKER     all  --  anywhere             anywhere            

Chain DOCKER-CT (1 references)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED

Chain DOCKER-FORWARD (1 references)
target     prot opt source               destination         
DOCKER-CT  all  --  anywhere             anywhere            
DOCKER-ISOLATION-STAGE-1  all  --  anywhere             anywhere            
DOCKER-BRIDGE  all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
RETURN     all  --  anywhere             anywhere            
DOCKER-ISOLATION-STAGE-2  all  --  anywhere             anywhere            
DOCKER-ISOLATION-STAGE-2  all  --  anywhere             anywhere            

Chain DOCKER-ISOLATION-STAGE-2 (2 references)
target     prot opt source               destination         
DROP       all  --  anywhere             anywhere            
DROP       all  --  anywhere             anywhere            

Chain DOCKER-USER (1 references)
target     prot opt source               destination         

この状態でもmiscmemo.momose.orgまたは172.18.0.3にwebで繋いでも’Error establishing database connection’になる。DBにloginできないということか?

db containerを作るときは-p 3306:3306してあるので、localhostに繋げばいけるはずだが、やはりいけない(これは謎)ので、172.18.0.2にmysql clientで繋いでみる。

docker runしたときにMYSQL_USERとかMYSQL_PASSWORD設定したせいか、それらのユーザは設定されているが、databaseとしてwordpressは定義されていない。

mysql> select User from mysql.user;
+---------------+
| User          |
+---------------+
| root          |
| wordpress     |
| mysql.session |
| mysql.sys     |
| root          |
+---------------+
5 rows in set (0.01 sec)
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
+--------------------+
2 rows in set (0.00 sec)

結論から言えば、これはvolumeの設定の仕方(-v option)の設定の仕方が悪い。上記例では ‘-v /var/lib/mysql’としてしか設定していないが、これはcontainer内部の/var/lib/mysqlをホスト側の匿名ボリュームを使え、ということしか指定していない。今回は新たに匿名ボリュームを作ってそれを内部で使おうとしているのに過ぎないので、今までのmysqlのデータは見れなくなっている。

今まで使っていたmysqlコンテナはdocker inspectすると

        "Mounts": [
            {
                "Type": "volume",
                "Name": "437162831f28b01734805001401217d94ae83d2c2ba91df5121bf27b1ec582c2",
                "Source": "/var/lib/docker/volumes/437162831f28b01734805001401217d94ae83d2c2ba91df5121bf27b1ec582c2/_data",
                 "Destination": "/var/lib/mysql",

で、hostの437…というvolumeを使っていたが、新しい方だと

        "Mounts": [
            {
                "Type": "volume",
                "Name": "ffbcf68f7e10fe79b6252f374094d4fd9ed61e0ac884ece61966cbdb7595b7cb",
                "Source": "/var/lib/docker/volumes/ffbcf68f7e10fe79b6252f374094d4fd9ed61e0ac884ece61966cbdb7595b7cb/_data",
                "Destination": "/var/lib/mysql",
 

となっていて、全く別のffbcという匿名ボリュームを指している。なので、旧データが復活できていない。

というわけで、mysqlデータが入っているはずの匿名ボリュームを指してコンテナを作り直す。

$ sudo docker run -d --name miscmemo-wp-mysql --network routed-net --ip 172.18.0.2 -v 437162831f28b01734805001401217d94ae83d2c2ba91df5121bf27b1ec582c2:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=mysql -e MYSQL_USER=wordpress -e MYSQL_PASSWORD=wordpress -p 3306:3306   mysql:5.7.21
434a61c30c7b967c440adbd8c3b518825da99e9b1be1b7e7463eb6f867a71c7f

一応これで旧mysqlデータも読み込めて、接続できるようになった。

が、なんかのはずみですぐこのmysqlコンテナが落ちる。通常の閲覧画面は見えるが、admin画面にアクセスしたら落ちる(画面的にはしばらく待たせられる状態になる。その後切れる)、loginしようとしたら落ちる、などなど。

原因はよくわからないので、この際旧データを吸い上げて新しいコンテナを設置の上、そのデータを読み込ませて復旧させることにした。

$ mysqldump -h 127.0.0.1 -u root --ssl-mode=DISABLED -p wordpress > miscmemo-wp.sql
Enter password: 
-- Warning: column statistics not supported by the server.

ここで読み込んだファイルの先頭に、CREATE DATABASE wordpress;USE wordpress;を入れる。

$ mysql -h 172.18.0.2 -P 3306 -u root -p < miscmemo-wp.sql
$ mysql -h 172.18.0.2 -P 3306 -u root -p 
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 19
Server version: 9.4.0 MySQL Community Server - GPL

Copyright (c) 2000, 2025, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases
    -> ;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| wordpress          |
+--------------------+
5 rows in set (0.01 sec)

mysql> use wordpress;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+-----------------------+
| Tables_in_wordpress   |
+-----------------------+
| wp_aal_products       |
| wp_aal_request_cache  |
| wp_aal_tasks          |
| wp_commentmeta        |
| wp_comments           |
| wp_links              |
| wp_options            |
| wp_postmeta           |
| wp_posts              |
| wp_pz_linkcard        |
| wp_term_relationships |
| wp_term_taxonomy      |
| wp_termmeta           |
| wp_terms              |
| wp_usermeta           |
| wp_users              |
+-----------------------+
16 rows in set (0.01 sec)

mysql> ^DBye

rootユーザでセットアップしてしまったためか、wordpress dbにアクセスできるのがwordpressユーザではなくrootユーザになってしまったので、wordpressコンテナの/var/www/wp-config.phpのUSERとPASSWORDをroot用のに変更、起動し直すと今度はうまくいった。adminアクセスとかも問題なさそう。

ただ、adminダッシュボード画面ではwordpress.orgにアクセスできないとか言っている。どうも外にうまく繋がっていないようだ。iptableで外向きもいけるように設定。

$ sudo iptables -I DOCKER 1 -s 172.18.0.3 -p tcp -j ACCEPT

実は外向けルータでnatのルールに172.18.0.3が入っていないことがわかったので、そっちも設定。FreeBSDの/etc/ipnat.rules、172.16.0.0/16だったのを172.16..0.0/14に。今までも172.17.x.xだったからいけなかったはずなんだがいけていたのはちょっと不思議ではある。

map ng0 172.16.0.0/14 -> 0.0.0.0/32 portmap tcp/udp 60000:65000
#map ng0 172.16.0.0/46 -> 0.0.0.0/32 icmpidmap icmp
map ng0 172.16.0.0/14 -> 0.0.0.0/32 proxy port ftp ftp/tcp
map ng0 172.16.0.0/14 -> 0.0.0.0/32
#

これで一通り復活はできた。途中作りまくった匿名ボリュームとか今後使わないだろうimageとかは決しておく。今のところこのエントリをかける程度までは安定して動いている。

iptablesを次のreboot前までには安定させないといけない。

ipv6を復活させよう。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です