두 대의 컴퓨터가 있습니다: edge1(10.22.46.11)과 edge2(10.22.46.48). 둘 다 k8s 작업자 노드입니다. edge1에서 끝점이 edge2에 있는 서비스에 액세스하려고 합니다. 나는 다음과 같은 요청을 보냅니다.
curl -m 5 host-edge-nginx
curl: (28) Connection timed out after 5001 milliseconds\
bash-5.1# nslookup host-edge-nginx
Server: 169.254.25.10
Address: 169.254.25.10#53
Name: host-edge-nginx.fabedge-e2e-test.svc.cluster.local
Address: 10.233.52.186
서비스 호스트-edge-nginx-793의 IP는 10.233.52.186이며, 이는 edge1의 kube-ipvs0에 할당됩니다. 보시다시피 요청 시간이 초과되었습니다. tcpdump 출력:
[root@edge1 ~]# tcpdump -nn -i any port 80 or 30080
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
17:06:49.407148 IP 10.22.46.11.57104 > 10.22.46.48.30080: Flags [S], seq 1003993294, win 43690, options [mss 65495,sackOK,TS val 84142687 ecr 0,nop,wscale 7], length 0
17:06:49.407481 IP 10.22.46.48.30080 > 10.22.46.11.57104: Flags [S.], seq 4067044182, ack 1003993295, win 28960, options [mss 1460,sackOK,TS val 197964760 ecr 84142687,nop,wscale 7], length 0
17:06:50.407345 IP 10.22.46.11.57104 > 10.22.46.48.30080: Flags [S], seq 1003993294, win 43690, options [mss 65495,sackOK,TS val 84143688 ecr 0,nop,wscale 7], length 0
17:06:50.407688 IP 10.22.46.48.30080 > 10.22.46.11.57104: Flags [S.], seq 4067044182, ack 1003993295, win 28960, options [mss 1460,sackOK,TS val 197965760 ecr 84142687,nop,wscale 7], length 0
17:06:51.408815 IP 10.22.46.48.30080 > 10.22.46.11.57104: Flags [S.], seq 4067044182, ack 1003993295, win 28960, options [mss 1460,sackOK,TS val 197966762 ecr 84142687,nop,wscale 7], length 0
17:06:52.411309 IP 10.22.46.11.57104 > 10.22.46.48.30080: Flags [S], seq 1003993294, win 43690, options [mss 65495,sackOK,TS val 84145692 ecr 0,nop,wscale 7], length 0
17:06:52.411652 IP 10.22.46.48.30080 > 10.22.46.11.57104: Flags [S.], seq 4067044182, ack 1003993295, win 28960, options [mss 1460,sackOK,TS val 197967764 ecr 84142687,nop,wscale 7], length 0
17:06:54.808781 IP 10.22.46.48.30080 > 10.22.46.11.57104: Flags [S.], seq 4067044182, ack 1003993295, win 28960, options [mss 1460,sackOK,TS val 197970162 ecr 84142687,nop,wscale 7], length 0
17:06:58.808756 IP 10.22.46.48.30080 > 10.22.46.11.57104: Flags [S.], seq 4067044182, ack 1003993295, win 28960, options [mss 1460,sackOK,TS val 197974162 ecr 84142687,nop,wscale 7], length 0
연결이 핸드셰이크를 완료할 수 없고 클라이언트가 계속해서 syn 패킷을 재전송하는 것 같습니다.
ss와 netstat를 사용했지만 결과를 찾지 못했습니다. 그런 다음 conntrack을 사용하여 다음을 발견했습니다.
[root@edge1 ~]# conntrack -L | grep 30080
conntrack v1.4.4 (conntrack-tools): 17 flow entries have been shown.
tcp 6 59 SYN_RECV src=10.233.52.186 dst=10.233.52.186 sport=52626 dport=80 src=10.22.46.48 dst=10.22.46.11 sport=30080 dport=1147 mark=0 use=1
보시다시피 연결이 SYNC_RECV 상태에서 멈춰 있습니다. 클라이언트가 ACK 패킷을 받지 못한 것 같지만 iptables를 사용하여 다음을 추적했습니다.
[84771.535104] TRACE: raw:PREROUTING:policy:2 IN=eth0 OUT= MAC=fa:16:3e:39:f6:2d:fa:16:3e:c8:8d:b2:08:00 SRC=10.22.46.48 DST=10.22.46.11 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=30080 DPT=38970 SEQ=3634038526 ACK=1413810229 WINDOW=28960 RES=0x00 ACK SYN URGP=0 OPT (020405B40402080A0BD1B6490508ECD001030307)
[84771.535121] TRACE: mangle:PREROUTING:policy:1 IN=eth0 OUT= MAC=fa:16:3e:39:f6:2d:fa:16:3e:c8:8d:b2:08:00 SRC=10.22.46.48 DST=10.22.46.11 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=30080 DPT=38970 SEQ=3634038526 ACK=1413810229 WINDOW=28960 RES=0x00 ACK SYN URGP=0 OPT (020405B40402080A0BD1B6490508ECD001030307)
[84771.535148] TRACE: mangle:INPUT:policy:1 IN=eth0 OUT= MAC=fa:16:3e:39:f6:2d:fa:16:3e:c8:8d:b2:08:00 SRC=10.22.46.48 DST=10.233.52.186 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=30080 DPT=52628 SEQ=3634038526 ACK=1413810229 WINDOW=28960 RES=0x00 ACK SYN URGP=0 OPT (020405B40402080A0BD1B6490508ECD001030307)
[84771.535160] TRACE: filter:INPUT:rule:1 IN=eth0 OUT= MAC=fa:16:3e:39:f6:2d:fa:16:3e:c8:8d:b2:08:00 SRC=10.22.46.48 DST=10.233.52.186 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=30080 DPT=52628 SEQ=3634038526 ACK=1413810229 WINDOW=28960 RES=0x00 ACK SYN URGP=0 OPT (020405B40402080A0BD1B6490508ECD001030307)
[84771.535175] TRACE: filter:KUBE-NODE-PORT:return:2 IN=eth0 OUT= MAC=fa:16:3e:39:f6:2d:fa:16:3e:c8:8d:b2:08:00 SRC=10.22.46.48 DST=10.233.52.186 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=30080 DPT=52628 SEQ=3634038526 ACK=1413810229 WINDOW=28960 RES=0x00 ACK SYN URGP=0 OPT (020405B40402080A0BD1B6490508ECD001030307)
[84771.535186] TRACE: filter:INPUT:policy:2 IN=eth0 OUT= MAC=fa:16:3e:39:f6:2d:fa:16:3e:c8:8d:b2:08:00 SRC=10.22.46.48 DST=10.233.52.186 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=30080 DPT=52628 SEQ=3634038526 ACK=1413810229 WINDOW=28960 RES=0x00 ACK SYN URGP=0 OPT (020405B40402080A0BD1B6490508ECD001030307)
보시다시피 ACK 패킷은 기본적으로 ACCPT인 필터 INPUT 정책을 통과했습니다.
[root@edge1 ~]# iptables -t filter -S | grep INPUT
-P INPUT ACCEPT
-A INPUT -m comment --comment "kubernetes health check rules" -j KUBE-NODE-PORT
따라서 이는 클라이언트가 ACK 패킷을 수신했다는 의미라고 생각합니다.
더 이상 단서가 없어 여기에 갇혀 있습니다. 어떤 도움이라도 환영하며 미리 감사드립니다.
답변1
ACK 패킷이 xfrm 정책과 일치하여 xfrm에 의해 삭제된 것으로 나타났습니다.
답변2
externalTrafficPolicy:Local 및 Proxy-mode=ipvs를 사용하는 경우 다음과 같은 문제가 발생할 수 있습니다.https://github.com/kubernetes/kubernetes/issues/93456#issuecomment-733069629