本文作者:知知行行 \
本文链接:https://www.cnblogs.com/loron...

docker容器网络

Docker在装置后主动提供3种网络,能够应用docker network ls命令查看

[root@localhost ~]# docker network lsNETWORK ID          NAME                DRIVER              SCOPEcd97bb997b84        bridge              bridge              local0a04824fc9b6        host                host                local4dcb8fbdb599        none                null                local

Docker应用Linux桥接,在宿主机虚构一个Docker容器网桥(docker0),Docker启动一个容器时会依据Docker网桥的网段调配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就可能通过容器的Container-IP间接通信。

docker的4种网络模式

网络模式配置阐明
host--network host容器和宿主机共享Network namespace
container--network container:NAME_OR_ID容器和另外一个容器共享Network namespace
none--network none容器有独立的Network namespace,但并没有对其进行任何网络设置,如调配veth pair 和网桥连贯,配置IP等
bridge--networkbridge 默认模式

bridge模式

当Docker过程启动时,会在主机上创立一个名为docker0的虚构网桥,此主机上启动的Docker容器会连贯到这个虚构网桥上。虚构网桥的工作形式和物理交换机相似,这样主机上的所有容器就通过交换机连在了一个二层网络中。

从docker0子网中调配一个IP给容器应用,并设置docker0的IP地址为容器的默认网关。在主机上创立一对虚构网卡veth pair设施,Docker将veth pair设施的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以vethxxx这样相似的名字命名,并将这个网络设备退出到docker0网桥中。能够通过brctl show命令查看。

bridge模式是docker的默认网络模式,不写--network参数,就是bridge模式。应用docker run -p时,docker理论是在iptables做了DNAT规定,实现端口转发性能。能够应用iptables -t nat -vnL查看。

bridge模式如下图所示:

假如上图的docker2中运行了一个nginx,大家来想几个问题:

  • 同主机间两个容器间是否能够间接通信?比方在docker1上能不能间接拜访到docker2的nginx站点?
  • 在宿主机上是否间接拜访到docker2的nginx站点?
  • 在另一台主机上如何拜访node1上的这个nginx站点呢?DNAT公布?

Docker网桥是宿主机虚构进去的,并不是实在存在的网络设备,内部网络是无奈寻址到的,这也意味着内部网络无奈通过间接Container-IP拜访到容器。如果容器心愿内部拜访可能拜访到,能够通过映射容器端口到宿主主机(端口映射),即docker run创立容器时候通过 -p 或 -P 参数来启用,拜访容器的时候就通过[宿主机IP]:[容器端口]拜访容器。

container模式

这个模式指定新创建的容器和曾经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创立本人的网卡,配置本人的 IP,而是和一个指定的容器共享 IP、端口范畴等。同样,两个容器除了网络方面,其余的如文件系统、过程列表等还是隔离的。两个容器的过程能够通过 lo 网卡设施通信。
container模式如下图所示:

host模式

如果启动容器的时候应用host模式,那么这个容器将不会取得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚构出本人的网卡,配置本人的IP等,而是应用宿主机的IP和端口。然而,容器的其余方面,如文件系统、过程列表等还是和宿主机隔离的。

应用host模式的容器能够间接应用宿主机的IP地址与外界通信,容器外部的服务端口也能够应用宿主机的端口,不须要进行NAT,host最大的劣势就是网络性能比拟好,然而docker host上曾经应用的端口就不能再用了,网络的隔离性不好。

Host模式如下图所示:

none模式
应用none模式,Docker容器领有本人的Network Namespace,然而,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。须要咱们本人为Docker容器增加网卡、配置IP等。

这种网络模式下容器只有lo回环网络,没有其余网卡。none模式能够在容器创立时通过--network none来指定。这种类型的网络没有方法联网,关闭的网络能很好的保障容器的安全性。

利用场景:

  • 启动一个容器解决数据,比方转换数据格式
  • 一些后盾的计算和解决工作

none模式如下图所示:

docker network inspect bridge   #查看bridge网络的具体配置

docker容器网络配置

Linux内核实现名称空间的创立

ip netns命令

能够借助ip netns命令来实现对 Network Namespace 的各种操作。ip netns命令来自于iproute安装包,个别零碎会默认装置,如果没有的话,请自行装置。

留神:ip netns命令批改网络配置时须要 sudo 权限。

能够通过ip netns命令实现对Network Namespace 的相干操作,能够通过ip netns help查看命令帮忙信息:

[root@localhost ~]# ip netns helpUsage: ip netns list       ip netns add NAME       ip netns set NAME NETNSID       ip [-all] netns delete [NAME]       ip netns identify [PID]       ip netns pids NAME       ip [-all] netns exec [NAME] cmd ...       ip netns monitor       ip netns list-id

默认状况下,Linux零碎中是没有任何 Network Namespace的,所以ip netns list命令不会返回任何信息。

创立Network Namespace

通过命令创立一个名为ns0的命名空间:

[root@localhost ~]# ip netns list[root@localhost ~]# ip netns add ns0[root@localhost ~]# ip netns listns0

新创建的 Network Namespace 会呈现在/var/run/netns/目录下。如果雷同名字的 namespace 曾经存在,命令会报Cannot create namespace file "/var/run/netns/ns0": File exists的谬误。

[root@localhost ~]# ls /var/run/netns/ns0[root@localhost ~]# ip netns add ns0Cannot create namespace file "/var/run/netns/ns0": File exists

对于每个 Network Namespace 来说,它会有本人独立的网卡、路由表、ARP 表、iptables 等和网络相干的资源。

操作Network Namespace

ip命令提供了ip netns exec子命令能够在对应的 Network Namespace 中执行命令。

查看新创建 Network Namespace 的网卡信息

[root@localhost ~]# ip netns exec ns0 ip addr1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

能够看到,新创建的Network Namespace中会默认创立一个lo回环网卡,此时网卡处于敞开状态。此时,尝试去 ping 该lo回环网卡,会提醒Network is unreachable

[root@localhost ~]# ip netns exec ns0 ping 127.0.0.1connect: Network is unreachable127.0.0.1是默认回环网卡

通过上面的命令启用lo回环网卡:

[root@localhost ~]# ip netns exec ns0 ip link set lo up[root@localhost ~]# ip netns exec ns0 ping 127.0.0.1PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.029 ms64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.029 ms^C--- 127.0.0.1 ping statistics ---2 packets transmitted, 2 received, 0% packet loss, time 1036msrtt min/avg/max/mdev = 0.029/0.029/0.029/0.000 ms

转移设施

咱们能够在不同的 Network Namespace 之间转移设施(如veth)。因为一个设施只能属于一个 Network Namespace ,所以转移后在这个 Network Namespace 内就看不到这个设施了。

其中,veth设施属于可转移设施,而很多其它设施(如lo、vxlan、ppp、bridge等)是不能够转移的。

veth pair

veth pair 全称是 Virtual Ethernet Pair,是一个成对的端口,所有从这对端口一 端进入的数据包都将从另一端进去,反之也是一样。
引入veth pair是为了在不同的 Network Namespace 间接进行通信,利用它能够间接将两个 Network Namespace 连接起来。

创立veth pair

[root@localhost ~]# ip link add type veth[root@localhost ~]# ip a4: veth0@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000    link/ether 0a:f4:e2:2d:37:fb brd ff:ff:ff:ff:ff:ff5: veth1@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000    link/ether 5e:7e:f6:59:f0:4f brd ff:ff:ff:ff:ff:ff

能够看到,此时零碎中新增了一对veth pair,将veth0和veth1两个虚构网卡连贯了起来,此时这对 veth pair 处于”未启用“状态。

实现Network Namespace间通信

上面咱们利用veth pair实现两个不同的 Network Namespace 之间的通信。方才咱们曾经创立了一个名为ns0的 Network Namespace,上面再创立一个信息Network Namespace,命名为ns1

[root@localhost ~]# ip netns add ns1[root@localhost ~]# ip netns listns1ns0

而后咱们将veth0退出到ns0,将veth1退出到ns1

[root@localhost ~]# ip link set veth0 netns ns0[root@localhost ~]# ip link set veth1 netns ns1

而后咱们别离为这对veth pair配置上ip地址,并启用它们

[root@localhost ~]# ip netns exec ns0 ip link set veth0 up[root@localhost ~]# ip netns exec ns0 ip addr add 192.0.0.1/24 dev veth0[root@localhost ~]# ip netns exec ns1 ip link set veth1 up[root@localhost ~]# ip netns exec ns1 ip addr add 192.0.0.2/24 dev veth1

查看这对veth pair的状态

[root@localhost ~]# ip netns exec ns0 ip a1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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    inet6 ::1/128 scope host       valid_lft forever preferred_lft forever4: veth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000    link/ether 0a:f4:e2:2d:37:fb brd ff:ff:ff:ff:ff:ff link-netns ns1    inet 192.0.0.1/24 scope global veth0       valid_lft forever preferred_lft forever    inet6 fe80::8f4:e2ff:fe2d:37fb/64 scope link       valid_lft forever preferred_lft forever
[root@localhost ~]# ip netns exec ns1 ip a1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:005: veth1@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000    link/ether 5e:7e:f6:59:f0:4f brd ff:ff:ff:ff:ff:ff link-netns ns0    inet 192.0.0.2/24 scope global veth1       valid_lft forever preferred_lft forever    inet6 fe80::5c7e:f6ff:fe59:f04f/64 scope link       valid_lft forever preferred_lft forever

从下面能够看出,咱们曾经胜利启用了这个veth pair,并为每个veth设施调配了对应的ip地址。咱们尝试在ns1中拜访ns0中的ip地址

[root@localhost ~]# ip netns exec ns1 ping 192.0.0.1PING 192.0.0.1 (192.0.0.1) 56(84) bytes of data.64 bytes from 192.0.0.1: icmp_seq=1 ttl=64 time=0.033 ms64 bytes from 192.0.0.1: icmp_seq=2 ttl=64 time=0.041 ms^C--- 192.0.0.1 ping statistics ---2 packets transmitted, 2 received, 0% packet loss, time 1001msrtt min/avg/max/mdev = 0.033/0.037/0.041/0.004 ms[root@localhost ~]# ip netns exec ns0 ping 192.0.0.2PING 192.0.0.2 (192.0.0.2) 56(84) bytes of data.64 bytes from 192.0.0.2: icmp_seq=1 ttl=64 time=0.025 ms64 bytes from 192.0.0.2: icmp_seq=2 ttl=64 time=0.025 ms^C--- 192.0.0.2 ping statistics ---2 packets transmitted, 2 received, 0% packet loss, time 1038msrtt min/avg/max/mdev = 0.025/0.025/0.025/0.000 ms

能够看到,veth pair胜利实现了两个不同Network Namespace之间的网络交互。

四种网络模式配置

bridge模式配置

[root@localhost ~]# docker run -it --name ti --rm busybox/ # ifconfigeth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02          inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1          RX packets:12 errors:0 dropped:0 overruns:0 frame:0          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0          collisions:0 txqueuelen:0          RX bytes:1032 (1.0 KiB)  TX bytes:0 (0.0 B)lo        Link encap:Local Loopback          inet addr:127.0.0.1  Mask:255.0.0.0          UP LOOPBACK RUNNING  MTU:65536  Metric:1          RX packets:0 errors:0 dropped:0 overruns:0 frame:0          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0          collisions:0 txqueuelen:1000          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

在创立容器时增加--network bridge与不加--network选项成果是统一的

 [root@localhost ~]# docker run -it --name t1 --network bridge --rm busybox/ # ifconfigeth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02          inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1          RX packets:8 errors:0 dropped:0 overruns:0 frame:0          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0          collisions:0 txqueuelen:0          RX bytes:696 (696.0 B)  TX bytes:0 (0.0 B)lo        Link encap:Local Loopback          inet addr:127.0.0.1  Mask:255.0.0.0          UP LOOPBACK RUNNING  MTU:65536  Metric:1          RX packets:0 errors:0 dropped:0 overruns:0 frame:0          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0          collisions:0 txqueuelen:1000          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

none模式配置

[root@localhost ~]# docker run -it --name t1 --network none --rm busybox/ # ifconfig -alo        Link encap:Local Loopback          inet addr:127.0.0.1  Mask:255.0.0.0          UP LOOPBACK RUNNING  MTU:65536  Metric:1          RX packets:0 errors:0 dropped:0 overruns:0 frame:0          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0          collisions:0 txqueuelen:1000          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

container模式配置

启动第一个容器

[root@localhost ~]# docker run -dit --name b3 busyboxaf5ba32f990ebf5a46d7ecaf1eec67f1712bbef6ad7df37d52b7a8a498a592a0[root@localhost ~]# docker exec -it b3 /bin/sh/ # ifconfigeth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02          inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1          RX packets:11 errors:0 dropped:0 overruns:0 frame:0          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0          collisions:0 txqueuelen:0          RX bytes:906 (906.0 B)  TX bytes:0 (0.0 B)

启动第二个容器

[root@localhost ~]# docker run -it --name b2 --rm busybox/ # ifconfigeth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:03          inet addr:172.17.0.3  Bcast:172.17.255.255  Mask:255.255.0.0          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1          RX packets:6 errors:0 dropped:0 overruns:0 frame:0          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0          collisions:0 txqueuelen:0          RX bytes:516 (516.0 B)  TX bytes:0 (0.0 B)

能够看到名为b2的容器IP地址是10.0.0.3,与第一个容器的IP地址不是一样的,也就是说并没有共享网络,此时如果咱们将第二个容器的启动形式扭转一下,就能够使名为b2的容器IP与B3容器IP统一,也即共享IP,但不共享文件系统。

[root@localhost ~]# docker run -it --name b2 --rm --network container:b3 busybox/ # ifconfigeth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02          inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1          RX packets:14 errors:0 dropped:0 overruns:0 frame:0          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0          collisions:0 txqueuelen:0          RX bytes:1116 (1.0 KiB)  TX bytes:0 (0.0 B)此时咱们在b1容器上创立一个目录/ # mkdir /tmp/data/ # ls /tmpdata

到b2容器上查看/tmp目录会发现并没有这个目录,因为文件系统是处于隔离状态,仅仅是共享了网络而已。
在b2容器上部署一个站点

/ # echo 'hello world' > /tmp/index.html/ # ls /tmpindex.html/ # httpd -h /tmp/ # netstat -antlActive Internet connections (servers and established)Proto Recv-Q Send-Q Local Address           Foreign Address         Statetcp        0      0 :::80                   :::*                    LISTEN

在b1容器上用本地地址去拜访此站点

/ # wget -O - -q 172.17.0.2:80hello world

host模式配置

启动容器时间接指明模式为host

[root@localhost ~]# docker run -it --name b2 --rm --network host busybox/ # ifconfigdocker0   Link encap:Ethernet  HWaddr 02:42:B8:7F:8E:2C          inet addr:172.17.0.1  Bcast:172.17.255.255  Mask:255.255.0.0          inet6 addr: fe80::42:b8ff:fe7f:8e2c/64 Scope:Link          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1          RX packets:3 errors:0 dropped:0 overruns:0 frame:0          TX packets:20 errors:0 dropped:0 overruns:0 carrier:0          collisions:0 txqueuelen:0          RX bytes:116 (116.0 B)  TX bytes:1664 (1.6 KiB)ens33     Link encap:Ethernet  HWaddr 00:0C:29:95:19:47          inet addr:192.168.203.138  Bcast:192.168.203.255  Mask:255.255.255.0          inet6 addr: fe80::2e61:1ea3:c05a:3d9b/64 Scope:Link          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1          RX packets:9626 errors:0 dropped:0 overruns:0 frame:0          TX packets:3950 errors:0 dropped:0 overruns:0 carrier:0          collisions:0 txqueuelen:1000          RX bytes:3779562 (3.6 MiB)  TX bytes:362386 (353.8 KiB)lo        Link encap:Local Loopback          inet addr:127.0.0.1  Mask:255.0.0.0          inet6 addr: ::1/128 Scope:Host          UP LOOPBACK RUNNING  MTU:65536  Metric:1          RX packets:0 errors:0 dropped:0 overruns:0 frame:0          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0          collisions:0 txqueuelen:1000          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)veth09ee47e Link encap:Ethernet  HWaddr B2:10:53:7B:66:AE          inet6 addr: fe80::b010:53ff:fe7b:66ae/64 Scope:Link          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1          RX packets:3 errors:0 dropped:0 overruns:0 frame:0          TX packets:19 errors:0 dropped:0 overruns:0 carrier:0          collisions:0 txqueuelen:0          RX bytes:158 (158.0 B)  TX bytes:1394 (1.3 KiB)

此时如果咱们在这个容器中启动一个http站点,咱们就能够间接用宿主机的IP间接在浏览器中拜访这个容器中的站点了。

容器的罕用操作

查看容器的主机名

[root@localhost ~]# docker run -it --name t1 --network bridge --rm busybox/ # hostname48cb45a0b2e7

在容器启动时注入主机名

[root@localhost ~]# docker run -it --name t1 --network bridge --hostname ljl --rm busybox/ # hostnameljl/ # cat /etc/hosts127.0.0.1    localhost::1    localhost ip6-localhost ip6-loopbackfe00::0    ip6-localnetff00::0    ip6-mcastprefixff02::1    ip6-allnodesff02::2    ip6-allrouters172.17.0.3    ljl/ # cat /etc/resolv.conf# Generated by NetworkManagersearch localdomainnameserver 192.168.203.2/ # ping www.baidu.comPING www.baidu.com (182.61.200.7): 56 data bytes64 bytes from 182.61.200.7: seq=0 ttl=127 time=31.929 ms64 bytes from 182.61.200.7: seq=1 ttl=127 time=41.062 ms64 bytes from 182.61.200.7: seq=2 ttl=127 time=31.540 ms^C--- www.baidu.com ping statistics ---3 packets transmitted, 3 packets received, 0% packet lossround-trip min/avg/max = 31.540/34.843/41.062 ms

手动指定容器要应用的DNS

[root@localhost ~]# docker run -it --name t1 --network bridge --hostname ljl --dns 114.114.114.114 --rm busybox/ # cat /etc/resolv.confsearch localdomainnameserver 114.114.114.114/ # nslookup -type=a www.baidu.comServer:        114.114.114.114Address:    114.114.114.114:53Non-authoritative answer:www.baidu.com    canonical name = www.a.shifen.comName:    www.a.shifen.comAddress: 182.61.200.6Name:    www.a.shifen.comAddress: 182.61.200.7

手动往/etc/hosts文件中注入主机名到IP地址的映射

[root@localhost ~]# docker run -it --name t1 --network bridge --hostname ljl --add-host www.a.com:1.1.1.1 --rm busybox/ # cat /etc/hosts127.0.0.1    localhost::1    localhost ip6-localhost ip6-loopbackfe00::0    ip6-localnetff00::0    ip6-mcastprefixff02::1    ip6-allnodesff02::2    ip6-allrouters1.1.1.1    www.a.com172.17.0.3    ljl

凋谢容器端口

执行docker run的时候有个-p选项,能够将容器中的利用端口映射到宿主机中,从而实现让内部主机能够通过拜访宿主机的某端口来拜访容器内利用的目标。

-p选项可能应用屡次,其所可能裸露的端口必须是容器的确在监听的端口。

-p选项的应用格局:

  • -p containerPort
  • 将指定的容器端口映射至主机所有地址的一个动静端口
  • -p hostPort : containerPort
  • 将容器端口 containerPort 映射至指定的主机端口 hostPort
  • -p ip :: containerPort
  • 将指定的容器端口 containerPort 映射至主机指定 ip 的动静端口
  • -p ip : hostPort : containerPort
  • 将指定的容器端口 containerPort 映射至主机指定 ip 的端口 hostPort

动静端口指的是随机端口,具体的映射后果可应用docker port命令查看。

[root@localhost ~]# docker run -dit --name web1 -p 192.168.203.138::80 httpde97bc1774e40132659990090f0e98a308a7f83986610ca89037713e9af8a6b9f[root@localhost ~]# docker psCONTAINER ID   IMAGE     COMMAND              CREATED          STATUS          PORTS                           NAMESe97bc1774e40   httpd     "httpd-foreground"   6 seconds ago    Up 5 seconds    192.168.203.138:49153->80/tcp   web1af5ba32f990e   busybox   "sh"                 48 minutes ago   Up 48 minutes                                   b3[root@localhost ~]# ss -antlState    Recv-Q   Send-Q        Local Address:Port        Peer Address:Port   ProcessLISTEN   0        128         192.168.203.138:49153            0.0.0.0:*LISTEN   0        128                 0.0.0.0:22               0.0.0.0:*LISTEN   0        128                    [::]:22                  [::]:*

以上命令执行后会始终占用着前端,咱们新开一个终端连贯来看一下容器的80端口被映射到了宿主机的什么端口上

[root@localhost ~]# docker port web180/tcp -> 192.168.203.138:49153

由此可见,容器的80端口被裸露到了宿主机的49153端口上,此时咱们在宿主机上拜访一下这个端口看是否能拜访到容器内的站点

[root@localhost ~]# curl http://192.168.203.138:49153<html><body><h1>It works!</h1></body></html>

iptables防火墙规定将随容器的创立主动生成,随容器的删除主动删除规定。

[root@localhost ~]# iptables -t nat -nvLChain PREROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target     prot opt in     out     source               destination    3   164 DOCKER     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCALChain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target     prot opt in     out     source               destinationChain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target     prot opt in     out     source               destination    4   261 MASQUERADE  all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0    0     0 MASQUERADE  tcp  --  *      *       172.17.0.3           172.17.0.3           tcp dpt:80Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target     prot opt in     out     source               destination    2   120 DOCKER     all  --  *      *       0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCALChain DOCKER (2 references) pkts bytes target     prot opt in     out     source               destination    1    60 RETURN     all  --  docker0 *       0.0.0.0/0            0.0.0.0/0    1    60 DNAT       tcp  --  !docker0 *       0.0.0.0/0            192.168.203.138      tcp dpt:49153 to:172.17.0.3:80

将容器端口映射到指定IP的随机端口

[root@localhost ~]# docker run -dit --name web1 -p 192.168.203.138::80 httpd

在另一个终端上查看端口映射状况

[root@localhost ~]# docker port web180/tcp -> 192.168.203.138:49153

自定义docker0桥的网络属性信息

自定义docker0桥的网络属性信息须要批改/etc/docker/daemon.json配置文件

[root@localhost ~]# cd /etc/docker/[root@localhost docker]# vim daemon.json[root@localhost docker]# systemctl daemon-reload[root@localhost docker]# systemctl restart docker{    "registry-mirrors": ["https://4hygggbu.mirror.aliyuncs.com/"],    "bip": "192.168.1.5/24"}EOF
[root@localhost ~]# vim /lib/systemd/system/docker.serviceExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -H tcp://0.0.0.0:2375  -H unix:///var/run/docker.sock[root@localhost ~]# systemctl daemon-reload[root@localhost ~]# systemctl restart docker

在客户端上向dockerd间接传递“-H|--host”选项指定要管制哪台主机上的docker容器

[root@localhost ~]# docker -H 192.168.203.138:2375 psCONTAINER ID   IMAGE     COMMAND              CREATED             STATUS          PORTS                           NAMESe97bc1774e40   httpd     "httpd-foreground"   30 minutes ago      Up 11 seconds   192.168.203.138:49153->80/tcp   web1af5ba32f990e   busybox   "sh"                 About an hour ago   Up 14 seconds                                   b3

创立新网络

[root@localhost ~]# docker network create ljl -d bridge883eda50812bb214c04986ca110dbbcb7600eba8b033f2084cd4d750b0436e12[root@localhost ~]# docker network lsNETWORK ID     NAME      DRIVER    SCOPE0c5f4f114c27   bridge    bridge    local8c2d14f1fb82   host      host      local883eda50812b   ljl       bridge    local85ed12d38815   none      null      local

创立一个额定的自定义桥,区别于docker0

[root@localhost ~]# docker network create -d bridge --subnet "192.168.2.0/24" --gateway "192.168.2.1" br0af9ba80deb619de3167939ec5b6d6136a45dce90907695a5bc5ed4608d188b99[root@localhost ~]# docker network lsNETWORK ID     NAME      DRIVER    SCOPEaf9ba80deb61   br0       bridge    local0c5f4f114c27   bridge    bridge    local8c2d14f1fb82   host      host      local883eda50812b   ljl       bridge    local85ed12d38815   none      null      local

应用新创建的自定义桥来创立容器:

[root@localhost ~]# docker run -it --name b1 --network br0 busybox/ # ifconfigeth0      Link encap:Ethernet  HWaddr 02:42:C0:A8:02:02          inet addr:192.168.2.2  Bcast:192.168.2.255  Mask:255.255.255.0          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1          RX packets:11 errors:0 dropped:0 overruns:0 frame:0          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0          collisions:0 txqueuelen:0          RX bytes:962 (962.0 B)  TX bytes:0 (0.0 B)

再创立一个容器,应用默认的bridge桥:

[root@localhost ~]# docker run --name b2 -it busybox/ # lsbin   dev   etc   home  proc  root  sys   tmp   usr   var/ # ifconfigeth0      Link encap:Ethernet  HWaddr 02:42:C0:A8:01:03          inet addr:192.168.1.3  Bcast:192.168.1.255  Mask:255.255.255.0          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1          RX packets:6 errors:0 dropped:0 overruns:0 frame:0          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0          collisions:0 txqueuelen:0          RX bytes:516 (516.0 B)  TX bytes:0 (0.0 B)

近期热文举荐:

1.1,000+ 道 Java面试题及答案整顿(2022最新版)

2.劲爆!Java 协程要来了。。。

3.Spring Boot 2.x 教程,太全了!

4.别再写满屏的爆爆爆炸类了,试试装璜器模式,这才是优雅的形式!!

5.《Java开发手册(嵩山版)》最新公布,速速下载!

感觉不错,别忘了顺手点赞+转发哦!