在docker容器里面使用docker
0. 前言
0.1 需求
对于我个人而言在docker容器里面使用docker其实最大的一个作用就是想在一个比较纯净的服务器里面测试一些软件和标本,碍于虚拟机无法使用宿主机的gpu有些程序是需要运行在cuda上的,所以就考虑在容器中部署docker进行调试。btw:docker hub上有已经安装好docker的容器,但是我需要一个完全纯净的环境并且直接想省去cudnn那些安装步骤所以不符合要求。
0.2 原理
首先docker里面是可以运行docker的,但是docker需要使用systemd进行守护进程,一般容器不能直接使用systemd所以其实问题就转换为在docker容器里面使用systemd了。btw: 按照这个原理docker容器里面使用podman应该很轻松就能实现。
1. 创建镜像
1.1 准备Dockerfile
在项目文件夹(可以是空文件夹)中创建名为 Dockerfile
的文件,内容如下: 可以考虑提前把父镜像拉取到本地
FROM ubuntu:20.04 # 修改为需要基于的镜像
#FROM nvidia/cuda:11.7.1-cudnn8-devel-ubuntu22.04# 设置时区,非必须但是建议提前设置好,不然后续安装可能会提示选择时区
ENV DEBIAN_FRONTEND=noninteractive
#ENV TZ=Asia/Shanghai# 设置apt国内阿里源,非必须
#RUN cp /etc/apt/sources.list /etc/apt/sources.list.bak \
#&& touch /etc/apt/sources.list \
#&& sed -i 's/archive.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list \
#&& sed -i 's/security.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list \
#&& sed -i 's/ports.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list# 安装systemd
RUN apt-get update && apt-get install systemd systemd-sysv -yENTRYPOINT ["/usr/sbin/init"] # 安装docker和其他用到的软件,考虑要模拟安装过程这里不等待容器运行后再安装
#RUN apt-get install docker docker-compose -y
1.2 build 新的镜像
使用以下命令创建新的镜像, -t(--tag) dind:ubuntu_2004
为镜像名自行修改,但是要和下面步骤的对应。
docker buildx build -f ./Dockerfile -t dind:ubuntu_2004 .
# docker build -f ./Dockerfile -t dind:ubuntu_2004 . # 旧版docker没有buildx使用这个
注意命令后面有个
.
, 表示当前文件夹。 docker buildx build 需要跨平台创建镜像时候可以使用--platform
参数(比如在mac上同时创建amd64镜像可以使用 –platform linux/amd64,linux/arm64 ),docker build也一样但是只能单一平台。
2. 启动
启动方式根据需要选其中一种即可
2.1 docker run启动
参考以下docker run命令修改后进行启动修改。
docker run -itd --privileged=true --name ubuntu_dind dind:ubuntu_2004
其中 --privileged=true
在这里为必须参数表示赋予容器几乎所有的宿主机权;末尾的dind:ubuntu_2004
对应1.2 中创建的新镜像的镜像名称,--name ubuntu_dind
为容器名, -itd
为
-i(--interactive)
保持标准输入(STDIN)打开,即使没有连接终端允许与容器进行交互(如输入命令)-t(--tty)
使容器像交互式终端一样运行-d(--detach)
在后台运行容器
2.2 docker-compose 启动
在项目文件夹中创建以下内容的docker-compose.yaml
文件,内容根据自己需要进行修改. 其中 stdin_open: true
(保持标准输入打开)、 privileged: true
(启用特权模式)、tty: true
(使容器像交互式终端一样运行)为必须项。 image: dind:ubuntu_2004
对应1.2 中创建的新镜像的镜像名称。
services:ubuntu_dind: # 容器名, 也可以使用name参数设置image: dind:ubuntu_2004 # 对应build时候的镜像名stdin_open: true privileged: truetty: truerestart: unless-stopped # 启动方式 # volumes: # 数据卷 目录映射# - ./install:/data/install## cuda的一些配置,一般情况下不需要# deploy:# resources:# reservations:# devices:# - driver: nvidia# count: 1# capabilities: [gpu]
保存后使用docker-compose up -d
启动,根据实际情况修改启动命令,-d
为后台运行, 这里隐藏了 -f ./docker-compose.yaml 参数 。
-1. 使用
docker exec xxx bash
进入容器(xxx 对应容器名),然后安装docker (可以使用 apt-get install docker 安装), 使用systemctl start docker
启动docker docker ps 能看到空的容器列表就可以在docker容器里面使用docker了。