Post #72
372
Сказ о том, как в Kubernetes'е работа с сетью устроена
Kubernetes - это не только ц̶е̶н̶н̶ы̶й̶ ̶м̶е̶х̶ про запуск контейнеров, но и про управление сетью. Правда, если вы хотите узнать как работа с этой самой сетью организована, это может оказаться задачкой не из легких. Но у меня есть рецепт! Не факт, что рабочий, но все равно поделюсь.
На мой взгляд, удобно различать следующие "уровни" ответственности:
1. Container networking в рамках одного сервера (ноды). По факту о том, как сделать так, чтобы каждый Pod видел отдельный изолированный network stack и чтобы Pod'ы, расположенные на одной ноде могли общаться между собой "по-сети". В основном решается средствами Linux по виртуализации сети (network namespaces, veth, Linux bridge, вот это все).
2. Pod to Pod networking между разными нодами. Kubernetes классно придумал, что все Pod'ы должны быть адресуемыми по их IP и чтобы никакого "видимого" NAT'а (а если точнее - sNAT'а). Т.е. получатель пакетов от Pod'а видит в source IP тот же самый адрес, что и сам отправитель видит при условном
3. Уровень Service'ов. Kubernetes из коробки предоставляет возможность объединять Pod'ы в логические группы, суть - микросервисы. Но что еще более приятно, задачи service discovery и load balancing решаются тоже из коробки, спасибо kube-proxy.
4. Уровень х̶а̶й̶п̶а̶ service mesh. Несмотря на то, что Service'ы все такие классные прямо из коробки, остается еще очень много нерешенных проблем, общих для каждого из приложений, которые также было бы здорово решить на уровен инфраструктуры. А именно - retry & timeouts, request tracing и прочая observability, mTLS и прочая security, и т.п. И оказывается, что уровень Service'ов вполне себе расширяемый, чему Linkerd и Istio яркое подтверждение.
5. Уровень Ingress. Уровни с 1 по 4 - это в основном о том, как трафик гонять внутри кластеров. А вот заводить трафик из внешнего мира внутрь кластера помогает Ingres. По факту это условный Nginx, который по динамически обновляемым правилам умеет (только) HTTP(S) запросы отправлять нужному Service'у.
Собственно, все. Дальше берем, и по каждому уровню проводим свое собственное расследование. Ах да, чуть не забыл. Работать с сетью в Linux из кода - то еще удовольствие. И поэтому добрые люди написали стандартизованные обертки (CNI) вокруг всяких сетевых комманд вроде iptables. Вот здесь можно посмотерть полный список.
Kubernetes - это не только ц̶е̶н̶н̶ы̶й̶ ̶м̶е̶х̶ про запуск контейнеров, но и про управление сетью. Правда, если вы хотите узнать как работа с этой самой сетью организована, это может оказаться задачкой не из легких. Но у меня есть рецепт! Не факт, что рабочий, но все равно поделюсь.
На мой взгляд, удобно различать следующие "уровни" ответственности:
1. Container networking в рамках одного сервера (ноды). По факту о том, как сделать так, чтобы каждый Pod видел отдельный изолированный network stack и чтобы Pod'ы, расположенные на одной ноде могли общаться между собой "по-сети". В основном решается средствами Linux по виртуализации сети (network namespaces, veth, Linux bridge, вот это все).
2. Pod to Pod networking между разными нодами. Kubernetes классно придумал, что все Pod'ы должны быть адресуемыми по их IP и чтобы никакого "видимого" NAT'а (а если точнее - sNAT'а). Т.е. получатель пакетов от Pod'а видит в source IP тот же самый адрес, что и сам отправитель видит при условном
ip addr show на своей стороне. Только вот Kubernetes забыл придумать, как это все организовать. Ну точнее не забыл, а справедливо решил, что сеть у каждого п̶р̶е̶д̶п̶р̶и̶я̶т̶и̶я̶ enterprise устроена на свой манер и поэтому пусть каждый по-своему и добивается нужной адресации. Тут на помощь приходят всякие проекты по виртуализации сети вроде flannel, calico, weave net и т.п.3. Уровень Service'ов. Kubernetes из коробки предоставляет возможность объединять Pod'ы в логические группы, суть - микросервисы. Но что еще более приятно, задачи service discovery и load balancing решаются тоже из коробки, спасибо kube-proxy.
4. Уровень х̶а̶й̶п̶а̶ service mesh. Несмотря на то, что Service'ы все такие классные прямо из коробки, остается еще очень много нерешенных проблем, общих для каждого из приложений, которые также было бы здорово решить на уровен инфраструктуры. А именно - retry & timeouts, request tracing и прочая observability, mTLS и прочая security, и т.п. И оказывается, что уровень Service'ов вполне себе расширяемый, чему Linkerd и Istio яркое подтверждение.
5. Уровень Ingress. Уровни с 1 по 4 - это в основном о том, как трафик гонять внутри кластеров. А вот заводить трафик из внешнего мира внутрь кластера помогает Ingres. По факту это условный Nginx, который по динамически обновляемым правилам умеет (только) HTTP(S) запросы отправлять нужному Service'у.
Собственно, все. Дальше берем, и по каждому уровню проводим свое собственное расследование. Ах да, чуть не забыл. Работать с сетью в Linux из кода - то еще удовольствие. И поэтому добрые люди написали стандартизованные обертки (CNI) вокруг всяких сетевых комманд вроде iptables. Вот здесь можно посмотерть полный список.

