Docker configures fixed IP and bridging implementation method (reproduced)

 

This article mainly introduces the relevant information of Docker configuration fixed IP and bridging implementation methods. Here, it introduces in detail the four network modes of Docker and the case of how to realize bridging. Friends who need it can refer to the following

Docker uses bridge mode by default, connecting to the host through the bridge, and the ip inside the container takes the unused ip from the ip segment where the bridge is located. The inconvenience of doing this is that the ip inside the container is not fixed. When you want to connect to the container, you can only map it to the port of the host machine. Therefore, many projects use overlay to provide network configuration for docker, such as Pipework, Flannel, Kubernetes, Weave, opencontrail, etc.

To use overlay to configure the network for docker, you need to first understand the network mode of docker:

1. Four network modes of Docker

Docker has four network modes when creating a container. By default, bridge does not need to be specified with --net. The other three modes need to be specified with --net when creating a container.

  1. bridge mode, specified with --net=bridge, the default setting.
  2. none mode, specified with --net=none.
  3. host mode, specified with --net=host.
  4. container mode, specified with --net=container: container name or ID. (eg: --net=container:30b668ccb630)

Bridge mode : The docker network isolation is based on the network namespace <Network Namespace>. When a docker container is created on a physical machine, a network namespace is allocated for each docker container, and the container IP is bridged to the virtual network bridge of the physical machine.

none mode : Create a container in this mode without configuring any network parameters for the container, such as: container network card, IP, communication routing, etc., all of which need to be configured by yourself.

host mode : The container created in this mode does not have its own independent network namespace, it shares a Network Namespace with the physical machine, and shares all ports and IPs of the physical machine, and this mode is considered insecure.

Container mode : This mode is similar to the host mode, except that the container created in this mode shares the IP and port of other containers instead of the physical machine. The container in this mode does not configure the network and port itself. After creating a container in this mode, you You will find that the IP inside is the container IP you specified and the port is shared, and others are isolated from each other, such as processes.

2. Docker configures its own bridge

Example one,

1), customize the new bridge

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
root@Docker:~ # dpkg -l | grep bridge*    #查看是否有安装brctl命令包
ii bridge-utils 1.5-6Ubuntu2  amd64    Utilities for configuring the Linux Ethernet bridge
 
root@Docker:~ # apt-get install bridge-utils #安装brctl命令包
 
root@Docker:~ # docker -v          #docker版本
 
Docker version 1.5.0, build a8a31ef
 
root@Docker:~ # ps -ef | grep docker     #正在运行
root   6834  1 0 16:28 ?    00:00:00 /usr/bin/docker -d
 
root@Docker:~ # service docker stop     #停止
 
 
root@Docker:~ # ifconfig | grep docker0   #docker默认网桥
docker0 Link encap:以太网 硬件地址 56:84:7a:fe:97:99
 
root@Docker:~ # ifconfig docker0 down    #停止docker默认网桥
 
root@Docker:~ # brctl show          #查看物理机上有哪些网桥
 
root@Docker:~ # brctl delbr docker0     #删除docker默认网桥
 
root@Docker:~ # brctl addbr docker_new0   #自定义网桥
 
root@Docker:~ # ifconfig docker_new0 192.168.6.1 netmask 255.255.255.0  #给自定义网桥指定IP和子网
 
root@Docker:~ # ifconfig | grep docker_new0 #查看发现自定义网桥已经启动
docker_new0 Link encap:以太网 硬件地址 0a:5b:26:48: dc :04
      inet 地址:192.168.6.1 广播:192.168.6.255 掩码:255.255.255.0
 
root@Docker:~ # echo 'DOCKER_OPTS="-b=docker_new0"' >> /etc/default/docker #指定网桥写入docker配置文件
 
root@Docker:~ # service docker start     #启动docker
 
root@Docker:~ # ps -ef | grep docker     #成功启动,并且成功加载了docker_new0
root  21345  1 0 18:44 ?    00:00:00 /usr/bin/docker -d -b=docker_new0
 
root@Docker:~ # brctl show          #查看当前网桥下是否有容器连接
bridge name       bridge id       STP enabled  interfaces
docker_new0      8000.fa3ce276c3b9      no     
 
root@Docker:~ # docker run -itd CentOS:centos6 /bin/bash         #创建容器测试
 
root@Docker:~ # docker attach 7f8ff622237f                #进入容器
 
[root@7f8ff622237f /] # ifconfig eth0 | grep addr             #容器IP已经和自定义网桥一个网段,该容器IP为DHCP自动分配,不属于指定固定IP
eth0   Link encap:Ethernet HWaddr 02:42:C0:A8:06:02
      inet addr:192.168.6.2 Bcast:0.0.0.0 Mask:255.255.255.0
      inet6 addr: fe80::42:c0ff:fea8:602 /64 Scope:Link
 
root@Docker:~ # brctl show          #该网桥上已经连接着一个网络设备了
bridge name        bridge id       STP enabled  interfaces
docker_new0      8000.fa3ce276c3b9      no     veth17f560a

Note: veth devices appear in pairs, one end is named eth0 inside the container, and the other end is veth17f560a (usually named veth*) added to the bridge and named, they form a data transmission channel, one end goes in and the other goes out, The veth device connects two network devices and realizes data communication.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
root@Docker:~ # wget https://github.com/jpetazzo/pipework/archive/master.zip #下载 pipework
 
root@Docker:~ # unzip master.zip      #解压
 
root@Docker:~ # cp pipework-master/pipework /usr/bin/           #拷贝pipework到 /usr/bin/下
 
root@Docker:~ # chmod +x /usr/bin/pipework  #赋予该命令执行权限
 
root@Docker:~ # pipework docker_new0 -i eth1 $(docker run -itd -p 9197:80 centos:centos6 /bin/bash) 192.168.6.27/[email protected] #创建容器,并指定固定IP
格式:pipework 网桥名 -i 指定在那块网卡上配置 <容器名or容器ID> 指定容器内IP/子网@网关 注:容器内网关就是物理机网桥的IP      
 
  
 
root@Docker:~ # docker attach 2966430e2dbe  #进入新容器
  
 
[root@2966430e2dbe /] # ifconfig       #容器内IP为指定的IP 192.168.6.27
eth0   Link encap:Ethernet HWaddr 02:42:C0:A8:06:05         
      inet addr:192.168.6.7 Bcast:0.0.0.0 Mask:255.255.255.0    #docker_new0网桥创建容器时DHCP分配的IP
 
 
eth1   Link encap:Ethernet HWaddr 82:DB:F7:A3:33:92
      inet addr:192.168.6.27 Bcast:0.0.0.0 Mask:255.255.255.0    #pipework指定的固定IP,网桥还是docker_new0
 
 
[root@2966430e2dbe /] # route -n       #查看路由路径
Kernel IP routing table
Destination  Gateway    Genmask    Flags Metric Ref  Use Iface
0.0.0.0    192.168.6.1  0.0.0.0    UG  0   0    0 eth0
192.168.6.0  0.0.0.0    255.255.255.0 U  0   0    0 eth0
192.168.6.0  0.0.0.0    255.255.255.0 U  0   0    0 eth1
 
 
[root@2966430e2dbe /] # ping www.linuxidc.com  #测试网络
PING www.linuxidc.com (119.75.218.70) 56(84) bytes of data.
64 bytes from 119.75.218.70: icmp_seq=1 ttl=127 time =3.98 ms
64 bytes from 119.75.218.70: icmp_seq=2 ttl=127 time =2.98 ms
 
 
[root@2966430e2dbe /] # netstat -anptu | grep 80               #容器内80端口已经开启
tcp    0   0 :::80           :::*            LISTEN   -
 
root@Docker:~ # telnet 192.168.6.27 80    #物理机上测试指定的IP是否和映射的端口等通信正常
Trying 192.168.6.27...
Connected to 192.168.6.27.
Escape character is '^]' .
 
root@Docker:~ # iptables-save > iptables-rules #拷贝防火墙规则到本地文件
 
root@Docker:~ # vi iptables-rules       #打开规则文件查看你会发现你物理机的防火墙自动添加了很多条规则,这个是容器到网桥到本地网卡到公网的地址转换通信规则<br>

例子二:

首先,配置一个用于创建container interface的网桥,可以使用ovs,也可以使用Linux bridge,以Linux bridge为例:

?
1
2
3
4
5
6
br_name=docker
brctl addbr $br_name
ip addr add 192.168.33.2 /24 dev $br_name
ip addr del 192.168.33.2 /24 dev em1
ip link set $br_name up
brctl addif $br_name eth0

接着,可以启动容器了,注意用--net=none方式启动:

?
1
2
3
4
# start new container
hostname = 'docker.test.com'
cid=$(docker run -d -i -h $ hostname --net=none -t centos)
pid=$(docker inspect -f '{{.State.Pid}}' $cid)

下面,为该容器配置网络namespace,并设置固定ip:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# set up netns
mkdir -p /var/run/netns
ln -s /proc/ $pid /ns/net /var/run/netns/ $pid
# set up bridge
ip link add q$pid type veth peer name r$pid
brctl addif $br_name q$pid
ip link set q$pid up
# set up docker interface
fixed_ip= '192.168.33.3/24'
gateway= '192.168.33.1'
ip link set r$pid netns $pid
ip netns exec $pid ip link set dev r$pid name eth0
ip netns exec $pid ip link set eth0 up
ip netns exec $pid ip addr add $fixed_ip dev eth0
ip netns exec $pid ip route add default via 192.168.33.1

这样,容器的网络就配置好了,如果容器内部开启了sshd服务,通过192.168.33.3就可以直接ssh连接到容器,非常方便。上面的步骤比较长,可以借助pipework来为容器设置固定ip(除了设置IP,还封装了配置网关、macvlan、vlan、dhcp等功能):

pipework docker0 be8365e3b2834 10.88.88.8/24

那么,当容器需要删除的时候,怎么清理网络呢,其实也很简单:

?
1
2
3
4
5
# stop and delete container
docker stop $cid
docker rm $cid
# delete docker's net namespace (also delete veth pair)
ip netns delete $pid

更多docker网络的配置,可以参考官方手册。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325090097&siteId=291194637