文档中使用的镜像不同,自行选择镜像
Docker提供了映射容器端口到宿主机和容器互联机制来为容器提供网络服务。
Docker网络从覆盖范围可分为单个host上的容器和跨多个host的网络
DOcker的原生网络
[root@docker ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 33fbe0ebf28f bridge bridge local e34526880b84 host host local bf23eec1f232 none null local指定网络的语法:
--network | none | host |自定义网络 |none 网络就是什么都没有的网络。挂在这个网络下的容器除了 lo,没有其他任何网卡。 当你用到None网络的容器,会发现他只有一个Loopback回环的网络,没有Mac地址、IP等信息,意味着他不能跟外界通信,是被隔离起来的网络,容器创建时,可以通过 --network=none 指定使用 none 网络
[root@docker ~]# docker run -itd --name none --network none busybox:latest e1778e6f353b70f153046f8bc4635d63518ef47beacb087a1604cb8bf423d8ec [root@docker ~]# docker exec -it none /bin/sh / # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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 foreverNone网络的使用场景:
封闭意味着隔离,一些对安全性要求高并且不需要联网的应用可以使用 none 网络。比如某个容器的唯一用途是生成随机密码,就可以放到 none 网络中避免密码被窃取。当然大部分容器是需要网络的 ,嘿嘿嘿!!
Host网络是在启动容器的时候使用 host 模式,那么这个容器将不会获得一个独立的Network Namespace ,而是和宿主机共用一个 Network Namespace。容器将不会虚拟出自己的网卡,配置自己的 IP 等,而是使用宿主机的 IP 和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。
[root@docker ~]# docker run -itd --name host --network host busybox:latest cc1f2488f734e1350be60982e710aa46694f690b189dfd54041bd2b74d3be436 [root@docker ~]# docker exec -it host /bin/sh / # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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 forever 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000 link/ether 00:0c:29:1b:88:f6 brd ff:ff:ff:ff:ff:ff inet 192.168.1.40/24 brd 192.168.1.255 scope global ens33 valid_lft forever preferred_lft forever inet6 fe80::84f5:b792:ed69:b569/64 scope link valid_lft forever preferred_lft forever 3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue qlen 1000 link/ether 52:54:00:70:12:c0 brd ff:ff:ff:ff:ff:ff inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0 valid_lft forever preferred_lft forever 4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 qlen 1000 link/ether 52:54:00:70:12:c0 brd ff:ff:ff:ff:ff:ff 5: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue link/ether 02:42:3f:4b:f1:13 brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 valid_lft forever preferred_lft foreverHost网络的使用场景:
直接使用 Docker host 的网络最大的好处就是性能,如果容器对网络传输效率有较高要求,则可以选择 host 网络。当然不便之处就是牺牲一些灵活性,比如要考虑端口冲突问题,Docker host 上已经使用的端口就不能再用了
bridge 模式是 docker 的默认网络模式,不写–net 参数,就是 bridge 模式。使用 docker run -p 时,docker 实际是在 iptables 做了 DNAT 规则,实现端口转发功能。可以使用 iptables -t nat -vnL 查看。
[root@docker ~]# iptables -t nat -vnL Chain PREROUTING (policy ACCEPT 5 packets, 497 bytes) pkts bytes target prot opt in out source destination 0 0 DOCKER all -- * * 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL Chain INPUT (policy ACCEPT 5 packets, 497 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 87 packets, 6774 bytes) pkts bytes target prot opt in out source destination 0 0 DOCKER all -- * * 0.0.0.0/0 !127.0.0.0/8 ADDRTYPE match dst-type LOCAL Chain POSTROUTING (policy ACCEPT 87 packets, 6774 bytes) pkts bytes target prot opt in out source destination 0 0 MASQUERADE all -- * !docker0 172.17.0.0/16 0.0.0.0/0 2 269 RETURN all -- * * 192.168.122.0/24 224.0.0.0/24 0 0 RETURN all -- * * 192.168.122.0/24 255.255.255.255 0 0 MASQUERADE tcp -- * * 192.168.122.0/24 !192.168.122.0/24 masq ports: 1024-65535 0 0 MASQUERADE udp -- * * 192.168.122.0/24 !192.168.122.0/24 masq ports: 1024-65535 0 0 MASQUERADE all -- * * 192.168.122.0/24 !192.168.122.0/24 Chain DOCKER (2 references) pkts bytes target prot opt in out source destination 0 0 RETURN all -- docker0 * 0.0.0.0/0 0.0.0.0/0docker0: 在我们安装docker这个服务的时候,默认就会生产一张docker0的网卡,一般默认IP为172.17.0.1/16. docker0此时相当于一个路由器,基于此网络的容器,网段都是和docker0一致的。
[root@docker ~]# docker run -itd --name test1 busybox:latest 60182b2680599ee0a6a673f6421c0ce2d21579db3149ef5612961bdfc20eafb7 [root@docker ~]# docker exec -it test1 /bin/sh / # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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 6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 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 foreverPS:自定义网络的优点是执行ping命令,可以通过容器的名称通信。
[root@docker ~]# docker run -itd --name test3 --network my_net1 busybox:latest fb520b6dcc8c5c9dd5ed9f1aaa6688371c11729ea0b2ec73402853bad5722d61 [root@docker ~]# docker run -itd --name test4 --network my_net1 busybox:latest b062d61731633a891fa793f318df39a34da71f2a7851852eacb68f831e7b00ca [root@docker ~]# docker exec -it test3 /bin/sh / # ping test4 PING test4 (172.18.0.3): 56 data bytes 64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.073 ms 64 bytes from 172.18.0.3: seq=1 ttl=64 time=0.066 ms 64 bytes from 172.18.0.3: seq=2 ttl=64 time=0.073 ms ^C --- test4 ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max = 0.066/0.070/0.073 ms自己定义网络,指定网关和网段
[root@docker ~]# docker network create -d bridge --subnet 192.168.2.0/24 --gateway 192.168.2.1 my_net2 90dc980ea9f6e34aa781d37f887b70810f729190c7b4469359cb658b5fa40245 [root@docker ~]# docker run -itd --name testA --network my_net2 --ip 192.168.2.2 busybox:latest dafa42495452649013ae8f879a83928eb61f92c3a58807e710bd06519770133d [root@docker ~]# docker run -itd --name testB --network my_net2 --ip 192.168.2.3 busybox:latest 1d4dc0c1ef87adc8728a91c01c1b7a97ce05a7d9bc2a76e379dd4dadaf5e86e5 [root@docker ~]# docker exec testA -it /bin/sh OCI runtime exec failed: exec failed: container_linux.go:349: starting container process caused "exec: \"-it\": executable file not found in $PATH": unknown [root@docker ~]# docker exec -it testA /bin/sh / # ping testB PING testB (192.168.2.3): 56 data bytes 64 bytes from 192.168.2.3: seq=0 ttl=64 time=0.070 ms 64 bytes from 192.168.2.3: seq=1 ttl=64 time=0.064 ms 64 bytes from 192.168.2.3: seq=2 ttl=64 time=0.072 ms ^C --- testB ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max = 0.064/0.068/0.072 ms之上创建的容器是:
test1和test2是docker0的桥接网络 网段: 172.17.0.0test3和test4是my_net1网络 网段: 172.18.0.0testA和testB是my_net2网络 网段:192.168.2.0 [root@docker ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 1d4dc0c1ef87 busybox:latest "sh" 6 minutes ago Up 6 minutes testB dafa42495452 busybox:latest "sh" 6 minutes ago Up 6 minutes testA b062d6173163 busybox:latest "sh" 11 minutes ago Up 11 minutes test4 fb520b6dcc8c busybox:latest "sh" 11 minutes ago Up 11 minutes test3 f834b2841d5b busybox:latest "sh" 2 seconds ago Up 1 second test2 60182b268059 busybox:latest "sh" 19 minutes ago Up 19 minutes test1查看容器Ip的命令
[root@docker ~]# docker inspect test3 | grep IPAddress "SecondaryIPAddresses": null, "IPAddress": "", "IPAddress": "172.18.0.2",查看网段的命令:
[root@docker ~]# docker network inspect my_net1 [ { "Name": "my_net1", "Id": "0adeb3f0a070d2225455e0c7c8b26d8fcbd6c3baa74b247e9a5ae82cb1ccd023", "Created": "2020-09-04T11:39:59.297034202+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.18.0.0/16", "Gateway": "172.18.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "b062d61731633a891fa793f318df39a34da71f2a7851852eacb68f831e7b00ca": { "Name": "test4", "EndpointID": "4afcb187b65e1405343f2a17f2ea196ee329e6a52a41e657923c78f707c40517", "MacAddress": "02:42:ac:12:00:03", "IPv4Address": "172.18.0.3/16", "IPv6Address": "" }, "f834b2841d5bdb96332049455468f24584ee11aeb261944aaa0947f707ae4b3f": { "Name": "test2", "EndpointID": "20bd2e092dfeadd0d730a6c9cb32b362f6f1bb754d1ac936cbceb90ba59a5610", "MacAddress": "02:42:ac:12:00:04", "IPv4Address": "172.18.0.4/16", "IPv6Address": "" }, "fb520b6dcc8c5c9dd5ed9f1aaa6688371c11729ea0b2ec73402853bad5722d61": { "Name": "test3", "EndpointID": "1afad173503592755035d8c5a8d7474d9cc6fa79ac9db64558d8e7f88469b04a", "MacAddress": "02:42:ac:12:00:02", "IPv4Address": "172.18.0.2/16", "IPv6Address": "" } }, "Options": {}, "Labels": {} } ]问题:
test2能ping的通 my_net1网关,但ping不通test3和test4,同理,test4能ping的通my_net2,但ping不通test5和test6。这是因为iptabeles防火墙规则导致的,但不允许为了实现这个功能对防火墙进行操作,因为涉及安全,须谨慎,所以,我们采用给容器添加网卡的方法。
PS:给test2容器内新添加一块网卡,并且让它获取my_net1的网段。
[root@docker ~]# docker network connect my_net1 test2 [root@docker ~]# docker exec -it test2 /bin/sh / # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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 22: eth0@if23: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever 24: eth1@if25: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue link/ether 02:42:ac:12:00:04 brd ff:ff:ff:ff:ff:ff inet 172.18.0.4/16 brd 172.18.255.255 scope global eth1 valid_lft forever preferred_lft forever / # ping test3 PING test3 (172.18.0.2): 56 data bytes 64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.072 ms 64 bytes from 172.18.0.2: seq=1 ttl=64 time=0.075 ms ^C --- test3 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.072/0.073/0.075 msPS:为了安全而考虑,在网卡不同之间需要访问,可以使用这种方法。
container是共享网络协议栈,容器和容器之间共享
这个模式指定新创建的容器和已经存在的一个容器共享一个 NetworkNamespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信。 语法:
--network container:共享的容器名 [root@docker ~]# docker run -itd --name web1 busybox:latest d952d665a823c1e055d0abae532e3c2ea6ef19348016063de1ef5fcd779fdbb8 [root@docker ~]# docker run -itd --name web2 --network container:web1 busybox:latest 77ca29f22519e3516c40a4752927a3cb379cf884dc89c25864e258a043ffee1f [root@docker ~]# docker exec -it web1 /bin/sh / # echo 123123123 > /tmp/index.html / # httpd -h /tmp/ / # exit [root@docker ~]# docker exec -it web2 /bin/sh / # wget -O - -q 127.0.0.1 #O是大写O 123123123PS:wget -O - -q 127.0.0.1 #O是大写O
Join容器的使用场景:
由于这种网络的特殊性,一般在运行同一个服务,并且合格服务需要 做监控,已经日志收集、或者网络监控的时候,可以选择这种网络。
容器启动后,如果不知道对应的端口,容器外是无法通过网络来访问容器内的服务的。Docker提供端口映射机制来将容器内的服务提供给外部网络访问,实质上就是将宿主机的端口映射到容器中,使得外部网络访问宿主机的端口可访问容器内的服务。
实现端口映射的参数:
-P:随机指定一个端口范围在49000-49900,但不是绝对的,也有例外情况不会映射到这个范围(大写P)-p:指定要映射的端口(小写p)首先 这个httpd:1.10镜像必须是 拥有nginx或者apache的一个服务
手动指定端口映射关系
[root@docker ~]# docker run -d --name nginx2 -p 90:80 httpd:1.10 ce9c18b17d4fc026186526d0d111fc7a8ffab99c6143b3354e14c6efc520d765从宿主机随机映射端口到容器
[root@docker ~]# docker run -d --name nginx3 -p 80 httpd:1.10 27495ba4bd10161410414947191a33459924ddbee7adc8d9ff036fca29e551ed每一个映射的端口,host 都会启动一个 docker-proxy 进程来处理访问容器的流量
[root@docker ~]# ps -ef | grep docker-proxy root 7215 2214 0 12:13 ? 00:00:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 80 -container-ip 172.17.0.6 -container-port 80 root 7298 2214 0 12:13 ? 00:00:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 32768 -container-ip 172.17.0.7 -container-port 80 root 7416 2214 0 12:15 ? 00:00:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 90 -container-ip 172.17.0.8 -container-port 80容器互联是通过容器的名称在容器间建立—条专门的网络通信隧道从而实现的互联。
语法:
--link name : alias其中name是要链接的容器名称,alias是这个链接的别名。
–link指定链接容器已实现容器互联
[root@docker ~]# docker run -itd --name Bs --link As:As docker.io/centos e70de2e4d7945c6d431982306d45f3352f945726af9b5d78c666059c172fb22a此时,可以看到As和Bs已经建立互联关系,这时Docker在两个容器之间创建了一条安全隧道,而且不用映射他们的端口到宿主机上,从而避免了暴露端口到外部网络。
为支持容器跨主机通信,Docker 提供了 overlay driver,使用户可以创建基于 VxLAN 的 overlay 网络。VxLAN 可将二层数据封装到 UDP 进行传输,VxLAN 提供与 VLAN 相同的以太网二层服务,但是拥有更强的扩展性和灵活性。Docerk overlay 网络需要一个 key-value 数据库用于保存网络状态信息,包括 Network、Endpoint、IP 等。Consul、Etcd 和 ZooKeeper 都是Docker 支持的 key-vlaue 软件,我们这里使用 Consul
实验环境:
环境限制:
必须按照key-value存储服务,如consul宿主机已经安装docker engine宿主机的hostname必须不同环境:
主机IP主机名192.168.1.40docker01192.168.1.41docker02关闭每一台服务器的防火墙和SELinux,更改主机名。
docker01配置
[root@docker1 ~]# docker pull progrium/consul Using default tag: latest latest: Pulling from progrium/consul c862d82a67a2: Pulling fs layer 0e7f3c08384e: Pulling fs layer 0e221e32327a: Pull complete 09a952464e47: Pull complete 60a1b927414d: Pull complete 4c9f46b5ccce: Pull complete 417d86672aa4: Pull complete b0d47ad24447: Pull complete fd5300bd53f0: Pull complete a3ed95caeb02: Pull complete d023b445076e: Pull complete ba8851f89e33: Pull complete 5d1cefca2a28: Pull complete Digest: sha256:8cc8023462905929df9a79ff67ee435a36848ce7a10f18d6d0faba9306b97274 Status: Downloaded newer image for progrium/consul:latest [root@docker1 ~]# docker run -d -p 8500:8500 -h consul --name consul --restart always progrium/consul -server -bootstrap f3e221286d9d755d8caf8b9275ab720f1230ed62465f63ee7d67e57075fda30d [root@docker1 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f3e221286d9d progrium/consul "/bin/start -server …" 3 seconds ago Up 2 seconds 53/tcp, 53/udp, 8300-8302/tcp, 8400/tcp, 8301-8302/udp, 0.0.0.0:8500->8500/tcp consul容器运行之后,我们通过访问consul服务,验证consul服务是否正常
http://192.168.1.40:8500/ui/#/dc1/services docker2配置
这一步操作docker01和docker02配置一样
[root@docker1 ~]# vim /usr/lib/systemd/system/docker.service 修改添加 ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2376 --cluster-store=consul://192.168.1.40:8500 --cluster-advertise=ens33:2376 [root@docker1 ~]# systemctl daemon-reload [root@docker1 ~]# systemctl restart docker然后返回浏览器consul服务界面,找到KEY/VALUE----> DOCKER---->NODES,会看到刚刚加入的docker02的信息
案例
实现docker1和docker2通信
docker1
[root@docker1 ~]# docker pull busybox Using default tag: latest latest: Pulling from library/busybox 9c075fe2c773: Pull complete Digest: sha256:c3dbcbbf6261c620d133312aee9e858b45e1b686efbcead7b34d9aae58a37378 Status: Downloaded newer image for busybox:latest #定义一个自定义网格 [root@docker1 ~]# docker network create -d overlay ov_net1 3d6710de1265cde9bc040ae472869335beff8d91677eb9372dd823870992db4e [root@docker1 ~]# docker run -it --name web1 --network ov_net1 busybox:latest / # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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 12: eth0@if13: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1450 qdisc noqueue link/ether 02:42:0a:00:00:02 brd ff:ff:ff:ff:ff:ff inet 10.0.0.2/24 brd 10.0.0.255 scope global eth0 valid_lft forever preferred_lft forever 15: eth1@if16: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff inet 172.18.0.2/16 brd 172.18.255.255 scope global eth1 valid_lft forever preferred_lft foreverdocker2
[root@docker2 ~]# docker pull busybox Using default tag: latest latest: Pulling from library/busybox 9c075fe2c773: Pull complete Digest: sha256:c3dbcbbf6261c620d133312aee9e858b45e1b686efbcead7b34d9aae58a37378 Status: Downloaded newer image for busybox:latest [root@docker2 ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 200f160f51b7 bridge bridge local a434051856e2 host host local 15048de267b2 none null local 3d6710de1265 ov_net1 overlay global [root@docker2 ~]# docker run -it --name web2 --network ov_net1 busybox:latest / # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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 8: eth0@if9: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1450 qdisc noqueue link/ether 02:42:0a:00:00:03 brd ff:ff:ff:ff:ff:ff inet 10.0.0.3/24 brd 10.0.0.255 scope global eth0 valid_lft forever preferred_lft forever 11: eth1@if12: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff inet 172.18.0.2/16 brd 172.18.255.255 scope global eth1 valid_lft forever preferred_lft forever / # ping web1 PING web1 (10.0.0.2): 56 data bytes 64 bytes from 10.0.0.2: seq=0 ttl=64 time=0.854 ms 64 bytes from 10.0.0.2: seq=1 ttl=64 time=0.545 ms 64 bytes from 10.0.0.2: seq=2 ttl=64 time=0.520 ms 64 bytes from 10.0.0.2: seq=3 ttl=64 time=0.541 ms ^C --- web1 ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.520/0.615/0.854 msmacvlan 本身是 Linux kernel 模块,其功能是允许在同一个物理网卡上配置多个 MAC 地址,即多个 interface,每个 interface 可以配置自己的 IP。macvlan 本质上是一种网卡虚拟化技术,Docker 用 macvlan 实现容器网络就不奇怪了。macvlan 的最大优点是性能极好,相比其他实现,macvlan 不需要创建Linux bridge,而是直接通过以太 interface 连接到物理网络
环境:
主机IP主机名192.168.1.40docker1192.168.1.41docker2关闭每一台防火墙和SELinux更改主机名
【1】打开网卡的混杂模式
docker1和docker2都进行操作
[root@docker1 ~]# ip link set ens33 promisc on [root@docker1 ~]# ip link show ens33 2: ens33: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000 link/ether 00:0c:29:1b:88:f6 brd ff:ff:ff:ff:ff:ff【2】创建MacVlan网络
[root@docker ~]# docker network create -d macvlan --subnet 172.22.16.0/24 --gateway 172.22.16.1 -o parent=ens33 mac_net1 ccb52f7b8147feb56a0251115fc0b369fe518dd91799499b7c22007e9d5d150fPS: -o parent=绑定在哪张网卡之上
【3】创建基于的MacVlan网络运行一个容器
[root@docker ~]# docker run -itd --name AA --ip 172.22.16.10 --network mac_net1 busybox:latest b62c4b1e38d82c30d296857098b3445a7057c85575ab6e6e00afab272f2cf47a【4】在docker02上创建macvlan网络,注意与docker01上的macvlan网络一模一样,并创建容器通信
[root@docker2 ~]# docker network create -d macvlan --subnet 172.22.16.0/24 --gateway 172.22.16.1 -o parent=ens33 mac_net1 f82483152a0873af4f8df49bda18ae2347bfca08829d222538d797db2bcbe55b [root@localhost ~]# docker run -it --name BB --network mac_net1 --ip 172.22.16.20 busybox:latest / # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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 13: eth0@if2: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue link/ether 02:42:ac:16:10:14 brd ff:ff:ff:ff:ff:ff inet 172.22.16.20/24 brd 172.22.16.255 scope global eth0 valid_lft forever preferred_lft forever / # ping 172.22.16.10 PING 172.22.16.10 (172.22.16.10): 56 data bytes 64 bytes from 172.22.16.10: seq=0 ttl=64 time=0.591 ms 64 bytes from 172.22.16.10: seq=1 ttl=64 time=0.419 ms 64 bytes from 172.22.16.10: seq=2 ttl=64 time=0.364 ms ^C --- 172.22.16.10 ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max = 0.364/0.458/0.591 msDocker1配置
【1】验证内核模块8021q封装
docker1和docker2都进行操作
[root@docker ~]# modinfo 8021q filename: /lib/modules/3.10.0-1127.el7.x86_64/kernel/net/8021q/8021q.ko.xz version: 1.8 license: GPL alias: rtnl-link-vlan retpoline: Y rhelversion: 7.8 srcversion: 1DD872AF3C7FF7FFD5B14D5 depends: mrp,garp intree: Y vermagic: 3.10.0-1127.el7.x86_64 SMP mod_unload modversions signer: CentOS Linux kernel signing key sig_key: 69:0E:8A:48:2F:E7:6B:FB:F2:31:D8:60:F0:C6:62:D8:F1:17:3D:57 sig_hashalgo: sha256 #如果内核模块没有开启,运行下面这条命令导入一下 [root@docker ~]# modprobe 8021q【2】基于ens33创建虚拟网卡
#修改ens33网卡配置文件 [root@docker ~]# cd /etc/sysconfig/network-scripts/ [root@docker network-scripts]# vim ifcfg-ens33 ...... BOOTPROTO="manual" ...... #添加虚拟网卡 [root@docker network-scripts]# cp -p ifcfg-ens33 ifcfg-ens33.10 # -p 保留源文件或目录的属性 [root@docker network-scripts]# vim ifcfg-ens33.10 BOOTPROTO=manual NAME=ens33.10 DEVICE=ens33.10 ONBOOT=yes IPADDR=192.168.10.10 PREFIX=24 GATEWAY=192.168.10.2 VLAN=yes PS:这里注意,IP要和ens33网段做一个区分,保证网关和网段IP的一致性,设备名称和配置文件的一致性,并且打开VLAN支持模式。 #添加第二个虚拟网卡 [root@docker network-scripts]# cp ifcfg-ens33.10 ifcfg-ens33.20 [root@docker network-scripts]# vim ifcfg-ens33.20 BOOTPROTO=manual NAME=ens33.20 DEVICE=ens33.20 ONBOOT=yes IPADDR=192.168.20.20 PREFIX=24 GATEWAY=192.168.20.2 VLAN=yes #启用虚拟网卡 [root@docker network-scripts]# ifup ifcfg-ens33.10 [root@docker network-scripts]# ifup ifcfg-ens33.20 [root@docker network-scripts]# systemctl restart network【3】基于虚拟网卡,创建MacVlan网络
[root@docker ~]# docker network create -d macvlan --subnet 172.16.10.0/24 --gateway 172.16.10.1 -o parent=ens33.10 mac_net10 90b339c5b06963917503ec2076f77643c9785b3e50bceb673c153446c1abc741 [root@docker ~]# docker network create -d macvlan --subnet 172.16.20.0/24 --gateway 172.16.20.1 -o parent=ens33.20 mac_net20 d211fe08b1e59a4ebcd78439e93484595c7a543655dd3b05e37bfd7eab6fcfef【4】基于创建的MacVlan网络,运行对应的容器
PS:运行容器与网络对应的网段相符合,IP不可一样。
[root@docker ~]# docker run -itd --name test1 --network mac_net10 --ip 172.16.10.10 busybox:latest b5ae044d34fa3cb48a29a4f72a3b1673813275077cb976c57b3b501352cce777 [root@docker ~]# docker run -itd --name test2 --network mac_net20 --ip 172.16.20.20 busybox:latest 90ef2b7174ae54d737188d797f7cbc3e1a76d25364abc14302887fbd60d7c99fDocker2配置
PS:步骤1和步骤2 跟docker1一样,修改网卡的时候 注意IP的唯一性。
【1】创建虚拟网卡
#修改ens33网卡配置文件 [root@docker ~]# cd /etc/sysconfig/network-scripts/ [root@docker ~]# scp -p /etc/sysconfig/network-scripts/ifcfg-ens33.* 192.168.1.41:/etc/sysconfig/network-scripts/ [root@docker2 network-scripts]# vim ifcfg-ens33.10 BOOTPROTO=manual NAME=ens33.10 DEVICE=ens33.10 ONBOOT=yes IPADDR=192.168.10.11 PREFIX=24 GATEWAY=192.168.10.2 VLAN=yes [root@docker2 network-scripts]#vim ifcfg-ens33.20 BOOTPROTO=manual NAME=ens33.20 DEVICE=ens33.20 ONBOOT=yes IPADDR=192.168.20.21 PREFIX=24 GATEWAY=192.168.20.2 VLAN=yes [root@docker2 network-scripts]# ifup ifcfg-ens33.10 [root@docker2 network-scripts]# ifup ifcfg-ens33.20 [root@docker2 network-scripts]# systemctl restart network【2】基于虚拟网卡,创建MacVlan网络
[root@localhost ~]# docker network create -d macvlan --subnet 172.16.10.0/24 --gateway 172.16.10.1 -o parent=ens33.10 mac_net10 9ff022430b00525aefc968c2cef803358982300ff231c4fa300a171e1f021088 [root@localhost ~]# docker network create -d macvlan --subnet 172.16.20.0/24 --gateway 172.16.20.1 -o parent=ens33.20 mac_net20 7567dda0a781b2a0cd81b7574cec966ac787ed818fb99ac09295e3e5bf642d6b【3】基于创建的MacVlan网络,运行对应的容器
[root@localhost ~]# docker run -itd --name test3 --network mac_net10 --ip 172.16.10.11 busybox:latest 1a5a012b57dac2cc42425952020cbd047797a7240d0987c65fde1d6b9831f224 [root@localhost ~]# docker run -itd --name test4 --network mac_net20 --ip 172.16.20.21 busybox:latest ec1dbd2996f2cf8d3808b65fd87f82a2aefcd364d19e35f05cf15db70af315c7验证:
[root@docker1 ~]# docker exec -it test1 sh / # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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 29: eth0@if27: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue link/ether 02:42:ac:10:0a:0a brd ff:ff:ff:ff:ff:ff inet 172.16.10.10/24 brd 172.16.10.255 scope global eth0 valid_lft forever preferred_lft forever / # ping 172.16.10.11 PING 172.16.10.11 (172.16.10.11): 56 data bytes 64 bytes from 172.16.10.11: seq=0 ttl=64 time=0.376 ms 64 bytes from 172.16.10.11: seq=1 ttl=64 time=0.274 ms 64 bytes from 172.16.10.11: seq=2 ttl=64 time=0.360 ms ^C --- 172.16.10.11 ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max = 0.274/0.336/0.376 ms / # exit [root@docker1 ~]# docker exec -it test2 sh / # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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 30: eth0@if28: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue link/ether 02:42:ac:10:14:14 brd ff:ff:ff:ff:ff:ff inet 172.16.20.20/24 brd 172.16.20.255 scope global eth0 valid_lft forever preferred_lft forever / # ping 172.16.20.21 PING 172.16.20.21 (172.16.20.21): 56 data bytes 64 bytes from 172.16.20.21: seq=0 ttl=64 time=0.725 ms ^C --- 172.16.20.21 ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 0.725/0.725/0.725 ms
