Docker网络相关操作

2024-01-07 17:15:13

网络相关操作

? docker使用Linux桥接网卡,在宿主机虚拟一个docker容器网桥(docker0),docker启动一个容器时会根据docker网桥的网段分配容器一个IP地址,称为Container-IP,同时docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信。

? docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着外部网络无法通过直接Container-IP访问到容器。如果容器希望外部访问能够访问到,可以通过映射容器端口到宿主主机(端口映射),即docker run创建容器时候通过 -p 或 -P 参数来启用,访问容器的时候就通过**[宿主机IP]:[容器端口]**访问容器。

? 可以使用下面的指令查询docker的网络部分信息:

[root@localhost ~]# docker info
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog

1 网络模式

? docker安装后会自动创建3种网络,可以通过下面的指令查看:

[root@localhost ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
0bb24ea90fd4        bridge              bridge              local
57dc55fb29de        host                host                local
a409b9b287ba        none                null                local

? 下面是docker的网络模式:

Docker网络模式配置说明
host模式–net=host容器和宿主机共享Network namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。
container模 式–net=container:NAME_or_ID容器和另外一个容器共享Network namespace。kubernetes中的pod就是多个容器共享一个Network namespace。创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围。
none模式–net=none容器有独立的Network namespace,并没有对其进行任何网络设置,如分配veth pair 和网桥连接,配置IP等。该模式关闭了容器的网络功能。
bridge模式–net=bridge(默认为该模式)。此模式会为每一个容器分配、设置IP等,并将容器连接到一个docker0虚拟网桥,通过docker0网桥以及Iptables nat表配置与宿主机通信。
Macvlan network容器具备Mac地址,使其显示为网络上的物理设备
Overlay(覆盖网络): 利用VXLAN实现的bridge模式

1.1 bridge模式

? bridge模式是默认的网络模式。bridge模式下容器没有一个公有ip,只有宿主机可以直接访问,外部主机是不可见的,但容器通过宿主机的NAT规则后可以访问外网。

? Bridge 桥接模式的实现步骤主要如下:

? 1,Docker Daemon 利用 veth pair 技术,在宿主机上创建两个虚拟网络接口设备,假设为veth0 和,veth1。而veth pair 技术的特性可以保证无论哪一个 veth 接收到网络报文,都会将报文传输给另一方。

? 2,Docker Daemon 将 veth0 附加到 Docker Daemon 创建的 docker0网桥上。保证宿主机的网络报,文可以发往 veth0;

? 3,Docker Daemon 将 veth1 添加到 Docker Container 所属的 namespace 下,并被改名为eth0。,如此一来,保证宿主机的网络报文若发往 veth0,则立即会被 eth0 接收,实现宿主机到DockerContainer网络的联通性;同时,也保证 Docker Container 单独使用 eth0,实现容器网络环境的隔离性。

? Bridge桥接模式的缺陷:

? 1,最明显的是,该模式下 Docker Container 不具有一个公有 IP,即和宿主机的 eth0 不处于同一个网段。导致的结果是宿主机以外的世界不能直接和容器进行通信。

? 2,虽然 NAT 模式经过中间处理实现了这一点,但是 NAT 模式仍然存在问题与不便,如:容器均需要在宿主机上竞争端口,容器内部服务的访问者需要使用服务发现获知服务的外部端口等。

? 3,另外 NAT 模式由于是在三层网络上的实现手段,故肯定会影响网络的传输效率。

? 注意:

? veth设备是成双成对出现的,一端是容器内部命名为eth0,一端是加入到网桥并命名的veth(通常命名为veth),它们组成了一个数据传输通道,一端进一端出,veth设备连接了两个网络设备并实现了数据通信。

1.2 host模式

? 相当于Vmware中的NAT模式,与宿主机在同一个网络中,但没有独立IP地址。如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。

? 使用host模式的容器可以直接使用宿主机的IP地址与外界通信,容器内部的服务端口也可以使用宿主机的端口,不需要进行NAT,host最大的优势就是网络性能比较好,但是docker host上已经使用的端口就不能再用了,网络的隔离性不好。

? host网络模式需要在容器创建时指定–network=host。

? host 模式是 bridge 桥接模式很好的补充。采用 host 模式的 Docker Container,可以直接使用宿主机的 IP地址与外界进行通信,若宿主机的 eth0 是一个公有 IP,那么容器也拥有这个公有IP。同时容器内服务的端口也可以使用宿主机的端口,无需额外进行 NAT 转换。

? host模式可以让容器共享宿主机网络栈,这样的好处是外部主机与容器直接通信,但是容器的网络缺少隔离性。

? Host 网络模式的缺陷:

? 最明显的是 Docker Container 网络环境隔离性的弱化。即容器不再拥有隔离、独立的网络环境。另外,使用 host 模式的 Docker Container 虽然可以让容器内部的服务和传统情况无差别、无改造的使用,但是由于网络隔离性的弱化,该容器会与宿主机共享竞争网络栈的使用;另外,容器内部将不再拥有所有的端口资源,原因是部分端口资源已经被宿主机本身的服务占用,还有部分端口已经用以 bridge 网络模式容器的端口映射。

1.3 Container网络模式

? Container网络模式是一种特殊host网络模式。Container 网络模式是 Docker 中一种较为特别的网络的模式。在容器创建时使用–

network=container:vm1指定。(vm1指定的是运行的容器名)处于这个模式下的 Docker 容器会共享一个网络环境,这样两个容器之间可以使用localhost高效快速通信。

? 缺陷:它并没有改善容器与宿主机以外世界通信的情况(和桥接模式一样,不能连接宿主机以外的其他设备)。这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo 网卡设备通信。

1.4 none模式

? 使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。这种网络模式下容器只有lo回环网络,没有其他网卡。none模式可以在容器创建时通过–network=none来指定。这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性。

1.5 overlay网络模式

? Overlay 网络,也称为覆盖网络。主要用于docker集群部署。Overlay 网络的实现方式和方案有多种。Docker自身集成了一种,基于VXLAN隧道技术实现。Overlay 网络主要用于实现跨主机容器之间的通信。

? 应用场景:需要管理成百上千个跨主机的容器集群的网络时。

1.6 macvlan网络模式

? macvlan网络模式,最主要的特征就是他们的通信会直接基于mac地址进行转发。这时宿主机其实充当一个二层交换机。Docker会维护着一个MAC地址表,当宿主机网络收到一个数据包后,直接根据mac地址找到对应的容器,再把数据交给对应的容器。容器之间可以直接通过IP互通,通过宿主机上内建的虚拟网络设备(创建macvlan网络时自动创建),但与主机无法直接利用IP互通。

? 应用场景:由于每个外来的数据包的目的mac地址就是容器的mac地址,这时每个容器对于外面网络来说就相当于一个真实的物理网络设备。因此当需要让容器来的网络看起来是一个真实的物理机时,使用macvlan模式。

? Macvlan是一个新的尝试,是真正的网络虚拟化技术的转折点。Linux实现非常轻量级,因为与传统的Linux Bridge隔离相比,它们只是简单地与一个Linux以太网接口或子接口相关联,以实现网络之间的分离和与物理网络的连接。

? Macvlan提供了许多独特的功能,并有充足的空间进一步创新与各种模式。这些方法的两个高级优点是绕过Linux网桥的正面性能以及移动部件少的简单性。删除传统上驻留在Docker主机NIC和容器接口之间的网桥留下了一个非常简单的设置,包括容器接口,直接连接到Docker主机接口。由于在这些情况下没有端口映射,因此可以轻松访问外部服务。Macvlan Bridge模式每个容器都有唯一的MAC地址,用于跟踪Docker主机的MAC到端口映射。

? Macvlan驱动程序网络连接到父Docker主机接口。示例是物理接口,例如eth0,用于802.1q VLAN标记的子接口eth0.10(.10代表VLAN 10)或甚至绑定的主机适配器,将两个以太网接口捆绑为单个逻辑接口。 指定的网关由网络基础设施提供的主机外部。 每个Macvlan Bridge模式的Docker网络彼此隔离,一次只能有一个网络连接到父节点。

? 每个主机适配器有一个理论限制,每个主机适配器可以连接一个Docker网络。 同一子网内的任何容器都可以与没有网关的同一网络中的任何其他容器进行通信macvlan bridge。 相同的docker network命令适用于vlan驱动程序。 在Macvlan模式下,在两个网络/子网之间没有外部进程路由的情况下,单独网络上的容器无法互相访问。这也适用于同一码头网络内的多个子网。

2 bridge网络

? 在演示本例子之前,先将本机里面的容器和镜像先都删除掉。执行下面的指令:

[root@localhost ~]# docker network inspect bridge

? 可以看到返回的详细信息里面的Containers项里面的内容是空的:

"Containers": {},

? 执行下面的指令:

[root@localhost ~]# docker pull nginx:1.19.3-alpine
[root@localhost ~]# docker run -itd --name nginx1 nginx:1.19.3-alpine

? 执行完上面的操作之后,再次执行查看bridge网络的信息:

[root@localhost ~]# docker network inspect bridge

? 可以看到Containers项里面有具体的内容了。

"Containers": {
            "0ab96fd6c8cfa2404d93bf374e6ad265d565c477ca1075e2541a70ce5f30cdb7": {
                "Name": "nginx1",
                "EndpointID": "6543a290d8147ed40dabb941fecc8c6a75a12ffa5766f0c59c32ad2530b069fb",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            }
        },

? 在本机上执行下面指令查询ip相关的信息:

[root@localhost ~]# ip a

? 发现多出一条网络的信息:

5: veth20e4d4f@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 6e:04:04:47:d7:04 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::6c04:4ff:fe47:d704/64 scope link 
       valid_lft forever preferred_lft forever

? 为什么会多出一条网络信息,这是因为Docker 创建一个容器的时候,会执行如下操作:

? 1,创建一对虚拟接口/网卡,也就是veth pair,分别放到本地主机和新容器中;

? 2,本地主机一端桥接到默认的 docker0 或指定网桥上,并具有一个唯一的名字,如 veth20e4d4f;

? 3,容器一端放到新容器中,并修改名字作为 eth0,这个网卡/接口只在容器的名字空间可见;

? 4,从网桥可用地址段中(也就是与该bridge对应的network)获取一个空闲地址分配给容器的 eth0,并配置默认路由到桥接网卡 veth20e4d4f。

? 完成这些之后,容器就可以使用 eth0 虚拟网卡来连接其他容器和其他网络。如果不指定–network,创建的容器默认都会挂到 docker0 上,使用本地主机上 docker0 接口的 IP 作为所有容器的默认网关。

? 可以通过下面的两个指令查询上面启动容器的网络信息。

[root@localhost ~]# docker exec -it nginx1 sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
4: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
/ # exit
[root@localhost ~]# docker exec -it nginx1 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
4: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

? 通过下面的指令安装brctl(用来查看桥接网络信息):

yum install -y bridge-utils
[root@localhost ~]# brctl show
bridge name	bridge id		STP enabled	interfaces
docker0		8000.024217c100dc	no		veth20e4d4f

在这里插入图片描述

? 多容器之间通讯

? 通过下面指令启动一个名字为nginx2的容器,然后查询网络信息。

[root@localhost ~]# docker run -itd --name nginx2 nginx:1.19.3-alpine
[root@localhost ~]# docker network inspect bridge
[root@localhost ~]# brctl show

? 进入到容器nginx1,执行下面三个ping操作。

[root@localhost ~]# docker exec -it nginx1 sh
/ # ping 172.17.0.3
PING 172.17.0.3 (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: seq=0 ttl=64 time=0.156 ms
64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.094 ms
^C
--- 172.17.0.3 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.094/0.125/0.156 ms
/ # ping nginx2
ping: bad address 'nginx2'
/ # ping www.baidu.com
PING www.baidu.com (182.61.200.7): 56 data bytes
64 bytes from 182.61.200.7: seq=0 ttl=127 time=41.811 ms
64 bytes from 182.61.200.7: seq=1 ttl=127 time=33.102 ms
64 bytes from 182.61.200.7: seq=2 ttl=127 time=33.679 ms
^C
--- www.baidu.com ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 33.102/36.197/41.811 ms
/ # 

? 通过上面的操作发现用ip来ping是可以通的,但是通过容器名字来ping就不通。因为通过上面的方式启动容器,容器重启后ip会变化,所以在实际使用中并不方便。关于这个问题,可以通过下面两个方式来解决。

2.1 通过link的方式

? 使用link的场景:在企业开发环境中,我们有一个mysql的服务的容器mysql_1,还有一个web应用程序web_1,肯定web_1这台容器肯定要连接mysql_1这个数据库。前面网络命名空间的知识告诉我们,两个容器需要能通信,需要知道对方的具体的IP地址。生产环境还比较好,IP地址很少变化,但是在我们内部测试环境,容器部署的IP地址是可能不断变化的,所以,开发人员不能在代码中写死数据库的IP地址。这个时候,我们就可以利用容器之间link来解决这个问题。下面,我们来介绍如何通过容器名称来进行ping,而不是通过IP地址。

? 先删除nginx2,然后在通过link的方式启动,最后进入到容器执行ping操作,发现可以通过容器名称nginx1访问容器nginx1:

[root@localhost ~]# docker rm -f nginx2
nginx2
[root@localhost ~]# docker run -itd --name nginx2 --link nginx1 nginx:1.19.3-alpine
d68792e9007e2383a0c4d74ba8a7bcfe463d762567b6de7ff18ea5b983282a96
[root@localhost ~]# docker exec -it nginx2 sh
/ # ping 172.17.0.3
PING 172.17.0.3 (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: seq=0 ttl=64 time=0.192 ms
64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.053 ms
^C
--- 172.17.0.3 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.053/0.122/0.192 ms
/ # ping nginx1
PING nginx1 (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.174 ms
64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.089 ms
^C
--- nginx1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.089/0.131/0.174 ms
/ # 

? 上面link命令,是在nginx2容器启动时link到nginx1容器,因此,在nginx2容器里面可以ping通nginx1容器名,link的作用相当于添加了DNS解析。这里提醒下,在nginx1容器里去ping nginx2容器是不通的,因为link关系是单向的,不可逆。实际工作中,docker官网已经不推荐我们使用link参数。docker用其他方式替换掉link参数。

2.2 新建bridge网络

? 通过下面的指令新建一个bridge网络,建好网络后查询网络的列表:

[root@localhost ~]# docker network create -d bridge dream21th-bridge
15225f3acb9344a7932735f716077d59318d2f8e211bae786d541b58f3c1172f
[root@localhost ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
0bb24ea90fd4        bridge              bridge              local
15225f3acb93        dream21th-bridge    bridge              local
57dc55fb29de        host                host                local
a409b9b287ba        none                null                local

? 上面命令参数-d 是指DRIVER的类型,后面的dream21th-bridge是network的自定义名称,这个和docker0是类似的。下面开始介绍,如何把容器连接到dream21th-bridge这个网络。启动一个nginx的容器nginx3,并通过参数network connect来连接dream21th-bridge网络。在启动容器nginx3之前,我们查看目前还没有容器连接到了dream21th-bridge这个网络上。

? 创建完网络后,执行下面查询:

[root@localhost ~]# brctl show
bridge name	bridge id		STP enabled	interfaces
br-15225f3acb93		8000.0242c6d363c4	no		
docker0		8000.024217c100dc	no		veth20e4d4f
							veth88174ec
[root@localhost ~]# docker network inspect dream21th-bridge
[root@localhost ~]# docker run -itd --name nginx3 --network dream21th-bridge nginx:1.19.3-alpine
2dd2ffca3873e8231fb1b75288e921e2d2547512c658d3d23e416e3992d6d80d
[root@localhost ~]# brctl show
bridge name	bridge id		STP enabled	interfaces
br-15225f3acb93		8000.0242c6d363c4	no		vethd1fecd0
docker0		8000.024217c100dc	no		veth20e4d4f
							veth88174ec
[root@localhost ~]# docker network inspect dream21th-bridge

? 通过下面指令把一个运行中容器连接到dream21th-bridge网络:

[root@localhost ~]# docker network connect dream21th-bridge nginx2
[root@localhost ~]# brctl show
bridge name	bridge id		STP enabled	interfaces
br-15225f3acb93		8000.0242c6d363c4	no		veth2b82700
							vethd1fecd0
docker0		8000.024217c100dc	no		veth20e4d4f
							veth88174ec
[root@localhost ~]# docker network inspect dream21th-bridge
[root@localhost ~]# docker exec -it nginx2 sh
/ # ping nginx3
PING nginx3 (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.179 ms
64 bytes from 172.18.0.2: seq=1 ttl=64 time=0.074 ms
^C
--- nginx3 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.074/0.126/0.179 ms


[root@localhost ~]# docker exec -it nginx3 sh
/ # ping nginx2
PING nginx2 (172.18.0.3): 56 data bytes
64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.199 ms
64 bytes from 172.18.0.3: seq=1 ttl=64 time=0.120 ms
^C
--- nginx2 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.120/0.159/0.199 ms
/ # [root@localhost ~]# docker exec -it nginx3 sh
/ # ping nginx2
PING nginx2 (172.18.0.3): 56 data bytes
64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.199 ms
64 bytes from 172.18.0.3: seq=1 ttl=64 time=0.120 ms
^C
--- nginx2 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.120/0.159/0.199 ms
/ # 

3 none网络

? 环境准备,先stop和rm掉全部之前开启的容器。并且把前面创建的lagou-bridge网络也删除。当然,更简单的办法是使用快照方式。将docker-100主机恢复到docker初始化安装时。

[root@localhost ~]# docker rm -f $(docker ps -aq)
4a256f4fbc6a
2dd2ffca3873
d68792e9007e
0ab96fd6c8cf
[root@localhost ~]# docker network rm dream21th-bridge
dream21th-bridge
[root@localhost ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
0bb24ea90fd4        bridge              bridge              local
57dc55fb29de        host                host                local
a409b9b287ba        none                null                local

? 启动一个ngnix的容器nginx1,并且连接到none网络。然后执行docker network inspect none,看看容器信息。

[root@localhost ~]# docker run -itd --name nginx1 --network none nginx:1.19.3-alpine
57cfa7e46e5901a723e7fd52a32be51068b41994f9d5da1e8b983ac8fa77bb71
[root@localhost ~]# docker network inspect none

? 注意,容器使用none模式,是没有物理地址和IP地址。我们可以进入到nginx1容器里,执行ip a命令看看。只有一个lo接口,没有其他网络接口,没有IP。也就是说,使用none模式,这个容器是不能被其他容器访问。这种使用场景很少,只有项目安全性很高的功能才能使用到。例如:密码加密算法容器。

[root@localhost ~]# docker exec -it nginx1 sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever

4 host网络

? 前面学习none网络模式特点就是,容器没有IP地址,不能和其他容器通信。下面来看看host网络是什么特点。我们使用前面命令,启动一个nginx的nginx4容器,连接到host网络。然后docker network inspect host, 看看容器信息。

[root@localhost ~]# docker run -itd --name nginx4 --network host nginx:1.19.3-alpine
4a256f4fbc6a62f31cde6e4228d83899ab043ec2f3ddb8e127b1c2f58514408f
[root@localhost ~]# docker network inspect host

? 查看到的容器的信息如下:

 "Containers": {
            "4a256f4fbc6a62f31cde6e4228d83899ab043ec2f3ddb8e127b1c2f58514408f": {
                "Name": "nginx4",
                "EndpointID": "36a58ee69431ef9905076492ec7abb48b48107faa318b4c7c26f8b6aa3abe2cd",
                "MacAddress": "",
                "IPv4Address": "",
                "IPv6Address": ""
            }
        },

? 这里来看,也不显示IP地址。那么是不是和none一样,肯定不是,不然也不会设计none和host网络进行区分。下面我们进入nginx4容器,执行ip a看看效果。我们在容器里执行ip a,发现打印内容和在linux本机外执行ip a是一样的。

[root@localhost ~]# docker exec -it nginx4 sh
/ # ip a

? 这说明什么呢?容器使用了host模式,说明容器和外层linux主机共享一套网络接口。VMware公司的虚拟机管理软件,其中网络设置,也有host这个模式,作用也是一样,虚拟机里面使用网络和你自己外层机器是一模一样的。这种容器和本机使用共享一套网络接口,缺点还是很明显的,例如我们知道web服务器一般端口是80,共享了一套网络接口,那么你这台机器上只能启动一个nginx端口为80的服务器了。否则,出现端口被占用的情况。本篇很简单,就是简单了解下docker中none和host网络模式。学习重点还是如何使用bridge网络。

5 网络命令汇总

? 可以通过下面指令查询network的相关操作指令:

[root@localhost ~]# docker network --help

Usage:	docker network COMMAND

Manage networks

Commands:
  connect     Connect a container to a network
  create      Create a network
  disconnect  Disconnect a container from a network
  inspect     Display detailed information on one or more networks
  ls          List networks
  prune       Remove all unused networks
  rm          Remove one or more networks

5.1 查看网络

查看网络 – docker network ls
# 作用:查看已经建立的网络对象 
# 命令格式: 
docker network ls [OPTIONS] 
# 命令参数(OPTIONS): 
-f, --filter filter 过滤条件('driver=bridge’)
--format string 格式化打印结果 
--no-trunc 不缩略显示 
-q, --quiet 只显示网络对象的ID 
# 注意:默认情况下,docker安装完成后,会自动创建bridge、host、none三种网络驱动 
# 命令演示 
docker network ls 
docker network ls --no-trunc 
docker network ls -f 'driver=host'

5.2 创建网络

创建网络 – docker network create
# 作用:创建新的网络对象 
# 命令格式: 
docker network create [OPTIONS] NETWORK 
# 命令参数(OPTIONS): 
-d, --driver string 指定网络的驱动(默认 "bridge") 
--subnet strings 指定子网网段(如192.168.0.0/16、172.88.0.0/24) 
--ip-range strings 执行容器的IP范围,格式同subnet参数 
--gateway strings 子网的IPv4 or IPv6网关,如(192.168.0.1) 
# 注意:
host和none模式网络只能存在一个 
docker自带的overlay 网络创建依赖于docker swarm(集群负载均衡)服务 
192.168.0.0/16 等于 192.168.0.0~192.168.255.255
172.88.0.0/24 等于 172.88.0.0~172.88.0.255 
# 命令演示 
docker network ls 
docker network create -d bridge my-bridge 
docker network ls

5.3 删除网络

网络删除 – docker network rm 
# 作用:删除一个或多个网络 
# 命令格式: 
docker network rm NETWORK [NETWORK...] 
# 命令参数(OPTIONS): 

5.4 查看网络详细信息

查看网络详细信息 docker network inspect 
# 作用:查看一个或多个网络的详细信息 
# 命令格式: 
docker network inspect [OPTIONS] NETWORK [NETWORK...] 
或者 docker inspect [OPTIONS] NETWORK [NETWORK...] 
# 命令参数(OPTIONS): 
-f, --format string 
根据format输出结果

5.5 使用网络

使用网络 – docker run –-network 
# 作用:为启动的容器指定网络模式 
# 命令格式: 
docker run/create --network NETWORK 
# 命令参数(OPTIONS):# 注意:默认情况下,docker创建或启动容器时,会默认使用名为bridge的网络

5.6 使用网络

网络连接与断开 – docker network connect/disconnect 
# 作用:将指定容器与指定网络进行连接或者断开连接 
# 命令格式: 
docker network connect [OPTIONS] NETWORK CONTAINER 
docker network disconnect [OPTIONS] NETWORK CONTAINER
# 命令参数(OPTIONS): 
-f, --force 
强制断开连接(用于disconnect)

5.7 练习

docker network create -d bridge --subnet=172.172.0.0/24 --gateway 172.172.0.1 dream21th-network 
172.172.0.0/24: 24代表子码掩码是255.255.255.0 
172.172.0.0/16: 16 代表子码掩码 
docker network ls 
docker run -itd --name nginx3 -p 80:80 --net dream21th-network --ip 172.172.0.10 nginx:1.19.3-alpine 
--net mynetwork:选择存在的网络 
--ip 172.172.0.10:给nginx分配固定的IP地址 
docker network inspect dream21th-network
docker stop nginx3 
docker start nginx3 
docker network inspect dream21th-network

文章来源:https://blog.csdn.net/qq_36305027/article/details/135421389
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。