摘要
在日常开发中,其实我这里是没有使用 Docker 的,依然是手动安装依赖、配置环境。
但是近期在抄别人的开源项目时,发现 Docker 基本已经成了开发者必备,因此我也特意学习了下,没啥深度,只是记录基础使用。
正文
在日常开发中,其实我这里是没有使用 Docker 的,依然是手动安装依赖、配置环境。
但是近期在抄别人的开源项目时,发现 Docker 基本已经成了开发者必备,因此我也特意学习了下,没啥深度,只是记录基础使用。
一、引言
1.1 Docker 是什么?
Docker 是一个开源的容器化平台,它能够让开发者在任何环境下构建、打包和运行应用程序。Docker 通过 容器(Container) 技术,使应用程序及其依赖项能够在不同环境中保持一致性,从而提高部署效率并减少环境差异带来的问题。
Docker 的核心容器引擎(Docker Engine)是开源的,但 Docker 公司围绕它构建了一些 商业化产品(如 Docker Desktop 和 Docker Hub 的高级功能)
简单来说,Docker 就像一个轻量级的虚拟机,但它比传统虚拟机更高效,占用更少资源,同时具备更快的启动速度。
1.2 Docker vs 传统虚拟机
在传统的软件开发和部署过程中,我们通常使用 虚拟机(Virtual Machine,VM) 来运行应用,而 Docker 提供了一种更轻量级的容器化方案。
1.2.1 Docker 与虚拟机对比
| 对比项 | Docker 容器 | 传统虚拟机(VM) |
|---|
| 架构 | 共享宿主机的操作系统内核 | 每个 VM 运行一个完整的操作系统 |
| 启动速度 | 秒级启动(轻量级) | 分钟级启动(需要引导 OS) |
| 资源占用 | 共享主机资源,占用少 | 每个 VM 需要独立的 CPU、内存 |
| 运行效率 | 接近原生性能 | 受限于虚拟化开销,性能较低 |
| 环境隔离 | 进程级隔离,共享宿主机内核 | 完全隔离,适用于多种 OS |
| 移植性 | 一次构建,到处运行 | 依赖 VM 具体配置,移植性较差 |
| 部署难度 | 轻量级部署,直接运行 | 需要完整安装操作系统,部署复杂 |
| 存储管理 | 使用 分层镜像,减少重复存储 | 每个 VM 独立存储,磁盘占用大 |
| 适用场景 | 微服务、CI/CD、云原生应用 | 运行不同操作系统、传统 IT 业务 |
1.2.2 为什么选择 Docker?
Docker 由于 启动快、占用资源少、易于部署,在现代软件开发中越来越流行,特别适用于:
- 微服务架构:可以将每个服务独立打包成一个容器,方便部署和扩展。
- 持续集成/持续部署(CI/CD):配合 Jenkins、GitHub Actions,快速构建和发布应用。
- 云计算和 DevOps:可以轻松迁移、扩展应用,适用于 AWS、Kubernetes 等云平台。
什么时候用传统虚拟机?
如果需要运行 不同操作系统,如 Windows + Linux 环境,或者需要完整的系统级隔离,传统虚拟机仍然是更好的选择。
1.3 Docker 的核心概念
Docker 主要由 镜像(Image)、容器(Container) 和 仓库(Registry) 三个核心部分组成:
- 镜像(Image):应用程序及其依赖的封装,类似于一个模板,用于创建容器。
- 容器(Container):镜像的运行实例,一个独立的进程,拥有自己的文件系统、网络环境等。
- 仓库(Registry):用于存储和分发 Docker 镜像,类似于代码仓库,常见的有 Docker Hub、阿里云镜像仓库等。
镜像 → 容器 → 运行应用,这是 Docker 的基本流程,后续章节会详细介绍如何使用 Docker 进行构建、管理和部署应用。
1.4 总结
Docker 和传统虚拟机各有适用场景,但对于大多数现代 Web 应用、微服务架构和 DevOps 流水线,Docker 更加轻量级、高效,能提升开发和运维效率。
Docker 不是要完全取代虚拟机,而是提供了一种更灵活、更高效的应用运行方式!
二、Docker 安装与环境准备
这个安装过程,是以我自己的电脑环境为准。
- Windows:Windows11
- Linux:CentOS7
2.1 Windows
官方下载地址:Docker 官网
安装步骤
- 下载
Docker Desktop 安装包。 - 双击运行安装程序。
- 安装完成后,重启计算机。
- 启动 Docker Desktop 并检查是否正常运行。
验证安装
我使用的是VMware16.1版本,安装docker后发现挂起功能无法正常使用了。因此我将Windows上的docker卸载了。
Docker Desktop 需要 Hyper-V 或 WSL2 运行容器。
VMware Workstation Pro 依赖 裸机虚拟化(VT-x / AMD-V),但 Hyper-V 可能会抢占虚拟化权限,导致 VMware 运行变慢或无法启动。
windows 安装完docker, hype-v开启之后,vmware无法使用 - sunny123456 - 博客园
Docker Desktop傻瓜式的包含了许多工具,当然了Docker Desktop仅对个人免费。
2.2 Linux
如果是还在维护的Linux版本,可以参考官网的版本安装 | Docker 文档,而我测试使用的CentOS7已经不再维护了,所以单独记录一下。
2.2.1 安装 DockerEngine
DockerEngine 是 Docker 的核心组件,支持镜像管理和容器管理。
首先,安装 DockerEngine,这包含 Docker 守护程序 dockerd 和 Docker 客户端 docker 。
创建init.sh,将以下内容复制粘贴进去,然后执行sh init.sh,注册docker-daemon服务。参考二进制文件 | Docker 文档
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
| #!/usr/bin/env bash
set -e # 遇到任何非零退出码的命令就立即退出
echo "$(date +"%Y-%m-%d %H:%M:%S"): 下载docker..."
curl -L -k -o docker-27.5.1.tgz https://download.docker.com/linux/static/stable/x86_64/docker-27.5.1.tgz
echo "$(date +"%Y-%m-%d %H:%M:%S"): 解压docker..."
tar -zxvf docker-27.5.1.tgz
echo "$(date +"%Y-%m-%d %H:%M:%S"): 添加docker命令..."
cp docker/* /usr/bin/
echo "$(date +"%Y-%m-%d %H:%M:%S"): 创建docker数据目录..."
mkdir -p /data/docker
echo "$(date +"%Y-%m-%d %H:%M:%S"): 创建docker配置文件..."
mkdir -p /etc/docker
cat>/etc/docker/daemon.json<<EOF
{
"builder": {
"gc": {
"defaultKeepStorage": "20GB",
"enabled": true
}
},
"data-root": "/data/docker",
"experimental": false,
"log-driver": "json-file",
"log-opts": {
"max-file": "3",
"max-size": "100m"
},
"registry-mirrors": [
"https://dockerpull.pw",
"https://docker.1ms.run"
]
}
EOF
echo "$(date +"%Y-%m-%d %H:%M:%S"): 注册docker服务..."
cat >/etc/systemd/system/docker.service<<EOF
[Unit]
Description=docker
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/dockerd
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
echo "$(date +"%Y-%m-%d %H:%M:%S"): 启动docker..."
systemctl start docker
echo "$(date +"%Y-%m-%d %H:%M:%S"): 配置docker开机自启动..."
systemctl enable docker
echo "$(date +"%Y-%m-%d %H:%M:%S"): 使用方式: systemctl status docker"
echo "成功"
|
当脚本执行成功后,运行命令进行镜像拉取、并运行。
1
| docker run --rm hello-world
|
2.2.2 插件 DockerCompose
若有docker compose的需要,还需要再次安装插件。参考插件 | Docker 文档或者docker/compose
DockerCompose 是一个用于定义和管理多容器应用的工具,通过 docker-compose.yml 文件描述多个服务及其依赖,支持一键启动、停止整个应用栈。
创建compose.sh,将以下内容复制粘贴进去,然后执行sh compose.sh,安装插件。
1
2
3
4
5
6
7
8
9
10
11
| #!/bin/bash
set -e # 遇到任何非零退出码的命令就立即退出
echo "$(date +"%Y-%m-%d %H:%M:%S"): 下载compose..."
curl -L -k -o docker-compose https://github.com/docker/compose/releases/download/v2.32.4/docker-compose-linux-x86_64
echo "$(date +"%Y-%m-%d %H:%M:%S"): 创建compose的lib目录..."
mkdir -p /usr/lib/docker/cli-plugins
echo "$(date +"%Y-%m-%d %H:%M:%S"): 安装docker-compose..."
mv docker-compose /usr/lib/docker/cli-plugins
chmod +x /usr/lib/docker/cli-plugins/docker-compose
echo "成功"
|
当脚本执行成功后,验证
2.2.3 插件 DockerBuildx
docker buildx 是 Docker 的一个扩展工具,用于支持跨平台构建(如 ARM、x86 等)。
执行以下命令,安装插件
1
2
3
4
5
6
7
8
9
10
11
| #!/bin/bash
set -e # 遇到任何非零退出码的命令就立即退出
echo "$(date +"%Y-%m-%d %H:%M:%S"): 下载buildx..."
curl -L -k -o docker-buildx https://github.com/docker/buildx/releases/download/v0.20.1/buildx-v0.20.1.linux-amd64
echo "$(date +"%Y-%m-%d %H:%M:%S"): 创建buildx的lib目录..."
mkdir -p /usr/lib/docker/cli-plugins
echo "$(date +"%Y-%m-%d %H:%M:%S"): 安装docker-buildx..."
mv docker-buildx /usr/lib/docker/cli-plugins
chmod +x /usr/lib/docker/cli-plugins/docker-buildx
echo "成功"
|
当脚本执行成功后,验证
2.3 特殊问题
2.3.1 开启IPv4转发
Docker 默认使用 bridge 网络模式,在宿主机上创建一个 docker0 网桥,并给它分配一个子网(如 172.17.0.0/16)。当容器需要访问外网或其他容器时,Linux 需要通过 iptables 和 net.ipv4.ip_forward 进行数据包转发。
如果 net.ipv4.ip_forward=0,则宿主机不会转发数据包,导致容器无法访问外网或其他容器。
验证是否开启ipv4
1
2
3
4
| # 方式一
sysctl net.ipv4.ip_forward
# 方式二
cat /proc/sys/net/ipv4/ip_forward
|
临时修改,服务器重启后失效
1
2
3
4
| # 方式一
sysctl -w net.ipv4.ip_forward=1
# 方式二
echo 1 > /proc/sys/net/ipv4/ip_forward
|
永久修改
1
2
3
| echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
# 重新加载内核参数
sysctl -p
|
2.3.2 failed to find iptables
在ARM架构机器上启动docker时,遇到报错。日志如下
1
| level=warning msg="failed to find iptables" error="exec: \"iptables\": executable file not found in $PATH"
|
解决办法
1
2
| apt install -y iptables
iptables --version
|
2.3.3 映射端口监听0.0.0.0但只能通过127.0.0.1访问
我使用 docker 启动容器
1
2
3
4
5
6
7
8
| -v /etc/localtime:/etc/localtime:ro \
-v /root:/root \
-e TZ=Asia/Shanghai \
-e POSTGRES_USER=postgres \
-e POSTGRES_PASSWORD=postgres \
-p 5432:5432 \
--name postgresql \
4f25b6d58984
|
发现是 docker0 这个网卡丢失了 ipv4 的地址。
解决办法:重启 docker 或者 手动配置 ip
1
2
3
| ip addr add 172.17.0.1/16 dev docker0
ip addr del 172.17.0.1/16 dev docker0
|
三、Docker 核心概念详解
Docker 主要由三大核心概念组成:镜像(Image)、容器(Container)和仓库(Registry)。
3.1 镜像(Image)
镜像是 Docker 的基础,可以理解为一个包含应用及其依赖环境的模板。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
| # 从仓库拉取指定镜像(推荐显式指定 tag 避免使用默认的 latest)
docker pull <repository>:<tag>
# 列出本地镜像(不包括中间层)
docker images
# 列出所有镜像(包含中间层缓存)
docker images -a
# 删除指定镜像(推荐优先使用 repository:tag 格式)
docker rmi <repository>:<tag>
# 通过镜像ID删除
docker rmi <image_id>
# 删除所有镜像
docker rmi -f $(docker images -q)
# 从运行中的容器创建新镜像(注意:不会包含挂载的 volume 数据!若需要包含数据,需要使用docker cp)
# 建议仅用于调试,生产环境应使用 Dockerfile
docker commit <container_id|name> <repository>:<tag>
# 无网模式下导出本地镜像
docker save -o myimage.tar <repository>:<tag>
docker save -o myimage.tar <image_id>
# 无网模式下加载镜像(加载后需要手动打tag)
docker load -i /root/myimage.tar
# 为加载单独镜像添加标签
docker tag <image_id> <repository>:<tag>
# 使用 Dockerfile 构建镜像(推荐最佳实践)
# -t 指定镜像标签
# --rm=true 构建成功后删除中间容器(默认)
# 注意末尾的构建上下文路径(.)
docker build -t <repository>:<tag> .
# 查看docker镜像信息
docker inspect <image_id>
|
3.2 容器(Container)
启动容器时,需要考虑时间和时区的影响,可以添加如下两个参数
1
2
3
4
| # 表示只读模式同步宿主机的时间
-v /etc/localtime:/etc/localtime:ro
# 表示只读模式同步宿主机的时区
-v /etc/timezone:/etc/timezone:ro
|
在一些信创机器上,发现/etc/timezone被阉割掉了。可以通过设置环境变量解决。
容器是镜像的运行实例,包含所有应用运行所需的环境。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
| # 后台运行特权容器(生产环境慎用 --privileged!)
# --privileged 赋予容器宿主机级权限(安全隐患!)
# --rm 容器退出时自动删除(适合临时任务)
# -v 挂载宿主机时区配置(ro 表示只读保护)
docker run -d \
--privileged \
--rm \
-v /etc/localtime:/etc/localtime:ro \
-v /etc/timezone:/etc/timezone:ro \
--name <container_name> \
<image_id>
# 交互式运行特权容器(适用于调试)
# -it 开启交互终端
# 末尾的 bash 指定启动 shell
docker run -it \
--privileged \
--rm \
-v /etc/localtime:/etc/localtime:ro \
-v /etc/timezone:/etc/timezone:ro \
--name <container_name> \
<image_id> \
bash
# 运行 Java 应用容器
# -w 设置工作目录(确保 jar 包存在该路径)
# bash -c 执行复合命令
# 如果需要执行初始化命令,然后再进入bash,可以bash -c "cp -r /data/* /root/. && bash"
docker run -d \
--privileged \
--rm \
-v /etc/localtime:/etc/localtime:ro \
-v /etc/timezone:/etc/timezone:ro \
-w /opt/project \
--name <container_name> \
<image_id> \
bash -c "java -jar test.jar"
# 查看运行中的容器
docker ps
# 查看所有容器(包括已停止的)
docker ps -a
# 查看容器资源占用(实时监控)
docker stats
# 查看指定容器资源占用
docker stats <container_id|name>
# 以附加模式进入容器(推荐方式,退出不会终止容器)
# 使用 sh 或 bash 根据镜像基础系统决定
docker exec -it <container_id|name> sh
docker exec -it <container_id|name> bash
# 以主进程模式连接容器(危险!退出可能导致容器停止)
docker attach <container_id|name>
# 优雅停止容器(发送 SIGTERM)
docker stop <container_id|name>
# 强制停止容器(发送 SIGKILL)
docker kill <container_id|name>
# 启动容器
docker start <container_id|name>
# 重启容器
docker restart <container_id|name>
# 删除容器(必须先停止)
docker rm <container_id|name>
# 查看容器日志
docker logs <container_id|name>
# 实时跟踪日志(类似 tail -f)
docker logs -f <container_id|name>
# 从最新10行开始实时跟踪
docker logs -f --tail 10 <container_id|name>
# 设置容器自启动策略
docker update --restart=always <container_id|name> # 总是重启
docker update --restart=on-failure:5 <container_id|name> # 失败时重启最多5次
docker update --restart=no <container_id|name> # 禁用自启
# 查看容器详细信息(包括配置、网络、挂载等)
docker inspect <container_id|name>
# 查看容器资源使用情况
docker stats
# 宿主机到容器的文件拷贝。这个文件拷贝是双向的,即可以宿主到容器,也可以容器到宿主。类似于scp命令
# 拷贝目录:将宿主的jdk11文件夹,拷贝到容器的/opt/下面
docker cp /opt/jdk11 <container_id|name>:/opt/
# 拷贝单个文件:
docker cp test.txt <container_id|name>:/opt/test.txt
|
docker run常用参数速查表,可以通过docker run --help获取。
| 参数 | 作用说明 | 示例 |
|---|
--add-host | 增加 hosts 映射 | --add-host example.com:192.168.1.1 |
--cap-add | 增加特权能力 | --cap-add=NET_ADMIN |
--cap-drop | 移除特权能力 | --cap-drop=ALL |
--cpus | 限制使用 CPU 核心数 | --cpus=1.5 |
--cpu-shares | 设置相对 CPU 权重 | --cpu-shares=512 |
--cpuset-cpus | 指定使用哪些 CPU 核心 | --cpuset-cpus=0,1 |
--detach (-d) | 后台运行容器(detached 模式) | -d |
--device | 授权容器访问宿主设备 | --device /dev/snd |
--dns | 指定容器的 DNS 服务器 | --dns 8.8.8.8 |
--entrypoint | 自定义入口命令 | --entrypoint /bin/bash |
--env(-e) | 设置环境变量 | -e TZ=Asia/Shanghai |
--env-file | 从文件加载环境变量 | --env-file .env |
--expose | 声明容器暴露端口(不映射) | --expose 3306 |
--hostname(-h) | 设置容器主机名 | -h myhost |
--interactive (-i) | 保持标准输入流打开 | -i |
--ipc | 设置 IPC 命名空间 | --ipc=host |
--label | 给容器加标签 | --label app=myapp |
--log-driver | 指定日志驱动(json-file、syslog、none 等),默认为json-file | --log-driver=json-file |
--log-opt | 日志驱动选项 | --log-opt max-size=10m |
--memory(-m) | 限制内存大小 | --memory 512m |
--memory-swap | 限制 swap 使用 | --memory-swap=1g |
--mount | 推荐写法:挂载绑定卷或命名卷 | --mount type=bind,source=/data,target=/app |
--name | 容器命名 | --name my-container |
--network | 设置网络模式(bridge、host、none、自定义),默认为bridge。若设置 host 模式会让容器直接使用宿主机的网络命名空间,不需端口映射。 | --network=host |
--oom-kill-disable | 禁止因 OOM 杀掉容器 | --oom-kill-disable |
--pid | 设置 PID 命名空间。默认为private,为容器分配独立的PID命名空间。 | --pid=host |
--privileged | 启用特权模式(访问全部设备) | --privileged |
--publish(-p) | 端口映射(宿主:容器) | --publish 8080:80 |
--rm | 容器退出后自动删除 | --rm |
--security-opt | 安全配置项,如 seccomp | --security-opt seccomp=unconfined |
--sysctl | 设置内核参数 | --sysctl net.ipv4.ip_forward=1 |
--tty (-t) | 分配伪终端 | 一般是组合使用。-it |
--tmpfs | 使用内存挂载 | --tmpfs /run:size=65536k |
--user | 指定容器用户(uid:gid) | --user 1000:1000 |
--uts | 设置 UTS 命名空间 | --uts=host |
--volume(-v) | 绑定挂载目录或文件 | --volume /host:/container |
--volume-driver | 指定使用的卷驱动 | --volume-driver=local |
--workdir(-w) | 设置容器内工作目录 | --workdir /app |
3.3 仓库(Registry)
Docker 镜像存放的地方,可以是 Docker Hub 也可以是私有仓库。
1
2
3
4
5
6
7
8
| # 登录 Docker Hub
docker login
# 推送镜像到仓库
docker push <用户名|镜像名>:<标签>
# 从私有仓库拉取镜像
docker pull <私有仓库地址>/<镜像名>:<标签>
|
3.4 数据管理
针对一些必要的数据,进行数据卷挂载,实现持久化。
1
2
3
4
5
6
7
8
| # 数据卷挂载
docker run -d -v /host/path:/container/path --name mycontainer ubuntu
# 查看所有卷
docker volume ls
# 删除数据卷
docker volume rm <卷名>
|
四、Dockerfile 与自定义镜像
示例代码meethigher/docker-learn: 编写一个Java项目学习Docker使用
4.1 构建 Docker 镜像
Dockerfile 是用于定义自定义镜像的文本文件,包含构建镜像所需的指令。
示例代码meethigher/docker-learn at 构建docker镜像
1
2
3
4
5
6
7
8
9
10
11
| # 使用 Java 8 运行时环境 docker pull eclipse-temurin:8-jre-alpine
FROM eclipse-temurin:8-jre-alpine
# 设置容器中的工作目录
WORKDIR /docker-learn
# 复制 JAR 文件到设置的容器目录中
COPY target/docker-learn.jar app.jar
# 运行 Java 应用
CMD ["java", "-jar", "app.jar"]
|
使用 docker build 命令基于 Dockerfile 构建镜像。
1
2
3
4
5
| # 格式。如果不使用标签,默认是latest
docker build -t <镜像名>:<标签> <构建上下文>
# -t指定镜像名。.表示当前目录(目录应是Dockerfile所在目录)
docker build -t docker-learn .
|
4.2 多阶段构建优化 Docker 镜像
使用多阶段构建可以减少最终镜像的大小,它仅保留运行时所需的文件,而不会把构建过程中产生的无关文件带入最终镜像,提高构建效率。
示例代码meethigher/docker-learn at 多阶段构建docker镜像
1
2
3
4
5
6
7
8
9
10
11
| # 第一阶段:构建阶段
FROM maven:3.6.3-openjdk-8 AS builder
WORKDIR /app
COPY . .
RUN mvn clean package -DskipTests
# 第二阶段:运行阶段。将第一阶段的构建产物复制到第二阶段中
FROM eclipse-temurin:8-jre-alpine
WORKDIR /app
COPY --from=builder /app/target/docker-learn.jar app.jar
CMD ["java", "-jar", "app.jar"]
|
执行构建命令后如图
4.3 推送镜像到 Docker Hub/私有仓库
1
2
3
4
5
6
7
8
| # 登录 Docker Hub
docker login
# 给镜像打标签(格式:仓库名/镜像名:标签)
docker tag my-nginx your_dockerhub_username/my-nginx:v1
# 推送到 Docker Hub
docker push your_dockerhub_username/my-nginx:v1
|
五、Docker Compose(多容器管理)
5.1 什么是 Docker Compose?
Docker Compose 允许使用 docker-compose.yml 文件来定义和管理多个容器。
5.2 使用 Docker Compose 启动多容器
示例代码meethigher/docker-learn at docker-compose
以下是一个 docker-compose.yml 文件示例,定义了 app和 db 两个服务。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| services:
app:
build: .
container_name: java_app
depends_on:
- db
environment:
DB_URL: jdbc:postgresql://db:5432/mydatabase
DB_USER: myuser
DB_PASSWORD: mypassword
ports:
- "8080:8080"
db:
image: postgres:15
container_name: postgres_db
restart: always
environment:
POSTGRES_DB: mydatabase
POSTGRES_USER: myuser
POSTGRES_PASSWORD: mypassword
ports:
- "5432:5432"
|
启动容器
1
2
3
4
5
6
7
8
| # 在当前目录下启动所有服务 -d表示后台 --build表示重新构建
docker compose up -d
# 查看运行中的容器
docker compose ps
# 停止并删除所有容器
docker compose down
|
日志与调试
1
2
3
4
5
| # 查看所有服务的日志
docker compose logs -f
# 查看特定服务的日志
docker compose logs -f nginx
|
六、Docker 替代品之 Podman
6.1 Podman 简介
Podman(Pod Manager)是一个无守护进程的容器管理工具,功能类似 Docker,主要用于管理 OCI(Open Container Initiative)容器。与 Docker 不同,Podman 不需要后台守护进程(daemon),并且支持 rootless 模式,使得容器运行更加安全。
Podman vs Docker:
| 特性 | Docker | Podman |
|---|
| 守护进程 | 需要 Docker Daemon | 无需守护进程 |
| 权限管理 | 需要 root 或 sudo | 可 rootless 运行 |
| 兼容 Docker CLI | ✅ | ✅(几乎 100% 兼容) |
| 适用于生产环境 | ✅ | ✅(更安全) |
6.2 为什么选择 Podman?
Podman 具有以下优势:
- 无守护进程(Daemonless):不像 Docker 依赖
dockerd 守护进程,Podman 直接运行容器,使得系统更加安全稳定。 - Rootless 模式:Podman 允许普通用户运行容器,而不需要
root 权限,降低安全风险。 - 兼容 Docker:Podman 的 CLI 命令与 Docker 几乎一致。
- Pod 支持:Podman 内置 Pod 概念,能够更好地支持 Kubernetes 生态。
- 更轻量:相比 Docker,Podman 不依赖后台进程,资源占用更少。