Redis: Can’t open the log file: Read-only file system

Автор: | 04/03/2019
 

Имеется новый сервис Redis, который должен работать параллельно с уже существующим.

При его запуске — он сообщает, что Can’t open the log file: Read-only file system — хотя права на /var/log правильные, на сам файл лога — тоже.

Причина оказалась достаточно неочевидной.

Проблема

Полностью ошибка выглядит так:

--- Unit redis-cluster.service has begun starting up.
Apr 03 10:12:28 bttrm-dev-console redis-server[18010]: *** FATAL CONFIG FILE ERROR ***
Apr 03 10:12:28 bttrm-dev-console redis-server[18010]: Reading the configuration file, at line 11
Apr 03 10:12:28 bttrm-dev-console redis-server[18010]: >>> ‘logfile /var/log/redis/redis-cluster.log’
Apr 03 10:12:28 bttrm-dev-console redis-server[18010]: Can’t open the log file: Read-only file system
Apr 03 10:12:28 bttrm-dev-console systemd[1]: redis-cluster.service: Control process exited, code=exited status=1
Apr 03 10:12:28 bttrm-dev-console systemd[1]: Failed to start Redis relication cluster node.
--- Subject: Unit redis-cluster.service has failed

Конфигурация

Файл лога указан в настройках ноды /etc/redis-cluster/redis-cluster-master.conf:

...
logfile /var/log/redis/redis-cluster.log
...

Запускается новый Redis из самогописного systemd unit-файла, который копировался из существующего файла /lib/systemd/system/redis-server.service:

[Unit]
Description=Advanced key-value store
After=network.target
Documentation=http://redis.io/documentation, man:redis-server(1)

[Service]
Type=forking
ExecStart=/usr/bin/redis-server /etc/redis/redis.conf
PIDFile=/var/run/redis/redis-server.pid
TimeoutStopSec=0
Restart=always
User=redis
Group=redis
RuntimeDirectory=redis

ExecStartPre=-/bin/run-parts --verbose /etc/redis/redis-server.pre-up.d
ExecStartPost=-/bin/run-parts --verbose /etc/redis/redis-server.post-up.d
ExecStop=-/bin/run-parts --verbose /etc/redis/redis-server.pre-down.d
ExecStop=/bin/kill -s TERM $MAINPID
ExecStopPost=-/bin/run-parts --verbose /etc/redis/redis-server.post-down.d

UMask=007
PrivateTmp=yes
LimitNOFILE=65535
PrivateDevices=yes
ProtectHome=yes
ReadOnlyDirectories=/
ReadWriteDirectories=-/var/lib/redis
ReadWriteDirectories=-/var/log/redis
ReadWriteDirectories=-/var/run/redis
CapabilityBoundingSet=~CAP_SYS_PTRACE

# redis-server writes its own config file when in cluster mode so we allow
# writing there (NB. ProtectSystem=true over ProtectSystem=full)
ProtectSystem=true
ReadWriteDirectories=-/etc/redis

[Install]
WantedBy=multi-user.target
Alias=redis.service

Файл нового сервиса сохранён как /etc/systemd/system/redis-cluster.service и выглядит сейчас так:

[Unit]
Description=Redis relication cluster node
After=network.target

[Service]
Type=forking
ExecStart=/usr/bin/redis-server /etc/redis-cluster/redis-cluster-master.conf
PIDFile=/var/run/redis/redis-cluster.pid
TimeoutStopSec=0
Restart=always
User=redis
Group=redis
RuntimeDirectory=redis-cluster

ExecStop=/bin/kill -s TERM $MAINPID

UMask=007
PrivateTmp=yes
LimitNOFILE=65535
PrivateDevices=yes
ProtectHome=yes
ReadOnlyDirectories=/
ReadWriteDirectories=-/var/lib/redis-cluster
ReadWriteDirectories=-/var/log/redis-cluster
ReadWriteDirectories=-/var/run/redis-cluster
CapabilityBoundingSet=~CAP_SYS_PTRACE

ProtectSystem=true
ReadWriteDirectories=-/etc/redis-cluster

[Install]
WantedBy=multi-user.target

Причина и решение

Собственно проблема возникает из-за параметра ReadWriteDirectories в unit-файле: во время копирования — я просто обновил все пути и имена в нём с просто redis на redis-cluster, в том числе — и путь к каталогу логов — /var/log/redis-cluster.

Меняем ReadWriteDirectories=-/var/log/redis-cluster на ReadWriteDirectories=-/var/log/redis, если logfile /var/log/redis/redis-cluster.log — или наоборот.

Я всё-таки решил не нарушать «красоту» unit-файла, и создал отдельный каталог:

root@bttrm-dev-console:/home/admin# mkdir /var/log/redis-cluster
root@bttrm-dev-console:/home/admin# chown redis:redis /var/log/redis-cluster

Затем обновил /etc/redis-cluster/redis-cluster-master.conf:

root@bttrm-dev-console:/home/admin# cat /etc/redis-cluster/redis-cluster-master.conf | grep logfile
logfile /var/log/redis-cluster/redis-cluster.log

Проверяем:

root@bttrm-dev-console:/home/admin# systemctl start redis-cluster.service
root@bttrm-dev-console:/home/admin# systemctl status redis-cluster.service
● redis-cluster.service - Redis relication cluster node
Loaded: loaded (/etc/systemd/system/redis-cluster.service; disabled; vendor preset: enabled)
Active: active (running) since Wed 2019-04-03 10:39:42 EEST; 6s ago
Process: 18501 ExecStart=/usr/bin/redis-server /etc/redis-cluster/redis-cluster-master.conf (code=exited, status=0/SUCCESS)
Main PID: 18502 (redis-server)
Tasks: 3 (limit: 4915)
Memory: 1.1M
CPU: 11ms
CGroup: /system.slice/redis-cluster.service
└─18502 /usr/bin/redis-server 0.0.0.0:6389
Apr 03 10:39:42 bttrm-dev-console systemd[1]: Starting Redis relication cluster node...
Apr 03 10:39:42 bttrm-dev-console systemd[1]: redis-cluster.service: PID file /var/run/redis/redis-cluster.pid not readable (yet?) after start: No such file or directory
Apr 03 10:39:42 bttrm-dev-console systemd[1]: Started Redis relication cluster node.

Готово.