Skip to main content

Command Palette

Search for a command to run...

share file based scatch with docker

Updated
2 min read

不是特别想用英文,但确实是想不到一个比较好的中文题目了……

背景

加入新公司快两个月了,随着对团队项目的了解,也逐步发现了一些问题,比如我们有A、B两个后端项目:

  • A 是使用 java 开发的,部署在 K8s 中

  • B 是 go 开发,使用supervisor部署在宿主机上

Action

"熟谙" DevOps 的笔者在 A 的构建脚本中发现 B 项目的可执行文件,竟然直接被打到了 jar 包中,具体做法就是

  • B 项目在构建后产生的二进制文件 b-bin 被拷贝到 /opt/ 目录

  • A 构建过程中将 /opt/b-bin 拷贝到自己的目录中来,然后完成构建

先不论合理不合理,显而易见,A、B是相互依赖的,当时我就想到几种解决办法

  1. B 使用 Dockerfile 构建(镜像 tag 必须是 commit-id 啊), 在 A 的 Dockerfile 中使用 multi-stage 技术将 b-bin 拷贝过来即可

  2. A、B 本身存在依赖关系,它俩应该保持开发版本的一致,不如将其合并为一个 repo

这两种办法都可以, 方法1对当前现状的影响最小,最容易实施。但为何 b-bin 会被打到 A的 jar 包中呢?原因为 A 需要将 b-bin 安装到不同的宿主机上……A 与 B 如此耦合的缺点就是:当B有重大变化时,A需要重新打包,当然也有办法可以解决这个问题:

  • 搭一个 ftp server,将 b-bin 扔上去,在 A 中记录下对应的 b-bin 的版本号即可

为了这个需求单独再维护一个 ftp server 太不值当了,还有没有其它办法?

既然 A 部署在 K8s 中,就必然会有一个镜像中心 harbor,何不将 b-bin 存到 harbor 中, harbor 不支持直接存储二进制文件,但我可以把 b-bin 打入镜像中啊,在需要的时候将期取出即可,so easy!

## Build the manager binary
FROM golang:1.17 as builder
​
WORKDIR /opt
# Copy the Go Modules manifests
COPY go.mod go.mod
COPY go.sum go.sum
​
RUN go env -w GO111MODULE=on && \
    go env -w GOPROXY=https://goproxy.cn,direct && \
    go mod download
​
# Copy the go source
COPY cmd/ cmd/
COPY pkg/ pkg/
COPY internal/ internal/
​
# Build
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o b-bin cmd/b.go
​
FROM alpine
COPY --from=builder /opt/b-bin /opt/b-bin
​

执行 docker build -t my-b-bin 需要的时候直接通过命令取出即可

$ docker run -v $(PWD):/itmp --rm my-b-bin sh -c "cp /opt/b-bin /itmp/"

换成瑞士军刀 busybox,最终镜像还能小一点,但依然有多余的东西,此时我脑海中想到一个镜像: scatch

an explicitly empty image, especially for building images "FROM scratch"

一个空镜像,真的是空的,里面啥也没有,这很有趣

➜  ~ dive scratch
Fetching image... (this can take a while with large images)
Image not available locally. Trying to pull 'scratch'...
Using default tag: latest
Error response from daemon: 'scratch' is a reserved name
cannot fetch image: Error response from daemon: No such image: scratch

将前面 Dockerfile 改一下,将 FROM alpine 替换为 FROM scratch , 但发现取出 b-bin 的命令不好使了,因为 scratch 镜像中既没有 sh 也没有 cp,因为 scratch 真是空的,啥也没有,所以这个法子不管用了。本来到这里我要放弃了,就为了几M存储空间值得吗?不是值不值得的问题,我只是想验证这方法到底行不行!go on

在 Dockerfile 最后一行加上:CMD [ "" ] ,最后三行即视感:

FROM scratch
COPY --from=builder /opt/b-bin /opt/b-bin
CMD [ "" ]

一个空命令,得以让我们可以创建容器,然后再利用以下命令即可取出 b-bin:

CID=$(docker create my-b-bin) 
docker cp ${CID}:/opt/b-bin /tmp/b-bin
docker rm ${CID}

如果没有 CMD [ "" ] 这一行,创建容器时会报错:

docker create my-b-bin
Error response from daemon: No command specified

为了骗过docker daemon,索性加一个空命令好了。

总结

虽然费了点时间,但最终达到了目的。大胆设想一下,在容器化环境,镜像中心可以用于文件分发啊,理论上 mvn、npm 等仓库是不是也可以使用这种方式呢?当然,前提是得有足够的收益(比如容器的分层缓存),最好能兼容现状,改动还要尽可能小……嗯,可不可行是一回事,适不适用是另一回事。

虽然最终A、B的依赖问题我通过其它方式解决了,是的,B直接容器化部署不就行了。那之前为啥不这么干呢?因为之前我还没来嘛^-^

55 views

More from this blog

2025: 祛魅 灰度 念头通达

今天是2025年的最后一天,当大家都在准备下班的时候,好巧不巧的,我刚好发现了一个不大不小的问题,大胆猜想,小心求证,向上反馈,暴露风险,作为2025年工作注解,实在是再有趣不过了。 今年的工作,从结果上看,还算平稳,至于过程,有太多不可言说的部分。厂里打镙丝的牛马,有工资可拿,理应知足了,至于其它的,与己无关,也没那么重要了。 祛魅 近距离观察大厂,才发现一些违背常识/直觉的事实:路人以为的高大

Feb 28, 20261 min read21

大厂祛魅:破碎的专注力

毁掉一个人最直接的方法,就是毁掉ta的专注力。 这句话的出处已然模糊,但放在大厂环境中,却显得格外深刻。 围城 大厂宛如一座围城。城外的人满怀憧憬,目之所及皆是光鲜;城内的人却如困笼之鸟,翅膀日渐退化,每日挣扎求生。 高大上 不可否认,大厂的硬件设施确实令人艳羡:宽敞的独立园区内,来往穿梭的人群中,几乎人人手握智能设备。这看似现代化的景象背后,却藏着一个无奈的事实:在工作时段,每台电脑都被严密监控,连听音乐都成奢望。于是,工作之余玩手机,成了许多人难得的解压方式。 大厂的品牌效应确实强大。外界对...

Jul 29, 20251 min read138

Black Swan

黑天鹅理论 是指极不可能发生,实际上却又发生的事件 来到大厂打工已经满一个月了,从一开始的手足无措,到逐渐度过不适期,也算是适应了吧。 不适应 刚入职时,不适应的地方还是挺多的。 第一次只使用台式机工作,这就限制了我一天中的绝大部分时间,都必须呆在自己的工位上,好在工位足够大。只是人与人的沟通少了很多,有问题只能在工位上通过 IM 呼对方,有种魔幻又现实的感觉 第一次只能用 Windows,也不能 WSL,这给我的工作效率带来了很大影响,不能用熟悉的软件,就连写代码用的 VSCode 的...

Jan 24, 20251 min read74

2024年: 逐渐平静

这个世界是一面镜子,会把你的感受反射给你 2024 开端: 相由心生 那时,还带着一着愤懑,因为拿到了低绩效,虽然内心知道这是公司经营困难,想让我离开的一种策略,但仍然感受到自己那可笑的自尊受到了践踏。自那之后,非必要不加班,只做份内事,尽可能地不去涉及份外之事。 2024 年中: 与人为善 组里的项目眼见不行了,我被迫去支援 AI 项目,久违地写起了 python,项目接近完成时,意外收到通知:我拿到大礼包了。在这之前,架构师因故裸辞。在我离开之后不到两周,我的 TL 也裸辞了,直到同事告诉...

Jan 9, 20251 min read92

企业软件之殇

殇 动词 未成年而死。 名词 战死者。 笔者经历了两家打着云原生旗号的企业软件/解决方案公司,都是中途加入,项目都以解(失)散(败)告终。 云原生解决方案 NB 公司:一个传统的 IDC 小厂,想着借云原生的热度,进军企业软件市场。 在加入这个项目之前,笔者考取了 CKAD 认证,彼时对 K8s 相当着迷。先简要介绍一下这个项目背景: 基于 Rancher (换皮肤)的二次开发项目,名字叫:HCaaS ,在笔者加入这个团队之前,项目已经开发近两年了,除了 TL 之外,其它人之前都...

Jul 1, 20241 min read103

just for fun

57 posts

I'm a Software Engineer