文章目录

  • 前言
  • 一、docker原生网络
  • 二、docker自定义网络
  • docker通信
  • 跨主机容器网络
  • macvlan网络方案实现


前言

一、docker原生网络

可以用这个命令查看docker网络

[root@docker1 ~]# docker network ls
NETWORK ID     NAME            DRIVER    SCOPE
368a90ff7913   bridge          bridge    local       桥接网络
7f27e562ae29   harbor_harbor   bridge    local
f577e8e0ee5a   host            host      local       主机网络
1ce8cdcdca9e   none            null      local

可以用docker … prune命令关闭没有在使用的卷、容器、镜像

[root@docker1 harbor]# docker volume prune
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
dfe9905bc30fb2efe0b7a1dd95f345fb2022c17f11f16778a7e13339336fa33c
188825e84698767448da4d7b24c9de820a46e296d3eb45a11028caa03c451861
8f6338781702a9c92eeeb7cc91d0467c2003cc4bcfddddae722f265b0a8b89c0
c71c64704f5cd2c033bd903c4d2107ed297cb3dae1286fef8e7499cb7df674f1
bca118a8f52ce3f96c30177cbf5f105acecc22caaf737d8e4143e7df92f2f612
3c01140b1bb585ae8b4735b43b12d0c08804341c998a06a6bd7006b572ce8a97
c82838b08244a6433dc4989620449c00e4ea97423524c1ca2e91078ef2e77044
d9ca2b37727fd883dcca2e6a786009f79650c5db807c334bf433a6c1adb6eea5
1ee598c1fcde6e221bb0bb12e6342cd1b1a450a52d2fffb9c8288ef4120b87a4

Total reclaimed space: 84B

当我们运行一个容器时去查看它的docker网络,就可以看到它的docker网卡,如果我们命令中包含了–rm,那么我们就需要在另一个窗口来检测,不然退出就会呢自动销毁

[root@docker1 ~]# docker run -it --rm busybox
/ # ip addr
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
27: eth0@if28: <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 forever
[root@docker1 ~]# brctl show
bridge name	bridge id		STP enabled	interfaces
docker0		8000.02429048f8e8	no		veth375725b

上边的方式是以桥接的方式连接docker与宿主机,但是桥接模式存在许多不方便的地方,比如本机可以访问仓库但是其他主机不能访问,所以host网络就可以弥补这些缺陷,但是host网络又缺少了网络隔离性,也存在一定的问题
以下是以host网络的方式开启容器

[root@docker1 123721]# docker run -d --name vm2 --network host nginx
1125696765b51108f9d7df739d09956cc856997b7b66aedf7ac8d3ebaf8df058
[root@docker1 123721]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS     NAMES
1125696765b5   nginx     "/docker-entrypoint.…"   6 seconds ago   Up 6 seconds             vm2
b24f35bb6f6a   nginx     "/docker-entrypoint.…"   5 minutes ago   Up 5 minutes   80/tcp    vm1

none是指禁用网络功能,比如管理员在存储一些比较敏感或者重要的东西时,往往只是自己查询或者使用不需要别人通过网络访问,这个时候就需要禁用网络

[root@docker1 ~]# docker run -it --rm --network none busybox
/ # ip addr
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

二、docker自定义网络

docker通信

首先创建一个自定义网络,然后以自定义网络的方式运行一个容器

[root@docker1 ~]# docker network create mynet1
57dcfde27d592c396845fb977cf606e0a9d4a4db493194430600c7450737f847
[root@docker1 ~]# docker run -d --name web1 --network mynet1 nginx
69a401e6bbc9c887926a7babeb2a134e70cde31e0bee4bd778a8ab7732bdd3b5

使用自定义网络就可以直接通过名称来访问服务,更加便捷;因此我们一般部署应用服务时都会使用自定义网络

[root@docker1 ~]# docker run -it --rm --name vm3 --network mynet1 yakexi007/busyboxplus
/ # curl web1
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

我们在自定义网络的时候,它的网段和ip都是自动分配的,我们也可以对他们进行自定义,具体如下:

[root@docker1 ~]# docker network create --subnet 10.0.0.0/24 --gateway 10.0.0.1 mynet2
5492fe1b9f4de8831e1279ff9f6026fa061ad2c36b09aa63070c72224f8f2771

按照上边的方式做的好处就是我们可以在运行容器的时候自定义IP,可以支持更多的功能

[root@docker1 ~]# docker run -it --rm --name vm3 --network mynet2 --ip 10.0.0.10 yakexi007/busyboxplus
/ # ipaddr
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
45: eth0@if46: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:0a:00:00:0a brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.10/24 brd 10.0.0.255 scope global eth0
       valid_lft forever preferred_lft forever

但是由于在docker网络中网络是相互隔离的,所以我们要想能够相互访问就应该将其网络互连,也就相当于给其中一个网络添加一块网卡来让它们达到互联

[root@docker1 ~]# docker network connect mynet1 vm3
[root@docker1 ~]# docker attach vm3
/ # ipaddr 
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
49: eth0@if50: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:0a:00:00:0a brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.10/24 brd 10.0.0.255 scope global eth0
       valid_lft forever preferred_lft forever
51: eth1@if52: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:13:00:03 brd ff:ff:ff:ff:ff:ff
    inet 172.19.0.3/16 brd 172.19.255.255 scope global eth1
       valid_lft forever preferred_lft forever
/ # curl web1
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

我们也可以通过与其他容器共享网络的方式来达到通信的目的,但是这样两个容器就不同暴露相同的端口,以防冲突

[root@docker1 ~]# docker run -it --name vm1 --network container:web1 yakexi007/busyboxplus
/ # ip addr
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
40: eth0@if41: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:13:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.19.0.2/16 brd 172.19.255.255 scope global eth0
       valid_lft forever preferred_lft forever
/ # curl localhost

那么我们的docker网络又是如何访问外网的呢,首先不论是自定义网络还是其他,都先连接到docker0上,然后由docker0连接到外部net,所以我们要做一个端口映射

[root@docker1 ~]# docker run -d --name web1 -p 80:80 nginx
f2c8a9a680a0077bed02482a5c4c3e8340f679faece8c85a42bd2bc9fd166343
[root@docker1 ~]# netstat -antlp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      126946/docker-proxy 
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      7204/sshd           
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      7319/master         
tcp        0      0 192.168.1.51:22         192.168.1.225:58608     ESTABLISHED 8452/sshd: root@pts 
tcp        0      0 192.168.1.51:22         192.168.1.225:54214     ESTABLISHED 123401/sshd: root@p 
tcp6       0      0 :::80                   :::*                    LISTEN      126951/docker-proxy 
tcp6       0      0 :::22                   :::*                    LISTEN      7204/sshd           
tcp6       0      0 ::1:25                  :::*                    LISTEN      7319/master
[root@docker1 ~]# iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
DOCKER     all  --  0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
DOCKER     all  --  0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCAL

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
MASQUERADE  all  --  10.0.0.0/24          0.0.0.0/0           
MASQUERADE  all  --  172.19.0.0/16        0.0.0.0/0           
MASQUERADE  all  --  172.17.0.0/16        0.0.0.0/0           
MASQUERADE  tcp  --  172.17.0.2           172.17.0.2           tcp dpt:80

Chain DOCKER (2 references)
target     prot opt source               destination         
RETURN     all  --  0.0.0.0/0            0.0.0.0/0           
RETURN     all  --  0.0.0.0/0            0.0.0.0/0           
RETURN     all  --  0.0.0.0/0            0.0.0.0/0           
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            **tcp dpt:80 to:172.17.0.2:80**
我们可以看到这里直接将80端口映射到docker容器的80端口

双冗余机制保证一方失效,通信不会中断

列出docker网络列表的命令 docker列出当前主机所有网络_运维

跨主机容器网络

列出docker网络列表的命令 docker列出当前主机所有网络_运维_02

macvlan网络方案实现

它是Linux内核提供的一种网卡虚拟化技术,不需要桥接,直接使用物理接口,性能更好,首先我们要在两个主机上都打开网卡混杂模式

[root@docker2 ~]# docker network create -d macvlan --subnet 10.0.0.0/24 --gateway 10.0.0.1 -o parent=ens33.1 macvlan1
ccaca9c84164b5ffb334a77ad861cf3f4202e3b5cf6e63bb9f5a8d8398965ad9
[root@docker2 ~]# docker network ls
NETWORK ID     NAME       DRIVER    SCOPE
94ca87616a04   bridge     bridge    local
ee354a2dcbdb   host       host      local
ccaca9c84164   macvlan1   macvlan   local
9e0876543baa   none       null      local

我们可以看到ens33这块网卡的混杂模式已经打开(PROMISC)

2: ens33: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:e8:f8:7e brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.52/24 brd 192.168.1.255 scope global ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fee8:f87e/64 scope link 
       valid_lft forever preferred_lft forever

我们在运行容器的时候出现了这个警告,那么我们就需要修改下面这个文件,将ipv4网络able,然后重启网络和docker服务,就不会出现警告

[root@docker2 sysctl.d]# docker run -it --rm --name vm1 --network macvlan1 yakexi007/busyboxplus
WARNING: IPv4 forwarding is disabled. Networking will not work.
[root@docker2 sysctl.d]# cat /usr/lib/sysctl.d/00-system.conf
# Kernel sysctl configuration file
#
# For binary values, 0 is disabled, 1 is enabled.  See sysctl(8) and
# sysctl.conf(5) for more details.

# Disable netfilter on bridges.
net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0
net.bridge.bridge-nf-call-arptables = 0
net.ipv4.ip_forward=1

在我们使用macvlan网络的时候尽量对ip进行手动分配,因为自动分配可能会造成冲突

[root@docker2 sysctl.d]# docker run -it --rm --name vm1 --network macvlan1 --ip 10.0.0.12 yakexi007/busyboxplus
/ # ip addr
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
10: eth0@if6: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:0a:00:00:0c brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.12/24 brd 10.0.0.255 scope global eth0
       valid_lft forever preferred_lft forever

列出docker网络列表的命令 docker列出当前主机所有网络_运维_03