Docker-compose tmpfs не работает
У меня есть файл файл для докеры, который я пытаюсь защитить, создав корневые тома контейнеров, которые он создает только для чтения.
Соответствующие части docker-compose.yml
:
version: '2'
services:
mysql:
image: mariadb:10.1
read_only: true
tmpfs:
- /var/run/mysqld:uid=999,gid=999
- /tmp
volumes:
- mysql:/var/lib/mysql
restart: always
volumes:
mysql:
Проблема в том, что tmpfs
не создается. Если я запускаю экземпляр контейнера с помощью docker-compose run --rm mysql /bin/bash
, каталог /var/run/mysqld
остается доступным только для чтения, несмотря на запись tmpfs
, и любая попытка touch /var/run/mysqld/foo
завершается с ошибкой. Так как именно MySQL создает свой сокет и файл pid, это приводит к сбою всего процесса. Я не уверен, почему запись tmpfs
не работает в этом случае.
mysql_1 | 2017-01-27 20:53:45 140515784030144 [Note] mysqld (mysqld 10.1.21-MariaDB-1~jessie) starting as process 1 ...
mysql_1 | 2017-01-27 20:53:45 140515784030144 [Note] InnoDB: Using mutexes to ref count buffer pool pages
mysql_1 | 2017-01-27 20:53:45 140515784030144 [Note] InnoDB: The InnoDB memory heap is disabled
mysql_1 | 2017-01-27 20:53:45 140515784030144 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
mysql_1 | 2017-01-27 20:53:45 140515784030144 [Note] InnoDB: GCC builtin __atomic_thread_fence() is used for memory barrier
mysql_1 | 2017-01-27 20:53:45 140515784030144 [Note] InnoDB: Compressed tables use zlib 1.2.8
mysql_1 | 2017-01-27 20:53:45 140515784030144 [Note] InnoDB: Using Linux native AIO
mysql_1 | 2017-01-27 20:53:45 140515784030144 [Note] InnoDB: Using SSE crc32 instructions
mysql_1 | 2017-01-27 20:53:45 140515784030144 [Note] InnoDB: Initializing buffer pool, size = 256.0M
mysql_1 | 2017-01-27 20:53:45 140515784030144 [Note] InnoDB: Completed initialization of buffer pool
mysql_1 | 2017-01-27 20:53:45 140515784030144 [Note] InnoDB: Highest supported file format is Barracuda.
mysql_1 | 2017-01-27 20:53:48 140515784030144 [Note] InnoDB: 128 rollback segment(s) are active.
mysql_1 | 2017-01-27 20:53:48 140515784030144 [Note] InnoDB: Waiting for purge to start
mysql_1 | 2017-01-27 20:53:48 140515784030144 [Note] InnoDB: Percona XtraDB (http://www.percona.com) 5.6.34-79.1 started; log sequence number 239403989
mysql_1 | 2017-01-27 20:53:48 140515005662976 [Note] InnoDB: Dumping buffer pool(s) not yet started
mysql_1 | 2017-01-27 20:53:48 140515784030144 [Note] Plugin 'FEEDBACK' is disabled.
mysql_1 | 2017-01-27 20:53:49 140515784030144 [Note] Server socket created on IP: '::'.
mysql_1 | 2017-01-27 20:53:49 140515784030144 [ERROR] Can't start server : Bind on unix socket: Read-only file system
mysql_1 | 2017-01-27 20:53:49 140515784030144 [ERROR] Do you already have another mysqld server running on socket: /var/run/mysqld/mysqld.sock ?
mysql_1 | 2017-01-27 20:53:49 140515784030144 [ERROR] Aborting
Я могу проверить правильность разрешений в каталоге (и что UID пользователя mysql
равен 999):
$ ls -la /var/run/mysqld
total 8
drwxrwxrwx 2 mysql mysql 4096 Jan 17 22:14 .
drwxr-xr-x 4 root root 4096 Jan 18 22:55 ..
Но я все еще не могу:
$ touch /var/run/mysqld/foo
touch: cannot touch '/var/run/mysqld/foo': Read-only file system
Даже если я выполняю роль root.
Любые идеи, что я делаю неправильно?
В стороне, файловая система /tmp
работает нормально.
Ответы
Ответ 1
Я делал некоторые тесты в этом отношении, похоже, что каталог /var/run
является специальным в докере.
Вот пример конфигурации и вывода:
ubuntu:
image: ubuntu
command: "bash -c 'mount'"
tmpfs:
- /var/run
- /var/cache
Запуск docker-compose up ubuntu
показывает, что монтируется. Может видеть, что /var/cache
установлен, но /var/run
нет.
...
ubuntu_1 | tmpfs on /var/cache type tmpfs (rw,nosuid,nodev,noexec,relatime)
...
Если вы используете docker-compose run ubuntu bash
, вы можете видеть, что он также установлен там, но не /var/run
.
Причина в том, что /var/run
обычно является символической ссылкой на /run
, и поэтому вы создаете /var/run/mysql
, поскольку tmpfs не работает.
Он будет работать, если вы измените его на /run/mysql
, но /run
обычно монтируется как tmpfs, так что вы можете просто сделать /run
tmpfs. Например:
ubuntu:
image: ubuntu
command: "bash -c 'mount'"
tmpfs:
- /run
- /var/cache
Примечание. Я хотел бы изменить свой ответ и показать способ сделать это, используя volumes
:
services:
ubuntu:
image: ubuntu
command: "bash -c 'mount'"
volumes:
- cache_vol:/var/cache
- run_vol:/run
volumes:
run_vol:
driver_opts:
type: tmpfs
device: tmpfs
cache_vol:
driver_opts:
type: tmpfs
device: tmpfs
Это также позволяет вам совместно использовать монтируемые tmpfs
.
Ответ 2
это некоторые изображения, такие как alpine
, каталог /var/run
просто ссылка на /run
Вы можете проверить это с помощью
$ docker run --rm -ti mariadb:10.1 ls -lh /var/run
lrwxrwxrwx 1 root root 4 Aug 7 13:02 /var/run -> /run
Это означает, что /var/run/mysqld
на самом деле /run/mysqld
ваш обновленный docker-compose.yml
version: '2'
services:
mysql:
image: mariadb:10.1
read_only: true
tmpfs:
- /run/mysqld:uid=999,gid=999
- /tmp
volumes:
- mysql:/var/lib/mysql
restart: always
volumes:
mysql:
в этом случае просто сделайте так, чтобы ваши tmpfs указали на /run
похоже, что каталог /var/run является специальным в докере.
нет, это только потому, что это ссылка