【Docker】学习笔记(二)

安装Docker时,它会自动创建三个网络,bridge(创建容器默认连接到此网络)、 none 、host

网络模式
简介
Host 容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。
Bridge 此模式会为每一个容器分配、设置IP等,并将容器连接到一个docker0虚拟网桥,通过docker0网桥以及Iptables nat表配置与宿主机通信。
None 该模式关闭了容器的网络功能。
Container 创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围。

1. 默认网络

当你安装Docker时,它会自动创建三个网络。你可以使用以下 docker network ls 命令列出这些网络:

在这里插入图片描述

Docker 内置这三个网络,运行容器时,你可以使用该 –network 标志来指定容器应连接到哪些网络。

该 bridge 网络代表 docker0 是所有 Docker 安装中存在的网络。除非你使用该 docker run --network=XXX 选项指定,否则 Docker 守护程序默认将容器连接到此网络。

在这里插入图片描述

我们在使用 docker run 创建 Docker 容器时,可以用 --net 选项指定容器的网络模式,Docker可以有以下4种网络模式:

  • host 模式:使用 --net=host 指定
  • none 模式:使用--net=none 指定
  • bridge 模式:使用 --net=bridge 指定,默认设置
  • container 模式:使用 --net=container:NAME_or_ID 指定

2. host 模式

相当于 Vmware 中的桥接模式,与宿主机在同一个网络中,但没有独立IP地址

众所周知,Docker 使用了 Linux 的 Namespaces 技术来进行资源隔离,如 PID Namespace 隔离进程,Mount Namespace 隔离文件系统,Network Namespace 隔离网络等。

一个 Network Namespace 提供了一份独立的网络环境,包括网卡、路由、Iptable 规则等都与其他的 Network Namespace 隔离。一个 Docker 容器一般会分配一个独立的Network Namespace。但如果启动容器的时候使用 host 模式,那么这个容器将不会获得一个独立的 Network Namespace,而是和宿主机共用一个 Network Namespace。容器将不会虚拟出自己的网卡,配置自己的 IP 等,而是使用宿主机的 IP 和端口

在这里插入图片描述

可以看到,容器的网络使用的是宿主机的网络(这里是我的腾讯云的内网 IP),但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。

3. Container 模式

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

4. None 模式

该模式将容器放置在它自己的网络栈中,但是并不进行任何配置。实际上,该模式关闭了容器的网络功能,在以下两种情况下是有用的:容器并不需要网络(例如只需要写磁盘卷的批处理任务)。

5. Bridge 模式

相当于 VMware 中的 Nat 模式,容器使用独立 Network Namespace,并连接到 docker0 虚拟网卡(默认模式)。通过 docker0 网桥以及 Iptables nat 表配置与宿主机通信;bridge 模式是 Docker 默认的网络设置,此模式会为每一个容器分配 Network Namespace、设置 IP 等,并将一个主机上的 Docker 容器连接到一个虚拟网桥上。下面着重介绍一下此模式。

5.1 Bridge 模式的拓扑

当 Docker server 启动时,会在主机上创建一个名为 docker0 的虚拟网桥,此主机上启动的 Docker 容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。接下来就要为容器分配 IP 了,Docker 会从 RFC1918 所定义的私有 IP 网段中,选择一个和宿主机不同的 IP 地址和子网分配给 docker0,连接到 docker0 的容器就从这个子网中选择一个未占用的 IP 使用。如一般 Docker 会使用 172.18.0.0/16 这个网段,并将 172.18.0.1/16 分配给 docker0 网桥(在主机上使用 ip addr 命令是可以看到 docker0 的,可以认为它是网桥的管理接口,在宿主机上作为一块虚拟网卡使用)。

这里可能是由于我的腾讯云内网是172.17.XX.XX,所以默认 docker0 使用 18 的网段了

单机环境下的网络拓扑如下:

在这里插入图片描述

5.2 Bridge 网络模式详解

Docker完成以上网络配置的过程大致是这样的:

  1. 在主机上创建一对虚拟网卡 veth pair 设备。veth 设备总是成对出现的,它们组成了一个数据的通道,数据从一个设备进入,就会从另一个设备出来。因此,veth 设备常用来连接两个网络设备。

  2. Docker 将 veth pair 设备的一端放在新创建的容器中,并命名为 eth0。另一端放在主机中,以 veth5f56268 这样类似的名字命名,并将这个网络设备加入到 docker0 网桥中,可以通过 brctl show 命令查看。

    [root@VM-0-4-centos ~]# brctl show
    bridge name	  bridge id	          STP enabled     interfaces
    docker0	      8000.0242652b8c9d   no              veth5f56268
    
  3. 从 docker0 子网中分配一个 IP 给容器使用,并设置 docker0 的 IP 地址为容器的默认网关。

    运行容器:

    docker run --name=nginx_bridge --net=bridge -p 80:80 -d nginx
    

    查看容器:

    docker ps
    

    在这里插入图片描述

    docker inspect nginx_bridge
    

    在这里插入图片描述

    docker network inspect bridge
    

    在这里插入图片描述

6. --link

思考一个场景,我们编写了一个微服务,如何通过名字来访问容器以避免因容器 IP 变更而导致项目不可访问?

在这里插入图片描述

我们可以使用 --link 来解决

docker run -d -P --name tomcat03 --link tomcat02 tomcat

在这里插入图片描述

但是,这种连接是单向的:

在这里插入图片描述

真实开发不会用 --link

7. 自定义网络

建议使用自定义的网桥来控制哪些容器可以相互通信,还可以自动 DNS 解析容器名称到IP地址。Docker 提供了创建这些网络的默认网络驱动程序,你可以创建一个新的 Bridge 网络,Overlay 或 Macvlan 网络。你还可以创建一个网络插件或远程网络进行完整的自定义和控制。

你可以根据需要创建任意数量的网络,并且可以在任何给定时间将容器连接到这些网络中的零个或多个网络。此外,您可以连接并断开网络中的运行容器,而无需重新启动容器。当容器连接到多个网络时,其外部连接通过第一个非内部网络以词法顺序提供。

一个 Bridge 网络是 Docker 中最常用的网络类型。桥接网络类似于默认 Bridge 网络,但添加一些新功能并删除一些旧的能力。以下示例创建一些桥接网络,并对这些网络上的容器执行一些实验。

docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet

在这里插入图片描述

我们自己的网络就创建好了:

docker network inspect mynet

在这里插入图片描述

用创建的网络启动容器:

docker run -d -P --name tomcat-net-01 --net mynet tomcat
docker run -d -P --name tomcat-net-02 --net mynet tomcat

再次查看创建的网络:

docker network inspect mynet

在这里插入图片描述

此时两个容器是可以 ping 通的

docker run -d -P --name tomcat-net-01 --net mynet tomcat
docker run -d -P --name tomcat-net-01 --net mynet tomcat

这两个容器可以相互 ping 通了!

8. 网络连通

基于 docker0 的容器和基于 mynet 的容器之间是不互通的,所以需要进行网络连通,还是以 tomcat 为例:

docker run -d -P --name tomcat01 tomcat

现在将 tomcat01 连接到 mynet

docker network connect mynet tomcat01

现在查看一下 mynet

docker network inspect mynet

在这里插入图片描述

一个容器,2 个 IP,类似于云服务器,有公网 IP 和内网 IP

此时再 ping 就能 ping 通了

在这里插入图片描述

但是 tomcat02 还是 ping 不通的:

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/dreaming_coder/article/details/113881431
今日推荐