Docker详解(一)Docker的核心概念及基本操作
文章目录
前言
在云原生时代,Docker 作为容器化技术的奠基者和代表,已成为应用开发、部署和运维的标准工具之一。它通过为应用提供轻量级、隔离的运行时环境,实现了“一次构建,到处运行”的愿景,极大地提升了软件交付的效率与一致性。无论您是开发人员、运维工程师还是技术爱好者,系统掌握 Docker 都至关重要。本文旨在带您深入浅出地了解 Docker 的核心概念、基本操作,助您从零开始构建扎实的容器化知识体系。
一、Docker 发展与简介
1.1 云服务与虚拟化基础
1.1.1 云服务模型介绍
云计算是通过网络按需提供可伸缩计算资源的一种模式。其主要服务模型包括:
- IaaS(基础设施即服务)
- 提供虚拟化的基础计算资源,如虚拟机、存储、网络。
- 用户需自主管理操作系统、中间件及应用程序。
- 优势:灵活性极高,资源可扩展性强。
- 劣势:需要用户具备较强的运维能力,管理复杂度相对较高。
- PaaS(平台即服务)
- 提供一个完整的开发和部署环境,用户专注于代码和业务逻辑。
- 优势:简化了开发、测试和部署流程,提升了开发效率。
- 劣势:用户对底层基础设施的控制力较弱,灵活性受到平台制约。
- SaaS(软件即服务)
- 提供完整的、可直接使用的应用程序,通常通过网页浏览器访问。
- 优势:无需安装和维护,开箱即用,总拥有成本低。
- 劣势:定制化能力有限,高度依赖服务提供商。
- DaaS(数据即服务)
- 提供数据存储、管理、分析和访问服务。
- 优势:降低了数据基础设施的管理复杂度和成本。
- 挑战:数据主权、隐私和安全性是关键考量因素。
1.1.2 常见云服务提供商
全球主流的云服务提供商包括 Amazon Web Services (AWS)、Microsoft Azure、Google Cloud Platform (GCP)、阿里云、腾讯云 和 华为云 等,它们提供从计算、存储、数据库到人工智能和机器学习的全方位服务。
1.2 虚拟化技术概述
1.2.1 虚拟化基础
虚拟化技术是云计算的基石,主要分为两种类型:
- 全虚拟化 (Full Virtualization)
- 通过 Hypervisor 完全模拟底层硬件,客户操作系统无需修改即可运行。
- 适用场景:需要运行未经修改的操作系统(如 Windows 和各种 Linux 发行版)。
- 半虚拟化 (Paravirtualization)
- 客户操作系统意识到自身处于虚拟化环境,并通过 API 与 Hypervisor 协作,性能开销更低。
- 适用场景:对性能有苛刻要求的场景,通常需使用修改过的操作系统内核。
常见的虚拟化产品包括 VMware vSphere/ESXi、基于内核的 KVM、微软的 Hyper-V 和甲骨文的 VirtualBox。
1.3 Docker 简介及其重要性
1.3.1 为什么使用 Docker
Docker 是一个开源的应用容器引擎,它允许开发者将应用及其所有依赖项打包到一个标准化单元中,这个单元称为容器。与传统虚拟机相比,Docker 容器共享主机操作系统内核,无需捆绑完整的操作系统,因而更加轻量、启动更快(秒级)、资源利用率更高。
1.3.2 Docker 发展历史
Docker 自 2013 年由 DotCloud 公司开源后便迅猛发展,成为容器技术的事实标准。其关键发展里程碑包括:
- 2013年:项目发布。
- 2014年:Docker 公司成立,宣布开源。
- 2017年:产品线划分为面向企业的 Docker EE 和面向社区的 Docker CE。
- 2018年:集成 Kubernetes 编排系统,推出 Docker Desktop。
- 2020年至今:持续聚焦开发者体验,增强与 CI/CD 流程的集成,并不断提升安全性和性能。
1.3.3 Docker 版本:CE vs EE
- Docker Community Edition (CE):免费版本,适用于个人学习、开发和小型团队。
- Docker Enterprise Edition (EE):企业级付费版本,提供额外的技术支持、安全扫描、镜像管理等功能,适用于大规模生产环境。
1.3.4 Docker 与传统虚拟化的区别
| 特性 | Docker 容器 | 虚拟机 |
|---|---|---|
| 启动速度 | 秒级 | 分钟级 |
| 性能开销 | 极低,近乎原生 | 较高,通常有 5-15% 的损耗 |
| 磁盘占用 | 通常为 MB 级别 | 通常为 GB 级别 |
| 隔离性 | 进程级别隔离,共享内核 | 完整的操作系统级隔离 |
| 单机部署密度 | 高,可部署上百个实例 | 低,通常几十个实例 |
Docker结构:

传统虚拟机结构:

1.3.5 容器化技术的生态系统
Docker 激发了庞大的生态系统,与之相关的核心技术包括:
- 容器编排:Kubernetes、Docker Swarm、Apache Mesos。
- 容器运行时:containerd(Docker 剥离出的核心运行时)、CRI-O。
- 替代工具:Podman(无守护进程)、Buildah(专用于构建镜像)。
1.3.6 Docker 容器的优势
- 一致性:消除了“在我这儿是好的”环境问题。
- 隔离性:应用运行在独立的上下文中,互不干扰。
- 便携性:轻松跨平台迁移,支持混合云策略。
- 敏捷性:简化了持续集成和交付 (CI/CD) 流程。
1.3.7 容器技术的应用场景
- 微服务架构:将单体应用分解为独立部署、扩展的微服务。
- DevOps 与 CI/CD:自动化构建、测试和部署流水线。
- 混合云与多云部署:实现应用在不同云环境中的无缝迁移和统一管理。
1.4 Docker 基础概念
1.4.1 Docker 简介
Docker 的 Logo 是一只驮着集装箱的鲸鱼,生动地体现了其理念:鲸鱼代表宿主机(Docker 引擎),集装箱代表一个个隔离的容器,容器内是标准化的应用。其宗旨是 “Build, Ship and Run Any App, Anywhere”。通过对应用组件的封装、发布、部署、运行等生命周期的管理,达到应用组件级别的“一次封装,到处运行”的目的。这里的组件可以是一个应用、一套服务,甚至是一个完整的操作系统。

1.4.2 容器化的优势
- 灵活:任何应用均可容器化。
- 轻量级:容器利用并共享主机内核。
- 可互换:可以无缝部署更新和升级。
- 便携性:可在本地构建,部署到云,在任何地方运行。
- 可扩展:可以增加并自动分发容器副本。
- 可堆叠:可以垂直和即时堆叠服务。
| 特性 | Docker 容器 | 虚拟机 |
|---|---|---|
启动速度 | 秒级 | 分钟级 |
计算能力损耗 | 几乎无 | 损耗 50%左右 |
性能 | 接近原生 | 弱于 |
系统支持量(单机) | 上千个 | 几十个 |
隔离性 | 资源隔离/限制 | 完全隔离 |
1.4.3 Linux 命名空间(Namespaces)
Docker 利用 Linux 内核的命名空间技术来实现资源隔离,这是容器独立性的基础:
| 命名空间 | 隔离的全局系统资源 |
|---|---|
pid | 进程 ID |
net | 网络设备、端口、协议栈等 |
ipc | System V IPC 和 POSIX 消息队列 |
mnt | 文件系统挂载点 |
uts | 主机名和域名 |
user | 用户和组 ID |
1.4.4 控制组(Cgroups)
控制组 (cgroups) 是 Linux 内核的另一项功能,用于限制、记录和隔离进程组所使用的物理资源(如 CPU、内存、磁盘 I/O、网络等)。它确保了容器之间不会互相争夺资源,实现了资源的公平分配和安全控制。
1.4.5 Docker 架构与核心组件
- Docker Daemon (
dockerd):常驻后台的守护进程,负责管理镜像、容器、网络和存储卷。它是 Docker 引擎的核心。 - Docker Client:用户与 Docker 交互的命令行工具 (
docker)。客户端通过 REST API 与守护进程通信。 - Docker Images:一个只读的模板,包含了运行应用所需的文件系统结构和内容。它通过分层机制构建,便于共享和存储。
- Docker Containers:镜像的一个可运行实例。容器在镜像的只读层之上增加了一个可写的薄薄顶层(容器层)。
- Docker Registry:用于存储和分发镜像的服务。Docker Hub 是默认的公共 registry,用户也可以搭建私有 registry(如 Docker Trusted Registry 或 Harbor)。
1.4.6 联合文件系统(UnionFS)
Docker 使用 Union File System(如 overlay2)来实现镜像的分层结构。这种技术允许将多个目录(称为层)透明地叠加在一起,形成一个统一的文件系统。这带来了两大好处:
- 分层构建:镜像的每一层都可以被复用和共享,极大节省了磁盘空间和镜像下载时间。
- 写时复制 (Copy-on-Write):当容器运行时,所有对文件的修改都发生在最上层的可写容器层中,而不影响底层的只读镜像。这保证了镜像的不可变性,并提升了性能。
1.4.7 Docker 的核心技术
Docker 容器本质上是宿主机的一个进程,通过以下技术实现资源隔离和限制:
- Namespace:实现资源隔离。
- Cgroup:实现资源限制。
- 写时复制技术(Copy-on-Write):实现高效的文件操作。
1.5 Docker 核心概念
- 镜像(Image)
- 镜像是包含应用程序及其所有依赖环境的可执行包。它是一个只读模板,基于该模板可以创建容器实例。
- 容器(Container)
- 容器是镜像的运行实例。容器提供了与外部环境隔离的运行时环境,可以在不同的系统上运行。
- 容器通过 Docker 引擎启动,具有独立的文件系统、网络、进程空间。
- 仓库(Repository)
- 仓库是存放 Docker 镜像的地方。Docker Hub 是最常用的公共仓库,用户也可以创建私有仓库。
1.6 Docker 安装
systemctl stop firewalld.service
setenforce 0
安装依赖包
yum install -y yum-utils device-mapper-persistent-data lvm2
#- yum-utils:提供了 `yum-config-manager` 工具。
#- device-mapper:Linux 内核中支持逻辑卷管理的通用设备映射机制。
#- device-mapper-persistent-data** 和 **lvm2**:device-mapper 存储驱动程序所需的依赖包。
设置阿里云镜像源
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
安装 Docker-CE 并设置为开机自动启动
yum install -y docker-ce docker-ce-cli containerd.io
注意:如果是指定版本docker-ce-20.10.18
systemctl start docker.service
systemctl enable docker.service
- Docker 系统包含两个程序:Docker 服务端和 Docker 客户端。
- Docker 服务端是一个服务进程,负责管理所有容器。
- Docker 客户端是 Docker 服务端的远程控制器,用于控制 Docker 服务端进程。
测试安装是否成功:
docker --version
docker info


1.6.1 Docker 系统信息
-
Client 部分:
- Context:当前使用的 Docker 上下文(默认为 “default”)。
- Debug Mode:客户端调试模式是否开启(此处为 false)。
- Plugins:列出已安装的 Docker 插件,如 Docker App 和 Buildx。
-
Server 部分(关键信息):
- Containers:
- Containers: 0(总容器数,包括运行、暂停和停止的容器)。
- Running: 0(正在运行的容器数)。
- Paused: 0(暂停的容器数)。
- Stopped: 0(停止的容器数)。
- Images: 1(本地镜像数)。
- Server Version: 20.10.3(Docker 服务器版本)。
- Storage Driver: overlay2(Docker 使用的存储驱动)。
- Backing Filesystem: xfs(宿主机上的底层文件系统)。
- Supports d_type: true(表示文件系统支持 d_type,有助于性能优化)。
- Native Overlay Diff: true(表示使用原生的 overlay diff 技术,提高性能)。
- Logging Driver: json-file(日志驱动)。
- Cgroup Driver: cgroupfs(Cgroups 驱动,用于资源限制和管理)。
- Plugins:列出 Docker 支持的卷、网络和日志插件。
- Swarm: inactive(Swarm 集群模式未启用)。
- Runtimes:列出 Docker 支持的运行时,如 runc。
- Default Runtime: runc(默认运行时)。
- Security Options:列出安全选项,如 seccomp(安全计算模式)。
- Kernel Version 和 Operating System:提供宿主机的内核版本和操作系统信息。
- Architecture:宿主机的架构(如 x86_64)。
- CPUs 和 Total Memory:宿主机的 CPU 数和总内存。
- Name 和 ID:Docker 主机的名称和唯一 ID。
- Docker Root Dir:Docker 数据存储的根目录(如 /var/lib/docker)。
- Debug Mode:服务器调试模式是否开启(此处为 false)。
- Registry:默认的 Docker 镜像仓库地址。
- Labels:Docker 主机的标签。
- Experimental:是否启用实验性功能(此处为 false)。
- Insecure Registries:列出不安全的镜像仓库地址(如 127.0.0.0/8)。
- Registry Mirrors:列出镜像加速站点,用于加速 Docker 镜像的拉取和推送。
- Live Restore Enabled:是否启用实时恢复功能(此处为 false)。
- Containers:
-
存储驱动(Storage Driver):Docker 使用 overlay2 作为其默认的存储驱动,它提供了高效的镜像和容器管理。
-
Cgroup 驱动(Cgroup Driver):cgroupfs 是 Linux 上用于限制、记录和隔离进程组所使用的物理资源(如 CPU、内存、磁盘 I/O 等)的机制。
-
运行时(Runtimes):Docker 支持多种容器运行时,其中 runc 是默认的运行时,用于启动和管理容器。
-
安全选项(Security Options):seccomp 是一种内核功能,用于在 Linux 上提供沙箱环境,限制容器内进程能够执行的系统调用。
-
镜像加速站点(Registry Mirrors):通过配置镜像加速站点,可以加速 Docker 镜像的下载速度,提高开发效率。
二、Docker 容器管理
2.1 Docker 镜像操作
2.1.1 搜索镜像
从 Docker Hub 等 registry 搜索镜像。
docker search nginx
2.1.2 获取镜像
从 registry 拉取(下载)镜像到本地。不指定标签时默认为 latest。
docker pull nginx
docker pull nginx:1.21-alpine # 拉取特定标签的镜像
2.1.3 配置镜像加速器
镜像下载可能会因为网络原因而比较慢,尤其是国内用户。这里给出了几种加速镜像下载的方法。
阿里云加速器:
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://ae3f5qei.mirror.aliyuncs.com"]
}
EOF
systemctl daemon-reload
systemctl restart docker
- 作用:配置 Docker 使用阿里云镜像加速器来提高镜像下载速度。
华为加速器:
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [ "https://[你的华为云账号].myhuaweicloud.com" ]
}
EOF
- 作用:配置 Docker 使用华为云镜像加速器。
国外小网站加速器:
{
"registry-mirrors": ["https://hub.littlediary.cn/"]
}
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["http://[...]"]
}
EOF
- 作用:使用一个国外小网站作为加速器,适用于国内网络环境下下载速度较慢的情况。
2.1.4 查看本地镜像
列出本地存储的所有镜像。
docker images
# 或
docker image ls

2.1.5 查看镜像详情
获取镜像的详细元数据,包括层次结构、配置等。
docker inspect nginx:latest

2.1.6 为镜像添加标签
为本地镜像创建一个新的别名(标签),常用于准备推送到自定义 registry。
docker tag nginx:latest myregistry.com/mynginx:v1.0

2.1.7 删除镜像
删除本地的一个镜像。如果镜像有多个标签,需先删除所有标签或使用 -f 强制删除。
docker rmi nginx:latest


2.1.8 导出镜像
将镜像保存为一个 tar 归档文件,用于备份或离线迁移。
docker save -o nginx.tar nginx:latest
打包好的.tar文件会在执行目录下

2.1.9 导入镜像
从 tar 归档文件中加载镜像到本地仓库。
docker load -i nginx.tar
# 或
docker load < nginx.tar

2.1.10 推送镜像
将本地镜像推送到 registry(如 Docker Hub)。
docker login # 先登录
docker tag nginx:latest your_username/your_nginx:tag # 打标签
docker push your_username/your_nginx:tag # 推送
2.2 Docker 容器操作
2.2.1 创建容器
根据镜像创建一个新的容器,但并不立即启动它。
docker create --name mycontainer nginx:latest
2.2.2 启动与停止容器
启动一个已创建的容器。
docker start mycontainer
停止一个运行中的容器(发送 SIGTERM,等待优雅终止)。
docker stop mycontainer
立即强制停止一个容器(发送 SIGKILL)。
docker kill mycontainer

2.2.3 查看容器状态
列出正在运行的容器。
docker ps
列出所有容器(包括已停止的)。
docker ps -a

2.2.4 运行容器
docker run --name mynginx nginx
创建并启动一个容器。这是最常用的命令。
--name可以给一个容器一个名字,但不使用时,系统也会默认给一个名字

直接执行 docker run 命令, 等同于先执行 docker create 命令,再执行 docker start 命令。
** 注意:容器是一个与其中运行的 shell 命令共存亡的终端,命令运行容器运行, 命令结束容器退出。**

docker 容器默认会把容器内部第一个进程,也就是 pid=1 的程序作为docker容器是否正在运行的依据,如果docker容器中 pid = 1 的进程挂了,那么docker容器便会直接退出,也就是说Docker容器中必须有一个前台进程,否则认为容器已经挂掉。
容器的生命周期包括创建、启动、停止、重启、删除等操作。容器会根据其进程的状态自动结束,例如当容器中的 PID=1 的进程退出时,容器也会停止。
当利用 docker run 来创建容器时, Docker 在后台的标准运行过程是:
(1)检查本地是否存在指定的镜像。当镜像不存在时,会从公有仓库下载;
(2)利用镜像创建并启动一个容器;
(3)分配一个文件系统给容器,在只读的镜像层外面挂载一层可读写层;
(4)从宿主主机配置的网桥接口中桥接一个虚拟机接口到容器中;
(5)分配一个地址池中的 IP 地址给容器;
(6)执行用户指定的应用程序,执行完毕后容器被终止运行。


但是这样会卡在前台,影响后续的操作
2.2.5 后台运行容器
使用 -d (--detach) 选项让容器在后台运行。
docker run -d --name mynginx nginx:latest
关键点:后台运行的容器,其内部的主进程必须是前台进程。如果主进程退出,容器也会终止。例如,bash 默认是交互式进程,需通过 -c "command" 让其执行命令后保持运行,或使用 tail -f /dev/null 这类永不退出的命令。

Docker容器主要有以下7个状态:
- created:已创建,还未运行的容器
- running:正在运行中的容器
- restarting:容器正在重启中
- removing:容器正在迁移中
- paused:已暂停状态的容器
- exited:停止状态的容器
- dead:死亡,主要是操作系统出现异常或者断电关机等有可能引发dead状态,不是很常见。
暂停和停止状态的区别
- docker pause 命令挂起指定容器中的所有进程
- docker stop 容器内主进程会在指定时间内被杀死,默认为10s后。

2.2.6 交互式运行容器
使用 -it 选项启动一个交互式容器并分配一个伪终端。
docker run -it --rm nginx /bin/bash
-i 选项表示让容器的输入保持打开;
-t 选项表示让 Docker 分配一个伪终端。
-it:合起来实现和容器交互的作用,运行一个交互式会话 shell
--rm 选项表示容器停止后自动删除,非常适合临时测试。
使用
docker run -itd nginx /bin/bash和使用docker run -d nginx,同样可以将容器启动并且放在后台持续运行,而不同的是前者持续运行的是容器内的shell界面,即PID1为bash,方便调试;而后者持续运行的是nginx主程序,即PID1为nginx,对外提供服务。而如果要启动一个容器更推荐使用docker run -itd nginx的方法。
docker run -itd nginx 的效果是:创建一个容器,它在后台运行,并且成功启动了Nginx服务来接收请求,同时这个容器被预先配置好了一个伪终端,为后续的交互式调试做好了准备。
在这个过程发生了什么:
1. 容器的主进程是什么?
答案是:Nginx服务进程。
2. 为什么Nginx能成功启动?
因为 -itd 中的 -d 是核心,它告诉Docker在后台运行容器。而 -it 虽然被指定了,但并没有覆盖掉Nginx镜像自己定义的默认启动命令。
Nginx镜像的Dockerfile中有一个 CMD ["nginx", "-g", "daemon off;"] 指令。当你执行 docker run -itd nginx 时,你没有在命令末尾提供新的命令(比如 /bin/bash),所以Docker会使用镜像默认的 CMD 来启动容器。
因此,容器的主进程是 nginx -g 'daemon off;',这是一个守护进程,会持续运行。
3. -it 参数起到了什么作用?
既然主进程是Nginx而不是Bash,-i和-t参数似乎没什么用了,对吗?不对,它们仍然有作用,只是作用方式不同。
Docker会将伪终端(TTY)分配给这个主进程(Nginx)。对于Nginx这样一个后台服务来说,它通常不需要与终端交互,所以它可能会忽略这个终端。但关键在于,这个配置留在了容器的元数据中。
这带来的最大好处是:你之后使用 docker exec 命令进入容器时,体验会更好。
- 没有
-it启动的容器:docker run -d --name nginx-normal nginx docker exec -it nginx-normal bash # 虽然也能进去,但可能提示“无法分配终端”之类的警告,或者某些终端功能不完整。 - 用
-itd启动的容器:docker run -itd --name nginx-with-tty nginx docker exec -it nginx-with-tty bash # 你会获得一个功能完整的终端体验,包括命令提示符、命令行编辑、清晰的输出格式等。
因为 docker exec 会继承容器创建时的 -i 和 -t 配置,使得后续进入容器进行操作更加方便。
所以,docker run -itd nginx 是一个“两全其美”的做法:
- 服务层面:容器在后台正常运行,Nginx服务如期启动并可以处理请求。
- 运维层面:为容器预先配置好了终端,极大方便了日后需要排查问题时进入容器 (
docker exec)。
这是一种非常常见且推荐的做法,尤其是在需要经常对服务进行调试和检查的开发或测试环境中。
2.2.7 执行命令
在正在运行的容器中执行一条命令。
docker exec -it mynginx /bin/bash # 进入容器shell
docker exec mynginx ls /etc/nginx # 在容器中执行ls命令
2.2.8 文件复制
在宿主机和容器之间复制文件。
# 从宿主机复制到容器
docker cp /path/to/local/file.txt mycontainer:/path/in/container/
# 从容器复制到宿主机
docker cp mycontainer:/path/in/container/file.txt /path/on/host/


2.2.9 查看容器日志
获取容器的标准输出和错误日志。
docker logs mycontainer
docker logs -f mycontainer # 实时跟踪日志输出

2.2.10 导出与导入容器
导出容器文件系统为一个 tar 归档文件。注意:导出的是容器当前的文件系统状态,不是镜像。
docker export mycontainer > mycontainer.tar

从导出的容器文件系统归档文件中创建一个新镜像。
导入后不再是容器而是一个镜像
cat mycontainer.tar | docker import - myimage:tag
# 或
docker import mycontainer.tar myimage:tag

2.2.11 删除容器
删除一个已停止的容器。
docker rm mycontainer
强制删除一个容器(无论是否在运行)。
docker rm -f mycontainer
清理所有已停止的容器。
docker container prune
批量删除
docker ps -a | awk 'NR>=2{print "docker stop "$1}' | bash #批量停止容器
docker ps -a | awk 'NR>=2{print $1}'| xargs docker stop
docker ps -a | awk 'NR>=2{print "docker rm "$1}' | bash #批量删除所有容器
docker ps -a | awk 'NR>=2{print $1}'| xargs docker rm
docker images | awk 'NR>=2{print "docker rmi "$3}'| bash #批量删除镜像
docker images | awk '{print $3}' | xargs docker rmi
docker images | grep none | awk '{print $3}' | xargs docker rmi #删除none镜像
docker rm $(docker ps -a -q) #批量清理后台停止的容器

三、Docker 网络管理
3.1 Docker 网络实现原理
Docker 的网络架构基于 Linux 的桥接、veth pair、iptables 和命名空间等技术。默认情况下,Docker 会在宿主机上创建一个名为 docker0 的虚拟网桥,所有容器通过 veth pair 设备对连接到这个网桥上。容器之间的通信通过 docker0 网桥进行,而与外部网络的通信则通过 iptables 进行 NAT(网络地址转换) 和端口映射来实现。

当安装docker时会自带iptables的相关功能,
3.2 Docker 的网络模式
Docker 容器支持多种网络模式,通过 --network 参数指定。
3.2.1 Bridge 模式(默认)
bridge模式是docker的默认网络模式,不用–net参数,就是bridge模式。
相当于Vmware中的 nat 模式,容器使用独立network Namespace,并连接到docker0虚拟网卡。通过docker0网桥以及iptables nat表配置与宿主机通信,此模式会为每一个容器分配Network Namespace、设置IP等,并将一个主机上的 Docker 容器连接到一个虚拟网桥上。
(1)当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。
(2)从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair设备。veth设备总是成对出现的,它们组成了一个数据的通道,数据从一个设备进入,就会从另一个设备出来。因此,veth设备常用来连接两个网络设备。两个veth建立了一个虚拟网桥隧道。
(3)Docker将 veth pair 设备的一端放在新创建的容器中,并命名为 eth0(容器的网卡),另一端放在主机中, 以 * 这样类似的名字命名,并将这个网络设备加入到 docker0 网桥中。可以通过 brctl show 命令查看。
(4)使用 docker run -p 时,docker实际是在iptables做了DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnL 查看。

virbr0是 Linux 系统中的一种网络接口,它是支持虚拟机网络通信的一种默认的虚拟桥接网络。当你安装虚拟化技术(比如 KVM、VirtualBox 等)的时候,就会创建这样的虚拟网络桥接。
用“大白话”来理解它,virbr0就像是一个虚拟的交换机或路由器,它把你的计算机和虚拟机连接起来,让虚拟机可以通过它与外界进行网络通信。简单来说,您的电脑和虚拟机可以被看作是在同一个局域网内。
这就像一栋大楼中的各个房间可以通过交换机(这里是虚拟的 virbr0)和大楼外的世界(互联网)进行通讯一样。每个房间(虚拟机)都有自己的门牌号(IP地址),通过这个"虚拟的交换机",门牌号可以被识别并且数据可以正确地在各个房间(虚拟机)和外部的世界之间传递
docker run -d --name test1 -P nginx
#随机映射端口(从32768开始),大写 -P 随机端口(32768开始)且不会和已有端口重复,小写 -p 80:80 指定端口
docker run -d --name web -p 10086:80 nginx
# 将容器的80端口映射到宿主机的8080端口


3.2.2 Host 模式
容器不会虚拟出自己的网卡和 IP,而是直接共享使用宿主机的 Network Namespace。容器不再拥有隔离的网络环境,直接使用宿主机的 IP 和端口。

docker run -d --name web --network=host nginx:latest
# 此时访问宿主机80端口即可访问容器内的nginx服务
优势:网络性能最好,无 NAT 损耗。
劣势:容器与宿主机网络无隔离,容易导致端口冲突。

3.2.3 None 模式
Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。 也就是说,这个Docker容器没有网卡、IP、路由等信息。这种网络模式下容器只有lo回环网络,没有其他网卡。这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性。
docker run -it --network=none alpine:latest

3.2.4 Container 模式
新创建的容器与一个已存在的容器共享 Network Namespace,两个容器拥有相同的网络栈(IP、端口、路由等),可以通过 lo 回环设备高效通信。

docker run -itd --name test1 nginx
docker inspect -f '{{.State.Pid}}' 9973947a3b18
#查看容器进程号
ls -l /proc/20794/ns
#查看容器的进程、网络、文件系统等命名空间编号
docker run -itd --name test2 --net=container:079c37b7f034 nginx /bin/bash
ls -l /proc/21002/ns
#查看可以发现两个容器的 net namespace 编号相同

3.2.5 自定义网络
强烈建议在生产环境中使用自定义的桥接网络,而不是默认的 bridge。自定义网络提供以下优势:
- 自动的 DNS 解析:容器之间可以通过容器名互相通信,无需使用 IP 地址。
- 更好的隔离性:不同的应用可以使用不同的自定义网络,实现网络层面的隔离。
- 可自定义网段、网关等配置。
- 环境匹配,方便迁移已经打好包的固定程序
Docker提供了创建这些网络的默认网络驱动程序,你可以创建一个新的Bridge网络,Overlay或Macvlan网络
bridge: 单机网络模式适合在一台宿主机内容器互联overlay:跨主机容器互联 (docker swarm、K8S)macvlan:Macvlan模式可以让容器直接连接到主机的物理网络,每个Macvlan接口都有一个唯一的MAC地址,此模式使得容器看起来就像是网络上的物理设备。
#直接使用bridge模式,是无法支持指定IP运行docker的,例如执行以下命令就会报错
docker run -itd --name test3 --network bridge --ip 172.17.0.10 centos:7 /bin/bash
#创建自定义网络
#可以先自定义网络,再使用指定IP运行docker
docker network create --subnet=172.18.0.0/16 --opt "com.docker.network.bridge.name"="docker1" mynetwork
----------------------------------------------------------------------------------------------------------
#docker1 为执行 ifconfig -a 命令时,显示的网卡名,如果不使用 --opt 参数指定此名称,那你在使用 ifconfig -a 命令查看网络信息时,看到的是类似 br-110eb56a0b22 这样的名字,这显然不怎么好记。
#mynetwork 为执行 docker network list 命令时,显示的bridge网络模式名称。
----------------------------------------------------------------------------------------------------------
docker run -itd --name test4 --net mynetwork --ip 172.18.0.10 centos:7 /bin/bash

总结
通过本文的系统性介绍,您应该已经对 Docker 的核心概念、生命周期管理以及网络模型有了全面而深入的理解。Docker 的强大之处在于它通过容器化技术标准化了应用的交付单元,从而彻底解决了环境不一致的难题,为现代软件工程的敏捷开发、持续交付和微服务架构奠定了坚实的基础。
学习 Docker 的关键在于实践。建议您从在个人开发环境中安装 Docker Desktop 或 Docker Engine 开始,逐步练习镜像构建、容器运行、网络配置等操作,并尝试将其集成到您的开发流程中。随着实践的深入,您可以进一步探索 Dockerfile 编写、Docker Compose 多容器编排以及如何与 Kubernetes 等更高级的编排系统结合使用。掌握 Docker,无疑是打开云原生世界大门的第一把钥匙。
最后,希望大家多多实践、夯实基础、聚沙成塔、与君共勉之!
更多推荐



所有评论(0)