Open lmk123 opened 2 years ago
在分析问题之前,先说说我是怎么在服务器上更新我的后端应用的。
我在服务器上安装了 docker,当我在本地修改了代码之后,我会将代码传送到服务器里,然后在服务器里用代码 build 出 docker image 并重新生成 container。
起初,这种方式运行的很好,但随着我 build 的次数越来越多,我能明显感觉到每次 build image 的时间变得越来越久,从一开始的 20 秒,到后来的 10 分钟,而到上一次的时候,过了半小时都没有 build 成功。
镜像 build 的过程其实就只是用 yarn install 安装了项目依赖,而且也确认不是网络原因,因为从 yarn install 的日志来看,模块很快就下载好了,但卡在了 Building fresh moudes [4/4] 这一步。
yarn install
Building fresh moudes [4/4]
而且,build 过程中还出现了 ssh 无法连接的情况,最终只能重启服务器,但这个问题也导致我无法再发布新的代码了。
从云服务器后台可以看到,在 build 过程中,除了硬盘读IOPS和硬盘IO繁忙比率,其它指标都是正常的。这俩指标的曲线都到顶了,其中硬盘IO繁忙比率直接冲到了 100%。
硬盘读IOPS
硬盘IO繁忙比率
总结一下此问题的特点:
解决这个问题的办法有两种:
由于不知道出现问题的原因,所以目前来看最好的办法就是在本地 build 镜像,然后上传到服务器并导入。
这个过程还是蛮简单的,只涉及到三条命令:
docker image build
-o
scp
docmer image load
但是,这一过程却出现了问题。
第一次尝试时,上面三条命令一切正常,但是当我用导入的镜像生成 container 运行的时候报错了:exec user process caused: exec format error。谷歌了一下找到了原因:我的开发机是 Macbook Air M1,CPU 是 arm,但服务器是 x86-64 的。
exec user process caused: exec format error
所以,普通的 docker image build 是不行了,得用 docker buildx build 来打包支持多架构的镜像。https://docs.docker.com/desktop/multi-arch/
docker buildx build
导出我用的是 docker buildx build -o type=tar,dest=out.tar --platform=linux/amd64 .,但导入的时候用 docker image load 会报错:open /var/lib/docker/tmp/docker-import-837327978/bin/json: no such file or directory
docker buildx build -o type=tar,dest=out.tar --platform=linux/amd64 .
docker image load
open /var/lib/docker/tmp/docker-import-837327978/bin/json: no such file or directory
简单 google 了下之后,改为用 docker image import 导入了 tar,但是作为 container 跑起来之后又报错了:No command specified——然而我的 Dockerfile 里明明写了 CMD 的 :joy:
docker image import
No command specified
到这里我觉得这问题一时半会儿是解决不了了,就决定找个其它时间再尝试。
此问题已解决,见 https://github.com/lmk123/docker-buildx-test
由于尝试过程中产生了很多没有用的 image,我决定清理一下,正好以前 build 过的代码镜像也一直没清理过,占用了很多硬盘空间,于是我运行了 docker image prune,然而这个命令运行了 3 分钟了没有任何反应,像极了 build image 时的表现,于是我赶紧上云服务器后台确认了一下指标,发现硬盘IO繁忙比率冲到了 82%,但是没到 100%,而且 ssh 也能正常连上去。大概 5 分钟后,命令运行完成了。
docker image prune
我突然想到,会不会是因为一直没清理 image 导致的这个问题?于是我又重新尝试了在服务器里 build image,结果居然 20 秒就好了,就像我第一次 build 时那样快 :joy:
到这里问题可以说圆满解决了,但是我仍然不明白为什么没有清理的 image 会导致这个问题 :joy:
在分析问题之前,先说说我是怎么在服务器上更新我的后端应用的。
我在服务器上安装了 docker,当我在本地修改了代码之后,我会将代码传送到服务器里,然后在服务器里用代码 build 出 docker image 并重新生成 container。
起初,这种方式运行的很好,但随着我 build 的次数越来越多,我能明显感觉到每次 build image 的时间变得越来越久,从一开始的 20 秒,到后来的 10 分钟,而到上一次的时候,过了半小时都没有 build 成功。
镜像 build 的过程其实就只是用
yarn install
安装了项目依赖,而且也确认不是网络原因,因为从 yarn install 的日志来看,模块很快就下载好了,但卡在了Building fresh moudes [4/4]
这一步。而且,build 过程中还出现了 ssh 无法连接的情况,最终只能重启服务器,但这个问题也导致我无法再发布新的代码了。
从云服务器后台可以看到,在 build 过程中,除了
硬盘读IOPS
和硬盘IO繁忙比率
,其它指标都是正常的。这俩指标的曲线都到顶了,其中硬盘IO繁忙比率
直接冲到了 100%。总结一下此问题的特点:
硬盘IO繁忙比率
冲到了 100%,但是不知道为什么在 yarn install 的Building fresh moudes [4/4]
这一步会导致这个问题。解决这个问题的办法有两种:
由于不知道出现问题的原因,所以目前来看最好的办法就是在本地 build 镜像,然后上传到服务器并导入。
这个过程还是蛮简单的,只涉及到三条命令:
docker image build
: 在本地 build 镜像,并指定-o
参数,将镜像作为 .tar 文件导出scp
: 将 .tar 上传到服务器docmer image load
: 在服务器上导入 .tar 镜像但是,这一过程却出现了问题。
第一次尝试时,上面三条命令一切正常,但是当我用导入的镜像生成 container 运行的时候报错了:
exec user process caused: exec format error
。谷歌了一下找到了原因:我的开发机是 Macbook Air M1,CPU 是 arm,但服务器是 x86-64 的。所以,普通的
docker image build
是不行了,得用docker buildx build
来打包支持多架构的镜像。https://docs.docker.com/desktop/multi-arch/导出我用的是
docker buildx build -o type=tar,dest=out.tar --platform=linux/amd64 .
,但导入的时候用docker image load
会报错:open /var/lib/docker/tmp/docker-import-837327978/bin/json: no such file or directory
简单 google 了下之后,改为用
docker image import
导入了 tar,但是作为 container 跑起来之后又报错了:No command specified
——然而我的 Dockerfile 里明明写了 CMD 的 :joy:到这里我觉得这问题一时半会儿是解决不了了,就决定找个其它时间再尝试。
由于尝试过程中产生了很多没有用的 image,我决定清理一下,正好以前 build 过的代码镜像也一直没清理过,占用了很多硬盘空间,于是我运行了
docker image prune
,然而这个命令运行了 3 分钟了没有任何反应,像极了 build image 时的表现,于是我赶紧上云服务器后台确认了一下指标,发现硬盘IO繁忙比率
冲到了 82%,但是没到 100%,而且 ssh 也能正常连上去。大概 5 分钟后,命令运行完成了。我突然想到,会不会是因为一直没清理 image 导致的这个问题?于是我又重新尝试了在服务器里 build image,结果居然 20 秒就好了,就像我第一次 build 时那样快 :joy:
到这里问题可以说圆满解决了,但是我仍然不明白为什么没有清理的 image 会导致这个问题 :joy: