乔克视界 乔克视界
首页
  • 运维
  • 开发
  • 监控
  • 安全
  • 随笔
  • Docker
  • Golang
  • Python
  • AIOps
  • 心情杂货
  • 读书笔记
  • 面试
  • 实用技巧
  • 博客搭建
友链
关于
收藏
  • 分类
  • 标签
  • 归档

乔克

云原生爱好者
首页
  • 运维
  • 开发
  • 监控
  • 安全
  • 随笔
  • Docker
  • Golang
  • Python
  • AIOps
  • 心情杂货
  • 读书笔记
  • 面试
  • 实用技巧
  • 博客搭建
友链
关于
收藏
  • 分类
  • 标签
  • 归档
  • Docker

    • Docker简介
    • Docker的架构
    • Docker的安装
    • Docker基础用法
    • Docker镜像和容器的基本操作
    • Docker的网络模式
    • Docker存储卷
    • Dockerfile介绍
    • 多阶段构建
    • 镜像加速
    • Docker的NS和CGroups
    • Docker用法整理
    • Docker和Containerd的区别
    • 镜像安全
  • Golang

  • AIOps

  • 专栏
  • Docker
乔克
2025-07-17

Docker的网络模式

# Bridge模式

当我们安装完docker后,启动Docker daemon,就会在主机上看到一个docker0的网桥,默认在此主机上启动的容器都会连接到这个网桥上。虚拟网桥的工作方式和物理交换机的工作方式类似,我们可以把主机当作是一个物理交换机,这样所有容器都通过交换机连接在了一个二层网络。

当我们启动一个容器,默认会从docker0的子网中分配一个IP给容器使用,并设置docker0的IP为容器的默认网关。并且会创建一对虚拟网卡veth pair设备,Docker将veth pair的一段放到容器中,命令为eth0,另一端放在主机上,并以vethxxxx命名,并将这个网络设备加入docker0网桥中。具体的网络信息可以通过brctl show查看,如果没有这个命令,可以通过如下方式安装。

yum install bridge-utils -y
1

ddf84867974cea95cd0288f64d248be7 MD5

如下,在我们没有启动容器的时候,我的服务器上的网卡信息

8cdd749738c0cb9e6d5ed422a0a30098 MD5

现在,我通过如下命令启动容器

docker run -it busybox /bin/sh
1

再次查看主机上网卡信息,可以看到主机上多了一个veth2978031@if51网卡信息

9f652f17090635e18db50dc0e69b6c43 MD5

而我们在容器里面,可以看到容器的网卡信息

e4841c5e13bb8b57ec389b279b7eb8d7 MD5

我们可以看到容器的网卡名为eth0,而且IP地址和docker0在同一个网段,这时候在容器内ping docker0是通的。

29db5b79e7942d191aa85aa579b89297 MD5

所以,如果用bridge模式,在同一台主机上启动的容器,默认情况下相互是可达的。

Bridge默认是docker默认的网络模式,如果不写-net参数,就是bridge模式。使用docker run -p时,docker实际是在iptables上做DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnL查看。

Bridge默认如下所示:

d4e92a5ab4aa8fb380c66973588ffb29 MD5

如果你之前有 Docker 使用经验,你可能已经习惯了使用--link参数来使容器互联。随着 Docker 网络的完善,强烈建议大家将容器加入自定义的 Docker 网络来连接多个容器,而不是使用 --link 参数。

下面先创建一个新的 Docker 网络。

$ docker network create -d bridge my-net
1

-d参数指定 Docker 网络类型,有 bridge overlay。其中 overlay 网络类型用于 Swarm mode,在本小节中你可以忽略它。

运行一个容器并连接到新建的 my-net 网络

$ docker run -it --rm --name busybox1 --network my-net busybox sh
1

打开新的终端,再运行一个容器并加入到 my-net 网络

$ docker run -it --rm --name busybox2 --network my-net busybox sh
1

再打开一个新的终端查看容器信息

$ docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
b47060aca56b        busybox             "sh"                11 minutes ago      Up 11 minutes                           busybox2
8720575823ec        busybox             "sh"                16 minutes ago      Up 16 minutes                           busybox1
1
2
3
4

下面通过 ping 来证明 busybox1 容器和 busybox2 容器建立了互联关系。 在 busybox1 容器输入以下命令

/ # ping busybox2
PING busybox2 (172.19.0.3): 56 data bytes
64 bytes from 172.19.0.3: seq=0 ttl=64 time=0.072 ms
64 bytes from 172.19.0.3: seq=1 ttl=64 time=0.118 ms
1
2
3
4

用 ping 来测试连接 busybox2 容器,它会解析成 172.19.0.3。 同理在 busybox2 容器执行 ping busybox1,也会成功连接到。

/ # ping busybox1
PING busybox1 (172.19.0.2): 56 data bytes
64 bytes from 172.19.0.2: seq=0 ttl=64 time=0.064 ms
64 bytes from 172.19.0.2: seq=1 ttl=64 time=0.143 ms
1
2
3
4

这样,busybox1 容器和 busybox2 容器建立了互联关系。

如果你有多个容器之间需要互相连接,推荐使用Docker Compose。

# Host模式

如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个 Network Namespace。容器将不会虚拟出自己的网卡,配置自己的 IP 等,而是使用宿主机的 IP 和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。 Host模式如下图所示:

fec7a218614fb31df1425fbb797eb67c MD5

例如:

首先启动两个容器,指定网络为host

docker run -itd --name docker1 --net=host busybox
docker run -itd --name docker2 --net=host busybox
1
2

然后进入容器查看容器的IP地址,以docker1为例

docker exec -it docker1 /bin/sh
1

5d79cb5e788ff39d003ca4903d17ccdc MD5

可以发现和宿主机一模一样。

# None模式

使用none模式,Docker 容器拥有自己的 Network Namespace,但是,并不为Docker 容器进行任何网络配置。也就是说,这个 Docker 容器没有网卡、IP、路由等信息。需要我们自己为 Docker 容器添加网卡、配置 IP 等。

例如:

docker run -it --name docker1 --net=none busybox
1

然后查看IP信息,是没有配置IP的。

792a06f2ff29d758c1fd7f892a4d15e3 MD5

# Container模式

这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信。

a51efe7e0d6eb6af3f8e17f3882531bf MD5

比如,我们启动先启动一个容器:

# # docker run -itd --name my_os ubuntu /bin/bash
1

然后我们共享my_web的网络:

# # docker run -itd --rm --net=container:my_os --name new_os ubuntu
1

我们分别查看两个容器的网络信息:

在my_os容器中:

docker exec -it my_os /bin/bash
ifconfig -a
1
2

在new_os中:

docker exec -it new_os /bin/bash
ifconfig -a
1
2
上次更新: 2025/07/18, 18:41:03
Docker镜像和容器的基本操作
Docker存储卷

← Docker镜像和容器的基本操作 Docker存储卷→

最近更新
01
2025年,SRE在企业中可以做哪些事
07-18
02
SRE 如何提升自己在团队中的影响力
07-18
03
使用Go开发MCP服务
07-18
更多文章>
Theme by Vdoing | Copyright © 2019-2025 乔克 | MIT License | 渝ICP备20002153号 |
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式