Commit Graph

9 Commits

Author SHA1 Message Date
jianmingfan 050ed008c3 Introduce ipvs_mode to share ipvs service and connection between net namespace
1) switch to default net ns during entry function
2) switch to skb's dev net ns during route
3) DNAT to local ip will set skb->dst to loopback dev
4) rename bpf_mode_on to ipvs_mode

Signed-off-by: jianmingfan <jianmingfan@tencent.com>
2020-09-08 00:42:25 +08:00
jianmingfan 9465674790 ipvs-ebpf: add non-masqurade-agent support.
previously, for clusterIP type service, no SNAT is done.
However, in some case, user may add rs ip outside vpc which may require
SNAT.

To address this issue, a non snat ip table of max 64 entries are added.

Usage:

1. echo -n "0.0.0.0/0" > /proc/net/ip_vs_non_masq_cidrs will make all ip
bypass snat.

2. echo -n ":" > /proc/net/ip_vs_non_masq_cidrs will make all ip do snat.

3. echo "a.b.c.d/24:a.b.c.e/24" >  /proc/net/ip_vs_non_masq_cidrs

Test case:

create a cluster with 9 PODS

172.19.0.175  172.19.0.176   172.19.0.177 172.19.0.241 172.19.0.242
172.19.0.243 172.19.0.244 172.19.0.100  172.19.0.101

0)

/proc/net/ip_vs_non_masq_cidrs is empty, curl cluster ip shall do SNAT
result: pass

1)

Three ip/32 in  /proc/net/ip_vs_non_masq_cidrs

echo "172.19.0.175/32:172.19.0.176/32:172.19.0.177/32" > /proc/net/ip_vs_non_masq_cidrs

Test:  curl the clusterip, and watch the tcpdump log

Expected result:

access to the ip in list no SNAT; access to the ip not in list do SNAT.

Result: pass, no leak.

2)  stress test

wrk  the clusterip , at the same time, run a program to modify the ip_vs_non_masq_cidrs in a loop

Expected result: curl ok. lo leak

    while [ 1 ]
    do
            echo "172.19.0.175/32:172.19.0.176/32:172.19.0.177/32" > /proc/net/ip_vs_non_masq_cidrs

            sleep 1
            cat /proc/net/ip_vs_non_masq_cidrs
            echo ""
            echo "172.19.0.175/32" > /proc/net/ip_vs_non_masq_cidrs
            sleep 1
            cat /proc/net/ip_vs_non_masq_cidrs
            echo ""
    done

result:  no leak;

3) corner test

write "0.0.0.0/0" to it.

expected result: shall not do SNAT.

result:  ok

echo  -n ":
expected result: do SNAT
result: ok

Signed-off-by: jianmingfan <jianmingfan@tencent.com>
2020-07-07 18:11:48 +08:00
YangYuxi a01a9445c0 ipvs: avoid drop first packet by reusing conntrack
Since 'commit f719e3754ee2 ("ipvs: drop first packet to
redirect conntrack")', when a new TCP connection meet
the conditions that need reschedule, the first syn packet
is dropped, this cause one second latency for the new
connection, more discussion about this problem can easy
search from google, such as:

1)One second connection delay in masque
https://marc.info/?t=151683118100004&r=1&w=2

2)IPVS low throughput #70747
https://github.com/kubernetes/kubernetes/issues/70747

3)Apache Bench can fill up ipvs service proxy in seconds #544
https://github.com/cloudnativelabs/kube-router/issues/544

4)Additional 1s latency in `host -> service IP -> pod`
https://github.com/kubernetes/kubernetes/issues/90854

5)kube-proxy ipvs conn_reuse_mode setting causes errors
with high load from single client
https://github.com/kubernetes/kubernetes/issues/81775

The root cause is when the old session is expired, the
conntrack related to the session is dropped by
ip_vs_conn_drop_conntrack. The code is as follows:
```
static void ip_vs_conn_expire(struct timer_list *t)
{
...

     if ((cp->flags & IP_VS_CONN_F_NFCT) &&
         !(cp->flags & IP_VS_CONN_F_ONE_PACKET)) {
             /* Do not access conntracks during subsys cleanup
              * because nf_conntrack_find_get can not be used after
              * conntrack cleanup for the net.
              */
             smp_rmb();
             if (ipvs->enable)
                     ip_vs_conn_drop_conntrack(cp);
     }
...
}
```
As shown in the code, only when condition (cp->flags & IP_VS_CONN_F_NFCT)
is true, the function ip_vs_conn_drop_conntrack will be called.

So we optimize this by following steps (Administrators
can choose the following optimization by setting
net.ipv4.vs.conn_reuse_old_conntrack=1):
1) erase the IP_VS_CONN_F_NFCT flag (it is safely because
   no packets will use the old session)
2) call ip_vs_conn_expire_now to release the old session,
   then the related conntrack will not be dropped
3) then ipvs unnecessary to drop the first syn packet, it
   just continue to pass the syn packet to the next process,
   create a new ipvs session, and the new session will related
   to the old conntrack(which is reopened by conntrack as a new
   one), the next whole things is just as normal as that the old
   session isn't used to exist.

The above processing has no problems except for passive FTP,
for passive FTP situation, ipvs can judging from
condition (atomic_read(&cp->n_control)) and condition (cp->control).
So, for other conditions(means not FTP), ipvs should give users
the right to choose,they can choose a high performance one processing
logical by setting net.ipv4.vs.conn_reuse_old_conntrack=1. It is necessary
because most business scenarios (such as kubernetes) are very sensitive
to TCP short connection latency.

This patch has been verified on our thousands of kubernets
node servers on Tencent Inc.

Signed-off-by: YangYuxi <yx.atom1@gmail.com>
2020-06-23 19:45:04 +08:00
jianmingfan 8ec35911f7 add no_route_to_host_fix switch to turn on/off the fix in bpf mode
Test case
	1) conn_reuse_mode = 1 && no_route_to_host_fix==1
	result: wrk performance good
	2) conn_reuse_mode = 1 && no_route_to_host_fix==0
	result: wrk performance bad, packet loss
	3) conn_reuse_mode = 0 && no_route_to_host_fix==0
	result: wrk performance good. icmp no route to host error
	4) conn_reuse_mode = 0 && no_route_to_host_fix==1
	result: wrk performance good. no icmp no route to host error

Signed-off-by: jianmingfan <jianmingfan@tencent.com>
2020-05-29 10:41:05 +08:00
jianmingfan ef8004f8fe 1) fix conn_reuse_mode=1 performance degradation as introduced in commit
year 2015 d752c364571743d696c2a54a449ce77550c35ac5
year 2016 f719e3754ee2f7275437e61a6afd520181fdd43b

current only fix it in bpf mode. It will later be promoted to ipvs mode.

The key is that add a ref count in ct so that old/new ip_vs_conn can share it
without packet loss.

Test case
./wrk http 1.0 test, the cps increases from 1.5K to 30K.

2) solve no route to host bug

when conn_reuse_mode = 0, new connection may be redirect to rs with weight=0
if client  port reuse. This cause icmp no route to host if the rs is
terminating

Test case:
 1. wrk http1.0 from client
 2. set rs to zero on lb, then kill the rs

in ipvs mode, you can see icmp error like
14:17:28.509454 IP 10.0.0.4 > 10.0.0.17: ICMP host 172.16.0.16 unreachable, length 68

in bpf mode, this is fixed.

Signed-off-by: jianmingfan <jianmingfan@tencent.com>
2020-05-29 10:41:03 +08:00
Yuxi Yang a44d7f91a8 ip_vs: add sysctl to bypass estimation
Signed-off-by: Fuhai Wang <fuhaiwang@tencent.com>
2020-05-29 10:40:54 +08:00
Hongbo Li fe66d659f4 net: ipvs print limit
When there is no rs, kernel will print:
ipvs will print IPVS: rr: TCP xxxxxX - no destination available
But this is common in k8s.

So add a sysctl to allow user ignore this error.

Signed-off-by: Hongbo Li <herberthbli@tencent.com>
2020-05-29 10:40:16 +08:00
jianmingfan d1a590ff87 This big patch exhances IPVS with BPF SNAT
It does the following

    * To bypass netfilter and conntrack in BPF mode
      ** Add mode=1 switch in modprobe to enable BPF mode
      ** Register different set of netfilter hooks in BPF mode so that
         incoming and response packets are handled in NF PRE-ROUTING
         bypassing conntrack hooks.
      ** Don't access skb->dst if it is null.
      ** Force route in handle_response
      ** Call ip_finish_output directly instead of Netfilter api.
      ** User space shall set /proc/sys/net/ipv4/vs/conntrack to be zero
      ** Call ip defragment during pre-route when needed!

    * To interact with BPF map
      ** ip_vs_conn_new_bpf add entries into BPF map
      ** ip_vs_conn_unlink_bpf del them
      ** in lc,wlc,rr,wrr scheduler, avoid loopback traffic since BPF can't
     handle it currently.

    * Interface
      ** Add file ip_vs_bpf_proc.c to pass BPF map id into IPVS.
2020-05-29 10:39:38 +08:00
Xiaoming Gao 78a8c3c2c2 Init Repo base on 4.14.105 long term, and add base tlinux kernel interfaces
Signed-off-by: Xiaoming Gao <newtongao@tencent.com>
2020-01-02 10:51:04 +08:00