首页 > 经验记录 > 关于我在Docker里用Docker的那些事(如何在Alpine Linux Docker 镜像中使用Docker)

关于我在Docker里用Docker的那些事(如何在Alpine Linux Docker 镜像中使用Docker)

Docker in Docker 实际上还是非常有意义的,就比如我遇到的下面这个场景。

我需要使用公有云提供的CIDI服务, 在云端触发一键构建+测试+部署, 那么在构建、发布的时候是需要一个环境的,但是云端的构建节点并不一定会符合我的标准。

 

云端的构建节点我们没办法控制(也就是无法直接SSH连上去)的情况下。

如果可以有一个自定义的、稳定的、符合我们要求的 Docker镜像来作为整个CI/DI 流水线的环境,就非常的舒服了。

这也是本篇文章的一个实现目标。

 

比如我要以下的环境:

  • 拥有Maven + JDK17 的环境,将我的源代码打包。
  • 拥有 Docker 环境,将我打包出的程序构建成镜像推送到指定的Docker制品仓库。

 

这环境反正主流的云端CIDI八成是没有的, 主要也是我用 JDK17 太前沿了造出来的恶果。所以我们来打一个拥有以上所有东西的Docker镜像,嗯,就是说我们要在Docker里用Docker。

 

其实Alpine Linux的Docker in Docker 还是有点坑的,之所以用这个也是为了让镜像小一点。还好坑也不是很大,我也都踩了

下面提供的命令与准备都是迭代过数次的,已经很完备,其他的 Alpine Linux Docker in Docker 环境也可以基于此来更改。那么下面正式开始陈列。

 

 

前置条件

 

你自个的环境要有Docker。因为我们构建的就是一个 专门用于构建发布的Docker镜像

首先确认Docker DNS,免得在Docker里下载软件的时候报错。 alpine 目前出现过这个错误。

重点是下面的 dns 选项,务必设置一下。

{
  "registry-mirrors": [
    "https://docker.mirrors.ustc.edu.cn"
  ],
  "exec-opts": [
    "native.cgroupdriver=systemd"
  ],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2",
  "dns": ["8.8.8.8","114.114.114.114"]
}

 

Build我们需要的环境镜像(Dockerfile)

FROM maven:3.8.5-eclipse-temurin-17-alpine

RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
RUN apk update && apk upgrade && apk add curl wget bash  && apk add ca-certificates && update-ca-certificates \
    && apk add --update tzdata && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
    && echo "Asia/Shanghai" > /etc/timezone \
    && apk add docker\
    && rm -rf /var/cache/apk/*

CMD ["dockerd"]

 

Tips:

  • apk update
  • apk add docker

这几个命令都是必要的

其他的都是补充库、源设置、时区校准, 可以自行调整。 比如你要一个 git 环境, 那就直接在里边添加一个 apk add git 即可。

 

CMD 启动命令 dockerd, 是用来启动 Docker 后台守护进程的。 不加的话在你使用 docker 命令时会报如下错误:

Cannot connect to the Docker daemon at unix:/var/run/docker.sock. Is the docker daemon running?

 

Alpine Linux 不能使用 systemctl 命令启动docker,不是那一套体系。

service 库也不存在,所以也用不了我们平时 service  docker start 这种命令。

 

 

执行构建命令:

docker build -t docker-maven:jdk17 .

这里的 docker-maven:jdk17 可自行替换。仅作为例子,下同。

 

 

运行启动

运行容器需给 privileged 权限,否则会报错:

failed to start daemon: Error initializing network controller: error obtaining controller instance: failed to create NAT chain DOCKER: iptables failed: iptables -t nat -N DOCKER: iptables v1.8.7 (legacy): can’t initialize iptables table `nat’: Permission denied (you must be root)
Perhaps iptables or your kernel needs to be upgraded.
(exit status 3)

 

启动的命令如下

docker run -itd --name dockermvn --privileged=true docker-maven:jdk17

 

 

启动完成后就可以进去容器大搞特搞了!

docker exec -it dockermvn /bin/bash

 

当然,我是拿这镜像来做构建环境的,所以也不需要进里边干啥,构建的实际操作都是在云端自动化。

后续我就直接将其 push 到私有制品库中,然后在流水线控制台直接挂载这个环境, 添加一个 –privileged=true  的启动参数就OK了。

总体效果非常满意。

 

 

           


EA PLAYER &

历史记录 [ 注意:部分数据仅限于当前浏览器 ]清空

      00:00/00:00