在同一网段下,docker 网络作用并不明显;实际工作中,docker 容器会分布在不同网段的机器上,docker 网络用来解决容器间的互联和通信以及端口映射,使得容器IP变动时候可以通过服务名直接网络通信而不受到影响,在容器编排时广泛使用
docker 启动后会创建一个名为 docker0 的网桥
启动 docker 后创建 docker0 网桥

基础操作:

docker 会自动创建 bridge、host、none 三大网络模式,而网络模式一共为四种:

  1. - **bridge**:网桥模式,为每一个容器分配、设置IP,并将容器连接到 docker 0,生成容器时不指定网络模式下默认使用该模式。**该模式在实际工作中使用场景最广**
  2. - **host:**主机模式,容器将不会虚拟出自己的网卡、配置自己的IP,将会使用宿主机的 IP 和端口
  3. - **none:**容器有独立的 Network namespace,但并没有对其进行任何网络设置,如分配 vethpair 和网桥连接、IP 等。**该模式在实际工作中几乎不会使用**
  4. - **container:**新创建的容器不会创建自己的网卡和配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等

指定方式:

网络模式(网桥模式) 参数
bridge —network bridge,或者不填
host —network host 或者 -net host
none —network none 或者 -net none
container —network container:NAME或者容器ID指定

查看网络:

  1. docker network ls
  1. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/21405095/1660141669998-eeedd2f0-d122-4923-a420-3843678785a3.png#clientId=ucdb73bac-dd64-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=99&id=u6763d2ac&margin=%5Bobject%20Object%5D&name=image.png&originHeight=148&originWidth=561&originalType=binary&ratio=1&rotation=0&showTitle=true&size=8809&status=done&style=stroke&taskId=u11b8834b-e2c5-4b52-b8d3-4747c38030e&title=docker%20%E8%87%AA%E5%8A%A8%E5%88%9B%E5%BB%BA%E7%9A%84%E4%B8%89%E5%A4%A7%E7%BD%91%E7%BB%9C%E6%A8%A1%E5%BC%8F&width=374 "docker 自动创建的三大网络模式")

创建网络:

用于创建自定义网络,自定义网络维护好了主机名和ip的对应关系,使得容器之间可以通过容器名、容器ID进行网络通信。通俗理解就是类似微服务项目的不同模块之间使用 OpenFeign 进行网络互通
具体演示说明查看 网络模式 - 自定义网络

  1. docker network create 网络名称

image.png

删除网络:

删除指定名称的网络

  1. docker network rm 网络名称

image.png

查看网络源数据:

  1. docker network inspect 网络名称

image.png


容器内默认网络IP生产规则:

使用网桥方式创建容器,当容器被删除后,后续新创建的容器可能会继承之前删除容器的 IP 地址

案例演示:

创建两个 ubuntu 容器实例,查看其对应网络详情

  1. docker run -it --name ubuntu1 ubuntu /bin/bash
  2. docker run -it --name ubuntu2 ubuntu /bin/bash
  1. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/21405095/1660144570315-2291ba57-082e-4777-b09e-675434245350.png#clientId=ue2a660ae-7e58-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=484&id=u9141310c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=963&originWidth=1286&originalType=binary&ratio=1&rotation=0&showTitle=true&size=66093&status=done&style=stroke&taskId=u94ad5eec-40ab-4315-bf04-c8aa10c4840&title=%E6%AF%8F%E4%B8%AA%20Ubuntu%20%E5%AE%B9%E5%99%A8%E9%83%BD%E6%9C%89%E5%85%B6%E5%90%84%E8%87%AA%E7%9A%84%20IP&width=646 "每个 Ubuntu 容器都有其各自的 IP")

删除 ubuntu2 容器,创建出新 ubuntu3 容器,查看其网络信息,发现其 IP 地址与被删除的 ubuntu2 容器一致
image.png

网络模式:

介绍 docker 的四种网络及自定义网络
在宿主机 ifconfig 或者 ip addr,就可以看到 docker0 和创建容器时产生的 network:eth0,eth1,eth2 …… ( 代表网卡一,网卡二,网卡三 ……),lo 代表127.0.0.1,即 localhost,inet addr 用来表示网卡的IP地址

bridge:

在启动 Docker 后默认会创建一个 docker0 网桥(其上有一个 docker0 内部接口),它在内核层连通了其他的物理或虚拟网卡(例如宿主机给外部访问的 ens33),这就将所有容器和本地主机都放到同一个物理网络
在创建容器时,没有指定 network 时默认使用 bridge 网络模式,其容器实例内部会创建 eth0 网卡,与 docker 中的 docker0 网桥上的 veth 接口进行对接,从而使容器各自拿到 docker 分配的ip,因此完成不同容器之间的网络互通
image_waifu2x_1x_1n_png.png

案例演示:

创建两个 Tomcat 容器,演示容器内部 eth0 网卡与 docker 创建的 docker0 上的 veth 接口关系

  1. docker run -d -p 8081:8080 --name tomcat81 billygoo/tomcat8-jdk8
  2. docker run -d -p 8082:8080 --name tomcat82 billygoo/tomcat8-jdk8

image.png
image.png
image.png

host:

直接使用宿主机的 IP 地址与外界进行通信,不再需要额外进行NAT 转换、
容器将不会获得一个独立的 Network Namespace, 而是和宿主机共用一个 Network Namespace。容器将不会虚拟出自己的网卡,而是使用宿主机的 IP 和端口
该模式下创建容器实例,指定其 -p 参数没有意义,会出现无效提示,且由于没有 -p ,在没有其他代理工具(例如 nginx )的情况下,只有宿主机才能访问容器
Image_W2xEX_2x_2n_bmp.jpg

案例演示:

创建一个使用 host 模式的 tomcat,观察容器网络情况

  1. docker run -d --network host --name tomcat83 billygoo/tomcat8-jdk8

image.png
image.png

查看容器网络情况:
image.png
image.png
image.png

none:

禁用网络功能,只有 lo 标识(就是127.0.0.1表示本地回环),实际工作中非常少用

案例演示:

创建一个网络为 none 的 tomcat 容器,观察其网络实例情况

  1. docker run -d -p 8084:8080 --network none --name tomcat84 billygoo/tomcat8-jdk8
  1. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/21405095/1660201704929-7ad0d3fc-f872-4636-bff3-9556a50dd325.png#clientId=ued00bb0b-71fb-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=89&id=u809b0c06&margin=%5Bobject%20Object%5D&name=image.png&originHeight=133&originWidth=959&originalType=binary&ratio=1&rotation=0&showTitle=true&size=30016&status=done&style=stroke&taskId=ud2fc621b-b4f8-4dcf-888c-7da5939959d&title=%E5%AE%B9%E5%99%A8%E5%86%85%E9%83%A8%E5%8F%AA%E6%9C%89%20lo%20%E6%A0%87%E8%AF%86%E7%9A%84%E7%BD%91%E7%BB%9C%E4%BF%A1%E6%81%AF&width=639.3333333333334 "容器内部只有 lo 标识的网络信息")

container:

新建的容器和已经存在的一个容器共享一个网络 ip 配置而不是和宿主机共享。新创建的容器不会创建自己的网卡、配置自己的 IP,而是和一个指定的容器共享IP、端口范围等网络信息
container 模式不适合共用一个端口的容器,例如 tomcat
Image_W2xEX_2x_2n_bmp.jpg

错误提示案例:

演示 tomcat 使用 container 方式创建时会出现的错误提示

  1. docker run -d -p 8085:8080 --name tomcat85 billygoo/tomcat8-jdk8
  2. docker run -d -p 8086:8080 --network container:tomcat85 --name tomcat86 billygoo/tomcat8-jdk8

image.png

案例演示:

创建两个 Alpine容器,第二个 Alpine 容器使用 container 方式,观察其网络信息
Alpine 操作系统是一个面向安全的轻型 Linux发行版,常用于容器打包

  1. docker run -it --name alpine1 alpine /bin/sh
  2. docker run -it --network container:alpine1 --name alpine2 alpine /bin/sh

使用 ip addr 查看网络信息:
image.png

停止 Alpine 1 容器后,Alpine 2 容器只剩 lo (本地回环)网络
image.png

重新启动 Alpine 1 容器,Alpine 2 容器依旧只剩 lo (本地回环)网络,不会恢复
image.png

自定义网络:

使用 bridge 模式创建的容器无法使用服务名进行网络互通,一旦容器发生 IP 变化,可能会导致服务失效
实际生产环境中,应使用自定义网络来确保容器之间可以通过服务名进行网络互通,从而解决以往 IP 变化导致的服务失效问题

默认模式演示:

创建两个 tomcat 容器案例

  1. docker run -d -p 8081:8080 --name tomcat81 billygoo/tomcat8-jdk8
  2. docker run -d -p 8082:8080 --name tomcat82 billygoo/tomcat8-jdk8

进入到两个 tomcat 容器内部,测试网络互通情况
image.png

当使用服务名时,两个容器无法相互 ping 通
image.png

自定义网络演示:

创建自定义网络

  1. docker network create dmbjz_network
  1. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/21405095/1660213068319-72ba1542-4adb-45da-b2ac-3b1fdd22073f.png#clientId=u47a8d67a-4b9e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=136&id=u27ec48af&margin=%5Bobject%20Object%5D&name=image.png&originHeight=204&originWidth=797&originalType=binary&ratio=1&rotation=0&showTitle=true&size=50275&status=done&style=stroke&taskId=u5218954a-a3ec-4700-856a-9be273b1067&title=%E5%88%9B%E5%BB%BA%E8%87%AA%E5%AE%9A%E4%B9%89%E7%BD%91%E7%BB%9C%20dmbjz_network%20%E6%88%90%E5%8A%9F&width=531.3333333333334 "创建自定义网络 dmbjz_network 成功")

创建使用自定义网络的容器

  1. docker run -d --network dmbjz_network -p 8081:8080 --name tomcat81 billygoo/tomcat8-jdk8
  2. docker run -d --network dmbjz_network -p 8082:8080 --name tomcat82 billygoo/tomcat8-jdk8

进入 tomcat81 与 tomcat82 容器,测试使用 容器名、容器ID 进行网络互通测试
image.png
image.png

网络关系:

如果觉得用 ip addr ifconfig 并不能非常直接体现 docker 网络关系,可以使用 brctl 进行查看

安装 brctl :

  1. yum install -y bridge-utils

image.png


容器网络操作:

用于容器运行时对其网络进行操作

设置容器使用的网络:

在容器原有网络上添加需要使用的新网络

  1. docker network connect 网络名 容器ID

image.png
image.png

删除容器使用的网络:

在容器原有网络上移除正在使用的网络

  1. docker network disconnect 网络名 容器ID

image.png