🐳
Docker DesktopのgRPC FUSE / VirtioFSが有効だとMySQLのentrypoint.shでエラーになる
Docker Desktop for Mac を 2.4.0.0
に更新したところ、突然 MySQL のコンテナ初期化時に /entrypoint.sh
がエラーになったのでメモ。
手っ取り早く解決策(?)
- gRPC FUSE / VirtioFS を無効化して Docker Desktop を再起動
以下、筆者が遭遇した事例のご紹介です。
環境
M1 Macを購入したので、改めて確認しました
Key | Value |
---|---|
Mac OS X | 12.4 |
Docker | 20.10.16 |
Docker Desktop | 2.4.0.0 〜 4.8.2 |
詳細
$ sw_vers
ProductName: macOS
ProductVersion: 12.4
BuildVersion: 21F79
$ docker version
Client: Docker Engine - Community
Version: 20.10.16
API version: 1.41
Go version: go1.18.2
Git commit: aa7e414fdc
Built: Wed May 11 16:22:17 2022
OS/Arch: darwin/arm64
Context: default
Experimental: true
Server: Docker Desktop 4.8.2 (79419)
Engine:
Version: 20.10.14
API version: 1.41 (minimum version 1.12)
Go version: go1.16.15
Git commit: 87a90dc
Built: Thu Mar 24 01:45:44 2022
OS/Arch: linux/arm64
Experimental: true
containerd:
Version: 1.5.11
GitCommit: 3df54a852345ae127d1fa3092b95168e4a88e2f8
runc:
Version: 1.0.3
GitCommit: v1.0.3-0-gf46b6ba
docker-init:
Version: 0.19.0
GitCommit: de40ad0
現象
準備
単純な SQL 文をわざわざシェルを介して実行させていますが、実際は他の処理も挟んでいます。
試してみましたが、 SQL を直接実行する場合はこのエラーは起きませんでした。
.
└── docker-entrypoint-initdb.d
├── entry.sh
└── files
└── create_db.sql
docker-entrypoint-initdb.d/entry.sh
#!/bin/bash
docker_process_sql < /tmp/files/create_db.sql
docker-entrypoint-initdb.d/files/create_db.sql
CREATE SCHEMA IF NOT EXISTS `sample`;
USE `sample`;
CREATE TABLE IF NOT EXISTS `user` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(10) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE = InnoDB;
MySQL のコンテナを起動
すると、謎の Permission denied
が起こります。
尚、ボリュームの :ro
オプションの有無では特に変化がありませんでした。
$ docker run --rm \
-v $(PWD)/docker-entrypoint-initdb.d/entry.sh:/docker-entrypoint-initdb.d/entry.sh:ro \
-v $(PWD)/docker-entrypoint-initdb.d/files:/tmp/files:ro \
-e MYSQL_ROOT_PASSWORD=password \
mysql:latest
(略)
[Note] [Entrypoint]: /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/entry.sh
/usr/local/bin/docker-entrypoint.sh: /docker-entrypoint-initdb.d/entry.sh: /bin/bash: bad interpreter: Permission denied
軽く調査
「 bad interpreter
って、あなたさっきまで動いてたじゃない...」と思いつつ、Permission denied
とあるのでまずは権限を確認。問題ありません。
# コンテナ内
$ ls -l /tmp/files
total 4
-rw-r--r-- 1 root root 198 Oct 2 17:11 create_db.sql
$ ls -l /docker-entrypoint-initdb.d
total 4
-rw-r--r-- 1 root root 59 Oct 2 17:11 entry.sh
# そんなはずないと思いつつ一応...
$ ls -l /bin/bash
-rwxr-xr-x 1 root root 1168776 Apr 18 2019 /bin/bash
ファイルの権限を変えて実行
一度コンテナから出て権限を変更し、再度実行。エラーが変わります。
シェルの実行はできますが、 docker_process_sql
が見つからないと言われてしまいます。
$ chmod -R 777 docker-entrypoint-initdb.d
$ docker run --rm \
-v $(PWD)/docker-entrypoint-initdb.d/entry.sh:/docker-entrypoint-initdb.d/entry.sh:ro \
-v $(PWD)/docker-entrypoint-initdb.d/files:/tmp/files:ro \
-e MYSQL_ROOT_PASSWORD=password \
mysql:latest
(略)
[Note] [Entrypoint]: /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/entry.sh
/docker-entrypoint-initdb.d/entry.sh: line 3: docker_process_sql: command not found
権限を確認。問題ありません。
# コンテナ内
$ ls -l /tmp/files
total 4
-rwxrwxrwx 1 root root 198 Oct 2 17:11 create_db.sql
$ ls -l /docker-entrypoint-initdb.d
total 4
-rwxrwxrwx 1 root root 59 Oct 2 17:11 entry.sh
$ ls -l /bin/bash
-rwxr-xr-x 1 root root 1168776 Apr 18 2019 /bin/bash
少し深堀り
実際にエラーが出ている部分のソースコードを見てみます。
下記、該当の関数のコードとなります。
docker_process_init_files()
docker_process_init_files() {
# mysql here for backwards compatibility "${mysql[@]}"
mysql=( docker_process_sql )
echo
local f
for f; do
case "$f" in
*.sh)
# https://github.com/docker-library/postgres/issues/450#issuecomment-393167936
# https://github.com/docker-library/postgres/pull/452
if [ -x "$f" ]; then
mysql_note "$0: running $f"
"$f"
else
mysql_note "$0: sourcing $f"
. "$f"
fi
;;
*.sql) mysql_note "$0: running $f"; docker_process_sql < "$f"; echo ;;
*.sql.gz) mysql_note "$0: running $f"; gunzip -c "$f" | docker_process_sql; echo ;;
*.sql.xz) mysql_note "$0: running $f"; xzcat "$f" | docker_process_sql; echo ;;
*) mysql_warn "$0: ignoring $f" ;;
esac
echo
done
}
すると、下記の不明点が見えてきます。しかしながら、実働環境への影響が無いことを踏まえてこれ以上の調査は断念しました。
-
if [ -x "$f" ]; ...
で実行権限のチェックをしているにも関わらず、1回目の実行で... running ...
のログが出ている(644
にも関わらず)。gRPC FUSE を無効化して実行するとログは... sourcing ...
になり、こちらは期待通りの動作
最後に
2.4.0.0
以降は 他にも色々つらい...
Linux や Docker のファイルシステムは詳しくないので大きな見落としがあるかもしれません。もし何かあればご指摘いただければ幸いです。
参考リンク
現象は異なるものの、同様に gRPC FUSE が有効な場合の不具合事例
Discussion