前言

在云原生时代,Docker 作为容器化技术的奠基者和代表,已成为应用开发、部署和运维的标准工具之一。它通过为应用提供轻量级、隔离的运行时环境,实现了“一次构建,到处运行”的愿景,极大地提升了软件交付的效率与一致性。无论您是开发人员、运维工程师还是技术爱好者,系统掌握 Docker 都至关重要。本文旨在带您深入浅出地了解 Docker 的核心概念、基本操作,助您从零开始构建扎实的容器化知识体系。


一、Docker 发展与简介

1.1 云服务与虚拟化基础

1.1.1 云服务模型介绍

云计算是通过网络按需提供可伸缩计算资源的一种模式。其主要服务模型包括:

  1. IaaS(基础设施即服务)
    • 提供虚拟化的基础计算资源,如虚拟机、存储、网络。
    • 用户需自主管理操作系统、中间件及应用程序。
    • 优势:灵活性极高,资源可扩展性强。
    • 劣势:需要用户具备较强的运维能力,管理复杂度相对较高。
  2. PaaS(平台即服务)
    • 提供一个完整的开发和部署环境,用户专注于代码和业务逻辑。
    • 优势:简化了开发、测试和部署流程,提升了开发效率。
    • 劣势:用户对底层基础设施的控制力较弱,灵活性受到平台制约。
  3. SaaS(软件即服务)
    • 提供完整的、可直接使用的应用程序,通常通过网页浏览器访问。
    • 优势:无需安装和维护,开箱即用,总拥有成本低。
    • 劣势:定制化能力有限,高度依赖服务提供商。
  4. DaaS(数据即服务)
    • 提供数据存储、管理、分析和访问服务。
    • 优势:降低了数据基础设施的管理复杂度和成本。
    • 挑战:数据主权、隐私和安全性是关键考量因素。

1.1.2 常见云服务提供商

全球主流的云服务提供商包括 Amazon Web Services (AWS)Microsoft AzureGoogle Cloud Platform (GCP)阿里云腾讯云华为云 等,它们提供从计算、存储、数据库到人工智能和机器学习的全方位服务。

1.2 虚拟化技术概述

1.2.1 虚拟化基础

虚拟化技术是云计算的基石,主要分为两种类型:

  1. 全虚拟化 (Full Virtualization)
    • 通过 Hypervisor 完全模拟底层硬件,客户操作系统无需修改即可运行。
    • 适用场景:需要运行未经修改的操作系统(如 Windows 和各种 Linux 发行版)。
  2. 半虚拟化 (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 激发了庞大的生态系统,与之相关的核心技术包括:

  • 容器编排KubernetesDocker SwarmApache 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网络设备、端口、协议栈等
ipcSystem 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)来实现镜像的分层结构。这种技术允许将多个目录(称为层)透明地叠加在一起,形成一个统一的文件系统。这带来了两大好处:

  1. 分层构建:镜像的每一层都可以被复用和共享,极大节省了磁盘空间和镜像下载时间。
  2. 写时复制 (Copy-on-Write):当容器运行时,所有对文件的修改都发生在最上层的可写容器层中,而不影响底层的只读镜像。这保证了镜像的不可变性,并提升了性能。

1.4.7 Docker 的核心技术

Docker 容器本质上是宿主机的一个进程,通过以下技术实现资源隔离和限制:

  • Namespace:实现资源隔离。
  • Cgroup:实现资源限制。
  • 写时复制技术(Copy-on-Write):实现高效的文件操作。

1.5 Docker 核心概念

  1. 镜像(Image)
    • 镜像是包含应用程序及其所有依赖环境的可执行包。它是一个只读模板,基于该模板可以创建容器实例。
  2. 容器(Container)
    • 容器是镜像的运行实例。容器提供了与外部环境隔离的运行时环境,可以在不同的系统上运行。
    • 容器通过 Docker 引擎启动,具有独立的文件系统、网络、进程空间
  3. 仓库(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 VersionOperating System:提供宿主机的内核版本和操作系统信息。
    • Architecture:宿主机的架构(如 x86_64)。
    • CPUsTotal Memory:宿主机的 CPU 数和总内存。
    • NameID: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)。
  • 存储驱动(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 是一个“两全其美”的做法:

  1. 服务层面:容器在后台正常运行,Nginx服务如期启动并可以处理请求。
  2. 运维层面:为容器预先配置好了终端,极大方便了日后需要排查问题时进入容器 (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 pairiptables 和命名空间等技术。默认情况下,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。自定义网络提供以下优势:

  1. 自动的 DNS 解析:容器之间可以通过容器名互相通信,无需使用 IP 地址。
  2. 更好的隔离性:不同的应用可以使用不同的自定义网络,实现网络层面的隔离。
  3. 可自定义网段、网关等配置。
  4. 环境匹配,方便迁移已经打好包的固定程序

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,无疑是打开云原生世界大门的第一把钥匙。
最后,希望大家多多实践、夯实基础、聚沙成塔、与君共勉之!

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐