На вашым ноўтбуку зялёны тунэль, кліенцкі лог паведамляе, што маршруты прасунуты, а адзіны адрас, які адказвае, — уласны тунэльны IP VPN-сервера. Пінгі далей паміраюць, куды б вы ні цэліліся: у ClusterIP, адрас іншага пода або публічнае імя хоста. Гэтая камбінацыя не расплывістая, а дыягнастычная: дэкапсуляцыя працуе, а другі хоп — не.

Я сутыкнуўся з гэтым на вузле Debian з вобразам OpenVPN, усталяваным праз chart, і тунэль быў самай простай часткай. Кліент атрымаў арэнду 10.8.0.x, 10.8.0.1 адказаў, а 10.96.0.10, кластарны сэрвіс DNS, скончыўся таймаўтам. У логу сервера нішто не выглядала хваравітым, і менавіта таму людзі пачынаюць перапісваць правілы iptables, якія ім ніколі не былі патрэбныя.

VPN-под — гэта маршрутызатар, і варта сказаць гэта проста. Шыфраваныя пакеты прыходзяць, разгортваюцца ва ўласным сеткавым namespace пода, а затым павінны выйсці праз іншы інтэрфейс. Linux адмаўляе гэты другі крок, пакуль уключэнне forward не ўключана ўнутры таго ж namespace.

Што кліент можа і не можа дасягнуць

Адрас, які адказвае, належыць канчатковай кропцы тунэля, і VPN-працэс валодае ім лакальна, таму forward тут зусім не задзейнічаны. Усё астатняе, уключаючы іншы под, VIP сэрвісу або інтэрнэт, патрабуе, каб ядро перамясціла пакет з tun0 на eth0. Калі гэты перанос адхілены, сімптом — раўнамерная цішыня, а не адмова, бо нішто не генеруе памылку ICMP назад у тунэль. Вы атрымліваеце таймаўты, а не паведамленні пра недасяжнасць, і гэта падказка, што маршрутызацыі няма зусім.

Дзве хвіліны класіфікацыі звужаюць узровень. Калі імёны DNS не працуюць, а сырыя пінгі да IP сэрвісу праходзяць, праблема ў DNS-сантэхніцы, а не ў forward. Калі кожны пункт прызначэння за адрасам піра скончваецца таймаўтам, уключаючы голы 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

Нуль пацвярджае дыягназ. Значэнне таксама не атрымліваецца ў спадчыну ад канфігурацыі часу выканання вузла: яно пачынаецца з дэфолту вобраза кожны раз, калі ствараецца кантэйнер. Таму выпраўленне, ужытае ўручную з kubectl exec ... sysctl -w, знікае пры наступным перазапуску і вяртаецца як недахоп, які выглядае перамежным.

Уключыць так, каб маніфест захаваў гэта

Доўгавечны варыянт — гэта 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 прымяняць sysctl для namespace без выдання прывілеяў любому кантэйнеру. Ён ахоплівае толькі імёны з белага спісу кластара. Ці ёсць net.ipv4.ip_forward у гэтым спісе, залежыць ад таго, як наладжаны kubelet, а под, які просіць sysctl па-за ім, адхіляецца пры admission або захрасае ў CreateContainerConfigError, пакуль sandbox паўтараецца. Праверце белы спіс, перш чым меркаваць, што поле зламанае.

Перш чым уручную будаваць любы з падыходаў, паглядзіце, ці ўжо chart прадстаўляе перамыкач, часта нешта накшталт ipForwardInitContainer: true. Выкарыстанне значэння chart захоўвае ваш файл пераабзазначэнняў малы і перажывае наступнае абнаўленне, чаго не робяць уручную выпраўленыя змены Deployment.

Другая палова: зваротны шлях і палітыка

Уключаны forward неабходны, але не дастатковы. Калі кліенты выкарыстоўваюць прыватны пул, для якога ў кластарнай сеткі няма маршруту, адказы не могуць знайсці дарогу назад у тунэль, і под павінен масіраваць гэты трафік у кірунку свайго прызначэння.

Палітыка ляжыць зверху. Аб'екты NetworkPolicy і правілы хмарных фаерволаў ацэньваюцца па адрасе крыніцы, які пакет нясе пасля трансляцыі, таму правіла, напісанае для кліенцкага пула, можа ціха перастаць супадаць, калі ўключана масіраванне.

Калі кліентам трэба дасягаць толькі сэрвісаў унутры кластара, завяршэнне VPN на VIP сэрвісу — больш кампактная канструкцыя, чым маршрутызацыя ў сетку подаў. Яна таксама цалкам трымае кліенцкі пул па-за табліцай маршрутызацыі CNI.

Ізаляваць збойны хоп ад кліента

Рухайцеся вонкі і спыніцеся на першым ціхім кроку. Пачніце з VPN-піра, затым паспрабуйце адрас якога-небудзь пода, потым VIP сэрвісу і толькі пасля гэтага публічны пункт прызначэння. Кожны поспех перасоўвае мяжу на адзін хоп, і кожная няўдача называе ўзровень, які варта агледзець. Пасля любога разгортвання ўвайдзіце і прачытайце sysctl зноў, бо заменены под пачынаецца з дэфолту вобраза, а выпраўленне, якога ніколі не было ў маніфесце, ужо знікла.

Дакументацыя Kubernetes пра выкарыстанне sysctl у кластары пералічвае, якія імёны можна задаць праз кантэкст бяспекі пода, і гэта першае месца, куды варта паглядзець, калі admission адмаўляе змену.

Падобныя артыкулы