docker内运行systemd并实现dockerindocker

通常的dockerindocker使用的是docker:dind并映射宿主机的/var/run/docker.sock就能实现在docker内控制宿主机的docker

现在这种方式是在docker中运行systemd服务并在内新启动一个docker服务(不使用宿主机的docker服务, 隔离宿主机的docker), 需要映射宿主机的cgroup实现docker功能和进程隔离, 且性能高

# 在docker中使用systemd, 然后可以启动容器内的docker(非doocker-in-docker)可以安装宝塔/1panel
# https://cloud-atlas.readthedocs.io/zh-cn/latest/docker/init/docker_systemd.html
FROM registry.cn-hangzhou.aliyuncs.com/jcleng/library-ubuntu:20.04
ENV container docker
# 跳过交互
ENV DEBIAN_FRONTEND=noninteractive

RUN sed -i 's/archive.ubuntu.com/mirrors.aliyun.com/g'  /etc/apt/sources.list && apt update && apt install -y \
systemd docker.io curl wget \
&& rm -rf /var/lib/apt/lists/*

# COPY --from=registry.cn-hangzhou.aliyuncs.com/jcleng/library-docker:24.0.9-cli /usr/local/bin/docker /usr/local/bin/docker
COPY --from=registry.cn-hangzhou.aliyuncs.com/jcleng/library-docker:24.0.9-cli /usr/local/bin/docker-compose /usr/local/bin/docker-compose


VOLUME [ "/sys/fs/cgroup", "/tmp", "/run" ]
ENTRYPOINT [ "/usr/lib/systemd/systemd" ]
CMD [ "log-level=info", "unit=sysinit.target" ]
  • 运行

# 使用网络隔离, 宿主机通过容器内的eth0网卡ip进行通信
# 转发端口, 容器ip是172.17.0.2
socat TCP4-LISTEN:1212,reuseaddr,fork TCP4:172.17.0.2:80
# 或者测试使用zerotier组网通信

docker run -itd \
    --restart=always \
    --privileged \
    --cgroupns=host \
    --cap-add=SYS_ADMIN \
    -v /sys/fs/cgroup:/sys/fs/cgroup \
    --name=systemdos \
    registry.cn-hangzhou.aliyuncs.com/jcleng/ubuntu-systemd:20.04

# 如果需要--network=host的网络, 那么需要宿主机和docker镜像需要统一系统,因为会直接对宿主机的iptables进行管理, 否则防火墙规则错乱; 或者增加启动参数
dockerd --iptables=false
# 进入
docker exec -it systemdos bash

# 查看systemd状态
systemctl status
#  State: running 
docker images
docker -v
# Docker version 24.0.7, build 24.0.7-0ubuntu2~20.04.1

# 可以安装 1panel, 测试用
curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_start.sh && sudo bash quick_start.sh
  • 实例创建一个隔离环境

# 应用名称 digapp
docker network create \
    --subnet=192.168.100.0/24 \
    systemdos-digapp-network
# 或者配合macvlan,可以实现同局域网同网段IP(创建br0桥接); 然后创建docker网络: docs/source/dir1/docker运行openwrt.md

# 查看网络
docker network ls|grep systemdos

# 使用nerdctl可以使用命名空间
export CONTAINERD_NAMESPACE=tt
export CONTAINERD_ADDRESS=unix:///run/containerd/containerd.sock
nerdctl ps

# 指定网络和静态ip
docker run -itd \
    --restart=always \
    --privileged \
    --cgroupns=host \
    --cap-add=SYS_ADMIN \
    -v /sys/fs/cgroup:/sys/fs/cgroup \
    --net systemdos-digapp-network \
    --ip 192.168.100.2 \
    --name=systemdos-digapp \
    registry.cn-hangzhou.aliyuncs.com/jcleng/ubuntu-systemd:20.04

# 物理机访问
ping 192.168.100.2