• 记一次docker进不去容器的经历


    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
    
    • 1

    连 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
    
    • 1

    在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" ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    可以看到里面有三次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
    在这里插入图片描述
    再把镜像导出对比一下
    在这里插入图片描述

  • 相关阅读:
    智慧交通解决方案-最新全套文件
    java基于ssm+jsp仓库管理系统
    SQL 学习笔记
    个人设计web前端大作业 HTML期末大作业 学生个人网页设计作品 学生个人网页设计作品 学生个人网页模板 简单个人主页成品
    【追求卓越03】数据结构--链表练习题
    代码随想录算法训练营第五十五天| LeetCode392. 判断子序列、LeetCode115. 不同的子序列
    nvm安装node后,在使用npm指令时候显示不是内部或外部指令
    学习在C++中使用位运算符做“int”和“4个char”之间的转换
    V100 GPU服务器安装CUDA教程
    4.6shell中的运算
  • 原文地址:https://blog.csdn.net/NOOBBB/article/details/126519868