docker 使用

 

配置

安装

Windows

在 Windows 上安装 Docker, 推荐使用 Docker Desktop你可以从 Docker 官网下载并按照向导安装

Linux

在 Linux 上安装 Docker, 使用 docker-ce(Docker Community Edition):

sudo apt update && sudo apt install -y ca-certificates curl gnupg lsb-release

curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt update && sudo apt install -y docker-ce docker-ce-cli containerd.io

启动

sudo systemctl start docker
sudo systemctl enable docker

# 或者使用 service 命令
sudo service docker start
sudo service docker enable

验证版本

docker --version

输出示例

Docker version 29.2.1, build a5c7197

配置

镜像加速

为了加速 docker 镜像的拉取, 可以编辑/etc/docker/daemon.json

{
    "builder": {
        "gc": {
            "defaultKeepStorage": "20GB",
            "enabled": true
        }
    },
    "experimental": false,
    "registry-mirrors": [
        "https://docker.hpcloud.cloud",
        "https://docker.m.daocloud.io",
        "https://docker.unsee.tech",
        "https://docker.1panel.live",
        "http://mirrors.ustc.edu.cn",
        "https://docker.chenby.cn",
        "http://mirror.azure.cn",
        "https://dockerpull.org",
        "https://dockerhub.icu",
        "https://hub.rat.dev"
    ]
}

重启服务

sudo systemctl daemon-reload
sudo systemctl restart docker

非 root 用户运行

默认情况下只有root用户和docker组用户才能运行docker命令, 为避免每次都用sudo, 可将当前用户添加到docker组,

sudo usermod -aG docker $USER

添加后需要注销或重启计算机, 更改生效

命令

启动

systemctl start docker

# 或
service docker start

重启

systemctl restart docker

# 或
service docker restart

清理构建缓存

docker builder prune

网络

docker进程启动时会在主机上创建虚拟网桥docker0, 容器启动时若不指定网络模式, 则容器网络默认连接到docker0

graph TB;
    subgraph 网络模式
        N(node模式)
        H(host模式)
        B(bridge模式)
    end
    docker0(docker0)
    eth(物理网卡eth0)

    H<-->eth
    B<-->docker0<-->eth

网络模式

bridge(桥接模式)

默认网络模式

docker启动时会在主机上创建docker0虚拟网桥, 容器网络通过这个网桥与宿主机网络连接

每个容器会分配独立IP, 容器间网络互相隔离, 但可以通过桥接模式与外部网络通信

host(主机模式)

容器直接使用宿主机网络, 容器除网络外其他比如文件系统、进程等依然隔离

none(无网络模式)

容器无任何网络接口, 无法与外部或其他容器通信

container(复用模式)

新创建容器会复用另一个已存在容器网络配置, 包括 IP 地址和端口配置

MACVALN模式

docker会为每个容器分配MAC地址, 使其在网络中表现为物理设备

容器能够与宿主机网络中的其他设备进行直接通信

命令

查看当前网络

docker network ls

示例输出

NETWORK ID     NAME      DRIVER    SCOPE
42f96accc822   bridge    bridge    local
10a212faef48   host      host      local
dc9407901757   none      null      local

创建

默认IP
docker network create --driver 网络类型 网络名
  • 示例, 创建默认网络default_bridge

docker会自定义为其分配IP网段和网关

docker network create --driver bridge default_bridge

创建成功后查看示例输出

NETWORK ID     NAME             DRIVER    SCOPE
......
1a27314dd4c0   default_bridge   bridge    local
......
自定义网关网络
docker network create --driver 网络类型 --subnet 网段 --gateway 网关IP 网络名
  • 示例, 创建自定义网络self_bridge

设置网段172.20.0.0/24, 网关172.20.0.1

docker network create --driver bridge --subnet 172.20.0.0/24 --gateway 172.20.0.1 self_bridge

创建成功后查看本机网络

......
br-66fe74768659: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.20.0.1  netmask 255.255.255.0  broadcast 172.20.0.255
        ether da:31:a9:11:b7:56  txqueuelen 0  (以太网)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
......

使用

docker run -itd --net=网络名 (--ip=自定义IP) (--name=容器名) 镜像
  • 示例, 使用默认与指定IP

创建busybox_1, 使用default_bridge与默认IP; 创建busybox_2, 使用self_bridge网络并指定IP

docker run -it --net=default_bridge --name=busybox_1 busybox

docker run -it --net=self_bridge --ip=172.20.0.99 --name=busybox_2 busybox

运行后可查看两个容器ip地址, 发现属于同一网段

互联
docker network connect 网络名 容器名
  • 示例, 容器网络互联

将busybox_2连接到busbox_1网络

docker network connect default_bridge busybox_2

连接之后可通过ping命令发现两个容器网络联通

删除

docker network rm 网络名

概念

镜像

docker镜像是一种轻量级、可执行软件包, 包含运行某个应用或服务所需所有代码、运行时环境、系统工具、库文件和设置, 可被docker引擎读取并用来创建和运行容器实例

组成

文件系统层

(1) 根文件系统

应用程序运行时所需根文件系统映像, 包括二进制文件、库文件和配置文件等, 其共同构成镜像基础运行环境

(2) 镜像层

docker镜像采用分层结构, 每个镜像都由一系列镜像层组成, 这些层通过UnionFS(联合文件系统)技术叠加在一起, 形成一个完整文件系统

每个层都包含对根文件系统增量更改, 使镜像存储和更新更加高效

元数据

(1) Manifest文件

JSON格式, 描述镜像内容、大小和标签等元数据, 是镜像核心组成部分, 包含镜像构建历史和层信息

(2) 配置文件

指定容器运行时配置信息, 如入口点(entrypoint)、环境变量(environment variables)和卷(volumes)等

配置信息决定容器在启动时行为和状态

(3) 标签

用于组织和标识镜像元数据键值对, 通过标签可以方便地管理和查找镜像

网络设置

docker镜像可以包含网络设置信息, 如IP地址和端口映射等, 在容器启动时会被docker引擎读取并应用到容器上, 从而实现容器与外部网络通信

用户和组

镜像中可以指定容器内进程所运行用户和组信息, 通过用户ID(UID)和组ID(GID)表示, 用于控制容器内进程权限和访问控制

命令

(1) 入口点(entrypoint)

容器启动时所执行命令, 是容器运行起点, 定义容器启动后要所执行主进程

(2) CMD

入口点默认参数, 指定entrypoint后, CMD中参数会被传递给Entrypoint命令作为执行参数

镜像层(image layer)

docker镜像由一系列镜像层(image layers)组成, 镜像层通过UnionFS(联合文件系统)技术叠加在一起, 形成一个完整文件系统

每个镜像层都包含指向其父层指针, 用于访问父层数据, 以及唯一ID标识符, 用于识别管理

graph BT;
    subgraph 宿主机
        X(内核)
    end
    subgraph 镜像
        B(基础镜像层, 轻量级镜像, 作为容器根文件系统)
        C(中间层, 用于安装和配置应用程序及其依赖项)
        D(顶层, 通常是最终配置文件或启动脚本)
    end
    A(共享宿主机内核, 极大降低内存开销)
    A-->X
    A-->B-->C-->D
可写层

docker容器启动时会在镜像最顶层添加一个可写层(容器层), 容器中所有更改(如文件写入、删除等)都会发生在可写层中, 而不影响到下面镜像层

可写层能通过docker commit转换为只读层

UnionFS允许docker将多个镜像层叠加在一起, 形成一个统一文件系统视图

只读层

除最顶层的容器层外, 所有镜像层都只读, 一旦镜像被创建, 其各个层内容就不能被修改

镜像层机制

创建

每个Dockerfile指令都会创建一个新层

缓存

docker会缓存每个层的构建结果, 若Dockerfile中指令没有变化, docker会重用先前构建结果

copy-on-write

容器需要修改文件时, docker不会直接修改底层镜像文件, 而是会在可写层创建一个文件副本, 进行修改

这种策略确保底层镜像不可变性, 同时提高容器性能和安全性

容器

docker容器基于镜像创建, 是镜像运行实例, 类似于类与对象关系

镜像由一系列层组成, 运行镜像时docker会从底向上读取层, 并在最上层创建一个新可写层, 作为容器运行时工作空间

容器 = 镜像 + 可写层

运行态容器(running container)

运行态容器表示容器当前正在执行, 已启动并正运行应用程序或服务

运行态容器中包含一或多个正在运行进程, 其在容器启动时由docker守护进程创建、负责管理和监控

组成

运行状态容器由一个可读写文件系统与隔离进程空间和进程构成

进程隔离

运行状态容器内进程运行在一个与宿主机和其他容器隔离进程空间中, 通过namespaceCgroups等特性实现

进程管理

容器内进程由docker守护进程负责创建、监控和终止

相关技术

namespace

为容器内进程提供独立系统视图, 包括文件系统、网络、用户ID等, 使得容器内进程看起来像是在一个独立操作系统环境中运行

cgroup

用于限制容器内进程资源(如CPU、内存等), 以确保不会消耗过多系统资源