Маємо відносно великі витрати на AWS NAT Gateway Processed Bytes, і стало цікаво що ж саме процеситься через нього.
Здавалося б, все просто – включи собі VPC Flow Logs, да подивись, що до чого. Але як діло стосується AWS Elasitc Kubernetes Service та NAT Gateways, то все трохи цікавіше.
Отже, про що будемо говорити:
- що таке NAT Gateway у AWS VPC
- що таке NAT та Source NAT
- включимо VPC Flow Logs, і розберемося з тим, що саме в них пишеться
- і розберемося з тим, як знайти Kubernetes Pod IP у VPC Flow Logs
Схема нетворкінгу досить стандартна:
- AWS EKS кластер
- VPC
- публічні сабнети для Load Balancers та NAT Gateways
- приватні для Kubernetes Worker Nodes
- окремі сабнети для баз даних
- окремі сабнети для Kubernetes Control Plain
Створення VPC для кластеру описано у Terraform: створення EKS, частина 1 – VPC, Subnets та Endpoints.
Зміст
AWS NAT Gateway Pricing
Документація – Amazon VPC pricing.
Отже, коли ми використовуємо NAT Gateway, то платимо за:
- за кожну годину роботи NAT Gateway
- за гігабайти, які він оброблює
Година роботи NAT Gateway коштує $0.045, тобто в місяць це буде:
0.045*24*30 32.400
32 долари.
Є варіант з використання NAT Instance замість NAT Gateway, але тоді мусимо мати справу з його менеджментом – і створення інстансу, і його апдейти, і конфігурація.
Амазон предоставляє AMI для цього – але вони давно не оновлюються, і не будуть.
Крім того, Terraform-модуль terraform-aws-modules/vpc/aws працює тільки з NAT Gateway, тому, якщо ви хочете використати NAT Instance – то маєте ще й автоматизацію писати під нього.
Отже – скіпаємо варіант з NAT Instance, і використовуємо NAT Gateway – як рішення, яке повністю підтримується і менеджиться Амазоном та VPC-модулем для Terraform.
Щодо вартості трафіку: платимо ті ж самі $0.045, але вже за кожен гігабайт. При чому рахується весь processed трафік – тобто і outbound (egress, TX – Transmitted), і inbound (ingress, RX – Recieved).
Отже, коли ви відправляєте один гігабайт даних в S3-бакет, а потім завантажуєте його назад на EC2 в приватній мережі – ви платите 0.045 + 0.045 долари.
Що таке NAT?
Давайте згадаємо, що таке NAT взагалі, і як він працює на рівні пакетів і архітектури мережі.
NAT – Network Address Translation – виконує операції над заголовками TCP/IP пакетів, міняючи (translate) адресу відправника або отримувача, дозволяючи мережевий доступ з або до машин, які не мають власного публічного IP.
Знаємо, що є декілька типів NAT:
- Source NAT: пакет “виходить” з приватної мережі, і NAT перед відправкою в Internet заміняє source IP пакету на власний (SNAT)
- Destination NAT: пакет “входить” в приватну мережу з Inernet, і NAT перед відправкою всередину мережі заміняє destination IP пакету з власного на приватну IP всередині мережі (DNAT)
Окрім того, є Static NAT, Port Address Translation (PAT), Twice NAT, Multicast NAT.
Нас зараз цікавить саме Source NAT, і далі ми будемо в основному розглядати саме його і те, як пакет потрапляє з VPC до інтернету.
Якщо відобразити це схемою, то вона буде виглядати так:
- Ініціація запиту з EC2: сервіс на EC2 з Private IP 10.0.1.5 генерує запит до External Server з IP 203.0.113.5
- ядро операційної системи EC2 створює пакет
- source IP: 10.0.1.5
- packet source IP: 10.0.1.5
- destintation IP: 203.0.113.5
- packet destination IP: 203.0.113.5
- ядро операційної системи EC2 створює пакет
- Маршрутизація пакета: мережевий інтерфейс на EC2 включений в Private Subnet, і має Route Table, яка підключена до цього сабнету
- ядро операційної системи визначає, що destintation IP не належить до VPC, і переадресує пакет до NAT GW Private IP 10.0.0.220
- source IP: 10.0.1.5
- packet source IP: 10.0.1.5
- destination IP: 10.0.0.220
- packet destination IP: 203.0.113.5
- ядро операційної системи визначає, що destintation IP не належить до VPC, і переадресує пакет до NAT GW Private IP 10.0.0.220
- Обробка пакета NAT Gateway: пакет приходить на мережевий інтерфейс NAT GW, який має адресу 10.0.0.220
- NAT Gateway зберігає запис про походження пакету з IP 10.0.1.5:10099 => 203.0.11.443 у своїй NAT-таблиці
- NAT GW змінює source IP з 10.0.1.5 на адресу свого інтерфейсу у публічній мережі з IP 77.70.07.200 (власне, сама операція SNAT), і пакет відправляється в Інтернет
- source IP: 77.70.07.200
- packet source IP: 10.0.1.5
- destination IP: 203.0.113.5
- packet destination IP: 203.0.113.5
Що таке NAT Table?
NAT-таблиця зберігається в пам’яті NAT Gateway та використовується, аби прийняти пакет від External Server до нашої EC2, коли він буде слати відповідь, і переадресувати його до відповідного серверу в приватній мережі.
Схематично його можна відобразити так:
Отримуючи відповідь від 203.0.113.5 до себе на 77.70.07.200 і порт 20588, NAT Gateway по таблиці знаходить відповідного адресата – IP 10.0.1.5 і порт 10099.
Добре. Тепер, як згадали що таке NAT – давайте включимо VPC Flow Logs, і розберемося з записами, які він створює.
Див. The Network Address Translation Table.
Налаштування AWS VPC Flow Logs
Див. також AWS: VPC Flow Logs – знайомство та аналітика з CloudWatch Logs Insights.
VPC Flow Logs можна налаштувати вручну в панелі AWS:
Або, якщо використовуєте Terraform модуль terraform-aws-modules/vpc, то задати параметри в ньому:
... module "vpc" { source = "terraform-aws-modules/vpc/aws" version = "~> 5.5.2" name = local.env_name cidr = var.vpc_params.vpc_cidr ... enable_flow_log = var.vpc_params.enable_flow_log create_flow_log_cloudwatch_log_group = true create_flow_log_cloudwatch_iam_role = true flow_log_max_aggregation_interval = 60 flow_log_cloudwatch_log_group_name_prefix = "/aws/${local.env_name}-flow-logs/" flow_log_log_format = "$${region} $${vpc-id} $${az-id} $${subnet-id} $${instance-id} $${interface-id} $${flow-direction} $${srcaddr} $${dstaddr} $${srcport} $${dstport} $${pkt-srcaddr} $${pkt-dstaddr} $${pkt-src-aws-service} $${pkt-dst-aws-service} $${traffic-path} $${packets} $${bytes} $${action}" #flow_log_cloudwatch_log_group_class = "INFREQUENT_ACCESS" } ...
Виконуємо terraform apply
, і маємо логи у VPC з власним форматом:
VPC Flow Logs – формат
У flow_log_log_format
описується формат того, як лог буде записаний, а саме – які поля в ньому будуть.
Я завжди використовую custom format з додатковою інформацією, бо дефолтний формат може бути недостатньо інформативним, особливо про роботі через NAT Gateways.
Всі поля є у документації Logging IP traffic using VPC Flow Logs.
Для Terraform, екрануємо записи з ${...}
через додатковий $
.
Вартість VPC Flow Logs в CloudWatch Logs
flow_log_cloudwatch_log_group_class
дозволяє задати клас Standard або Infrequent Access, і Infrequent Access буде дешевшим, але він має обмеження – див. Log classes.
В моєму випадку, я планую збирати логи до Grafana Loki через CloudWatch Log Subscription Filter – тому потрібен Standard. Але подивимось – може налаштую через S3 бакет, і тоді, мабуть, можна буде використати Infrequent Access.
Бо насправді витрати на логування трафіку досить помітні.
Наприклад, у невеликій VPC, де в Kubernetes крутиться наш Backend API, моніторинг (див. VictoriaMetrics: створення Kubernetes monitoring stack з власним Helm-чартом) та кілька інших сервісів, після включення VPC Flow Logs вартість CloudWatch почала виглядати так:
Тож майте це на увазі.
VPC Flow Logs в CloudWatch Logs vs AWS S3
Зберігання логів в CloudWatch Logs буде дорожчим – але дає можливість виконувати запити у CloudWatch Logs Insights.
Крім того, як на мене, то налаштування збору логів до Grafana Loki простіше через CloudWatch Subscription Filters, аніж робити через S3 – просто менше головної болі з IAM.
Про Loki та S3 – див. Grafana Loki: збираємо логи AWS LoadBalancer з S3 за допомогою Promtail Lambda.
Про Loki та CloudWatch – див. Loki: збір логів з CloudWatch Logs з використанням Lambda Promtail.
Втім, поки що тримаю Flow Logs в CloudWatch Logs, а як закінчу розбиратись з тим, звідки йде трафік – то подумаю про використання S3, і звідти вже буду збирати до Grafana Loki.
VPC Flow Logs та Log Insights
Окей – отже, маємо налаштовані VPC Flow Logs в CloudWatch Logs.
Що нас особливо цікавить – це трафік через NAT Gateway.
Використовуючи кастомний формат логів – в Logs Insights можемо зробити такий запит:
parse @message "* * * * * * * * * * * * * * * * * * *" | as region, vpc_id, az_id, subnet_id, instance_id, interface_id, | flow_direction, srcaddr, dstaddr, srcport, dstport, | pkt_srcaddr, pkt_dstaddr, pkt_src_aws_service, pkt_dst_aws_service, | traffic_path, packets, bytes, action | filter (dstaddr like "10.0.5.175") | stats sum(bytes) as bytesTransferred by interface_id, flow_direction, srcaddr, srcport, dstaddr, dstport, pkt_srcaddr, pkt_dstaddr, pkt_src_aws_service, pkt_dst_aws_service, bytes | sort bytesTransferred desc | limit 10
Тут ми робимо фільтр по запитам, які у dstaddr
мають Private IP нашого NAT Gateway:
Іноді pkt_src_aws_service
або pkt_dst_aws_service
не вказані, і тоді не дуже зрозуміло що за трафік.
Можна перевірити на сайті https://ipinfo.io – там може бути вказане ім’я хоста, і тоді ясно, що це, наприклад, S3-ендпоінт:
Flow Logs ingress
vs egress
Ми знаємо, що це ingress – це вхідний трафік (RX, Received), а egress – вихідний трафік (TX, Transmitted).
Але вхідний та вихідний до чого? VPC, Subnet або ENI – Elastic Network Interface?
Читаємо документацію Logging IP traffic using VPC Flow Logs:
- flow-direction: The direction of the flow with respect to the interface where traffic is captured. The possible values are: ingress | egress.
Тобто, відносно до мережевого інтерфейсу: якщо на інтерфейс EC2 або NAT Gateway (який під капотом є звичайним EC2) приходить трафік – то це ingress, якщо виходить з інтерфейсу – то egress.
Різниця srcaddr
vs pkt-srcaddr
та dstaddr
vs pkt-dstaddr
У нас є чотири поля, які вказують на адресатів.
При цьому для source та destination у нас є два різних типи полів – з pkt-
, або без.
В чому різниця:
srcaddr
– “поточна” маршрутизація:- адреса вхідного трафіку – звідки прийшов пакет, або:
- адреса інтерфейсу, який відправляє трафік
dstaddr
– “поточна” маршрутизація:- адреса “пункту призначення” пакета у вихідному трафіку, або
- адреса мережевого інтерфейсу для вхідного трафіку
pkt-srcaddr
: “оригінальна” адреса появи пакетуpkt-dstaddr
: “оригінальна” адреса “пункту призначення” пакету
Аби краще зрозуміти ці поля і взагалі структуру записів у Flow Logs – давайте розглянемо кілька прикладів з документації.
Flow Logs та приклади записів
Отже, маємо EC2 інстанс в приватній мережі, який робить запити до якогось зовнішнього сервісу через NAT Gateway.
Що ми побачимо в логах?
Приклади взяті з документації Traffic through a NAT gateway, і додав трохи схем, аби візуально було простіше зрозуміти.
Дивитись будемо на реальні дані:
- маємо EC2 інстанс в приватному сабнеті:
- Elastic Network Interface:
eni-0467f85cabee7c295
- Private IP:
10.0.36.132
- Elastic Network Interface:
- маємо NAT Gateway:
- Elastic Network Interface:
eni-0352f8c82da6aa229
- Private IP:
10.0.5.175
- Public IP:
52.54.3.183
- Elastic Network Interface:
На EC2 запущено curl
в циклі з запитом на 1.1.1.1:
root@ip-10-0-36-132:/home/ubuntu# watch -n 1 curl https://1.1.1.1
Формат VPC Flow Log той самий, що був вище, а для перевірки в CloudWatch Logs Insights будемо використовувати такий запит:
parse @message "* * * * * * * * * * * * * * * * * * *" | as region, vpc_id, az_id, subnet_id, instance_id, interface_id, | flow_direction, srcaddr, dstaddr, srcport, dstport, | pkt_srcaddr, pkt_dstaddr, pkt_src_aws_service, pkt_dst_aws_service, | traffic_path, packets, bytes, action | filter (interface_id = "eni-0352f8c82da6aa229" AND srcaddr = "10.0.36.132") | stats sum(bytes) as bytesTransferred by instance_id, interface_id, flow_direction, srcaddr, dstaddr, pkt_srcaddr, pkt_dstaddr | sort bytesTransferred desc
Тут робимо виборку по записам з мережевого інтерфейсу NAT Gateway та Private IP нашого EC2:
Отже, в результатах у нас буде “instance_id
, interface_id
, flow_direction
, srcaddr
, dstaddr
, pkt_srcaddr
, pkt_dstaddr
”
NAT Gateway Elastic Network Interface records
Спочатку глянемо записи, які стосуються мережевого інтерфейсу NAT Gateway.
Від EC2 через NAT GW до Remote server
Перший приклад запису в Flow Logs відображає інформацію з мережевого інтерфейсу NAT Gateway, де записано проходження пакету від EC2 в приватній мережі до зовнішнього серверу:
При роботі з VPC Flow Logs головне пам’ятати, що записи робляться для кожного інтерфейсу.
Тобто, якщо ми робимо curl 1.1.1.1
з EC2-інстансу – то отримаємо два записи у Flow Log:
- з Elastic Network Interface на самому EC2
- з Elastic Network Interface на NAT Gateway
В цьому прикладі ми бачимо запис з інтерфейсу NAT Gateway, бо:
- поле
instace-id
пусте (NAT GW хоч і є EC2, але це все ж Amazon-managed сервіс) flow-direction
– ingress, пакет прийшов на інтерфейс NAT Gateway- в полі
dstaddr
бачимо Private IP нашого NAT GW - і поле
pkt-dstaddr
не співпадає зdstaddr
– вpkt-dstaddr
у нас адреса “кінцевого отримувача”, а пакет прийшов наdstaddr
– NAT Gateway
Від NAT Gateway до Remote Server
В другому прикладі бачимо запис про пакет, який було відправлено з NAT Gateway до Remote Server:
flow-direction
– egress, пакет відправлено з інтерфейсу NAT Gatewaysrcaddr
таpkt-srcaddr
однаковіdstaddr
таpkt-dstaddr
однакові
Від Remote Server до NAT Gateway
Далі – наш Remote Server відправляє відповідь до нашого NAT Gateway:
flow-direction
– ingress, пакет прийшов на інтерфейс NAT Gatewaysrcaddr
таpkt-srcaddr
однаковіdstaddr
таpkt-dstaddr
однакові
Від Remote Server через NAT Gateway до EC2
Запис про пакет від Remote Server до нашого EC2 через NAT Gateway:
flow-direction
– egress, пакет відправлено з інтерфейсу NAT Gatewaysrcaddr
таpkt-srcaddr
різні – вsrcaddr
маємо NAT GW IP, а вpkt-srcaddr
– Remote Serverdstaddr
таpkt-dstaddr
однакові, з IP нашого EC2
EC2 Network Interface records
І пара прикладів записів у Flow Logs, які відносяться до EC2 Elastic Network Interface.
Від EC2 до Remote Server
Відправка пакета з EC2 до Remote Server:
-
instance_id
не пустий flow-direction
– egress, бо запис с інтерфейсу EC2, який відправляє пакет до Remote Serversrcaddr
таpkt-srcaddr
однакові, з Private IP цього EC2- поля
dstaddr
таpkt-dstaddr
– теж однакові, з адресою Remote Server
Від Remote Server до EC2
Відправка пакета з Remote Server до EC2:
-
instance_id
не пустий flow-direction
– ingress, бо запис с інтерфейсу EC2, який отримує пакет від Remote Serversrcaddr
таpkt-srcaddr
однакові, з адресою Remote Server- поля
dstaddr
таpkt-dstaddr
– теж однакові, з Private IP цього EC2
VPC Flow Logs, NAT, Elastic Kubernetes Service та Kubernetes Pods
Окей – ми побачили, як знайти інформацію по трафіку через NAT Gateway з EC2-інстансів.
А як щодо Kubernetes Pods?
Тут ситуація ще цікавіша, бо маємо різні типи мережевої комунікації:
- Worker Node to Pod
- Worker Node to ClusterIP
- Pod to ClusterIP Service
- Pod to Pod на одній Worker Node
- Pod to Pod на різних Worker Node
- Pod to External Server
Поди мають IP адреси з пулу VPC CIDR, і ці IP підключаються до WorkerNode як Secondary Private IP (або беруться з підключених префіксів /28 у випадку з VPC CNI Prefix Assignment Mode – див. AWS: VPC Prefix та максимальна кількість подів на Kubernetes WorkerNodes).
При комунікації Pod to Pod, якщо вони в одній VPC, то використовуються їхні IP/WorkerNode Secondary Private IP. Але якщо вони знаходяться на одній WorkerNode – то пакет піде через віртуальні мережеві інтерфейси, а не через “фізичний” інтерфейс на WorkerNode/EC2, і, відповідно, ми цей трафік у Flow Logs не побачимо взагалі.
А от коли Pod відправляє трафік до зовнішнього ресурсу – то по дефолту плагін VPC CNI транслює (міняє) Pod IP на WorkerNode Primary Private IP, і, відповідно, у Flow Logs ми не побачимо IP поду, який шле трафік через NAT Gateway.
Тобто, у нас на рівні ядра операційної системи WorkerNode/EC2 виконується один SNAT, а потім на NAT Gateway – ще один.
Виключення – якщо под запускається з hostNetwork: true
.
Документація – SNAT for Pods.
Давайте перевіримо.
Трафік з Pod до Pod, та VPC Flow Logs
Запустимо два поди. Додамо їм antiAffinity
та topologyKey
(див. Kubernetes: Pods та WorkerNodes – контроль розміщення подів на нодах), аби вони запустились на двох різних WorkerNodes:
apiVersion: v1 kind: Pod metadata: name: ubuntu-pod1 labels: app: ubuntu-app pod: one spec: containers: - name: ubuntu-container1 image: ubuntu command: ["sleep"] args: ["infinity"] ports: - containerPort: 80 affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchLabels: app: ubuntu-app topologyKey: "kubernetes.io/hostname" --- apiVersion: v1 kind: Pod metadata: name: ubuntu-pod2 labels: app: ubuntu-app pod: two spec: containers: - name: ubuntu-container2 image: ubuntu command: ["sleep"] args: ["infinity"] ports: - containerPort: 80 affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchLabels: app: ubuntu-app topologyKey: "kubernetes.io/hostname"
Деплоїмо, і на першому встановлюємо curl
, а на другому – NGINX.
Тепер маємо:
- ubuntu-pod1:
- Pod IP: 10.0.46.182
- WorkerNode IP: 10.0.42.244
- ubuntu-pod2:
- Pod IP: 10.0.46.127
- WorkerNode IP: 10.0.39.75
На другому стартуємо NGINX, і з першого поду запускаємо curl
в циклі на IP другого поду:
root@ubuntu-pod1:/# watch -n 1 curl 10.0.46.127
І за хвилину перевіряємо Flow Logs с запитом:
parse @message "* * * * * * * * * * * * * * * * * * *" | as region, vpc_id, az_id, subnet_id, instance_id, interface_id, | flow_direction, srcaddr, dstaddr, srcport, dstport, | pkt_srcaddr, pkt_dstaddr, pkt_src_aws_service, pkt_dst_aws_service, | traffic_path, packets, bytes, action | filter (dstaddr = "10.0.46.127" AND dstport = 80) | stats sum(bytes) as bytesTransferred by instance_id, interface_id, flow_direction, srcaddr, dstaddr, dstport, pkt_srcaddr, pkt_dstaddr | sort bytesTransferred desc
В srcaddr
у нас Primary Private IP з WorkerNode, на якій запущено ubuntu-pod-1, а в pkt_srcaddr
– IP самого Pod, який робить запити.
Трафік з Pod до External Server через NAT Gateway, та VPC Flow Logs
Тепер, нічого не міняючи, запустимо з того ж ubuntu-pod1 curl
на 1.1.1.1, і подивимось логи:
В першому записі бачимо:
eni-0352f8c82da6aa229
– інтерфейс NAT Gatewayflow-direction
– ingress, інтерфейс отримав пакетsrcaddr
10.0.42.244 – адреса WorkerNode, де запущений ubuntu-pod1dstaddr
10.0.5.175 – пакет для NAT Gatewaypkt_dstaddr
1.1.1.1 – і пакет призначається для Remote Server
Далі, у другому записі:
- той же мережевий інтерфейс, NAT GW
- але вже egress – пакет вийшов з інтерфейсу
srcaddr
10.0.5.175 – пакет з NAT GW
І третій запис:
- інстанс
i-023f37c7aad6fc69d
– там, де наш Pod - трафік egress – пакет вийшов з інтерфейсу
srcaddr
10.0.42.244 – пакет з Private IP цієї WorkerNode- і
dstaddr
1.1.1.1 – пакет для Remote Server
Але ми ніде не бачимо IP самого Kubernetes Pod.
Kubernetes Pod, hostNetwork: true
та VPC Flow Logs
Давайте передеплоїмо ubuntu-pod1 з hostNetwork: true
:
apiVersion: v1 kind: Pod metadata: name: ubuntu-pod1 labels: app: ubuntu-app pod: one spec: hostNetwork: true containers: - name: ubuntu-container1 image: ubuntu command: ["sleep"] args: ["infinity"] ports: - containerPort: 80 affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchLabels: app: ubuntu-app topologyKey: "kubernetes.io/hostname"
Деплоїмо, і перевіряємо IP самого Pod та IP його WorkerNode:
$ kubectl describe pod ubuntu-pod1 Name: ubuntu-pod1 ... Node: ip-10-0-44-207.ec2.internal/10.0.44.207 ... Status: Running IP: 10.0.44.207 ...
Обидва IP однакові, відповідно, якщо зробимо з цього поду curl 1.1.1.1
– то у Flow Logs будемо бачити IP пода (а фактично – IP тієї Worker Node, на якій запущено цей Pod).
Але використання hostNetwork: true
ідея погана (безпека, можливі проблеми з TCP-портами тощо), тому можемо зробити інакше.
AWS EKS та Source NAT for Pods
Якщо ми відключимо SNAT for Pods у VPC CNI нашого кластеру, то SNAT буде виконуватись тільки на NAT Gateway у VPC, а не двічі – спочатку на WorkerNode, а потім на NAT Gateway.
Див. AWS_VPC_K8S_CNI_EXTERNALSNAT
та AWS_VPC_K8S_CNI_EXCLUDE_SNAT_CIDRS
.
І, відповідно, в логах ми будемо бачити реальні IP наших подів.
Оновлюємо конфігурацію VPC CNI:
$ kubectl set env daemonset -n kube-system aws-node AWS_VPC_K8S_CNI_EXTERNALSNAT=true
Повертаємо конфіг для ubuntu-pod-1 без hostNetwork: true
, передеплоїмо, і глянемо логи з таким запитом:
parse @message "* * * * * * * * * * * * * * * * * * *" | as region, vpc_id, az_id, subnet_id, instance_id, interface_id, | flow_direction, srcaddr, dstaddr, srcport, dstport, | pkt_srcaddr, pkt_dstaddr, pkt_src_aws_service, pkt_dst_aws_service, | traffic_path, packets, bytes, action | filter (srcaddr = "10.0.37.171" OR pkt_srcaddr = "10.0.37.171") | stats sum(bytes) as bytesTransferred by instance_id, interface_id, flow_direction, srcaddr, dstaddr, pkt_srcaddr, pkt_dstaddr | sort bytesTransferred desc
Маємо два записи:
Перший запис – з інтерфейсу NAT Gateway, який отримав пакет від Pod з IP 10.0.37.171 для Remote Server 1.1.1.1:
Другий запис – з інтерфейсу EC2, який робить запит до Remote Server, тільки тепер у нас pkt_srcaddr
не такий же, як srcadd
(як було на схемі “З EC2 до Remote Server” вище), а має запис про IP нашого Kubernetes Pod:
І ось тепер ми зможемо відслідкувати який саме Kubernetes Pod шле або отримує трафік через NAT Gateway з таблиць DynamoDB або S3-корзин.
Сподіваюсь, я на схемах нічого не наплутав, бо трохи складна тема. В принципі, як майже завжди з нетворкінгом.
Корисні посилання
(ох, цей кайф, коли закриваєш купу вкладок в браузері…)
- RFC IP Network Address Translator (NAT) Terminology and Considerations
- Pv4 Packet Header
- CloudWatch Logs Insights query syntax
- How do I find the top contributors to NAT gateway traffic in my Amazon VPC?
- Using VPC Flow Logs to capture and query EKS network communications
- Kubernetes: Service, балансировка нагрузки, kube-proxy и iptables (rus)
- Identifying the Source of Network Traffic Originating from Amazon EKS Clusters
- The hidden cross AZ cost: how we reduced AWS Data Transfer cost by 80%
- Monitor NAT gateways with Amazon CloudWatch
- How do I reduce data transfer charges for my NAT gateway in Amazon VPC?
- AWS NAT Gateway Pricing: How To Reduce Your Costs In 5 Steps
- How do I find the top contributors to NAT gateway traffic in my Amazon VPC?