语境
我在集成过程中遇到了一些奇怪的事情舞会到我的堆栈
ERROR: for asmodius_promtail Cannot start service promtail: OCI runtime create failed: container_linux.go:349: starting container process caused "process_linux.go:449: container init caused \"rootfs_linux.go:58: mounting \\\"/var/lib/docker/volumes/asmodius_nginx-logs/_data\\\" to rootfs \\\"/var/lib/docker/overlay2/f6e22c4d99f1e9907a8ff4b05338386a38b9a7cd802944a877102bb805b97dac/merged\\\" at \\\"/var/lib/docker/overlay2/f6e22c4d99f1e9907a8ff4b05338386a38b9a7cd802944a877102bb805b97dac/merged/var/log/nginx\\\" caused \\\"mkdir /var/lib/docker/overlay2/f6e22c4d99f1e9907a8ff4b05338386a38b9a7cd802944a877102bb805b97dac/merged/var/log/nginx: read-only file system\\\"\"": unknown
这体积这个错误中提到的是我使用的,这样 promtail 就可以读取 Nginx 日志。(它只读取文件,不需要在目录中写入任何内容)以下是docker-compose.yml
version: '3.7'
services:
nginx:
container_name: ${SERVER_NAME}_nginx
restart: always
networks:
- monitoring
- web
image: nginx:1.17.5-alpine
entrypoint: /entrypoint.sh
ports:
- 80:80
- 443:443
volumes:
- ./nginx/site.conf:/etc/nginx/conf.d/site.conf
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./nginx/entrypoint.sh:/entrypoint.sh
- nginx-logs:/var/log/nginx
- certificates:/etc/letsencrypt/
promtail:
restart: always
container_name: ${SERVER_NAME}_promtail
image: grafana/promtail:master-b652f0a
command: -config.file=/etc/promtail/docker-config.yaml
volumes:
- nginx-logs:/var/log/nginx
- /var/log:/var/log:ro
- ./promtail/docker-config.yaml:/etc/promtail/docker-config.yaml:ro
networks:
- monitoring
和音量“检查“
{
"CreatedAt": "2020-04-28T20:08:41Z",
"Driver": "local",
"Labels": {
"com.docker.compose.project": "asmodius",
"com.docker.compose.version": "1.24.1",
"com.docker.compose.volume": "nginx-logs"
},
"Mountpoint": "/var/lib/docker/volumes/asmodius_nginx-logs/_data",
"Name": "asmodius_nginx-logs",
"Options": null,
"Scope": "local"
}
奇怪的是,同样的docker-compose.yml
功能在我的 Debian 9 上也运行良好
- Docker 版本 19.03.8,内部版本 afacb8b7f0
- docker-compose 版本 1.22.0,构建 f46880fe
但在 CentOS 上失败
- Docker 版本 19.03.8,构建 afacb8b
- docker-compose 版本 1.24.1,内部版本 4667896b
线索
我不太相信docker-compose版本可能是问题所在。我尝试了以下方法
- 停止整个堆栈,R M
nginx-logs
音量并重新开始 - 使用
:ro
不使用:ro
问题
由于我不完全理解该ERROR
信息,对以下元素的解释可能会帮助我弄清楚我做错了什么。
read-only file system\\\"\"": unknown
:我就是不"\"
明白- 为什么提到
merge
?与什么合并? mkdir
.... 因此它尝试在 中的某个位置创建一个文件夹/var/lib/docker
。但为什么它必须针对这个特定卷执行此操作,而所有其他卷(并且数量相当多)每次我执行此操作时都能成功docker-compose up -d --force-recreate
(因为这是我在此机器上添加/更新服务的方式)
欢迎任何见解
答案1
mkdir /var/lib/docker/overlay2/f6e22c4d99f1e9907a8ff4b05338386a38b9a7cd802944a877102bb805b97dac/merged/var/log/nginx: read-only file system\\\"\"
这是在抱怨无法在 下创建目录/var/lib/docker
。该文件系统不应是只读的。也许您没有以 root 身份启动 docker 引擎,或者文件系统本身有问题。我会再次检查您是否没有用尽容量(无论是可用字节还是可用 inode),方法是:
df /var/lib/docker/.
df -i /var/lib/docker/.
如果您正在运行 Docker Desktop,那么作为最后的手段,请销毁并重新创建 docker VM。这将导致丢失所有卷数据、构建的映像、正在运行的容器等,因此请备份您想要保存的所有内容。
答案2
这可能有点晚了,但我也遇到了类似的问题:
我相信该问题是由于两个(容器内部)安装位置重叠但同时具有不同的“只读”和“读写”权限引起的。
在原始帖子中,您会注意到promtail
服务有这两个支架:
volumes:
- nginx-logs:/var/log/nginx
- /var/log:/var/log:ro
这里第一个挂载是读写的,但是第二个挂载是只读的。
注意
- 从容器的角度
/var/log/nginx
来看里面/var/log/
。 - 如果容器(和/或卷)内的挂载路径不存在,docker 将尝试创建它
- 看来 docker 会尝试从目录层次结构的角度“从上到下”挂载路径,而不是按照它们在 中列出的顺序
docker-compose.yml
。
这意味着/var/log/
将首先安装,/var/log/nginx
然后尝试。如果nginx
子目录尚不存在(很可能),则显然无法创建它(如果/var/log
标记为只读)。
错误消息试图将这一点告知用户,但却以一种相当令人困惑、非直观的方式。
最简单的解决方案是,如果任何子目录需要具有写权限,则不要将父目录(容器内)标记为只读。
另一个解决方案是在启动服务之前确保/var/log/nginx
路径存在于支持介质(nginx-logs
本例中为卷)中。但是,这很难确保可靠性,例如在重新创建卷或移动主机的情况下。