背景
java服务是docker镜像,需要在启动容器后能在容器内调用docker run执行宿主机上的镜像。
原理
什么是/var/run/docker.sock?
/var/run/docker.sock是默认的Unix套接字。套接字用于在同一主机上的进程之间进行通信。Docker守护程序默认情况下侦听docker.sock。如果您在运行Docker守护程序的主机上,则可以使用/ var/run/docker.sock管理容器。
例如,如果运行以下命令,它将返回docker engine的版本。
curl --unix-socket /var/run/docker.sock http://localhost/version
在docker中运行docker
要在docker内部运行docker,要做的只是在默认Unix套接字docker.sock作为卷的情况下运行docker 。例如:
docker run -v /var/run/docker.sock:/var/run/docker.sock -it docker-image
现在,从容器中你就能够执行docker命令来构建镜像并将其推送到镜像仓库。在这里,实际的docker操作发生在运行docker容器的VM主机上,而不是在容器内部进行。意思是,即使您正在容器中执行docker命令,也指示Docker客户端通过以下docker.sock方式连接到VM主机docker-engine。
实现
好多文档上说直接挂载宿主机/var/run/docker.sock就行,实际试验下来这个方案是基于容器本身就是基于docker服务的镜像启动的,简单来说就是容器内必须安装有docker。下面就是对dockerfile改造用离线包方式制作jdk+docker基础镜像
dockerfile文件示例
# 使用debian jdk基础镜像
FROM openjdk:11.0.12-jdk
# 将 Docker 安装包添加到镜像中
ADD docker-20.10.17.tgz /usr/local/
# 添加docker用户
RUN groupadd docker
RUN usermod -aG docker root
# 解压 Docker 安装包
RUN mv /usr/local/docker /usr/local/docker-20.10.17
RUN ln -s /usr/local/docker-20.10.17/docker /usr/bin/docker
RUN ln -s /usr/local/docker-20.10.17/dockerd /usr/bin/dockerd
RUN ln -s /usr/local/docker-20.10.17/containerd /usr/bin/containerd
制作镜像
docker build . --no-cache=true -t test_docker -f ./Dockerfile
启动容器
# 挂载宿主机/var/run/docker.sock
docker run -itd --rm --name demo-docker -v /var/run/docker.sock:/var/run/docker.sock test_docker
进入容器查看docker
可以看到docker run、exec命令都是ok的,至此成功完成安装。