一、前言
在cloud环境中,不是所有的application都有使用80端口这种特权端口的权限;但是在IPVS direct routing模式下,VIP监听的端口必须要保持和后端real server上的application监听的端口一致,见文章http://www.austintek.com/LVS/LVS-HOWTO/HOWTO/LVS-HOWTO.rewrite_ports.html:
本文通过iptables来解决这个问题,最终达到IPVS DR模式监听80端口,后端HTTP服务监听8080端口,客户端访问VIP:80可以得到后端8080端口提供的服务。
转载自https://blog.csdn.net/cloudvtech
二、IPVS DR模式端口转换的实现
2.1 机器配置
1
2
3
4 1IPVS director: 192.168.166.102
2IPVS real server:192.168.166.103
3VIP:192.168.166.111
4
2.2
IPVS director的设置
1
2
3
4
5
6
7 1ipvsadm -C
2ipvsadm -A -t 192.168.166.111 -s rr
3ipvsadm -a -t 192.168.166.111:80 -r 192.168.166.103:80 -w 1 -g
4
5ifconfig ens33:0 192.168.166.111 broadcast 192.168.166.255 netmask 255.255.255.0 up
6route add -host 192.168.166.111 dev ens33:0
7
/etc/sysctl.conf
1
2
3
4
5
6 1net.ipv4.ip_forward = 1
2net.ipv4.conf.all.send_redirects = 0
3net.ipv4.conf.default.send_redirects = 0
4net.ipv4.conf.ens33.send_redirects = 0
5net.ipv4.conf.all.rp_filter = 0
6
2.3 IPVS real server的设置
/etc/sysctl.conf
1
2
3
4
5 1net.ipv4.conf.all.arp_ignore = 1
2net.ipv4.conf.all.arp_announce = 2
3net.ipv4.conf.ens33.arp_ignore = 1
4net.ipv4.conf.ens33.arp_announce = 2
5
1
2
3
4 1
2ifconfig lo:0 192.168.166.111 broadcast 192.168.166.255 netmask 255.255.255.255 up
3route add -host 192.168.166.111 dev lo:0
4
并且启动http服务监听在80端口
2.4 在IPVS director插入如下iptables debug LOG
1
2
3 1iptables -t mangle -A INPUT -p tcp -m tcp --dport 80 -j LOG --log-prefix "[INPUT|mangle] "
2iptables -t mangle -A OUTPUT -p tcp -m tcp --dport 80 -j LOG --log-prefix "[OUTPUT|mangle] "
3
2.5 在IPVS read server插入如下iptables debug LOG
1
2
3
4 1iptables -t mangle -A OUTPUT -p tcp -m tcp --sport 8080 -j LOG --log-prefix "[OUTPUT|mangle] port 8080 "
2iptables -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j LOG --log-prefix "[INPUT|nat] before REDIRECT "
3iptables -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080
4
2.6 从其它客户端访问VIP的80端口
curl 192.168.166.111:80
可以得到返回:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 1curl 192.168.166.111 -vvv
2* Rebuilt URL to: 192.168.166.111/
3* Trying 192.168.166.111...
4* TCP_NODELAY set
5* Connected to 192.168.166.111 (192.168.166.111) port 80 (#0)
6> GET / HTTP/1.1
7> Host: 192.168.166.111
8> User-Agent: curl/7.52.1
9> Accept: */*
10>
11< HTTP/1.1 403 Forbidden
12< Date: Tue, 01 May 2018 05:37:41 GMT
13< Server: Apache/2.4.6 (CentOS)
14< Last-Modified: Thu, 16 Oct 2014 13:20:58 GMT
15< ETag: "1321-5058a1e728280"
16< Accept-Ranges: bytes
17< Content-Length: 4897
18< Content-Type: text/html; charset=UTF-8
19<
20
21
2.7 IPVS director iptables LOG输出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 1May 1 01:38:04 k8s-node1 kernel: [INPUT|mangle] IN=ens33 OUT= MAC=00:0c:29:e7:54:7c:00:50:56:c0:00:08:08:00 SRC=192.168.166.1 DST=192.168.166.111 LEN=64 TOS=0x00 PREC=0x00 TTL=64 ID=51301 DF PROTO=TCP SPT=56047 DPT=80 WINDOW=65535 RES=0x00 SYN URGP=0
2May 1 01:38:04 k8s-node1 kernel: [OUTPUT|mangle] IN= OUT=ens33 SRC=192.168.166.1 DST=192.168.166.111 LEN=64 TOS=0x00 PREC=0x00 TTL=64 ID=51301 DF PROTO=TCP SPT=56047 DPT=80 WINDOW=65535 RES=0x00 SYN URGP=0
3May 1 01:38:04 k8s-node1 kernel: [INPUT|mangle] IN=ens33 OUT= MAC=00:0c:29:e7:54:7c:00:50:56:c0:00:08:08:00 SRC=192.168.166.1 DST=192.168.166.111 LEN=52 TOS=0x00 PREC=0x00 TTL=64 ID=12788 DF PROTO=TCP SPT=56047 DPT=80 WINDOW=4117 RES=0x00 ACK URGP=0
4May 1 01:38:04 k8s-node1 kernel: [OUTPUT|mangle] IN= OUT=ens33 SRC=192.168.166.1 DST=192.168.166.111 LEN=52 TOS=0x00 PREC=0x00 TTL=64 ID=12788 DF PROTO=TCP SPT=56047 DPT=80 WINDOW=4117 RES=0x00 ACK URGP=0
5May 1 01:38:04 k8s-node1 kernel: [INPUT|mangle] IN=ens33 OUT= MAC=00:0c:29:e7:54:7c:00:50:56:c0:00:08:08:00 SRC=192.168.166.1 DST=192.168.166.111 LEN=131 TOS=0x00 PREC=0x00 TTL=64 ID=43668 DF PROTO=TCP SPT=56047 DPT=80 WINDOW=4117 RES=0x00 ACK PSH URGP=0
6May 1 01:38:04 k8s-node1 kernel: [OUTPUT|mangle] IN= OUT=ens33 SRC=192.168.166.1 DST=192.168.166.111 LEN=131 TOS=0x00 PREC=0x00 TTL=64 ID=43668 DF PROTO=TCP SPT=56047 DPT=80 WINDOW=4117 RES=0x00 ACK PSH URGP=0
7May 1 01:38:04 k8s-node1 kernel: [INPUT|mangle] IN=ens33 OUT= MAC=00:0c:29:e7:54:7c:00:50:56:c0:00:08:08:00 SRC=192.168.166.1 DST=192.168.166.111 LEN=52 TOS=0x00 PREC=0x00 TTL=64 ID=61495 DF PROTO=TCP SPT=56047 DPT=80 WINDOW=4027 RES=0x00 ACK URGP=0
8May 1 01:38:04 k8s-node1 kernel: [OUTPUT|mangle] IN= OUT=ens33 SRC=192.168.166.1 DST=192.168.166.111 LEN=52 TOS=0x00 PREC=0x00 TTL=64 ID=61495 DF PROTO=TCP SPT=56047 DPT=80 WINDOW=4027 RES=0x00 ACK URGP=0
9May 1 01:38:04 k8s-node1 kernel: [INPUT|mangle] IN=ens33 OUT= MAC=00:0c:29:e7:54:7c:00:50:56:c0:00:08:08:00 SRC=192.168.166.1 DST=192.168.166.111 LEN=52 TOS=0x00 PREC=0x00 TTL=64 ID=11136 DF PROTO=TCP SPT=56047 DPT=80 WINDOW=4096 RES=0x00 ACK URGP=0
10May 1 01:38:04 k8s-node1 kernel: [OUTPUT|mangle] IN= OUT=ens33 SRC=192.168.166.1 DST=192.168.166.111 LEN=52 TOS=0x00 PREC=0x00 TTL=64 ID=11136 DF PROTO=TCP SPT=56047 DPT=80 WINDOW=4096 RES=0x00 ACK URGP=0
11May 1 01:38:04 k8s-node1 kernel: [INPUT|mangle] IN=ens33 OUT= MAC=00:0c:29:e7:54:7c:00:50:56:c0:00:08:08:00 SRC=192.168.166.1 DST=192.168.166.111 LEN=52 TOS=0x00 PREC=0x00 TTL=64 ID=10635 DF PROTO=TCP SPT=56047 DPT=80 WINDOW=4070 RES=0x00 ACK URGP=0
12May 1 01:38:04 k8s-node1 kernel: [OUTPUT|mangle] IN= OUT=ens33 SRC=192.168.166.1 DST=192.168.166.111 LEN=52 TOS=0x00 PREC=0x00 TTL=64 ID=10635 DF PROTO=TCP SPT=56047 DPT=80 WINDOW=4070 RES=0x00 ACK URGP=0
13May 1 01:38:04 k8s-node1 kernel: [INPUT|mangle] IN=ens33 OUT= MAC=00:0c:29:e7:54:7c:00:50:56:c0:00:08:08:00 SRC=192.168.166.1 DST=192.168.166.111 LEN=52 TOS=0x00 PREC=0x00 TTL=64 ID=46543 DF PROTO=TCP SPT=56047 DPT=80 WINDOW=4096 RES=0x00 ACK FIN URGP=0
14May 1 01:38:04 k8s-node1 kernel: [OUTPUT|mangle] IN= OUT=ens33 SRC=192.168.166.1 DST=192.168.166.111 LEN=52 TOS=0x00 PREC=0x00 TTL=64 ID=46543 DF PROTO=TCP SPT=56047 DPT=80 WINDOW=4096 RES=0x00 ACK FIN URGP=0
15May 1 01:38:04 k8s-node1 kernel: [INPUT|mangle] IN=ens33 OUT= MAC=00:0c:29:e7:54:7c:00:50:56:c0:00:08:08:00 SRC=192.168.166.1 DST=192.168.166.111 LEN=52 TOS=0x00 PREC=0x00 TTL=64 ID=53957 DF PROTO=TCP SPT=56047 DPT=80 WINDOW=4096 RES=0x00 ACK URGP=0
16May 1 01:38:04 k8s-node1 kernel: [OUTPUT|mangle] IN= OUT=ens33 SRC=192.168.166.1 DST=192.168.166.111 LEN=52 TOS=0x00 PREC=0x00 TTL=64 ID=53957 DF PROTO=TCP SPT=56047 DPT=80 WINDOW=4096 RES=0x00 ACK URGP=0
17
18
2.8 IPVS real server iptables LOG输出
1
2
3
4
5
6
7 1May 1 01:37:41 k8s-node2 kernel: [INPUT|nat] before REDIRECT IN=ens33 OUT= MAC=00:0c:29:75:24:37:00:0c:29:e7:54:7c:08:00 SRC=192.168.166.1 DST=192.168.166.111 LEN=64 TOS=0x00 PREC=0x00 TTL=64 ID=51301 DF PROTO=TCP SPT=56047 DPT=80 WINDOW=65535 RES=0x00 SYN URGP=0
2May 1 01:37:41 k8s-node2 kernel: [OUTPUT|mangle] port 8080 IN= OUT=ens33 SRC=192.168.166.103 DST=192.168.166.1 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=8080 DPT=56047 WINDOW=28960 RES=0x00 ACK SYN URGP=0
3May 1 01:37:41 k8s-node2 kernel: [OUTPUT|mangle] port 8080 IN= OUT=ens33 SRC=192.168.166.103 DST=192.168.166.1 LEN=52 TOS=0x00 PREC=0x00 TTL=64 ID=32293 DF PROTO=TCP SPT=8080 DPT=56047 WINDOW=227 RES=0x00 ACK URGP=0
4May 1 01:37:41 k8s-node2 kernel: [OUTPUT|mangle] port 8080 IN= OUT=ens33 SRC=192.168.166.103 DST=192.168.166.1 LEN=4396 TOS=0x00 PREC=0x00 TTL=64 ID=32294 DF PROTO=TCP SPT=8080 DPT=56047 WINDOW=227 RES=0x00 ACK URGP=0
5May 1 01:37:41 k8s-node2 kernel: [OUTPUT|mangle] port 8080 IN= OUT=ens33 SRC=192.168.166.103 DST=192.168.166.1 LEN=857 TOS=0x00 PREC=0x00 TTL=64 ID=32297 DF PROTO=TCP SPT=8080 DPT=56047 WINDOW=227 RES=0x00 ACK PSH URGP=0
6May 1 01:37:41 k8s-node2 kernel: [OUTPUT|mangle] port 8080 IN= OUT=ens33 SRC=192.168.166.103 DST=192.168.166.1 LEN=52 TOS=0x00 PREC=0x00 TTL=64 ID=32298 DF PROTO=TCP SPT=8080 DPT=56047 WINDOW=227 RES=0x00 ACK FIN URGP=0
7
转载自https://blog.csdn.net/cloudvtech
三、与从IPVS director访问VIP相结合
可以将本方案和根据文章《从IPVS DR模式下director不能访问VIP问题的探究》提供的解决方案绑定在一起,就可以为kubernetes容器云环境下的IPVS service找到无缝的解决方案:
- IPVS director可以和后端application混合部署
- IPVS director可以监听80特权端口
- application只需监听任意无特权端口
- 客户端可以在包括IPVS director所在的worker node之内的任何位置访问VIP:80服务