docker基本管理三:网络管理

1.docker 的网络原理

无论是Windows 还是 Linux中,当docker 安装完成后,docker 都会在宿主机中创建一个虚拟网桥,通过该网桥实现容器之间的以及容器和外部网络的连接。通常情况下虚拟网桥的名称为docker0.例如在Linux 系统中网桥信息如下:

  [root@localhost mnt]# ip a
1: 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 forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:a2:be:5a brd ff:ff:ff:ff:ff:ff
    inet 192.168.124.12/24 brd 192.168.124.255 scope global noprefixroute dynamic ens33
       valid_lft 1186sec preferred_lft 1186sec
    inet6 fe80::d635:15c0:d0e6:6ac1/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:e7:0d:b5:60 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 forever
    inet6 fe80::42:e7ff:fe0d:b560/64 scope link 
       valid_lft forever preferred_lft forever

上边输出中 编号为3的网络接口docker 0 是docker 所创建的虚拟网桥。
在OSI七层模型中,网桥工作在数据链路层。网桥是早期的两端口二层网络设备,用来连接不同的网段。网桥就像一个中继器,从一根网络电缆中接收信号,放大他们,再将其送入下一根电缆。网桥将网络中的多个网段在数据链路层连接起来。
在dicker中,各个容器是通过docker0 实现互联的,该虚拟网桥可以设置IP地址,相当于一个隐藏的虚拟网卡。
docker 守护进程在一个容器启动时,实际上他要创建网络连接的两端。一端是在容器中的网络设备,而另一端是在运行docker守护进程的主机上打开一个veth*的一个接口,用来实现docker0 这个网桥与容器的网络通信
我们使用 brctl 命令可以查看虚拟网桥docker 的信息

[root@localhost mnt]# brctl show
bridge name	bridge id		STP enabled	interfaces
docker0		8000.0242e70db560	no		vethf099af6

这个名为 vethf099af6 的接口是属于已经创建的容器的虚拟网络接口

2.网络模式

目前docker 支持四种网络模式,网络模式可以在创建容器时使用 --network参数来指定。这四种模式分别为: host、container、none 以及 bridge。下面详细对这四种网络模式进行介绍

a. host模式

docker使用了Linux的命名空间进行来进行资源隔离,如PID命名空间隔离进程,mount命名空间隔离文件系统,network命名空间隔离网络等。一个network 命名空间提供了一份独立的网络环境,包括网卡、路由、iptables 规则等都与其他的network命名空间隔离。一个docker 容器一般会分配一个独立的network命名空间。但是如果启动容器的时候使用的是 host模式,那么这个容器将不会获得一个独立的network命名空间,而是和宿主机共用一个network 命名空间。容器将不会虚拟出自己的网卡,配置自己的IP地址等,而是使用宿主机的IP和端口。
例如 :

  [root@localhost mnt]# docker run -itd --network=host couchbase/centos7-systemd 
273086c656565df6d912ead305b9d798fb86956c8d43ea06ae399742b3b49dde
[root@localhost ~]# docker exec 273086c65656  ip a  show
1: 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 forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:a2:be:5a brd ff:ff:ff:ff:ff:ff
    inet 192.168.124.12/24 brd 192.168.124.255 scope global noprefixroute dynamic ens33
       valid_lft 1537sec preferred_lft 1537sec
    inet6 fe80::d635:15c0:d0e6:6ac1/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:e7:0d:b5:60 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 forever
    inet6 fe80::42:e7ff:fe0d:b560/64 scope link 
       valid_lft forever preferred_lft forever

从输出结果上看,实际上容器的这些网络信息正是主机的网络信息。

b. container模式(容器模式)

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

c.none模式(无模式)

这个模式和前两者不同。这这个模式下,docker容器拥有自己的network 命名空间,但是并不为docker容器进行任何的网络配置。也就是说,这个docker 容器没有网卡、IP地址、路由信息等,需要我们自己为docker容器添加网卡、配置IP等。

d. bridge模式(桥接模式)

bridge模式是docker 默认的网络模式,此模式会为每一个容器分配network 命名空间、设置IP地址等、并将一个主机上的docker容器连接到一个虚拟网桥上。

3.docker 容器的互连

由于同一个主机中所有的容器都连接在同一个虚拟网桥docker0 上,因此在默认情况下,同一主机中的容器之间是可以互相连接的,
为了便于测试,我这里创建两个centos 的容器,使用ip 命令分别查看网卡信息:

   [root@localhost ~]# docker run -itd --name centos01  couchbase/centos7-systemd 
43d62f40d9468f8e52cb54f32f90c400e4fdaacb6dcf9c3de8b7b8ad4b22422b
[root@localhost ~]# docker run -itd --name centos02  couchbase/centos7-systemd 
70e550457f9691cad15cd2d413ab9ed4d2f2440417cd91230c9b18af9436866f
[root@localhost ~]# docker ps 
CONTAINER ID   IMAGE                       COMMAND            CREATED          STATUS          PORTS     NAMES
70e550457f96   couchbase/centos7-systemd   "/usr/sbin/init"   5 seconds ago    Up 4 seconds              centos02
43d62f40d946   couchbase/centos7-systemd   "/usr/sbin/init"   10 seconds ago   Up 10 seconds             centos01
[root@localhost ~]# docker exec  centos01 ip a
1: 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
12: eth0@if13: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
[root@localhost ~]# docker exec  centos02 ip a
1: 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
14: eth0@if15: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

从上边输出可以看到 ,这俩容器的IP分别为172.17.0.2和 172.17.0.3 ,分别在这两个容器上用ping 探测连通性,看是否可以与对方通信

[root@localhost ~]# docker exec  centos01 ping -c3 172.17.0.3
PING 172.17.0.3 (172.17.0.3) 56(84) bytes of data.
64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.123 ms
64 bytes from 172.17.0.3: icmp_seq=2 ttl=64 time=0.061 ms
64 bytes from 172.17.0.3: icmp_seq=3 ttl=64 time=0.069 ms

--- 172.17.0.3 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 0.061/0.084/0.123/0.028 ms
[root@localhost ~]# ^C
[root@localhost ~]# docker exec  centos02 ping -c3 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.092 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.073 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.088 ms

--- 172.17.0.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2001ms
rtt min/avg/max/mdev = 0.073/0.084/0.092/0.011 ms

4. 容器与外部网络的互连

容器与外部网络的互连涉及两个方面,一是容器内部访问外部网络,其次是外部网络访问容器内部,首先从容器内部访问外网测试,这里我们使用mtr 命令访问www.baidu.com .

[root@localhost ~]# docker exec  -it  centos01 /bin/bash
[root@43d62f40d946 /]# yum -y install mtr

```bash
[root@43d62f40d946 /]# mtr --address 172.17.0.2 -c20 -i0.2 -r -n  www.baidu.com
Start: Sat Mar 11 16:10:15 2023
HOST: 43d62f40d946                Loss%   Snt   Last   Avg  Best  Wrst StDev
  1.|-- 172.17.0.1                45.0%    20    0.0   0.1   0.0   0.1   0.0
  2.|-- 192.168.124.2              0.0%    20    0.4   0.3   0.2   0.9   0.0
  3.|-- 10.253.16.1                0.0%    20   14.4   6.8   2.8  51.8  10.9
  4.|-- ???                       100.0    20    0.0   0.0   0.0   0.0   0.0
  5.|-- 10.253.219.169             0.0%    20   36.4   7.3   2.4  36.4  10.0
  6.|-- 10.253.219.209             0.0%    20    5.8   5.5   3.3  15.0   2.6
  7.|-- 10.2.0.185                 5.0%    20    3.1   3.5   2.5   4.2   0.0
  8.|-- 10.2.0.83                  0.0%    20    2.6   3.1   2.3   4.2   0.2
  9.|-- 111.202.148.1              0.0%    20    2.8   3.9   2.4  15.3   2.7
 10.|-- 124.65.221.121             0.0%    20    4.5   4.0   3.2   5.1   0.2
 11.|-- 61.149.203.21              0.0%    20   11.6   8.7   5.0  17.5   2.7
 12.|-- 202.96.12.1               45.0%    20    7.8   6.5   5.2   9.4   1.1
 13.|-- 219.158.11.94             55.0%    20    7.9   9.6   7.3  19.8   3.8
 14.|-- 110.242.66.170            30.0%    20   11.9  12.2  10.4  22.1   2.9
 15.|-- 221.194.45.134             0.0%    20   13.7  13.1  10.9  25.9   3.2
 16.|-- ???                       100.0    20    0.0   0.0   0.0   0.0   0.0
 17.|-- ???                       100.0    20    0.0   0.0   0.0   0.0   0.0
 18.|-- ???                       100.0    20    0.0   0.0   0.0   0.0   0.0
 19.|-- ???                       100.0    20    0.0   0.0   0.0   0.0   0.0
 20.|-- 110.242.68.3               0.0%    19   11.0  11.7  10.7  15.2   0.8

从以上输出结果可以看到 我们从容器本省网卡出去第一跳连接到了虚拟网桥 docker0上,docker0 属于我虚拟机的虚拟网卡 192.168.124.2 是我虚拟机的交换机IP,因此默认情况下容器内部是可以访问外部网络的。

接下来是从外部如何访问容器的内部。通常情况下,外部网络是不可以直接访问容器内部的。如果要访问容器提供的网络服务。就需要通过端口映射实现,也就是说将主机的某个端口映射到容器的网络服务端口。通过端口映射,用户只要访问主机的指定端口就可以了。
例如 , 通过下面的命令创建一个 apache http server的容器,并且将主机的80端口映射到容器的80端口

[root@localhost ~]# docker run -itd -p 80:80 httpd

这时候我们通过浏览器 访问我们主机IP,可以看到访问到了容器默认的web主页
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值