05-Docker网络管理¶
容器的网络基础¶
1、docker0: 安装 docker 的时候,会生成一个 docker0 的虚拟网桥
2、Linux 虚拟网桥的特点: 可以设置 ip 地址 相当于拥有一个隐藏的虚拟网卡
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:7f:4f:f4:1b brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:7fff:fe4f:f41b/64 scope link
valid_lft forever preferred_lft forever
每运行一个 docker 容器都会生成一个 veth 设备对,这个 veth 一个接口在容器里,一个接口在物理机 上。
3、安装网桥管理工具:
yum install bridge-utils -y
brctl show 可以查看到有一个 docker0 的网桥设备,下面有很多接口,每个接口都表示一个启动的 docker 容器,因为我在 docker 上启动了很多容器,所以 interfaces 较多,如下所示:
[root@linux-bkce-node21 ~]# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.02427f4ff41b no
容器的网络互联¶
启动一个nginx容器,并查看他的IP地址
docker run --name nginx01 -it -d -p 8080:80 nginx
docker exec -it nginx01 /bin/bash
root@7edf3b000b1c:/# hostname -I
172.17.0.3
启动一个centos容器,并查看他的IP地址
docker run --name centos01 -it -d centos:7.9.2009 /bin/bash
docker exec -it centos01 /bin/bash
[root@57200f9459a2 /]# ping -c 4 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.080 ms
64 bytes from 172.17.0.3: icmp_seq=2 ttl=64 time=0.104 ms
64 bytes from 172.17.0.3: icmp_seq=3 ttl=64 time=0.092 ms
^C
[root@57200f9459a2 /]# curl 172.17.0.3|grep nginx
<title>Welcome to nginx!</title>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
<a href="http://nginx.org/">nginx.org</a>.<br/>
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
缺点:但是如果通过IP的方式进行容器之间的访问会存在问题,因为容器的IP地址会发生改变,所以在特殊情况下会造成连接失败的问题
清理环境
docker rm -f centos01
docker rm -f nginx01
容器的网络别名¶
我们可以通过给容器起一个代号,这样可以直接以代号访问,避免了容器重启 ip 变化带来的问题
启动一个nginx容器,
docker run --name nginx01 -it -d -p 8080:80 nginx
启动一个centos容器,并开始通过网络别名访问nginx
docker run --name centos01 -it -d --link=nginx01:nginx01link centos:7.9.2009 /bin/bash
docker exec -it centos01 /bin/bash
[root@cb4d59e39900 /]# curl nginx01link|grep nginx
<title>Welcome to nginx!</title>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
<a href="http://nginx.org/">nginx.org</a>.<br/>
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
清理环境
docker rm -f centos01
docker rm -f nginx01
容器的网络模式¶
none模式¶
这个模式和前两个不同。在这种模式下,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。
Docker 网络 none 模式是指创建的容器没有网络地址,只有 lo 网卡
我们开始创建一个none网络模式的容器
docker run --name centos01 -it -d --net=none centos:7.9.2009 /bin/bash
[root@linux-bkce-node21 ~]# sh in01.sh centos01
[root@3cdae9a8dd0d ~]# ip addr
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
清理环境
docker rm -f centos01
container模式¶
Docker网络container模式是指,创建新容器的时候,通过--net container
参数,指定其和已经存在的某个容器共享一个 Network Namespace。如下图所示,右方黄色新创建的container,其网卡共享左边容器。因此就不会拥有自己独立的 IP,而是共享左边容器的 IP 172.17.0.2,端口范围等网络资源,两个容器的进程通过 lo 网卡设备通信。
但这两个容器在其他的资源上,如文件系统、进程列表等还是隔离的。
我们开始创建一个container网络模式的容器
docker run --name centos01 -it -d centos:7.9.2009 /bin/bash
docker run --name nginx01 -it -d --net=container:centos01 nginx
sh in01.sh centos01
[root@98ac20343bf8 ~]# curl 127.0.0.1|grep nginx
<title>Welcome to nginx!</title>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
<a href="http://nginx.org/">nginx.org</a>.<br/>
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
清理环境
docker rm -f centos01
docker rm -f nginx01
host模式¶
众所周知,Docker使用了Linux的Namespaces技术来进行资源隔离,如PID Namespace隔离进程,Mount Namespace隔离文件系统,Network Namespace隔离网络等。一个Network Namespace提供了一份独立的网络环境,包括网卡、路由、Iptable规则等都与其他的Network Namespace隔离。一个Docker容器一般会分配一个独立的Network Namespace。但如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。
例如,我们在10.10.101.105/24的机器上用host模式启动一个含有web应用的Docker容器,监听tcp80端口。当我们在容器中执行任何类似ifconfig命令查看网络环境时,看到的都是宿主机上的信息。而外界访问容器中的应用,则直接使用10.10.101.105:80即可,不用任何NAT转换,就如直接跑在宿主机中一样。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。
Docker 网络 host 模式是指共享宿主机的网络
docker run --name nginx01 -it -d --net=host nginx
[root@linux-bkce-node21 ~]# curl 192.168.1.21|grep nginx
<title>Welcome to nginx!</title>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
<a href="http://nginx.org/">nginx.org</a>.<br/>
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
清理环境
docker rm -f nginx01
bridge模式¶
当Docker server启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。接下来就要为容器分配IP了,Docker会从RFC1918所定义的私有IP网段中,选择一个和宿主机不同的IP地址和子网分配给docker0,连接到docker0的容器就从这个子网中选择一个未占用的IP使用。如一般Docker会使用172.17.0.0/16这个网段,并将172.17.42.1/16分配给docker0网桥(在主机上使用ifconfig命令是可以看到docker0的,可以认为它是网桥的管理接口,在宿主机上作为一块虚拟网卡使用)。单机环境下的网络拓扑如下,主机地址为10.10.101.105/24。
默认选择 bridge 的情况下,容器启动后会通过 DHCP 获取一个地址
我们默认启动的容器的网络模式就是bridge模式
docker run --name centos01 -it -d centos:7.9.2009 /bin/bash
docker exec -it centos01 /bin/bash
清理环境
docker rm -f centos01
出现错误总结¶
当我配置好docker的nginx镜像时,出现无法访问,并且在创建nginx容器的时候出现如下提示
WARNING: IPv4 forwarding is disabled. Networking will not work.
警告:IPv4转发被禁用。网络将无法工作。
这里表示没有设置内核转发
解决方法:
# vi /etc/sysctl.conf
或者
# vi /usr/lib/sysctl.d/00-system.conf
添加如下代码:
net.ipv4.ip_forward=1
重启network服务
# systemctl restart network
查看是否修改成功
# sysctl net.ipv4.ip_forward
如果返回为“net.ipv4.ip_forward = 1”则表示成功了
这时使用外部的浏览器访问就会发现没有问题啦