type
status
date
slug
summary
tags
category
icon
password
Docker
1 安装 Docker Engine
1.1 Ubuntu
1.1.1 防火墙限制
在安装 Docker 之前,请确保考虑以下安全影响和防火墙不兼容性。
- 如果您使用 ufw 或 firewalld 来管理防火墙设置,请注意,当您使用 Docker 公开容器端口时,这些端口会绕过您的防火墙规则。有关更多信息,请参阅 Docker 和 ufw。
- Docker 仅兼容
iptables-nft
和iptables-legacy
. 使用以下命令创建的防火墙规则nft
安装了 Docker 的系统不支持。 确保您使用的任何防火墙规则集都是使用以下命令创建的iptables
或者ip6tables
, 并将它们添加到DOCKER-USER
链,参见 数据包过滤和防火墙.
1.1.2 操作系统要求
要安装 Docker 引擎,您需要以下 Ubuntu 版本之一的 64 位版本:
- Ubuntu Noble 24.04 (LTS)
- Ubuntu Jammy 22.04 (LTS)
- Ubuntu Focal 20.04 (LTS)
适用于 Ubuntu 的 Docker 引擎与 x86_64(或 amd64)、armhf、arm64、 s390x 和 ppc64le (ppc64el) 架构兼容。
1.1.3 卸载旧版本
在安装 Docker Engine 之前,您需要卸载所有冲突的软件包。
发行版维护者在 APT 中提供 Docker 软件包的非官方发行版。您必须先卸载这些软件包,然后才能安装官方 版本的 Docker Engine。
要卸载的非官方软件包有:
docker.io
docker-compose
docker-compose-v2
docker-doc
podman-docker
而且,Docker Engine 依赖于
containerd
和 runc
。 Docker Engine 将这些依赖项捆绑为一个包:containerd.io
。如果您已经安装了 containerd
或者 runc
之前,请卸载它们以避免与 Docker Engine 捆绑的版本发生冲突。运行以下命令卸载所有冲突的包:
apt-get
可能会报告您没有安装这些软件包。1.1.4 使用apt
存储库安装
在新主机上首次安装 Docker 引擎之前,需要设置 Docker 存储库并更新。
- 设置 Docker 的
apt
存储库。
- 安装 Docker 软件包。
- 要安装最新版本,请运行:
- 要安装特定版本的 Docker Engine,请首先列出 存储库中的可用版本:
然后选择所需的版本并安装:
- 通过运行映像来验证 Docker Engine 安装是否成功。
此命令将下载测试映像并在容器中运行它。当 container 运行时,它会打印确认消息并退出。
开机自启动 Docker。
1.1.5 从软件包安装
1.1.6 使用便捷脚本安装
1.1.7 升级 Docker 引擎
要升级 Docker 引擎,请按照 #1.1.4 的步骤 2 进行操作。
1.1.8 卸载 Docker Engine
- 卸载 Docker Engine、CLI、containerd 和 Docker Compose 软件包:
- 主机 上的映像、容器、卷或自定义配置文件不会自动删除。要删除所有映像、容器和卷:
你必须手动删除任何编辑的配置文件。
1.2 CentOS
1.2.1 操作系统要求
要安装 Docker 引擎,您需要以下 CentOS 版本之一的维护版本:
- CentOS 9 (stream)
必须启用存储库,默认情况下启用此存储库。如果你已经禁用了,需要重新启用
centos-extras
。1.2.2 卸载旧版本
在尝试安装新版本之前卸载任何此类旧版本以及相关的依赖项。
yum
可能会报告您没有安装这些软件包。存储在的图像、容器、卷和网络
/var/lib/docker/
当您卸载 Docker 时,不会自动删除。1.2.3 使用 rpm 存储库安装
您可以根据需要以不同的方式安装 Docker Engine:
- 您可以 设置 Docker 的存储库 并从中安装 ,以便于安装和升级任务。这是 推荐的方法。
- 您可以下载RPM包, 手动安装,并完全手动管理升级。这在诸如在无法访问互联网的系统上安装 Docker 等情况下非常有用。
- 在测试和开发环境中,您可以使用自动化 便利脚本 安装 Docker。
- 设置存储库
安装软件包(提供实用程序)并设置存储库。
yum-utils``yum-config-manager
- 安装 Docker Engine
要安装最新版本,请运行:
如果提示接受 GPG 密钥,请验证指纹是否匹配
060A 61C5 1B55 8A7F 742B 77AA C52F EB6B 621E 9F35
,如果是这样,请接受它。此命令会安装 Docker,但不会启动 Docker。它还创建一个
docker
但是,默认情况下它不会将任何用户添加到该组中。要安装特定版本,请首先列出存储库中的可用版本:
返回的列表取决于启用了哪些存储库,并且特定于您的 CentOS 版本(由
.el9
本例中的后缀)。通过其完全限定的软件包名称安装特定版本,即 软件包名称(
docker-ce
) 加上版本字符串(第二列), 用连字符分隔 (-
)。例如, docker-ce-3:27.1.1-1.el9
.代替
<VERSION_STRING>
使用所需的版本,然后运行以下 命令进行安装:此命令会安装 Docker,但不会启动 Docker。它还创建一个
docker
但是,默认情况下它不会将任何用户添加到该组中。- 启动 Docker。
开机自启动 Docker。
- 通过运行映像来验证 Docker Engine 安装是否成功。
hello-world
此命令下载测试映像并在容器中运行它。当容器运行时,它会打印一条确认消息并退出。
1.2.4 卸载 Docker Engine
- 卸载 Docker Engine、CLI、containerd 和 Docker Compose 软件包:
- 主机 上的映像、容器、卷或自定义配置文件不会自动删除。要删除所有映像、容器和卷:
你必须手动删除任何编辑的配置文件。
2 Docker 操作
2.1 Docker 命令
详情命令查看:
docker [Command] –-help
2.1.1 镜像
docker search
: 检索镜像
docker pull <镜像名字:版本号>
: 拉取/下载该某一版本镜像。若不指定版本号,则默认最新版本,也就是<镜像名字:latest>
docker images [Command]
: 查看镜像- null: 输出所有下载和导入的镜像
history <镜像名字>
: 查看镜像历史inspect <镜像名字>
: 查看镜像详情
docker rmi
: 删除镜像(不包含容器)
2.1.2 容器
docker run [OPTIONS] <image:版本号>
: 根据镜像运行容器。若是不写版本,则自动下载最新版本。-d
: 后台启动。--name
: 为容器赋名。-p 80:80
:端口映射。将容器内部的端口映射/绑定到物理机上,前者是物理机的端口,后者是容器内部的端口。前者的端口不可重复,因为物理机相同的端口只有一个;而每个容器都可以使用相同的端口,因为容器是相互独立的,端口是虚拟的,因此可以无限制使用。-e
: 环境配置。用于根据容器开放的api对容器进行自定义设置-v /aaa/bbb:/ccc/ddd
:挂载文件或目录。将物理机的/aaa/bbb
目录挂载到容器内的/ccc/ddd
目录,且无论容器的目录下是否有文件、文件是否冲突,一切都以物理机下的目录为准,哪怕是个空目录亦是如此。不止目录,单一个文件也可以。-v eee:/ccc/ddd
: 卷映射。这个看上去和上面那个一样,但区别于:
前不是一个目录,而是一个卷名。它的作用是可以让容器/ccc/ddd
目录下存在的文件在物理机/aaa/bbb
目录中不存在时,依然能够使用容器里默认的文件,但是文件冲突时仍然以/aaa/bbb
下的文件为准。而eee
本身也存在于物理机的/var/lib/docker/volumes/eee
,由docker决定。--netwaork <网络名>
:加入某个网络–restart always
: 崩溃后重启/开机后启动
docker ps [OPTIONS]
: 查看容器- null: 查看当前运行的容器
-a
:查看所有运行和停止的容器-p
: 只输出容器id-s
: 查看容器占用
docker stop <容器名/id>
: 停止容器
docker start <容器名/id>
: 启动容器
docker restart <容器名/id>
: 重启容器
docker stats <容器名/id>
: 状态
docker logs <容器名/id>
: 查看日志
docker exec -it <容器名/id> /bin/bash
: 进入容器内部-it
: 以交互模式进入/bin/bash
: 在容器内部执行的命令。/bin/bash
是大多数Linux发行版中的Shell绝对路径,相当于提供了一个命令行界面,允许用户以命令行的方式与操作系统交互。通过这个shell,你可以在Docker容器内执行各种命令,就仿佛你在一个独立的Linux环境中一样。
docker rm [OPTIONS] <容器名/id>
: 删除容器。- null: 前提必须停止容器,否则报错。
-f
: 强制删除,包括运行中的容器。
docker contatiner inspect <容器名/id>
: 查看容器细节
2.1.3 保存镜像
docker commit [OPTIONS] <容器名/id> <镜像名:版本号>
: 打包容器为一个镜像并提交-m ""
: 提交信息
docker save [OPTIONS] <镜像名:版本号>
-o <包名>.tar
: 打包为一个.tar
包,传输给别人使用
docker load [OPTIONS]
: 解压并加载本地文件到docker镜像列表中-i <包名>.tar
: 指定tar包所在文件
2.1.4 分享社区
docker login
: 登录docker网站,前提是去官网注册一个账号。- Username: 注册时的用户名或邮箱
- Password: 注册时的密码
docker tag <镜像名:版本号> <用户名>/<镜像名:版本号>
: docker官网中的容器都有一个独立的名字,也称之为tag,由唯一性的用户名做区分。此处建议除了指定版本号外,再打包一个版本号为latest
的tag包,防止pull时若没有版本号则会报错的问题。
docker push <用户名>/<镜像名:版本号>
: 推送
2.1.5 卷映射
docker volume [Commands]
: docker卷,存在于物理机的/var/lib/docker/volumes
下。ls
:列出卷create <卷名>
: 创建卷inspect <卷名>
:查看某一卷的详情
2.2 自定义网络
2.2.1 概述
docker 在安装时会创建一个名为
docker0
的虚拟网卡,默认网段为172.17.0.1/16
,理论上可以容纳65536个容器。每一个启动的容器都会默认加入这个网络,docker 为每个容器分配唯一IP,使用容器IP+容器端口可以以http形式互相访问。IP地址有可能会随着容器的崩溃和重启而变动,而域名不会,但是docker0
不支持主机域名,因此docker允许自定义网络,容器名就是稳定的域名。2.2.2 命令
docker network [Command]
create <网络名>
: 创建一个网络
2.2.3 详解
- 默认的
bridge
网络: - 当你启动 Docker 容器时,如果没有指定网络,Docker 会将容器连接到默认的
bridge
网络中。 - 在
bridge
网络中,容器之间 无法 直接通过容器名进行通信,需要使用容器的 IP 地址来通信。 - 如果你希望容器能够通过容器名进行通信,需要使用自定义的
bridge
网络。
- 自定义
bridge
网络: - 你可以创建一个自定义
bridge
网络,让所有需要相互通信的容器加入该网络。 - 在自定义的
bridge
网络中,Docker 会为每个容器配置一个 DNS 解析服务,使得容器可以通过容器名相互访问。 - 例如,以下命令创建一个自定义网络并运行两个容器:
- 在
my-network
中,container1
可以通过http://container2:<port>
访问container2
提供的服务,反之亦然。
host
网络:- 使用
host
网络模式时,容器将直接使用主机的网络栈,因此容器的网络配置与主机相同。 - 在这种模式下,容器之间可以通过主机的 IP 地址和端口进行通信,但不能使用容器名。
overlay
网络:- 在 Docker Swarm 或 Kubernetes 集群中,
overlay
网络允许跨多个主机的容器通过容器名进行通信。 overlay
网络非常适合分布式系统中的容器通信。
示例:通过容器名进行通信
假设你在
my-network
自定义网络中有两个容器,分别命名为 web
和 db
:- 你可以通过以下方式在
web
容器中访问db
容器提供的服务:
- 这里的
db
就是容器的名字,3306
是服务运行的端口号。
3 Docker Compose
Docker Compose 是一个用于定义和运行多容器 Docker 应用的工具。它允许你通过一个简单的配置文件(
docker-compose.yml
)来管理和编排多个 Docker 容器的创建、启动、停止和连接。使用 Docker Compose,你可以轻松地管理复杂的多容器应用,而不需要手动启动每个容器或进行复杂的网络配置。3.1 主要功能:
- 定义多容器服务: 你可以在一个文件中定义多个服务(容器),并指定每个服务的镜像、环境变量、端口、卷、网络等配置信息。
- 跨容器的网络管理: Docker Compose 自动创建默认的网络,所有定义的容器服务可以通过容器名轻松互相通信,无需手动配置网络。
- 简化的命令操作: 通过简单的命令,如
docker-compose up
或docker-compose down
,可以一键启动或停止所有服务。
- 支持持久化存储: 可以为容器轻松定义持久化卷,确保容器的存储数据在重启后依然可用。
- 环境隔离: Docker Compose 可以为不同的环境(开发、测试、生产)定义不同的配置,使用相同的代码和镜像,确保一致性。
- 依赖管理: 你可以设置服务的启动顺序,确保依赖的服务(如数据库)在应用启动前已经运行。
3.2 常用命令
docker-compose [OPTIONS] up -d
: 启动所有在docker-compose.yml
中定义的服务。-f /home/compose.yml
: 指定某个文件-d
: 后台启动
docker-compose [OPTIONS] down
: 停止并删除所有服务的容器。-f /home/compose.yml
: 指定某个文件,只停止该文件启动的容器--rmi all
: 同时删除所有镜像-v
: 同时删除卷
docker-compose logs
: 查看服务容器的日志。
docker-compose ps
: 查看当前运行的容器。
docker-compose exec
: 进入某个正在运行的容器进行操作。
3.3 配置文件
docker-compose.yml
主要是用来启动一整个项目的,比如说用Java做了一个程序,需要用到MySQL
、redis
、nginx
,则可以一键启动。容器启动后若修改了
docker-compose.yml
,则需要重新输入一次启动命令。[!tip]docker compose 会查看修改内容,只会重新启动修改过的容器。
示例:
如果你不在
docker-compose.yml
中指定 networks
配置块,Docker Compose 也会自动创建一个默认的 bridge
网络,并将所有服务加入该网络。networks
配置块的作用无非是自定义一个网络名称而已。4 制作镜像
4.1 命令
docker build [options] .
-f /root/Dockerfile
: 指定文件-t springboot01:1.0.1
: 给镜像起名.
或者./
:代表当前目录,且这是一个上下文目录。意思是dockerfile中出现的所有与物理机有关的目录,都需要在前面加上这个路径,因此dockerfile中指定物理机的目录时不能使用绝对路径!如:此处写的是/root/
,那么在执行dockerfile中的COPY
命令时就会自动补充为/root/springboot01.jar
。
4.2 dockerfile
详情请见官网
常见指令 | 作用 |
FROM | 指定镜像基础环境 |
RUN | 运行自定义命令 |
CMD | 容器启动命令或参数 |
LABEL | 自定义标签 |
EXPOSE | 指定暴露端口 |
ENV | 环境变量 |
ADD | 添加文件到镜像 |
COPY | 复制文件到镜像 |
ENTRYPOINT | 容器固定启动命令 |
VOLUME | 数据卷 |
USER | 指定用户和用户组 |
WORKDIR | 指定默认工作目录 |
ARG | 指定构建参数 |
示例:
如下将一个jar包制作成镜像
4.3 镜像分层机制
Docker 的镜像分层机制是 Docker 的核心特性之一,它为镜像的构建、存储和分发带来了极大的效率和灵活性。理解这个机制对于高效使用 Docker 至关重要。
4.3.1 Docker 镜像的分层机制概述
Docker 镜像不是一个单一的文件或结构,而是由多个只读层(Layers)组成的堆栈。每一层都是对镜像的某种增量更新,这些层彼此叠加在一起,最终形成一个完整的镜像。

如上图所示,
d3
为源镜像,而c2
、d7
、91
都为源镜像基础上稍作修改后自己制作的镜像,这四个都会在docker images
下展示,并且看似占用了四倍空间,实则它们有着类似git的机制,只会保存修改的部分,从而避免了空间浪费。4.3.2 分层机制的主要特点
- 每个命令对应一层:
- 在
Dockerfile
中,每一个命令(如RUN
,COPY
,ADD
等)都会创建一层新的镜像层。每一层都包含了从上一层到当前命令所带来的所有变化。 - 例如:
在上面的示例中,
Dockerfile
中的每个命令都会生成一个新的层。- 层的共享:
- Docker 利用分层机制来共享层。如果两个不同的镜像使用了相同的基础镜像或命令生成的层,Docker 只会存储一份共享层,减少了存储空间的浪费。
- 例如,如果你有两个镜像都基于
ubuntu:20.04
,这两个镜像会共享相同的基础层。
- 层是只读的:
- 镜像的每一层都是不可变的(只读的)。这意味着一旦创建了某一层,它就不会改变。如果需要更改,只会在这个层之上创建一个新的层。
- 容器的独立可写层:
- 每个容器在启动时都会创建一个独立的可写层。所有对文件系统的写操作(如创建、修改文件)都会发生在这个可写层中。
- 由于只读层是共享的,如果容器只读取文件或不修改文件,读取操作会直接访问共享的只读层。
- 如果容器对文件进行修改,Docker 会将该文件从只读层复制到可写层,然后在可写层中进行修改。这就是“写时复制”的工作原理。
- Union File System (联合文件系统):
- Docker 使用联合文件系统(如 OverlayFS、AUFS 等)将这些只读层组合在一起,形成一个可用的文件系统。联合文件系统可以将多个目录(即层)叠加为一个单一的文件系统视图。
- 镜像构建的缓存机制:
- 当你构建镜像时,Docker 会缓存每一层。如果你对
Dockerfile
进行小幅修改,比如只修改了后面的某条命令,那么 Docker 会复用之前构建的前几层,从而加快构建速度。 - 例如,如果你只修改了最后一个
COPY
命令,前面的层将被缓存,Docker 只会重新构建受影响的层。
4.3.3 分层机制的优势
- 效率高:
- 分层机制通过共享和缓存显著减少了镜像构建时间和存储空间。例如,多个镜像基于同一个基础镜像时,只需存储一次基础镜像的层。
- 灵活的镜像管理:
- 由于镜像由多个层组成,可以轻松地在镜像之间添加或移除功能,而不必重建整个镜像。例如,可以在某个镜像基础上创建一个新的应用层。
- 快速分发和部署:
- 镜像的分发和部署非常高效,因为每次只需要传输新增或修改的层,而不是整个镜像。
4.3.4 分层的实际构建过程
- 示例
Dockerfile
:
这个
Dockerfile
构建了一个简单的 Python 应用。构建镜像的过程如下:FROM ubuntu:20.04
:- Docker 首先下载
ubuntu:20.04
镜像(如果本地没有),这个镜像本身也是分层的,比如包含了基础的 Ubuntu 文件系统和一些工具。
RUN apt-get update
:- 执行
apt-get update
命令,这会在基础镜像的层之上创建一个新层,包含更新后的包索引。
RUN apt-get install -y python3
:- 安装 Python 3,这个操作会再创建一个新的层,包含 Python 3 的文件和依赖。
COPY . /app
:- 复制当前目录的文件到容器的
/app
目录,生成新的层,包含了应用的代码。
CMD ["python3", "/app/app.py"]
:- 这个命令不会创建新的层,但会指定容器启动时执行的命令。
4.3.5 层的管理与优化
- 减少层数:
- 尽量合并命令,减少层数可以减少镜像大小。例如:
这条命令会创建一个包含所有更改的单一层,而不是两个独立的层。
- 避免无用文件进入层:
- 在构建过程中,避免将无用文件(如编译产生的临时文件)保留在层中,可以通过
RUN
命令后清理这些文件。
- 使用
.dockerignore
文件: - 使用
.dockerignore
文件排除不必要的文件或目录进入构建上下文,从而减少镜像的大小。
- 作者:林明菁
- 链接:https://blog.lxuan.fun/article/docker
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
相关文章