J'ai un fichier docker-compose que j'essaye de sécuriser en rendant les volumes racine des conteneurs qu'il crée en lecture seule.
Parties pertinentes de 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:
Le problème est que le tmpfs
n'est pas en cours de création. Si j'exécute une instance du conteneur à l'aide de docker-compose run --rm mysql /bin/bash
, les /var/run/mysqld
le répertoire est toujours en lecture seule malgré l'entrée tmpfs
et toute tentative de touch /var/run/mysqld/foo
échoue. Puisque c'est là que MySQL place son fichier socket et pid, cela provoque l'échec du tout. Je ne sais pas pourquoi l'entrée tmpfs
ne fonctionne pas dans ce cas.
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
Je peux vérifier que les autorisations sur le répertoire sont correctes (et que l'UID de l'utilisateur mysql
est 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 ..
Mais je ne peux toujours pas:
$ touch /var/run/mysqld/foo
touch: cannot touch '/var/run/mysqld/foo': Read-only file system
Même si je lance en tant que root.
Des idées sur ce que je fais mal?
En passant, le /tmp
le système de fichiers fonctionne correctement.
J'ai fait quelques tests à cet égard, il semble que le répertoire /var/run
Soit spécial dans docker.
Voici quelques exemples de configuration et de sortie:
ubuntu:
image: ubuntu
command: "bash -c 'mount'"
tmpfs:
- /var/run
- /var/cache
L'exécution de docker-compose up ubuntu
Montre ce qui est monté. Peut voir que /var/cache
Est monté mais que /var/run
Ne l'est pas.
...
ubuntu_1 | tmpfs on /var/cache type tmpfs (rw,nosuid,nodev,noexec,relatime)
...
Si vous utilisez docker-compose run ubuntu bash
, Vous pouvez voir qu'il est également monté là mais pas /var/run
.
La raison en est que /var/run
Est normalement un lien symbolique vers /run
Et donc que vous créez /var/run/mysql
En tant que tmpfs ne fonctionne pas.
Cela fonctionnera si vous le changez en /run/mysql
, Mais /run
Est normalement monté comme tmpfs de toute façon, vous pourriez tout aussi bien faire de /run
Un tmpfs. Ainsi:
ubuntu:
image: ubuntu
command: "bash -c 'mount'"
tmpfs:
- /run
- /var/cache
Remarque: je voudrais modifier ma réponse et montrer comment procéder à l'aide de 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
Cela vous permet également de partager les montures tmpfs
si nécessaire.
quelques images comme Alpine
le répertoire /var/run
n'est qu'un lien vers /run
vous pouvez vérifier qu'en utilisant
$ docker run --rm -ti mariadb:10.1 ls -lh /var/run
lrwxrwxrwx 1 root root 4 Aug 7 13:02 /var/run -> /run
ce qui signifie que /var/run/mysqld
est en fait /run/mysqld
votre docker-compose.yml mis à jour est
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:
dans ce cas, faites simplement pointer votre tmpfs vers /run
il semble que le répertoire/var/run soit spécial dans docker.
non, c'est juste parce que c'est un lien