Ваш лаптоп приказује зелени тунел, клијентски лог јавља да су руте послате, а једина адреса која одговара јесте сопствени тунелски IP VPN сервера. Пингови даље умиру без обзира на то у шта циљате, било да је то ClusterIP, адреса другог пода или јавно име хоста. Та комбинација је дијагностичка, а не нејасна: декапсулација ради, а други хоп не.

На то сам наишао на Debian чвору са OpenVPN сликом инсталираном преко chart-а, а тунел је био лакши део. Клијент је добио закуп 10.8.0.x, 10.8.0.1 је одговорио, а 10.96.0.10, кластер DNS услуга, је истекла. Ништа у серверском логу није изгледало болесно, и управо зато људи почињу да преписују iptables правила која никада нису требали дирати.

VPN под је рутер, и то вреди рећи отворено. Шифровани пакети стижу, распакују се у сопственом мрежном namespace-у пода, а затим морају изаћи кроз други интерфејс. Linux одбија тај други корак осим ако је прослеђивање омогућено унутар тог истог namespace-а.

Шта клијент може, а шта не може да достигне

Адреса која одговара припада крајњој тачки тунела, а VPN процес је поседује локално, па прослеђивање уопште није укључено. Све остало, укључујући други под, VIP услуге или интернет, захтева да кернел премести пакет са tun0 на eth0. Када је то премештање одбијено, симптом је једнолична тишина, а не одбијање, јер ништа не генерише ICMP грешку назад низ тунел. Добијате истеке, а не поруке о недостатности, и то је траг да нико уопште не рутира.

Два минута класификације сужавају слој. Ако DNS имена падају док сирови пингови на IP услуге пролазе, проблем је у DNS водоводу, не у прослеђивању. Ако свака дестинација иза адресе peer-а истекне, укључујући голи IP, почните од namespace-а.

Прочитајте поставку унутар namespace-а

Сваки под добија сопствени мрежни namespace, а net.ipv4.ip_forward је sysctl по namespace-у. Његово мењање на чвору вам не говори ништа о контејнеру, и то је поуздан начин да проведете поподне на погрешној машини.

kubectl exec -it deploy/openvpn -- sysctl net.ipv4.ip_forward
# net.ipv4.ip_forward = 0

Нула потврђује дијагнозу. Вредност се такође не наслеђује из runtime конфигурације чвора: почиње од подразумеване вредности слике сваки пут када се контејнер креира. Зато поправка примењена ручно са kubectl exec ... sysctl -w нестаје при следећем рестарту и враћа се као квар који изгледа повремен.

Омогућити тако да manifest то задржи

Трајна опција је init контејнер који ради у истом pod sandbox-у и уписује вредност пре него што се VPN контејнер покрене. Контејнери у поду деле мрежни namespace, па се поставка преноси у главни контејнер.

initContainers:
- name: enable-forwarding
  image: busybox:1.36
  command: ["sysctl", "-w", "net.ipv4.ip_forward=1"]
  securityContext:
    privileged: true

Управо privileged: true је линија на коју рецензенти приговарају, и с правом. Писање sysctl-а захтева или привилегију или уско ограничену способност, а кластер са рестриктивним Pod Security Standard-ом може привилеговани init контејнер одбити одмах. Ако admission одбије под, сазнајете у тренутку креирања, што је барем искрено и лако читљиво.

Чистија алтернатива је листа securityContext.sysctls на нивоу пода, која омогућава kubelet-у да примени namespaced sysctl-ове без давања привилегија било ком контејнеру. Покрива само имена са allowlist-е кластера. Да ли је net.ipv4.ip_forward на тој листи зависи од тога како је kubelet конфигурисан, а под који тражи sysctl изван ње се одбија при admission-у или заглављује у CreateContainerConfigError док се sandbox поново покушава. Проверите allowlist пре него што претпоставите да је поље покварено.

Пре него што ручно изградите било који приступ, погледајте да ли chart већ излаже прекидач, често као нешто попут ipForwardInitContainer: true. Коришћење вредности из chart-а држи ваш override фајл малим и преживљава следећу надоградњу, што ручно закрпљене измене Deployment-а не чине.

Друга половина: повратни пут и политика

Укључено прослеђивање је неопходно, не и довољно. Ако клијенти користе приватни базен за који кластер мрежа нема руту, одговори не налазе пут назад у тунел, и под мора да маскира тај саобраћај према својој дестинацији.

Политика стоји изнад тога. NetworkPolicy објекти и правила cloud firewall-а се оцењују према изворној адреси коју пакет носи након превода, па правило написано за базен клијената може тихо престати да се поклапа када се маскирање омогући.

Када клијенти треба да достигну само услуге унутар кластера, завршавање VPN-а на VIP-у услуге је мањи дизајн од рутирања у под-мрежу. Такође држи базен клијената потпуно изван табеле рутирања CNI-ја.

Изоловање хопа који пада од клијента

Радите према ван и зауставите се на првом тихом кораку. Почните са VPN peer-ом, затим пробајте адресу неког пода, па VIP услуге, и тек након тога јавну дестинацију. Сваки успех помера границу за један хоп, а сваки неуспех именује слој који вреди прегледати. Након сваког распоређивања уђите и поново прочитајте sysctl, јер замењени под почиње од подразумеване вредности слике, а поправка која никада није била у manifest-у је већ отишла.

Kubernetes документација о коришћењу sysctl-ова у кластеру наводи која имена се могу поставити кроз безбедносни контекст пода, и то је прво место на које треба погледати када admission одбије промену.

Повезани чланци