这里的使用场景为混合云。一部分系统和网络环境位于IDC托管机房中, 其中部署了公司内部的yum安装源。另一部分资源是位于另一个机房中的云平台中,其中使用云主机运行docker容器,以提高云主机的资源利用率,以及提高工作效率等。两套系统环境之间配置了加密通信线路打通了两端的私网。

以下配置可以达到几个目的:

  • 可以在容器系统中使用加密线路访问远程yum源安装软件;
  • 可以在容器中使用我们指定的IP地址段;
  • 可以给每个容器指定一个固定的IP地址,不随容器的重启而变化;

先安装好docker ce工具包,默认使用docker0网桥,网段地址为172.17.0.1/16。然后按下面步骤进行配置。

解决方法一:使用docker默认网桥

1、docker0网桥的配置

先关闭docker服务:

systemctl stop docker

编辑docker服务启动文件:

# vi /usr/lib/systemd/system/docker.service

ExecStart=/usr/bin/dockerd --mtu=1400 --bip=192.168.20.1/24

 

我们在ExecStart所在的一行中补充了两个参数,以下是详细说明:

  • --mtu=1400,将容器网络docker0的报文mtu设置为1400bytes,因为我们要配置容器通过加密线路使用远程的yum源。加密通信和docker宿主机所使用的云主机网络,都有对数据包重新封装的需求。如果容器网络是使用默认1500bytes的mtu配置,会导致重新封装后的报文不能被云主机和加密网络所发出。网络会无法正常使用。
  • --bip=192.168.20.1/24,将docker0网桥默认使用的网络地址变更为我们指定的地址。

重新启动docker服务:

systemctl daemon-reload

systemctl restart docker

 

观察一下配置结果:

[root@docker-centos7 system]# brctl show

bridge name    bridge id        STP enabled    interfaces

docker0        8000.02423ffeb51a    no    

    

[root@docker-centos7 system]# ip a

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN

    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: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1400 qdisc pfifo_fast state UP qlen 1000

    link/ether fa:16:3e:e2:48:2d brd ff:ff:ff:ff:ff:ff

    inet 192.168.240.204/24 brd 192.168.240.255 scope global dynamic eth0

       valid_lft 467sec preferred_lft 467sec

    inet6 fe80::f816:3eff:fee2:482d/64 scope link

       valid_lft forever preferred_lft forever

4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN

    link/ether 02:42:3f:fe:b5:1a brd ff:ff:ff:ff:ff:ff

    inet 192.168.20.1/24 brd 192.168.20.255 scope global docker0

       valid_lft forever preferred_lft forever

 

2、创建docker容器并通过脚本为容器系统配置静态的IP地址

1)创建三个未配置网络的容器实例,用于测试

docker run -itd --name mytest1 --net none centos-with-nettools-v1

docker run -itd --name mytest2 --net none centos-with-nettools-v1

docker run -itd --name mytest3 --net none centos-with-nettools-v1

查看容器的网络配置:

[root@docker-centos7 system]# docker attach mytest1

[root@2e09acd2b27f /]# ip a

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN

    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

 

2)部署一个动态为容器配置静态IP地址的perl脚本

需要创建一个目录:

mkdir -pv /var/run/netns/

将下面的脚本中红色部分按实际信息进行修改,然后把脚本部署在docker宿主机方便执行的位置上。

待修改的内容包括:

  • 将容器的mtu设置为1400;
  • 将容器网络的网关设置为docker0网络的地址192.168.20.1;
  • 在末尾部分以"hostname"="IP"的格式,把需要配置固定的静态IP地址的容器实例信息罗列好。

start_container.pl

#!/usr/bin/perl

use strict;

use warnings;

my $num = @ARGV;

if ($num == 0) {

print "error\n";

exit;

}

(my $hostname) = @ARGV;

system("docker start $hostname");

my @host_info;

for (<DATA>){

if (/^$hostname/) {

@host_info = split('=',$_);

}

}

($hostname,my $ip) = @host_info;

chomp($ip);

my $pid = readpipe("docker inspect -f '{{.State.Pid}}' $hostname");

chomp($pid);

system("ln -sf /proc/$pid/ns/net /var/run/netns/$pid");

system("ip link add neto_$hostname type veth peer name neti_$hostname");

system("brctl addif docker0 neto_$hostname");

system("ip link set neto_$hostname up");

system("ip link set neti_$hostname netns $pid");

system("ip netns exec $pid ip link set dev neti_$hostname name eth0");

system("ip netns exec $pid ip link set dev eth0 mtu 1400");

system("ip netns exec $pid ip link set eth0 up");

system("ip netns exec $pid ip addr add $ip/24 dev eth0"); #这里为虚拟机添加ip,如果是别的掩码,可以自行修改

system("ip netns exec $pid ip route add default via 192.168.20.1"); #这里调用shell,如果网关ip是别的,可以自行修改

__DATA__

mytest1=192.168.20.21

mytest2=192.168.20.22

mytest3=192.168.20.23

#脚本会根据__DATA__下面的配置设置ip,前面是容器名--name定义的,后面=,在后面是ip地址,格式是必须严格按照样例配置

 

chmod +x start_container.pl

 

执行固定IP地址配置脚本,格式为: ./start_container.pl  容器名

[root@docker-centos7 ~]# ./start_container.pl mytest1

mytest1

[root@docker-centos7 ~]# ./start_container.pl mytest2

mytest2

[root@docker-centos7 ~]# ./start_container.pl mytest3

mytest3

 

[root@docker-centos7 ~]# docker exec mytest1 ifconfig

eth0      Link encap:Ethernet  HWaddr BA:87:BB:3E:D5:6B  

          inet addr:192.168.20.21  Bcast:0.0.0.0  Mask:255.255.255.0

          UP BROADCAST RUNNING MULTICAST  MTU:1400  Metric:1

          RX packets:16 errors:0 dropped:0 overruns:0 frame:0

          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1000

          RX bytes:1296 (1.2 KiB)  TX bytes:0 (0.0 b)

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)

 

3)进入mytest1容器继续检查下网络配置信息

[root@2e09acd2b27f ~]# ip r

default via 192.168.20.1 dev eth0

192.168.20.0/24 dev eth0  proto kernel  scope link  src 192.168.20.21

 

[root@2e09acd2b27f ~]# ping 192.168.110.24

PING 192.168.110.24 (192.168.110.24) 56(84) bytes of data.

64 bytes from 192.168.110.24: icmp_seq=1 ttl=60 time=9.78 ms

64 bytes from 192.168.110.24: icmp_seq=2 ttl=60 time=9.21 ms

^C

--- 192.168.110.24 ping statistics ---

2 packets transmitted, 2 received, 0% packet loss, time 1668ms

rtt min/avg/max/mdev = 9.218/9.501/9.785/0.299 ms

 

3、为容器实例配置内网yum安装源

 

[root@2e09acd2b27f ~]# cd /etc/yum.repos.d/

[root@2e09acd2b27f yum.repos.d]# ls

CentOS-Base.repo  CentOS-Debuginfo.repo  CentOS-fasttrack.repo  CentOS-Media.repo  CentOS-Vault.repo

[root@2e09acd2b27f yum.repos.d]# rm -rf *

 

[root@2e09acd2b27f yum.repos.d]# vi base.repo

[yum]

name=CentOS-Yum-$releasever

baseurl=http://192.168.110.24/yum/$releasever

gpgcheck=0

enabled=1

 

[root@2e09acd2b27f yum.repos.d]# vi epel.repo

[epel]

name= CentOS-Epel-$releasever

baseurl=http://192.168.110.24/epel/$releasever

enabled=1

gpgcheck=0

 

[root@2e09acd2b27f yum.repos.d]# ls

base.repo  epel.repo

[root@2e09acd2b27f yum.repos.d]# yum clean all

Loaded plugins: fastestmirror, ovl

Cleaning repos: epel yum

Cleaning up Everything

Cleaning up list of fastest mirrors

[root@2e09acd2b27f yum.repos.d]# yum makecache

Loaded plugins: fastestmirror, ovl

Determining fastest mirrors                                                                                                           

Metadata Cache Created

安装一个工具试试:

[root@2e09acd2b27f yum.repos.d]# yum -y install lrzsz

Loaded plugins: fastestmirror, ovl

Setting up Install Process

Loading mirror speeds from cached hostfile

Resolving Dependencies

--> Running transaction check

---> Package lrzsz.x86_64 0:0.12.20-27.1.el6 will be installed

--> Finished Dependency Resolution

Dependencies Resolved

Install       1 Package(s)

Total download size: 71 k

Installed size: 159 k

Downloading Packages:

lrzsz-0.12.20-27.1.el6.x86_64.rpm                                                                                                                                    |  71 kB     00:00     

Running rpm_check_debug

Running Transaction Test

Transaction Test Succeeded

Running Transaction

  Installing : lrzsz-0.12.20-27.1.el6.x86_64                                                                                                                                            1/1

  Verifying  : lrzsz-0.12.20-27.1.el6.x86_64                                                                                                                                            1/1

Installed:

  lrzsz.x86_64 0:0.12.20-27.1.el6                                                                                                                                                           

Complete!

[root@2e09acd2b27f yum.repos.d]#

 

4、注意事项

  1. 因为是使用脚本动态为容器实例配置的IP地址,所以如果docker宿主机系统重启,则这些容器实例的网络配置会变成none的状态。需要手动执行该perl脚本为容器实例配置指定的ip地址;
  2. 如果有多个docker宿主机时,相互之间的容器实例网络是完全隔离的。如果需要互相访问,需要预先为容器配置好端口映射,然后通过docker宿主机的地址+端口对外提供服务;

解决方案二:使用自定义网桥并在创建容器时指定网络和ip地址参数

 

1、创建一个自定义网桥my-network

# docker network create --subnet=192.168.20.1/24 --opt com.docker.network.driver.mtu=1400  my-network

 

2、在创建应用容器时使用网络和ip参数

# docker run -itd --network=my-network --ip=192.168.20.10  --name=mytest4  centos-with-nettools-v1

 

这样以更简便的方式同样可以达到解决方案一的效果。

 

 

 

 

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐