Зошто GKE pod-овите не можат да стигнат до локалните хостови преку VPN
Јазолот стигнува до локалната мрежа, pod-от не. Masquerade-исклучоците на GKE ги оставаат pod-адресите непреведени за 10.x одредишта.
Ping работи од јазолот и не успева од pod-от, а локално не пристигнува ништо. Тунелот и рутата се во ред; изворната адреса на кабелот не е. Она што ги разликува тие два случаи е што пакетот тврди дека е кога го напушта кластерот, а GKE има мислење за тоа. Механизмот е листа на masquerade-исклучоци, а за нејзино читање е потребна една команда.
Прочитајте ја важечката листа пред да смените нешто
GKE испорачува агент кој по опсег на одредиште одлучува дали pod-сообраќајот при излез ќе се препише на адресата на јазолот. Неговата испорачана конфигурација ги наведува трите RFC1918 блокови, 10.0.0.0/8, 172.16.0.0/12 и 192.168.0.0/16, како изземени одредишта. Затоа сѐ што ќе испратите од pod до локален 10.x хост го напушта јазолот со сопствената адреса на pod-от сѐ уште прикачена. Сообраќајот на самиот јазол не се препишува, и токму затоа неговиот ping работи.
Прочитајте ја предвидената конфигурација и инсталираните правила, бидејќи тие можат да не се совпаѓаат. kubectl -n kube-system get configmap ip-masq-agent -o yaml покажува што му е кажано на агентот, а kubectl -n kube-system get pods -l k8s-app=ip-masq-agent покажува дали нешто работи за да го примени. На јазол, iptables-save | grep -i masq ги покажува правилата што навистина постојат во јадрото. Кога ConfigMap вели едно, а правилата друго, осомничениот е агентот, а не мрежата.
Потврдете ја изворната адреса со снимање
Направете снимање пред да смените листа. Филтер на едно одредиште го држи излезот читлив: tcpdump -ni any host 10.20.30.40.
Споредете го тоа со она што го известува спротивната страна. Снимање локално што ја покажува адресата на pod-от и без одговор го затвора кругот: листата на исклучоци ја објаснува асиметријата без никаков дефект на тунелот. Две набљудувања на една изворна адреса се доволни за да престанете да шпекулирате за CNI.
Стеснете го исклучокот на pod CIDR-от
Поддржаната поправка го стеснува изземањето наместо да го отстрани: задржете го pod CIDR-от изземен и отфрлете го остатокот од 10.x просторот. Таа листа живее во ConfigMap-от на агентот под nonMasqueradeCIDRs, а нејзината промена е уредување проследено со распоредување. Заменете го широкиот запис со вистинскиот опсег на pod-ови на кластерот, задржете ги другите приватни блокови ако сообраќајот внатре во кластерот сѐ уште ги бара, и оставете го resyncInterval на мир освен ако имате причина. Применете го, потврдете дека pod-овите на агентот се рестартирани и потврдете дека правилата во јадрото се променети.
Ова е промена на целиот кластер со вистински радиус на влијание. Откако ќе стапи на сила, сообраќајот што претходно го задржувал своето pod-потекло сега пристигнува препишан на јазолот, па сѐ што било врзано за тие pod-адреси гледа друг испраќач. Жртвите се дневниците, листите за дозвола и локалните firewall правила што наведуваат pod-адреси, и тие тивко паѓаат. Објавете ја промената како промена на однесувањето, а не како поправка.
На кластер со неколку базени на јазли, проверете дали агентот е закажан на јазлите каде што навистина работат засегнатите pod-ови. Базен без DaemonSet ги задржува старите правила, и ништо во ConfigMap-от нема да го покаже тоа.
Алтернативата и нејзината цена
Другата опција ги остава pod-адресите недопрени и го учи патот за нив. Pod CIDR-от влегува во селекторите за сообраќај на Cloud VPN, а локалната страна бара повратна рута за него за да знаат одговорите каде да одат. Тоа го зачувува идентитетот на pod-от, што го сакаат некои безбедносни модели, и го проширува и опсегот на рутирање и опсегот на firewall-от што спротивната страна мора да го прифати.
Зделката е читливост наспроти опсег. Преведувањето прави локалната страна да гледа една адреса по јазол, што е лесно за ставање на листа за дозвола и го крие тоа кој pod што испратил. Без преведување, pod-адресата останува од крај до крај, што е подобро за припишување и полошо за секој уред на патот што мора да научи нов опсег. Ниту едната опција не е дефект на Docker или CNI; двете се одлуки за рутирање со оперативна сметка. Изберете ја онаа чија сметка вашиот тим може да ја плати, и запишете зошто.
Проверете и вратете
Пуштете го истото снимање повторно. Снимање на ниво на јазол што и по вашето уредување сѐ уште ја печати pod-адресата значи дека правилата никогаш не се смениле, што и да вели ConfigMap-от. Кабелот е фактот; сѐ друго е заклучок.
Потоа проверете го обратниот правец, бидејќи половина од овие промени се проверуваат само на излез. Потврдете дека одговорот стигнува до јазолот или pod-от што го испратил барањето и потврдете дека апликацијата завршила, а не само примила SYN. Снимање што покажува барање без одговор е проблем со рутирање на спротивната страна, а не masquerade проблем на оваа.
Враќањето е претходниот ConfigMap, применет на ист начин, со истата потврда дека агентот се рестартирал и правилата се смениле. Зачувајте ја изворната адреса пред и по за едно познато барање во записот за промени, бидејќи токму таа една линија докажува дека промената го направила тоа што го рековте. Водичот на GKE за IP masquerade агентот ги документира стандардните вредности и полињата на ConfigMap-от. Ако изворната адреса е непроменета по распоредувањето, агентот не работи на тој јазол и никакво уредување на YAML нема да го поправи.