以每周一个节点,记录知识点。
2023-11-13~15
docker buildx cache 在哪里?
在 dockerfile 中使用 cache 后
RUN --mount=type=cache,id=gomod,target=/go/pkg/mod \
--mount=type=cache,id=gobuild,target=/root/.cache/go-build \
go build *.go -o main
这个cache 存在哪里呢?,可以通过以下步骤寻找。
-
使用
docker system df -v
找到 cache 的 id# docker system df -v | grep exec.cachemount 9496ft5v8aa1 exec.cachemount 2.89GB 4 hours ago 6 minutes ago 7 false rexojumy2pb2 exec.cachemount 184MB 2 hours ago 6 minutes ago 2 false lb6ry3m3f4ne exec.cachemount 292MB 2 hours ago 6 minutes ago 2 false wal4kf5q180m exec.cachemount 1.8GB 4 hours ago 6 minutes ago 7 false
-
显示的 cache id 是简写的,可以通过 find 命令来查找目录。
[root@prd-idc-ops-ci-agent-23 /home/yunwei]# find / -name 9496ft5v8aa1* -type d /data/docker-data/overlay2/9496ft5v8aa1ypf7tdr85te9d [root@prd-idc-ops-ci-agent-23 /home/yunwei]# ls -al /data/docker-data/overlay2/9496ft5v8aa1ypf7tdr85te9d total 76 drwx--x---. 3 root root 30 Nov 16 14:19 . drwx--x---. 124 root root 114688 Nov 16 18:11 .. drwxr-xr-x. 258 root root 8192 Nov 16 14:20 diff -rw-r--r--. 1 root root 26 Nov 16 14:19 link [root@prd-idc-ops-ci-agent-23 /home/yunwei]# ls -al /data/docker-data/overlay2/9496ft5v8aa1ypf7tdr85te9d/diff/ total 2924 drwxr-xr-x. 258 root root 8192 Nov 16 14:20 . drwx--x---. 3 root root 30 Nov 16 14:19 .. drwxr-xr-x. 2 root root 4096 Nov 16 16:56 00 drwxr-xr-x. 2 root root 8192 Nov 16 16:56 01 drwxr-xr-x. 2 root root 8192 Nov 16 16:56 02 drwxr-xr-x. 2 root root 8192 Nov 16 16:56 03 drwxr-xr-x. 2 root root 8192 Nov 16 16:56 04 drwxr-xr-x. 2 root root 8192 Nov 16 16:56 05
这就找到啦。
ack node /tmp 目录被占满,导致节点容器服务不可用。
现象总览:
# 现象1-告警信息:
节点 xxx 磁盘 tmpfs 可用率不足10%,当前可用磁盘 0%
(node-exporter 告警的)
# 现象2-rpc应用:
Get "http://consul-client:8500/v1/health/service/sfs.id_generator.rpc?near=_agent&wait=30000ms": dial tcp 192.168.148.180:8500: connect: connection refused
(错误日志只在同一个节点上)
# 现象3-consul agent:
2023-11-15T00:47:45.614+0800 [INFO] agent: Deregistered service: service=demo.rpc-10.130.32.90-8080
(所有节点服务都被注销)
# 现象3-节点:
[8939541.979333] IPVS: rr: TCP 192.168.148.180:8500 - no destination available
(大量的相同信息)
# 现象4-节点 kubelet 事件:
Readiness probe failed: OCI runtime exec failed: write /tmp/runc-process266902010: no space left on device: unknown
(大量的容器检查错误)
以上顺序是按照排查排查方向依次发现的。
原因:
由于某一程序将节点的/tmp
目录写文件至空间饱和,这导致 kubelet
在执行容器的健康检查时发生异常。因此,kubelet
将容器视为不可用,并进一步将容器的状态设置为不可用,从 ipvs
服务 service
上移除容器 ip
。此行为使得 go rpc
服务无法连接到 consul agent
,在超过心跳时间后,consul agent
将服务注销。
后面就是寻找 某一程序
了,下面就是描述怎么找到这个程序的过程, 在确定好应用后,后面就是验证猜想是否正确了。
- 查看集群内pod,有没有对节点
/tmp
的操作。 - 确定事故发生时间,查看时间范围内的应用日志,节点日志。
- 确定事故发生时间,查看时间范围内的节点资源使用情况,节点上 pod的使用情况,重点关注cpu,内存使用率高的容器。
- 节点开启审计规则,监控
/tmp
目录的变化情况。
经过上面的一些操作,目光锁定在了一个处理阿里云 oss 文件的 的 go 程序,这个 go 程序 容器中挂载了使用 csi 方式挂载了 oss bucket,做的业务逻辑是从oss中读取文件,进行处理后,在写入到 oss 中。
在进行猜想确认后,就去翻阅阿里云oss的文档,从中发现了具体原因:
ossfs默认通过分片上传的方式上传大文件。上传时,ossfs会将临时缓存文件写入/tmp目录下,写入前需要先判断/tmp目录所在的磁盘可用空间是否小于multipart_size * parallel_count。如果磁盘可用空间大于multipart_size * parallel_count,则正常写入文件。如果磁盘可用空间小于 multipart_size * parallel_count,则出现本地磁盘可用空间不足的报错。
为提升性能,默认情况下ossfs会使用磁盘空间来保存上传或下载的临时数据。您可以通过该选项设置保留的可用硬盘空间大小,单位为MB。例如,您需要设置ossfs保留1024 MB的可用磁盘空间,则使用 -o ensure_diskfree=1024。
解决:
- 业务使用 oss sdk 方式 对 oss 文件进行处理。
- 创建 pv 时,加上
-o ensure_diskfree=10240
限制。
参考:
- https://help.aliyun.com/zh/oss/developer-reference/ossfs-faq#section-p2d-siy-jqs
- https://help.aliyun.com/zh/oss/developer-reference/ossfs-faq#section-9l3-tkc-shw