Docker | 容器的网络连接

Docker容器的网络基础

  • Docker提供的网桥

首先,查看一个名为docker0的“网络设备”:

[root@localhost ~]# ifconfig docker0
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 0.0.0.0
        inet6 fe80::42:2fff:fe56:7b2e  prefixlen 64  scopeid 0x20<link>
        ether 02:42:2f:56:7b:2e  txqueuelen 0  (Ethernet)
        RX packets 27406  bytes 2657911 (2.5 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 42036  bytes 58020300 (55.3 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

docker守护进程就是通过docker0为docker容器提供网络连接的各种服务。docker0实质事Linux的虚拟网桥;
在这里插入图片描述

  • Linux虚拟网桥的特点:

    1- 可以设置IP地址
    2- 相当于拥有一个隐藏的虚拟网卡

  • docker0的地址划分,例如:

	IP:172.17.42.1 子网掩码: 255.255.0.0
	MAC: 02:42:ac:11:00:00 到 02:42:ac:11:ff:ff
	总共提供65534个地址

docker守护进程在一个容器启动时,实际上它要创建网络连接的两端。一端是在容器中的网络设备,而另一端是在运行docker守护进程的主机上打开一个名为veth*的一个接口,用来实现docker这个网桥与容器的网络通信。
在这里插入图片描述

查看网桥:
查看网桥,需要linux的网桥管理程序,在Ubuntu中通过 apt-get install bridge-utils 命令安装。如下查看网桥,可以看到一个叫docker0的网桥设备。

[root@localhost ~]#  brctl show
bridge name    bridge id              STP    enabled    interfaces
docker0        8000.0242ed943d02      no

可以对docker0进行修改,使之成为我们希望的网段。

  • 语法ifconfig docker0 IP netmask NATMASK
  • 实例
[root@localhost docker]# ifconfig docker0 172.25.11.1 netmask 255.255.255.0
[root@localhost docker]# ifconfig docker0
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.25.11.1  netmask 255.255.255.0  broadcast 172.25.11.255
        inet6 fe80::42:2fff:fe56:7b2e  prefixlen 64  scopeid 0x20<link>
        ether 02:42:2f:56:7b:2e  txqueuelen 0  (Ethernet)
        RX packets 27406  bytes 2657911 (2.5 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 42047  bytes 58023011 (55.3 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
[root@localhost docker]# service docker restart   #最好重新启动下docker
Redirecting to /bin/systemctl restart  docker.service

自定义虚拟网桥
有时候,不希望使用docker默认提供的虚拟网桥,就可以添加自定义的虚拟网桥,如下添加虚拟网桥

  • 语法
#新建网桥
brctl addbr br_name(新建的网桥名)
#修改新建网桥的IP网段
ifconfig br_name IP netmask NETMASK_NAME

修改docker默认指定的网桥,需要修改/lib/systemd/system.docker.service文件,如下修改docker默认指定的网桥

  • 语法:
ExecStart=ExecStart=/usr/bin/dockerd -b=br_name 	//br_name 为宿主机的默认指定的网络桥接设备

#完成之后要重启docker服务
[root@localhost docker]# service docker restart

docker容器的网络设备查看 ( 如果没有ifconfig命令,通过apt-get install -y net-tools):

root@b2a3136f5425:/# ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:ac:11:00:02 
inet addr:172.17.0.2 Bcast:0.0.0.0 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:145 errors:0 dropped:0 overruns:0 frame:0
TX packets:60 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0 
RX bytes:184985 (184.9 KB) TX bytes:4758 (4.7 KB)

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:0 
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

启动容器后,docker已经自动创建了容器对应的eth0的网卡,注意观察ip地址和mac地址。不要退出容器,再运行如下查看网桥的状态,可以看到在interface中多了一个veth*的这样一个接口。通过ifconfig命令同样可以看到这个网络接口:

[root@localhost ~]#  sudo brctl show
bridge name    bridge id           STP    enabled    interfaces
docker0    8000.0242ed943d02       no                veth95521e6

Docker容器的互联

用于测试的Docker镜像 Dockerfile:

FROM ubuntu:14.04
RUN apt-get install -y ping
RUN apt-get update
RUN apt-get install -y nginx
RUN apt-get install -y curl
EXPOSE 80
CMD /bin/bash
  • 允许所有容器互联
    在同一宿主机下,docker的容器是通过“”虚拟网桥bridge“来进行连接的。那么在默认情况下,在同一宿主机中运行的容器都是可以互相连接的。
    –icc=true 默认

[root@localhost docker]# docker run -it --name cct1 ubuntu:latest /bin/bash    //构建容器cct1
root@db83f8dbedcc:/# nginx      //启动cct1的nginx服务
root@db83f8dbedcc:/# ifconfig eth0
eth0      Link encap:Ethernet  HWaddr 02:42:ac:11:00:02  
          inet addr:172.17.0.2  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:acff:fe11:2/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:24 errors:0 dropped:0 overruns:0 frame:0
          TX packets:14 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:1858 (1.8 KB)  TX bytes:1862 (1.8 KB)
root@db83f8dbedcc:/#        //使用ctrl+p ctrl+q 退出,启动守护式容器
[root@localhost docker]# docker run -it --name cct2 ubuntu:latest /bin/bash      //构建容器cct2
root@2f8c3a090194:/# ifconfig eth0
eth0      Link encap:Ethernet  HWaddr 02:42:ac:11:00:03  
          inet addr:172.17.0.3  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:acff:fe11:3/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:648 (648.0 B)  TX bytes:648 (648.0 B)
root@2f8c3a090194:/# ping 172.17.0.2        //可以ping通cct1
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.066 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.102 ms
root@2f8c3a090194:/# curl 172.17.0.2    //可以访问cct1的nginx服务
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
</head>
<body>
<h1>Welcome to nginx!</h1>
</body>
</html>

在同一个宿主机下都是通过虚拟网桥连接,但是容器的IP地址是不可靠的连接(容器的重启会导致容器IP的改变),在docker上提供的服务,以IP地址连接不可靠,所以在容器启动时可以添加–link选项:
–link:

docker run --link=[CONTAINER_NAME]:[ALIAS] [IMAGE] [COMMAND]

CONTAINER_NAME: 需要连接的容器名字;
ALIAS: 在容器中连接的代号,自己指定一个别名,用来连接指定;

#如下实例:
[root@localhost docker]# docker run -it --name cct3 --link=cct1:web_test  ubuntu:latest /bin/bash      //创建cct3,连接cct1,且别名为web_test
root@02bd05e6a6ab:/# ping web_test      //可以直接ping通web_test
PING web_test (172.17.0.2) 56(84) bytes of data.
64 bytes from web_test (172.17.0.2): icmp_seq=1 ttl=64 time=0.110 ms
64 bytes from web_test (172.17.0.2): icmp_seq=2 ttl=64 time=0.105 ms
^C
--- web_test ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.105/0.107/0.110/0.010 ms

root@02bd05e6a6ab:/# env |grep WEB      //可以看到有大量web_test的环境变量,在容器启动时,由docker添加
WEB_TEST_PORT_80_TCP_ADDR=172.17.0.2
WEB_TEST_PORT=tcp://172.17.0.2:80
WEB_TEST_PORT_80_TCP_PORT=80
WEB_TEST_NAME=/cct3/web_test
WEB_TEST_PORT_80_TCP=tcp://172.17.0.2:80
WEB_TEST_PORT_80_TCP_PROTO=tcp

root@02bd05e6a6ab:/# cat /etc/hosts     //hosts文件里也有相关一些信息(web_test的地址映射)
127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2  web_test db83f8dbedcc cct1
172.17.0.4  02bd05e6a6ab
//重启cct3之后,也可以ping通cct1

  • 查看在容器中产生的哪些影响,如:$ env

    $ env 查看环境变量,可以看到大量以WEBTEST*开头的环境变量,这些环境变量是在容器启动时,由docker添加的。我们还可以查看在/ect/host文件,这里添加了webtest的地址映射。当docker重启启动容器时 /ect/host所对应的ip地址发生了变化。也就是说,针对于指定了link选项的容器,在启动时docker会自动修改ip地址和我们指定的别名之间的映射。环境变量也会做出相应的改变。

拒绝所有容器间互联
Docker守护进程的启动选项
–icc=false
修改vim /etc/default/docker,在末尾添加配置 DOCKER_OPTS="–icc=false"。
需要重启docker的服务 $ sudo service docker restart.即使是link也ping不通。

允许特定容器间的连接
要允许特定容器连接,需要三个启动选项:

--icc=false

--iptables=true	允许docker容器将配置添加到Linux的iptables设置中

--link

#docker利用iptables中的机制,在icc=false时,阻断所有的docker容器间的访问,仅仅运行利用link选项配置的容器进行相互的访问。

示例:

  • 关闭cct1、cct2、cct3
[root@localhost docker]# docker stop cct1 cct2 cct3 
cct1
cct2
cct3
​
  • 修改配置文件:/lib/systemd/system/docker.services
ExecStart=
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock --iptables=true --icc=false
[root@localhost system]# systemctl daemon-reload    //重启
[root@localhost system]# systemctl restart docker.service
  • 重新启动cct1、cct2、cct3
[root@localhost docker]# docker start cct1 cct2 cct3 
cct1
cct2
cct3
//attach到cct1、cct2、cct3,查看各自ip
  • 测试:
[root@localhost docker_file]# docker attach cct2
root@c1ab09b07e87:/# 
root@c1ab09b07e87:/# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
^C
--- 172.17.0.2 ping statistics ---
4 packets transmitted, 0 received, 100% packet loss, time 2999ms
//ping不通
root@c1ab09b07e87:/# curl 172.17.0.2
^C
//同样不能访问
​
[root@localhost rhel7mplayer]# docker attach cct3
root@0a3b40758348:/# curl web_test
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
</head>
<body>
<h1>Welcome to nginx!</h1>
</body>
</html>
//curl访问成功

  • 查看宿主机上的iptables规则:
[root@localhost system]# iptables -L
Chain DOCKER (1 references)
target     prot opt source               destination         
ACCEPT     tcp  --  172.17.0.4           172.17.0.2           tcp dpt:http
ACCEPT     tcp  --  172.17.0.2           172.17.0.4           tcp spt:http
ACCEPT     tcp  --  172.17.0.5           172.17.0.2           tcp dpt:http
ACCEPT     tcp  --  172.17.0.2           172.17.0.5           tcp spt:http
​
Chain DOCKER-ISOLATION (1 references)
target     prot opt source               destination         
RETURN     all  --  anywhere             anywhere            
//可以看到,DOCKER表中放行了两个IP的http访问
  • 注: 允许特定容器间的连接中如果出现容器间ping不通的情况,可能为iptables的问题(DROP规则在docker之前了)。
sudo iptables -L -n    查看iptables规则的情况
sudo iptables -F    清空iptables规则设置
sudo service docker restart 重新启用docker的服务
sudo iptables -L -n 再来查看iptables的设置,docker的规则链已经在第一位

# 然后重启容器即可

引用:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值