"lo" 인터페이스를 통해 나가는 패킷 라우팅 건너뛰기

"lo" 인터페이스를 통해 나가는 패킷 라우팅 건너뛰기

소개하다

다음과 같은 부하 분산 구성이 있습니다.

10.0.1.31 - lb
10.0.1.35 - virtual IP
10.0.1.32 - node1 (tomcat + mysql)
10.0.1.33 - node2 (tomcat + mysql)

나는 keepalived이를 사용하여 패킷을 활성 노드로 리디렉션합니다. 공유 IP 주소는 10.0.1.35입니다. lb에는 구성이 필요합니다.

echo "net.ipv4.ip_nonlocal_bind = 1" >> /etc/sysctl.conf

들어오는 패킷을 적절하게 처리하려면 node1과 node2가 10.0.1.35를 열어야 합니다.lo

[root@lb-node1 ~]# ip addr list dev lo
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 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
   inet 10.0.1.35/32 scope global lo
   inet6 ::1/128 scope host 
   valid_lft forever preferred_lft forever

질문

lo로케일 Tomcat이 lb를 통해 mysql에 연결을 시도하는 경우 포트는 10.0.1.35이므로 연결은 로컬 인스턴스에 설정됩니다 .

lo나가는 패킷을 건너뛰고 싶습니다.

시험

mysql 서비스가 비활성화되고 lo인터페이스의 ip가 10.0.1.35인 node1에서 node2의 mysql에 연결을 시도합니다. 안타깝게도 결과는

   [root@lb-node1 ~]# telnet 10.0.1.35 3306
   Trying 10.0.1.35...
   telnet: connect to address 10.0.1.35: Connection refused 

물론 lo 인터페이스에서 10.0.1.35 IP를 제거하면 node2의 mysql 인스턴스에 연결할 수 있습니다.

해결책(?)

적절한 측정항목을 사용하여 경로를 추가해 보았지만 도움이 되지 않았습니다./

    [root@lb-node1 ~]# route -n
    Kernel IP routing table
    Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
    10.0.1.0        0.0.0.0         255.255.255.255 UH    0      0        0 eth0
    10.0.1.0        0.0.0.0         255.255.255.255 UH    100    0        0 lo
    169.254.0.0     0.0.0.0         255.255.0.0     U     1002   0        0 eth0
    0.0.0.0         10.0.1.1        0.0.0.0         UG    0      0        0 eth0

@패트릭 솔루션

vip=10.0.1.35

ip route add local $vip dev lo table 10 proto kernel scope host
ip rule add to $vip lookup 10 prio 1
ip route del local $vip dev lo table local
ip rule add to $vip iif lo lookup main prio 0

@Patrick 솔루션 문제

초기 상태

VIP+IP 라우팅 구성, mysql은 두 노드 모두에서 작동합니다.


P Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.0.1.35:http rr persistent 6
TCP  10.0.1.35:mysql rr persistent 6
  -> 10.0.1.32:mysql              Route   10     0          0
  -> 10.0.1.33:mysql              Route   10     0          2
UDP  10.0.1.35:snmptrap rr persistent 6
  -> 10.0.1.32:snmptrap           Route   10     0          0
  -> 10.0.1.33:snmptrap           Route   10     0          1




root@lb-node1 ~]# mysql -h 10.0.1.35 -u test -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 126
Server version: 5.5.36-MariaDB-wsrep-log MariaDB Server, wsrep_25.9.r3961

Copyright (c) 2000, 2014, Oracle, Monty Program Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> SHOW VARIABLES WHERE Variable_name = 'hostname';
+---------------+----------+
| Variable_name | Value    |
+---------------+----------+
| hostname      | lb-node2 |
+---------------+----------+
1 row in set (0.00 sec)

MariaDB [(none)]> 


[root@lb-node2 ~]# mysql -h 10.0.1.35 -u test -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 133
Server version: 5.5.36-MariaDB-wsrep-log MariaDB Server, wsrep_25.9.r3961

Copyright (c) 2000, 2014, Oracle, Monty Program Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

ariaDB [(none)]> ;
ERROR: No query specified

MariaDB [(none)]> SHOW VARIABLES WHERE Variable_name = 'hostname';
+---------------+----------+
| Variable_name | Value    |
+---------------+----------+
| hostname      | lb-node2 |
+---------------+----------+
1 row in set (0.00 sec)

MariaDB [(none)]> 

보시다시피 모든 것이 잘 작동합니다.

질문

그러나 현재 활성화된 mysql 서버를 종료하면:

[root@lb-node2 ~]# service mysql stop
Shutting down MySQL.... SUCCESS! 
[root@lb-node2 ~]# 



Every 2.0s: ipvsadm -l                                                                                          Fri May  9 10:20:49 2014

IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.0.1.35:http rr persistent 6
TCP  10.0.1.35:mysql rr persistent 6
  -> 10.0.1.32:mysql              Route   10     0          0
UDP  10.0.1.35:snmptrap rr persistent 6
  -> 10.0.1.32:snmptrap           Route   10     0          0
  -> 10.0.1.33:snmptrap           Route   10     0          1

두 노드에서 mysql에 연결할 수 없습니다

[root@lb-node2 ~]# mysql -h 10.0.1.35 -u test -p
Enter password: 

..... 

로드 밸런서가 패킷을 올바르게 리디렉션하기 때문에 node1이 들어오는 패킷을 수락하지 않는 것 같습니다.

[root@lb-node1 ~]# tcpdump -i eth0 'port 3306' and src 10.0.1.33 or dst 10.0.1.33
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
10:35:26.915640 ARP, Reply 10.0.1.35 is-at 52:54:00:30:a3:4b (oui Unknown), length 28
10:35:26.915987 IP 10.0.1.33.38517 > 10.0.1.35.mysql: Flags [S], seq 2024730796, win 14600, options [mss 1460,sackOK,TS val 1298907 ecr 0,nop,wscale 7], length 0
10:35:27.914788 IP 10.0.1.33.38517 > 10.0.1.35.mysql: Flags [S], seq 2024730796, win 14600, options [mss 1460,sackOK,TS val 1299907 ecr 0,nop,wscale 7], length 0
10:35:29.914784 IP 10.0.1.33.38517 > 10.0.1.35.mysql: Flags [S], seq 2024730796, win 14600, options [mss 1460,sackOK,TS val 1301907 ecr 0,nop,wscale 7], length 0

VIP 액세스 권한이 아직 있는데 뭐가 이상한가요?

[root@lb-node1 ~]# ip addr list dev lo
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 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
    inet 10.0.1.35/32 scope global lo
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever



[root@lb-node1 ~]# ip route
10.0.1.0/24 dev eth0  proto kernel  scope link  src 10.0.1.32 
169.254.0.0/16 dev eth0  scope link  metric 1002 
default via 10.0.1.1 dev eth0 

답변1

나는 당신이 달성하려는 것과 비슷한 일을 하는 아주 오래된 코드를 찾아냈습니다. 원하는 효과를 얻으려면 다음을 수행할 수 있습니다.

vip=10.0.1.35

ip route add local $vip dev lo table 10 proto kernel scope host
ip rule add to $vip lookup 10 prio 1
ip route del local $vip dev lo table local
ip rule add to $vip iif lo lookup main prio 0

이렇게 하면 상자가 모든 트래픽을 10.0.1.35네트워크(따라서 해당 IP에 대한 ARP 요청에 응답하는 로드 밸런서)로 전송하게 됩니다. 그러나 상자는 로드 밸런서가 제공하는 모든 트래픽을 계속 허용합니다.


설명하다

더 이해하기 쉽기 때문에 순서대로 설명하겠습니다.
 

ip route del local $vip dev lo table local

10.0.1.35이렇게 하면 모든 트래픽을 localhost 로 보내 표시되는 경로가 제거됩니다 lo.
 

ip route add local $vip dev lo table 10 proto kernel scope host

그러면 방금 삭제한 테이블이 대체되지만 완전히 새로운 테이블( 10)에 배치됩니다.
 

ip rule add to $vip iif lo lookup main prio 0

iif lo이는 로컬 박스( )에서 트래픽을 보낼 때 10.0.1.35"로컬" 경로 대신 기본 경로를 사용하도록 시스템에 지시합니다 . 이렇게 하면 10.0.1.35트래픽이 10.0.1.0/24서브넷(또는 그렇지 않은 경우 로컬 서브넷 /24)으로 라우팅됩니다.
 

ip rule add to $vip lookup 10 prio 1

이 규칙은 나중에 일치하도록 위의 규칙보다 낮은 우선순위(높은 숫자)로 추가됩니다. 트래픽이 위의 규칙과 일치하지 않는 경우(아님 ) 테이블에 일치하는 경로가 있는지 iif lo확인 하고 이전에 추가한 경로를 선택합니다. 이 규칙(및 우리가 표에 추가한 경로 )의 이유는 로드 밸런서가 이 상자로 전송한(따라서 전송되지 않은 ) 모든 트래픽이 거부되지 않기 때문입니다. 기본적으로 이는 커널에 "예, 이 IP는 내 것입니다"라고 알려줍니다.10
10iif lo
 

"로컬" 경로를 테이블로 옮기는 이유 는 규칙이 일치하기를 10원하기 때문입니다 . iif lo lookup main prio 0그러나 "로컬" 테이블은 우선순위가 가장 높으므로 항상 먼저 일치합니다.

 

규칙을 순서대로 추가하는 이유는 방해를 방지하기 위해서입니다. 지침에 표시된 순서대로 추가하면 간격이 생기고 라우팅이 없어 로컬 상자로 전송되는 모든 트래픽이 거부됩니다 10.0.1.35.10.0.1.35

관련 정보