K8s Metal LB Service Trafic Flow: различия между версиями
Sirmax (обсуждение | вклад) |
Sirmax (обсуждение | вклад) |
||
| Строка 13: | Строка 13: | ||
==Если повезло== |
==Если повезло== |
||
Если события логгируются то можно достать из логов |
Если события логгируются то можно достать из логов |
||
| − | [[Файл:OpenSearch MetalLB 250925155617.png]] |
+ | [[Файл:OpenSearch MetalLB 250925155617.png|400px]] |
<PR> |
<PR> |
||
| − | [[Файл:OpenSearch_MetalLB_250925155617.png |
+ | [[Файл:OpenSearch_MetalLB_250925155617.png|400px]] |
<BR> |
<BR> |
||
К сожалению этот простой путь доступен не всегда |
К сожалению этот простой путь доступен не всегда |
||
Версия 15:00, 25 сентября 2025
K8s Metal LB Service Trafic Flow
Заметка о пути трафика с MetalLB
Заметка появилась в процессе расследования почему на сервис можно ходить с некоторых адресов, а с других нельзя.
Для определнности "проблемный" сервис
iam-proxy-alertmanager
"Проблемный" взят в кавычки так как не ясно в сервисе ли дело или в чем-то другом
Найти с какой ноды анонсируется адрес
Если повезло
Если события логгируются то можно достать из логов
<PR>
К сожалению этот простой путь доступен не всегда
Описание сервиса
kubectl -n stacklight get svc iam-proxy-alertmanager NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE iam-proxy-alertmanager LoadBalancer 10.232.100.189 10.80.8.102 443:30358/TCP 42d
Тут виден внешний адрес сервиса - 10.80.8.102
Поиск адреса в логах
Посмотреть все логи по всем подам можно например так:
kubectl -n metallb-system logs daemonset/mcc-metallb-speaker --prefix
|
Обращать внимание на сообщения вроде Found 3 pods, using pod/mcc-metallb-speaker-8k5wl Если такое есть - то логи не полные и нужно смотреть по метке |
|
Можно и нужно искать и по метке, а не только по принадлежности к kubectl -n metallb-system logs -l "app.kubernetes.io/component"="speaker" --prefix |
|
Не забывать что логи могут выводится не все
|
Финальный запрос
kubectl childctl -n metallb-system logs -l app.kubernetes.io/component=speaker --prefix --since=5h --tail=-1 --timestamps | LC_ALL=C sort -k2,2 | grep '10.80.8.102'
[pod/mcc-metallb-speaker-8k5wl/speaker] 2025-09-25T10:24:15.767871702Z {"caller":"main.go:409","event":"serviceAnnounced","ips":["10.80.8.102"],"level":"info","msg":"service has IP, announcing","pool":"default","protocol":"layer2","ts":"2025-09-25T10:24:15Z"}
[pod/mcc-metallb-speaker-8k5wl/speaker] 2025-09-25T10:26:10.381353840Z {"caller":"main.go:453","event":"serviceWithdrawn","ip":["10.80.8.102"],"ips":["10.80.8.102"],"level":"info","msg":"withdrawing service announcement","pool":"default","protocol":"layer2","reason":"notOwner","ts":"2025-09-25T10:26:10Z"}
[pod/mcc-metallb-speaker-hgksn/speaker] 2025-09-25T10:26:10.458269685Z {"caller":"main.go:409","event":"serviceAnnounced","ips":["10.80.8.102"],"level":"info","msg":"service has IP, announcing","pool":"default","protocol":"layer2","ts":"2025-09-25T10:26:10Z"}
[pod/mcc-metallb-speaker-hgksn/speaker] 2025-09-25T10:26:10.535686056Z {"caller":"main.go:409","event":"serviceAnnounced","ips":["10.80.8.102"],"level":"info","msg":"service has IP, announcing","pool":"default","protocol":"layer2","ts":"2025-09-25T10:26:10Z"}
root@nest:~/MOSK/CURRENT/003-K8S-Control-Machines-Objects#
Из этого лога можно понять какой POD анонсировал адрес
- Сначала это был
pod/mcc-metallb-speaker-8k5wl/speaker - Потом он прекратил обслуживание этого сервиса
serviceWithdrawnnotOwner - Сервис теперь анонсируется с
mcc-metallb-speaker-hgksn
Получение адреса ноды
Зная имя POD можно получить ноду (k8s-control-3):
kubectl -n metallb-system get pod/mcc-metallb-speaker-hgksn -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES mcc-metallb-speaker-hgksn 1/1 Running 0 102m 10.80.3.13 k8s-control-3 <none> <none>
Путь прохождени трафика
Трафик на ноде
Тут мы уже знаем на какую ноду (k8s-control-3) прийдет запрос и можем на ней запустить tcpdump и для теста "дернуть" сервис curl https://10.80.8.102 -I -k
root@k8s-control-3:~# tcpdump -n -i any host 10.80.8.102
... 12:12:44.576113 mlb In IP 192.168.22.253.52582 > 10.80.8.102.443: Flags [S], seq 3953098481, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 1301733900 ecr 0,sackOK,eol], length 0 12:12:44.577625 mlb Out IP 10.80.8.102.443 > 192.168.22.253.52582: Flags [S.], seq 1124290493, ack 3953098482, win 64308, options [mss 1410,sackOK,TS val 3194506911 ecr 1301733900,nop,wscale 7], length 0 12:12:44.579051 mlb In IP 192.168.22.253.52582 > 10.80.8.102.443: Flags [.], ack 1, win 2053, options [nop,nop,TS val 1301733903 ecr 3194506911], length 0 12:12:44.579593 mlb In IP 192.168.22.253.52582 > 10.80.8.102.443: Flags [P.], seq 1:302, ack 1, win 2053, options [nop,nop,TS val 1301733903 ecr 3194506911], length 301 ...
192.168.22.253 адрес хоста откуда запускался curl https://10.80.8.102 -I -k
10.80.8.102 адрес сервиса
Разбор сервиса
Для того что бы проследить дальнейший путь трафика нужно подробно разобрать сервис
kubectl -n stacklight get svc iam-proxy-alertmanager -o yaml
selector
Селектор определяет на какие поды будет направлен трафик
selector:
app.kubernetes.io/instance: iam-proxy-alertmanager
app.kubernetes.io/name: iam-proxy
Их можно найти командой
kubectl get pod -A -l app.kubernetes.io/name=iam-proxy,app.kubernetes.io/instance=iam-proxy-alertmanager -o wide
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES stacklight iam-proxy-alertmanager-76997d95b-d9czm 1/1 Running 0 42d 192.168.105.143 stacklight-1 <none> <none> stacklight iam-proxy-alertmanager-76997d95b-mqd2f 1/1 Running 0 42d 192.168.104.66 stacklight-3 <none> <none>
|
Тут видно что трафик будет направлен на 2 пода с адресами
192.168.105.143192.168.104.66
Что можно проверить используя tcpdump
tcpdump -n -i any host 192.168.105.143 or host 192.168.104.66
Вывод сокращен, до нескольких пакетов что бы показать что трафик идет поочередно на один или второй POD
12:26:50.893669 vxlan.calico Out IP 192.168.106.0.36057 > 192.168.105.143.4180: Flags [S], seq 2888292147, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 976299430 ecr 0,sackOK,eol], length 0 12:26:50.894698 vxlan.calico In IP 192.168.105.143.4180 > 192.168.106.0.36057: Flags [S.], seq 1236287622, ack 2888292148, win 64308, options [mss 1410,sackOK,TS val 3195353228 ecr 976299430,nop,wscale 7], length 0 12:26:50.896305 vxlan.calico Out IP 192.168.106.0.36057 > 192.168.105.143.4180: Flags [.], ack 1, win 2053, options [nop,nop,TS val 976299433 ecr 3195353228], length 0 12:26:50.896972 vxlan.calico Out IP 192.168.106.0.36057 > 192.168.105.143.4180: Flags [P.], seq 1:302, ack 1, win 2053, options [nop,nop,TS val 976299433 ecr 3195353228], length 301 ... 12:27:00.868844 vxlan.calico In IP 192.168.104.66.4180 > 192.168.106.0.22319: Flags [S.], seq 2502063474, ack 1294456302, win 64308, options [mss 1410,sackOK,TS val 931778658 ecr 3753725410,nop,wscale 7], length 0 12:27:00.881856 vxlan.calico Out IP 192.168.106.0.22319 > 192.168.104.66.4180: Flags [.], ack 1, win 2053, options [nop,nop,TS val 3753725424 ecr 931778658], length 0 12:27:00.882748 vxlan.calico Out IP 192.168.106.0.22319 > 192.168.104.66.4180: Flags [P.], seq 1:302, ack 1, win 2053, options [nop,nop,TS val 3753725424 ecr 931778658], length 301 ...
Вопросом доставки трафика до пода далее занимается Calico и обзор прохождения трафика через VxLAN сейчас не важен (что то есть тут: Calico_Kubernetes_the_hard_way_v2_How_packet_goes_from_pod)
В данный момент важно то что видны запросы и ответы
sessionAffinity: None
sessionAffinity: None
Такая настройка означает RoundRobin
ports
- name: https
nodePort: 30358
port: 443
protocol: TCP
targetPort: https
тут кажется что трафик должен идти на 443 порт (но дамп выше это не подтверждает - там порт 4180)
На самом деле https тут это ИМЯ порта в поде
targetPort: https
Что можно проверить:
kubectl get pod -A -l app.kubernetes.io/name=iam-proxy,app.kubernetes.io/instance=iam-proxy-alertmanager -o yaml \
| yq '.items[].spec.containers[].ports'
- containerPort: 4180 name: https protocol: TCP - containerPort: 4180 name: https protocol: TCP
name: httpsсоответвуетcontainerPort: 4180и совпадает с тем что видно вtcpdump:
192.168.106.0.36057 > 192.168.105.143.4180
22
нашлось 2 пода дальше на той ноде которая анонсирует мак сервиса должны увидеть трафик на один из подов tcpdump -n -i any host 192.168.105.143 or host 192.168.104.66 tcpdump: data link type LINUX_SLL2 tcpdump: verbose output suppressed, use -v[v]... for full protocol decode listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes 16:06:08.104697 vxlan.calico Out IP 192.168.107.192.5013 > 192.168.105.143.4180: Flags [S], seq 2027178047, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 2603473557 ecr 0,sackOK,eol], length 0 Если такой трафик есть - смотреть на подах доходит ли Для этого для обоих подов действия (пример 192.168.104.66 на ноде stacklight-3 Для начала определить контейнер - но сделать это может быть сложно по тому заходим в под и запускаем там top (процессов /bin/oauth2-proxy может быть несколько а top скорее всего - один) childctl -n stacklight exec -ti iam-proxy-alertmanager-76997d95b-mqd2f -- sh top Дальше найти PID ps auxfw | grep top root 8244 0.0 0.0 2788 1712 ? S< Aug14 38:36 /usr/sbin/atopacctd root 1921049 0.0 0.0 7008 2200 pts/1 S+ 16:10 0:00 \_ grep --color=auto top nobody 1920805 0.0 0.0 1596 968 pts/0 S+ 16:10 0:00 \_ top root 796509 0.8 0.0 19616 19452 ? S<Ls 01:00 7:54 /usr/bin/atop -R -w /var/log/atop/atop_20250924 60 Интересует 1920805 nobody 1920805 0.0 0.0 1596 968 pts/0 S+ 16:10 0:00 \_ top 19:11 Далее по PID провалиться в NameSpace nsenter -t 1886583 -n 19:12 root@stacklight-3:~# nsenter -t 1920805 -n root@stacklight-3:~# ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450
inet 192.168.104.66 netmask 255.255.255.255 broadcast 0.0.0.0
ether fe:cd:df:e1:24:d3 txqueuelen 1000 (Ethernet)
RX packets 12212837 bytes 1400942826 (1.4 GB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 10131352 bytes 3843343988 (3.8 GB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ifconfig нужен для контроля - сравнить IP тот ли тут тот - 192.168.104.66 что и iam-proxy-alertmanager-76997d95b-mqd2f 1/1 Running 0 41d 192.168.104.66 19:15 Далее в поде (в 2-х !!!! одновременно!!!!) запускать tcpdump (трафик есть постоянно но не много) и дергать курлом tcpdump -n -i eth0 tcpdump: verbose output suppressed, use -v[v]... for full protocol decode listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes 16:12:45.747433 IP 192.168.107.192.64528 > 192.168.104.66.4180: Flags [S], seq 1723519164, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 3632424568 ecr 0,sackOK,eol], length 0 16:12:45.747474 IP 192.168.104.66.4180 > 192.168.107.192.64528: Flags [S.], seq 3246211835, ack 1723519165, win 64308, options [mss 1410,sackOK,TS val 1325901618 ecr 3632424568,nop,wscale 7], length 0 16:12:45.749724 IP 192.168.107.192.64528 > 192.168.104.66.4180: Flags [.], ack 1, win 2053, options [nop,nop,TS val 3632424571 ecr 1325901618], length 0 16:12:45.751215 IP 192.168.107.192.64528 > 192.168.104.66.4180: Flags [P.], seq 1:302, ack 1, win 2053, options [nop,nop,TS val 3632424571 ecr 1325901618], length 301 Сначала с другой ноды - должны быть запросы и ответы Потом откуда (c локальной машины клиента) не работат - и тут надо понимать есть ли запросы Если нет то проверить childctl -n stacklight get networkpolicy iam-proxy-alertmanager -o yaml apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata:
annotations: meta.helm.sh/release-name: iam-proxy-alertmanager meta.helm.sh/release-namespace: stacklight creationTimestamp: "2025-08-14T08:14:35Z" generation: 1 labels: app.kubernetes.io/managed-by: Helm name: iam-proxy-alertmanager namespace: stacklight resourceVersion: "565154" uid: ab15862b-b7a9-45b3-ba2d-b378fce80d4c
spec:
egress:
- {}
ingress:
- from:
- ipBlock:
cidr: 0.0.0.0/0
ports:
- port: 4180
protocol: TCP
podSelector:
matchLabels:
app.kubernetes.io/instance: iam-proxy-alertmanager
app.kubernetes.io/name: iam-proxy
policyTypes:
- Ingress
- Egress
status: {}