LVS DR模式

一、测试环境说明

操作系统:CentOS6.7-X64

IP_VS版本:1.2.26

DR:10.10.10.130

VIP:10.10.10.140

RS1:10.10.10.131

RS2:10.10.10.132


二、LVS-DR模式原理

blob.png

a)客户端发送一个请求(源地址为CIP,目标地址为VIP,我们简称为CIP:VIP)到LVS的DR

b)通过在调度器上修改数据包的目的MAC地址来实现转发(仍旧保持为CIP:VIP)

c)请求的报文经过调度器,而RS响应处理后的报文无需经过调度器,直接将返回请求给客户端(VIP:CIP)

d)因为DR模式是通过MAC地址的改写机制来实现的转发,因此,所有RS节点和调度器只能在同一个LAN中

e)RS节点需要绑定VIP(如果有多个VIP地址,lo:vip,lo1:vip)以及配置ARP抑制问题

f)RS节点默认网关不需要是调度器的DIP,而直接是IDC机房分配的上级路由器的IP(这是RS带有外网IP的情况),理论上:只要RS可以出网即可,不需要配置外网IP

h)由于DR模式的调度器仅进行了目的MAC地址的改写,因此,调度器无法改变请求的报文的目的端口

i)调度器支持大多数UNIX及Linux(暂不支持windows),RS可以是windows


三、实际操作配置

1)DR上的配置:

关闭iptables:
[root@DR1 ~]# iptables -X
[root@DR1 ~]# iptables -F
[root@DR1 ~]# iptables -Z
[root@DR1 ~]# service iptables stop
iptables:将链设置为政策 ACCEPT:filter                    [确定]
iptables:清除防火墙规则:                                 [确定]
iptables:正在卸载模块:                                   [确定]
[root@DR1 ~]# chkconfig iptables off
安装配置http服务,并设置好软链接:
[root@DR1 ~]# yum -y install httpd
[root@DR1 ~]# sevice httpd start
[root@DR1 ~]# chkconfig httpd on
[root@DR1 ~]# echo "网站维护中">/var/www/html/index.html
[root@DR1 ~]# ln -s /usr/src/kernels/2.6.32-573.el6.x86_64/ /usr/src/linux
[root@DR1 ~]# ll /usr/src/
总用量 8
drwxr-xr-x. 2 root root 4096 9月  23 2011 debug
drwxr-xr-x. 3 root root 4096 7月   5 23:49 kernels
lrwxrwxrwx  1 root root   39 8月  31 08:49 linux -> /usr/src/kernels/2.6.32-573.el6.x86_64/
安装并加载ip_vs模块:
[root@DR1 ~]# yum -y install libnl* popt*
[root@DR1 ~]# lsmod | grep ip_vs
[root@DR1 ~]# cd /usr/local/src/
[root@DR1 src]# wget http://www.linuxvirtualserver.org/software/kernel-2.6/ipvsadm-1.26.tar.gz
root@DR1 src]# tar -zxvf ipvsadm-1.26.tar.gz
[root@DR1 src]# cd ipvsadm-1.26
[root@DR1 ipvsadm-1.26]# make
[root@DR1 ipvsadm-1.26]# make install 
[root@DR1 ipvsadm-1.26]# ipvsadm
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
说明:也可以使用modprobe ip_vs
[root@DR1 ipvsadm-1.26]# lsmod | grep ip_vs
ip_vs                 126534  0 
libcrc32c               1246  1 ip_vs
ipv6                  335589  285 ip_vs,cnic,ip6t_REJECT,nf_conntrack_ipv6,nf_defrag_ipv6
配置VIP地址:
[root@DR1 ~]# ifconfig eth0:0 10.10.10.140/24 up
[root@DR1 ~]# route add -host 10.10.10.140 dev eth0 
[root@DR1 ~]# ifconfig -a
eth0      Link encap:Ethernet  HWaddr 00:0C:29:53:CF:52  
          inet addr:10.10.10.130  Bcast:10.10.10.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fe53:cf52/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:2849 errors:0 dropped:0 overruns:0 frame:0
          TX packets:955 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:268088 (261.8 KiB)  TX bytes:112049 (109.4 KiB)
eth0:0    Link encap:Ethernet  HWaddr 00:0C:29:53:CF:52  
          inet addr:10.10.10.140  Bcast:10.10.10.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:6 errors:0 dropped:0 overruns:0 frame:0
          TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:344 (344.0 b)  TX bytes:344 (344.0 b)
  
查看路由表信息:
[root@DR1 ~]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.10.10.140    0.0.0.0         255.255.255.255 UH    0      0        0 eth0
10.10.10.0      0.0.0.0         255.255.255.0   U     0      0        0 eth0
169.254.0.0     0.0.0.0         255.255.0.0     U     1002   0        0 eth0
0.0.0.0         10.10.10.2      0.0.0.0         UG    0      0        0 eth0
手动配置LVS-ipvs规则:
[root@DR1 ~]# ipvsadm -A -t 10.10.10.140:80 -s rr
[root@DR1 ~]# ipvsadm -A -t 10.10.10.140:80 -s rr -p 20
可选:-p,是会话保持时间
[root@DR1 ~]# ipvsadm -a -t 10.10.10.140:80 -r 10.10.10.131 -g -w 1
[root@DR1 ~]# ipvsadm -a -t 10.10.10.140:80 -r 10.10.10.132 -g -w 1
-g:代表DR模式
-w 1:指的是设置权重为1
查看ipvs,可以看到使用rr算法,下面的real server分别是10.10.10.131和10.10.10.132
[root@DR1 ~]# ipvsadm -L -n
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.10.10.140:80 rr persistent 20
  -> 10.10.10.131:80              Route   1      0          0         
  -> 10.10.10.132:80              Route   1      0          0 
  
扩充选项:
a) 删除LVS
[root@DR1 ~]# ipvsadm -D -t 10.10.10.140:80 -s rr -p 20
[root@DR1 ~]# ipvsadm -D -t 10.10.10.140:80
[root@DR1 ~]# ipvsadm -d -t 10.10.10.140:80 -r 10.10.10.131
[root@DR1 ~]# ipvsadm -d -t 10.10.10.140:80 -r 10.10.10.132 
 
b) 查看连接状态
[root@DR1 ~]# ipvsadm -L -n
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.10.10.140:80 rr
  -> 10.10.10.131:80              Route   1      0          194       
  -> 10.10.10.132:80              Route   1      0          194       
[root@DR1 ~]# watch -n 2 ipvsadm -L -n
[root@DR1 html]# watch -n 2 ipvsadm -L -n --stats

2)RS1的配置:

停用iptables规则:
[root@C67-X64-A2 ~]# iptables -X
[root@C67-X64-A2 ~]# iptables -F
[root@C67-X64-A2 ~]# iptables -Z
[root@C67-X64-A2 ~]# service iptables stop
iptables:将链设置为政策 ACCEPT:filter                    [确定]
iptables:清除防火墙规则:                                 [确定]
iptables:正在卸载模块:                                   [确定]
[root@C67-X64-A2 ~]# chkconfig iptables off
绑定lo地址(注意网关为255.255.255.255):
[root@RS1 ~]# ifconfig lo:0 10.10.10.140 netmask 255.255.255.255 up
[root@RS1 ~]# route add -host 10.10.10.140 dev lo
[root@RS1 ~]# ifconfig -a
eth0      Link encap:Ethernet  HWaddr 00:0C:29:38:73:A5  
          inet addr:10.10.10.131  Bcast:10.10.10.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fe38:73a5/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:2794 errors:0 dropped:0 overruns:0 frame:0
          TX packets:504 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:188141 (183.7 KiB)  TX bytes:52385 (51.1 KiB)
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:4 errors:0 dropped:0 overruns:0 frame:0
          TX packets:4 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:240 (240.0 b)  TX bytes:240 (240.0 b)
lo:0      Link encap:Local Loopback  
          inet addr:10.10.10.140  Mask:255.255.255.255
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
  
[root@RS1 ~]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.10.10.140    0.0.0.0         255.255.255.255 UH    0      0        0 lo
10.10.10.0      0.0.0.0         255.255.255.0   U     0      0        0 eth0
169.254.0.0     0.0.0.0         255.255.0.0     U     1002   0        0 eth0
0.0.0.0         10.10.10.2      0.0.0.0         UG    0      0        0 eth0
配置httpd服务:
[root@RS1 ~]# yum -y install httpd
[root@RS1 ~]# service httpd start
[root@RS1 ~]# chkconfig httpd on
[root@RS1 ~]# echo "10.10.10.131">/var/www/html/index
配置ARP抑制:
[root@RS1 ~]# echo 1 >/proc/sys/net/ipv4/conf/lo/arp_ignore
[root@RS1 ~]# echo 1 >/proc/sys/net/ipv4/conf/all/arp_ignore
[root@RS1 ~]# echo 2 >/proc/sys/net/ipv4/conf/lo/arp_announce
[root@RS1 ~]# echo 2 >/proc/sys/net/ipv4/conf/all/arp_announce
补充资料:
arp_announce:
说明:对网络接口上,本地IP地址的发出的,ARP回应,作出相应级别的限制: 确定不同程度的限制,宣布对来自本地源IP地址发出Arp请求的接口 
0 - (默认) 在任意网络接口(eth0,eth1,lo)上的任何本地地址 
1 -尽量避免不在该网络接口子网段的本地地址做出arp回应. 当发起ARP请求的源IP地址是被设置应该经由路由达到此网络接口的时候很有用.此时会检查来访IP是否为所有接口上的子网段内ip之一.如果改来访IP不属于各个网络接口上的子网段内,那么将采用级别2的方式来进行处理. 
2 - 对查询目标使用最适当的本地地址.在此模式下将忽略这个IP数据包的源地址并尝试选择与能与该地址通信
arp_ignore:
说明:定义对目标地址为本地IP的ARP询问不同的应答模式0 
0 - (默认值): 回应任何网络接口上对任何本地IP地址的arp查询请求 
1 - 只回答目标IP地址是来访网络接口本地地址的ARP查询请求 
2 -只回答目标IP地址是来访网络接口本地地址的ARP查询请求,且来访IP必须在该网络接口的子网段内 
3 - 不回应该网络界面的arp请求,而只对设置的唯一和连接地址做出回应 
4-7 - 保留未使用 
8 -不回应所有(本地地址)的arp查询

RS2的配置:

清空iptables策略:
[root@C67-X64-A3 ~]# iptables -X
[root@C67-X64-A3 ~]# iptables -F
[root@C67-X64-A3 ~]# iptables -Z
[root@C67-X64-A3 ~]# service iptables stop
iptables:将链设置为政策 ACCEPT:filter                    [确定]
iptables:清除防火墙规则:                                 [确定]
iptables:正在卸载模块:                                   [确定]
[root@C67-X64-A3 ~]# chkconfig iptables off
绑定lo地址(注意网关为255.255.255.255):
[root@RS2 ~]# ifconfig lo:0 10.10.10.140 netmask 255.255.255.255 up
[root@RS2 ~]# route add -host 10.10.10.140 dev lo
[root@RS2 ~]# ifconfig -a
eth0      Link encap:Ethernet  HWaddr 00:0C:29:D7:1F:73  
          inet addr:10.10.10.132  Bcast:10.10.10.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fed7:1f73/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:2671 errors:0 dropped:0 overruns:0 frame:0
          TX packets:450 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:176939 (172.7 KiB)  TX bytes:48342 (47.2 KiB)
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:4 errors:0 dropped:0 overruns:0 frame:0
          TX packets:4 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:240 (240.0 b)  TX bytes:240 (240.0 b)
lo:0      Link encap:Local Loopback  
          inet addr:10.10.10.140  Mask:255.255.255.255
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
  
[root@RS2 ~]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.10.10.140    0.0.0.0         255.255.255.255 UH    0      0        0 lo
10.10.10.0      0.0.0.0         255.255.255.0   U     0      0        0 eth0
169.254.0.0     0.0.0.0         255.255.0.0     U     1002   0        0 eth0
0.0.0.0         10.10.10.2      0.0.0.0         UG    0      0        0 eth0
配置httpd服务:
[root@RS2 ~]# yum -y install httpd
[root@RS2 ~]# service httpd start
[root@RS2 ~]# chkconfig httpd on
[root@RS2 ~]# echo "10.10.10.132">/var/www/html/index
配置ARP抑制:
[root@RS2 ~]# echo 1 >/proc/sys/net/ipv4/conf/lo/arp_ignore
[root@RS2 ~]# echo 1 >/proc/sys/net/ipv4/conf/all/arp_ignore
[root@RS2 ~]# echo 2 >/proc/sys/net/ipv4/conf/lo/arp_announce
[root@RS2 ~]# echo 2 >/proc/sys/net/ipv4/conf/all/arp_announce
补充资料:
arp_announce:
说明:对网络接口上,本地IP地址的发出的,ARP回应,作出相应级别的限制: 确定不同程度的限制,宣布对来自本地源IP地址发出Arp请求的接口 
0 - (默认) 在任意网络接口(eth0,eth1,lo)上的任何本地地址 
1 -尽量避免不在该网络接口子网段的本地地址做出arp回应. 当发起ARP请求的源IP地址是被设置应该经由路由达到此网络接口的时候很有用.此时会检查来访IP是否为所有接口上的子网段内ip之一.如果改来访IP不属于各个网络接口上的子网段内,那么将采用级别2的方式来进行处理. 
2 - 对查询目标使用最适当的本地地址.在此模式下将忽略这个IP数据包的源地址并尝试选择与能与该地址通信
arp_ignore:
说明:定义对目标地址为本地IP的ARP询问不同的应答模式0 
0 - (默认值): 回应任何网络接口上对任何本地IP地址的arp查询请求 
1 - 只回答目标IP地址是来访网络接口本地地址的ARP查询请求 
2 -只回答目标IP地址是来访网络接口本地地址的ARP查询请求,且来访IP必须在该网络接口的子网段内 
3 - 不回应该网络界面的arp请求,而只对设置的唯一和连接地址做出回应 
4-7 - 保留未使用 
8 -不回应所有(本地地址)的arp查询

到此LVS-DR模式的配置基本完成,实际工作中,我们大多不会手动进行配置,而是写成配置脚本

编译LVS报错:(解决CentOS 6.7下编译安装ipvsadm-1.26报错)

[root@DR1 ipvsadm-1.26]# make
make -C libipvs
make[1]: Entering directory `/usr/local/src/ipvsadm-1.26/libipvs'
gcc -Wall -Wunused -Wstrict-prototypes -g -fPIC -DLIBIPVS_USE_NL  -DHAVE_NET_IP_VS_H -c -o libipvs.o libipvs.c
gcc -Wall -Wunused -Wstrict-prototypes -g -fPIC -DLIBIPVS_USE_NL  -DHAVE_NET_IP_VS_H -c -o ip_vs_nl_policy.o ip_vs_nl_policy.c
ar rv libipvs.a libipvs.o ip_vs_nl_policy.o
ar: creating libipvs.a
a - libipvs.o
a - ip_vs_nl_policy.o
gcc -shared -Wl,-soname,libipvs.so -o libipvs.so libipvs.o ip_vs_nl_policy.o
make[1]: Leaving directory `/usr/local/src/ipvsadm-1.26/libipvs'
gcc -Wall -Wunused -Wstrict-prototypes -g  -DVERSION=\"1.26\" -DSCHEDULERS=\""rr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq"\" -DPE_LIST=\""sip"\"  -DHAVE_NET_IP_VS_H -c -o ipvsadm.o ipvsadm.c
ipvsadm.c: 在函数‘print_largenum’中:
ipvsadm.c:1383: 警告:域宽 的类型应该是‘int’,但实参 2 的类型为‘size_t’
gcc -Wall -Wunused -Wstrict-prototypes -g  -DVERSION=\"1.26\" -DSCHEDULERS=\""rr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq"\" -DPE_LIST=\""sip"\"  -DHAVE_NET_IP_VS_H -c -o config_stream.o config_stream.c
gcc -Wall -Wunused -Wstrict-prototypes -g  -DVERSION=\"1.26\" -DSCHEDULERS=\""rr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq"\" -DPE_LIST=\""sip"\"  -DHAVE_NET_IP_VS_H -c -o dynamic_array.o dynamic_array.c
gcc -Wall -Wunused -Wstrict-prototypes -g -o ipvsadm ipvsadm.o config_stream.o dynamic_array.o libipvs/libipvs.a  -lnl
ipvsadm.o: In function `parse_options':
/usr/local/src/ipvsadm-1.26/ipvsadm.c:432: undefined reference to `poptGetContext'
/usr/local/src/ipvsadm-1.26/ipvsadm.c:435: undefined reference to `poptGetNextOpt'
/usr/local/src/ipvsadm-1.26/ipvsadm.c:660: undefined reference to `poptBadOption'
/usr/local/src/ipvsadm-1.26/ipvsadm.c:502: undefined reference to `poptGetNextOpt'
/usr/local/src/ipvsadm-1.26/ipvsadm.c:667: undefined reference to `poptStrerror'
/usr/local/src/ipvsadm-1.26/ipvsadm.c:667: undefined reference to `poptBadOption'
/usr/local/src/ipvsadm-1.26/ipvsadm.c:670: undefined reference to `poptFreeContext'
/usr/local/src/ipvsadm-1.26/ipvsadm.c:677: undefined reference to `poptGetArg'
/usr/local/src/ipvsadm-1.26/ipvsadm.c:678: undefined reference to `poptGetArg'
/usr/local/src/ipvsadm-1.26/ipvsadm.c:679: undefined reference to `poptGetArg'
/usr/local/src/ipvsadm-1.26/ipvsadm.c:690: undefined reference to `poptGetArg'
/usr/local/src/ipvsadm-1.26/ipvsadm.c:693: undefined reference to `poptFreeContext'
collect2: ld 返回 1
make: *** [ipvsadm] 错误 1
[root@DR1 ipvsadm-1.26]# echo $?
2

解决方法:

[root@DR1 ipvsadm-1.26]# yum -y install popt-static
[root@DR1 ipvsadm-1.26]# make
make -C libipvs
make[1]: Entering directory `/usr/local/src/ipvsadm-1.26/libipvs'
make[1]: Nothing to be done for `all'.
make[1]: Leaving directory `/usr/local/src/ipvsadm-1.26/libipvs'
gcc -Wall -Wunused -Wstrict-prototypes -g -o ipvsadm ipvsadm.o config_stream.o dynamic_array.o libipvs/libipvs.a -lpopt -lnl
[root@DR1 ipvsadm-1.26]# echo $?
0

参考资料:

http://vqiao.blog.51cto.com/9368913/1571200

http://oldboy.blog.51cto.com/2561410/1240412

lvs-dr为前段调度器的脚本

lvs-rs为后端Real Server的脚本

LVS DR模式lvsdr.txt

LVS DR模式lvsrs.txt

原创文章,作者:Net21-冰冻vs西瓜,如若转载,请注明出处:http://www.178linux.com/42589

(0)
Net21-冰冻vs西瓜Net21-冰冻vs西瓜
上一篇 2016-09-19
下一篇 2016-09-19

相关推荐

  • 【26期】Linux第五周学习小总结

        第五周的学习内容很丰富, 从查找到压缩打包,到软件包的管理,其中尤其是以压缩的内容最为丰富,而且庞大的选项让人绝望,那我今天就总结了一下压缩的一些东西,和大家一起分享。     为什么会产生压缩工具呢?因为我们的现在的很多文件会利用到的东西很多,电脑的读存速度也越来越快,一些大的文件在传输和使用上就会很麻烦,虽…

    2017-08-12
  • linux上的LVM简明教程

    LVM是一个多才多艺的硬盘系统工具。在Linux上非常的好用,传统分区使用固定大小分区,重新调整大小十分麻烦。但是,LVM可以创建和管理“逻辑”卷,而不是直接使用物理硬盘。可以让管理员弹性的管理逻辑卷的扩大缩小,操作简单,而不损坏已存储的数据。可以随意将新的硬盘添加到LVM,以直接扩展已经存在的逻辑卷。 首先是实际的物理磁盘及其划分的分区和其上的物理卷(PV…

    Linux干货 2017-05-02
  • 马哥教育网络20期+第8周练习博客

    1、请描述网桥、集线器、二层交换机、三层交换机、路由器的功能、使用场景与区别。 网桥:链接层设备,基于MAC地址过滤。 集线器:物理层设备,基本都属于半双工模式。集线器与网桥在现在的局域网中基本都不用了。 二层交换机:基本MAC转发数据,功能齐全的可支持VLAN等功能。常见的有100/1000M、16口/24口/48口。 三层交换机:功能齐全的交换机,具备都…

    Linux干货 2016-08-01
  • Linux设备驱动Hello World程序介绍

    by Valerie Henson07/05/2007 (译者注:本文的例子是只能在linux的2.6内核下使用的,2.6以上的内核,译者没有做过实验,2.4是要修改make文件才能运行。) 本文的出处:这里 自古以来,学习一门新编程语言的第一步就是写一个打印“hello world”的程序(可以看《hello world 集中营》这个帖子供罗列了300个“…

    Linux干货 2015-04-01
  • ansible学习笔记之1

    ansible学习笔记之1 ansible学习笔记之1 ansible 基础 ad-hoc 基础概念 ansible学习笔记之1 说说运维工具的类型 > 运维工具按是否需要有代理程序来划分分为两类:      agent(需要代理工具):          基于专用的age…

    2016-11-21
  • 学习linux命令和帮助

    一、初级命令: 命令的语法通用格式:  #COMMAND OPTIONS ARGUMRNTS OPTIONS:制定命令的运行特性 选项有两种表现形式:    段选项: -c    短选项:–word 例如 –help –human-readable ARGUM…

    Linux干货 2016-10-30