Docker 网络基础
背景知识
- 桥接模式:虚拟机直接连接外部的物理网络,主机起到了网桥的作用,虚拟机可以直接访问外网,并且是透明的。
- NAT 模式:NAT 服务器和 DHCP 服务器会对 IP 进行地址转换,虚拟机通过共享主机 IP 可以访问外部网络,而外网是不能访问虚拟机的。
作用
- 容器之间的互连和通信以及端口映射
- 容器 IP 变动时候可以通过服务名直接网络通信而不受到影响
docker0 虚拟网桥
- Docker 服务默认会创建一个 docker0 网桥(其上有一个 docker0 内部接口),该桥接网络的名称为 docker0,它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络
- Docker 默认指定了 docker0 接口的 IP 地址和子网掩码,让主机和容器之间可以通过网桥相互通信。
docker0 具体如何工作?
- docker0 创建一对对等虚拟设备接口一个叫veth、一个叫eth0,成对匹配
- 整个宿主机的网桥模式都是 docker0,类似于一个交换机有一堆接口,每个接口叫 veth,在本地主机和容器内分别创建一个虚拟接口,并让他们彼此连通,这样一对接口叫 veth pair
- 每个容器实例内部也有一块网卡,每个接口叫 eth0。docker0 上面的每个 veth 匹配某个容器实例内部的 eth0,两两配对,一一匹配
- 这样将宿主机上的所有容器都连接到这个内部网络上,两个容器在同一网络下,会从这个网关下各自拿到分配的 IP,此时两个容器的网络是互通的
常用基础命令
名称 | 命令 |
---|---|
查看网络 | docker network ls |
在外部 Docker 中查看网络源数据 | docker network inspect 网络名称 |
在容器内部查看网络源数据 | ip addr |
创建自定义网络 | docker network create 自定义的网络名称 |
删除网络 | docker network rm 网络名称 |
注意
- Docker 容器和 docker0 之间使用桥接的方式,docker0 再到宿主机则是通过 NAT 模式
- Docker 容器内部的 IP 是有可能改变的,一般固定容器名称作为唯一指定
Docker 网络模式
bridge
- 默认使用网桥模式为 bridge
- Docker 使用 Linux 桥接,在宿主机虚拟一个 Docker 容器网桥(docker0),Docker 启动一个容器时会根据 Docker 网桥的网段分配给容器一个 IP 地址称为 Container-IP,同时 Docker 网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的 Container-IP 直接通信。
host
- 使用命令 --network host 指定
- 容器将不会获得一个独立的 Network Namespace,而是和宿主机共有一个 Network Namespace。容器将不会虚拟出自己的网卡而是使用宿主机的 IP 和端口,不再需要额外进行 NAT 转换,类似于桥接模式
- 此时 docker 启动时如果指定 -p 端口映射,-p 设置的参数将不会起到任何作用,端口号会以主机端口号为主,重复时则递增
none
- 使用命令 --network none 指定
- 容器有独立的 network namespace,但并没有对其进行任何网络设置
- 此 Docker 没有 veth pair、网卡、IP、路由等信息,只有 lo 本地回环地址。需要我们自己为 Docker 容器添加网卡、配置 IP 等
container
- 使用命令 --network container:NAME/容器ID 指定
- 新建的容器和已经存在的一个容器共享一个网络 IP 配置而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的
- 新建容器为 name1,指定的共享容器为 name2。此时,如果 name2 关闭了,name1 的共享网络连接也关闭了
自定义网络模式
- 创建自定义网络:docker network create 自定义的网络名称
- 由于 Docker 容器内部的 IP 是有可能改变的,所以不能直接使用 IP 地址连接不同的 docker 容器。然而直接使用 容器名作为唯一指定 ping 不通。所以需要自定义网络模式,容器启动的时候通过“--network 自定义的网络名称” 连接。这样可以通过容器名称来通信了
- 自定义网络本身维护好了主机名与ip的对应关系(ip和域名都能通)
名称 | 命令 |
---|---|
创建自定义网络 | |
启动容器使用自定义网络 | |
进入 tomcat2 容器 ping tomcat1 | ping tomcat1 |
进入 tomcat1 容器 ping tomcat2 | ping tomcat2 |