与机器打交道的工作:细节决定浪费生命的时间——记一次 Docker 与软链接的故障

开发 前端
所见即所得。我明明已经 ls 出了 20240101 20240102 ... 20240716 20240717 ,为什么还会出现 no such file or directory: /data/daily/20240716 ?显然, 20240716 是软链接的、是来自 /mnt/gfs-data/ 的,而这个庞大的分布式文件系统很有可能存在一些兼容性问题

问题背景

假设在一台 ubuntu 服务器上,我们有一个专门存放日频数据的路径:

ls /data/daily -lh
20240101
20240102
20240103
...
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

这些数据过于庞大,我们无法将其全部保存在服务器中。对于这些数据,只有当天的路径,我们需要对其有「写」的权限,历史数据我们只读即可。

因此,假设今天是 20240717 ,那么,我们可以将小于 20240717 的数据软链接到一个 mount 到服务器上的分布式文件系统中,比如:

ls /data/daily -lh
20240101 -> /mnt/gfs-data/daily/20240101
20240102 -> /mnt/gfs-data/daily/20240102
...
20240716 -> /mnt/gfs-data/daily/20240716
20240717
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

接下来,我们希望启动的 docker 容器可以访问 daily 数据,那么:

docker run \
  -v /data/daily:/data/daily \
  --name my-service-container \
  my-service-image
  run-service-command
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

此时 my-service-container 报错:

no such file or directory: /data/daily/20240716
  • 1.

但是当你进入容器:

docker exec -it my-service-container /bin/bash

$ cd /data/daily
$ ls
20240101  20240102  ...  20240716 20240717
# 数据似乎存在?

$ ls -l 20240716
no such file or directory: 20240716
# 明明存在,却无法访问?
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

那么,问题出在了哪里?

我估计读到这里的读者中,至少有一半已经知道了问题所在。

但是让我们先来看看一些错误的思路(也是困住了我的思路):

一、会不是文件系统权限问题?

  • 显然, docker 容器在未开启 --privileged ,权限是不完整的
  • 尤其是涉及到与 mount 分布式文件系统的交互,这其中是很容易出问题的

二、软链接的问题?

  • 软链接本身不复杂,但是 docker 与软链接的结合,可能有点问题?
  • 于是甚至很傻地去搜了 stackoverflow ,尝试类比 docker 、 softlink 、 mount 相关的问题

三、其他更复杂的原因导致的?

  • 问问 ChatGPT 吧!免费版不聪明,再问问 ChatGPT-4o !
  • 嗯...是我的 prompt 写得太差了?获得了一些正确的废话

如果你已经知道问题,你或许会嘲笑上述费力不讨好的一番折腾。但是为什么我(或者其他陷入误区的读者)会想到这些呢?

  1. 思维惯性。大多数日常使用 docker 的人(比如现在的我),对于 docker 的了解是不够深入的,在经历过一些 docker 的 bug 后,再遇到类似的问题,首先会顺其自然想到是不是 docker 本身的问题
  2. 所见即所得。我明明已经 ls 出了 20240101 20240102 ... 20240716 20240717 ,为什么还会出现 no such file or directory: /data/daily/20240716 ?显然, 20240716 是软链接的、是来自 /mnt/gfs-data/ 的,而这个庞大的分布式文件系统很有可能存在一些兼容性问题

真正的解决之道

我在 docker 内部敲入下面的命令让我恍然大悟,甚至为自己的愚蠢发笑:

docker exec -it my-service-container /bin/bash

$ cd /data/daily
$ ls -lh
20240101 -> /mnt/gfs-data/daily/20240101
20240102 -> /mnt/gfs-data/daily/20240102
...
20240716 -> /mnt/gfs-data/daily/20240716
20240717
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

显然,软链接在 docker 内部链接到了 /mnt/gfs-data/ ,那么,你也需要让 /mnt/gfs-data/ 映射到本地的 /data/daily/ 路径上!

增加一行挂载直接解决问题:

docker run \
  -v /data/daily:/data/daily \
  -v /mnt/gfs-data:/mnt/gfs-data \
  --name my-service-container \
  my-service-image
  run-service-command
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

所以,既不是 docker 的问题,也不是权限的问题,更不是文件系统的问题。

为什么程序员的下班时间不同

所以,为什么有些程序员下班早,看起来还很轻松?

他可能并不是摸鱼大事。相反,他对于机器有更好的直觉与灵感,而这一切的前提是他积累了足够的知识与经验。

显然,对于 docker ,仅仅知道基本的 cgroups 实现原理是不够的。没有更扎实的基础知识与经验作为支撑,我们甚至总是焦头烂额地走向了错误的解决问题的方向。

细节决定浪费生命的时间。停下来,想一想自己是不是刚刚死脑筋了。

责任编辑:武晓燕 来源: Piper蛋窝
相关推荐

2021-01-08 13:52:15

Consul微服务服务注册中心

2011-03-11 10:43:52

数据迁移

2010-05-25 13:22:43

2019-07-31 08:56:07

故障JavaBlockingQue

2021-12-02 07:50:30

NFS故障内存

2011-06-15 16:22:38

2020-11-04 07:13:57

数据工程代码编程

2014-10-13 13:40:07

程序员

2015-11-24 10:18:52

数据中心线缆

2023-07-21 10:28:31

高管技术领导者

2014-10-13 09:47:22

程序员工作

2017-05-11 22:58:59

2018-07-03 10:49:22

性能故障排查

2021-12-06 17:21:05

异常报错故障

2022-09-15 14:51:05

Python机器学习人工智能

2020-04-20 11:52:37

Static变量静态

2022-06-01 06:17:42

微服务Kafka

2022-12-17 19:49:37

GCJVM故障

2020-01-17 09:00:00

HashMapJava编程语言

2020-06-12 13:26:03

线程池故障日志
点赞
收藏

51CTO技术栈公众号