2022年8月25日早上
最近在学习prometheus 那一套 监控系统。
在docker安装了一个redis-exporter,竟然怎么都进不去 容器。
开始百度,测试了 sh bash csh 都不行,都是这种错误

OCI runtime exec failed: exec failed: unable to start container process: exec: "bash": executable file not found in $PATH: unknown

连 docker exec -it redis-exporter echo $PATH
都是

OCI runtime exec failed: exec failed: unable to start container process: exec: "echo": executable file not found in $PATH: unknown

在gitub上发了issue,刚发完2分钟,我仔细一看README。还有个alpine版本,可以进入shell,正常版本进不了shell 。 github上是这样说的

在这里插入图片描述

当时压根没仔细看。
---------------------------分割线----------------------------------------

这就带来一个问题,我一直以为docker只是轻量级的虚拟机,应用装在一个base image 上面 。base image 肯定是一个操作系统,不管是mac 还是win 还是类linux,但是一个镜像还能只包含一个binary文件吗,那这个binary运行在什么上面?
这值得研究一下,从Dockerfile入手先
把redis-exporter 的Dockerfile 链接放在这里:
https://github.com/oliver006/redis_exporter/blob/master/docker/Dockerfile

等有时间回来

--------------------------------------------------------------分割线-------------------------------------------------------------
我回来了(2022年8月25日16点23分)
分析了一下Dockfile

ARG GOARCH
#
# build container
#
FROM --platform=linux/amd64 golang:1.19-alpine as builder
WORKDIR /go/src/github.com/oliver006/redis_exporter/

ADD . /go/src/github.com/oliver006/redis_exporter/

ARG SHA1="[no-sha]"
ARG TAG="[no-tag]"
ARG GOARCH

RUN apk --no-cache add ca-certificates git
RUN BUILD_DATE=$(date +%F-%T) CGO_ENABLED=0 GOOS=linux GOARCH=$GOARCH go build -o /redis_exporter \
    -ldflags  "-s -w -extldflags \"-static\" -X main.BuildVersion=$TAG -X main.BuildCommitSha=$SHA1 -X main.BuildDate=$BUILD_DATE" .

RUN [ "$GOARCH" = "amd64" ]  && /redis_exporter -version || ls -la /redis_exporter

#
# scratch release container
#
FROM --platform=linux/$GOARCH scratch as scratch

COPY --from=builder /redis_exporter /redis_exporter
COPY --from=builder /etc/ssl/certs /etc/ssl/certs
COPY --from=builder /etc/nsswitch.conf /etc/nsswitch.conf

# Run as non-root user for secure environments
USER 59000:59000

EXPOSE     9121
ENTRYPOINT [ "/redis_exporter" ]


#
# Alpine release container
#
FROM --platform=linux/$GOARCH alpine as alpine

COPY --from=builder /redis_exporter /redis_exporter
COPY --from=builder /etc/ssl/certs /etc/ssl/certs

# Run as non-root user for secure environments
USER 59000:59000

EXPOSE     9121
ENTRYPOINT [ "/redis_exporter" ]

可以看到里面有三次From。 这里涉及到一个概念:多阶段构建。
这里引用
https://blog.csdn.net/cheng_fu/article/details/122207305

如下:
在这里插入图片描述
所以可以看到redis-exporter 也是先用golang编译了程序。
第一个From:FROM --platform=linux/amd64 golang:1.19-alpine as builder
而golang的镜像很大有300多M

在这里插入图片描述
顺便一提,–platform是为了跨平台的配置,
在这里插入图片描述
https://docs.docker.com/engine/reference/builder/#from
as builder 的用法见官方文档,这样下面就可以直接COPY --from builder 了
在这里插入图片描述
https://docs.docker.com/develop/develop-images/multistage-build/

第二个From 是 FROM --platform=linux/$GOARCH scratch as scratch

scratch 是docker提供的基础镜像,可以用来构建超小的镜像。具体解释如下:
在这里插入图片描述
go语言 编译后直接是可执行文件,所以From scratch 就可以,但是里面没有shell/ls/echo等一些基础的东西。
那么第三个From:FROM --platform=linux/$GOARCH alpine as alpine
Alpine Linux是一个面向安全的轻量级Linux发行版,基于musl libc和Busybox。
讲真,linux的东西我也不懂,就不冒充了。各位自行百度哈。这里说一下我知道的。
Alpine Linux 只有5M多,你敢信··
在这里插入图片描述
对比一下alpine 和普通版本,发现alpine14.8M,普通的9.28M,多的5M多就是Alpine Linux。
还可以看到nginx142M。对比很明显。 再看一下docker history
在这里插入图片描述
再把镜像导出对比一下
在这里插入图片描述

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐