Kubernetes дахь OpenVPN под юу ч дамжуулахгүй байна уу? ip_forward-ыг шалгана уу
Клиентүүд VPN под руу ping илгээдэг ч цааш юу ч байхгүй. Namespace-д дамжуулалт унтарсан бөгөөд засвар нь admission, дахин эхлүүлэлт, буцах замыг давах ёстой.
Таны зөөврийн компьютер ногоон туннель харуулж, клиентийн лог маршрутууд түлхэгдсэнийг мэдээлж, хариу өгдөг цорын ганц хаяг нь VPN серверийн өөрийн туннелийн IP юм. Түүнээс цааш ping-үүд юу ч онилсон хамаагүй үхдэг, тэр нь ClusterIP ч бай, өөр подын хаяг ч бай, нийтийн хост нэр ч бай. Энэ хослол бүдэг биш, оношлогооны шинжтэй: задлалт ажиллаж байна, хоёр дахь үсрэлт ажиллахгүй байна.
Би үүнтэй chart-аар суулгасан OpenVPN образ ажиллуулж байсан Debian зангилаа дээр таарсан бөгөөд туннель нь хялбар хэсэг байв. Клиент 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 рүү түүхий ping амжилттай болбол, асуудал дамжуулалтад биш, DNS хоолойд байна. Хэрэв peer хаягаас цаашх бүх очих газар тайм-аут болвол, нүцгэн IP-г оролцуулан, namespace-ээс эхэл.
Тохиргоог namespace дотор уншина уу
Под бүр өөрийн сүлжээний namespace-ийг авдаг бөгөөд net.ipv4.ip_forward нь namespace бүрийн sysctl юм. Үүнийг зангилаа дээр өөрчлөх нь контейнерын талаар юу ч хэлэхгүй, мөн буруу машинд үдээс хойш цагийг өнгөрөөх найдвартай арга юм.
kubectl exec -it deploy/openvpn -- sysctl net.ipv4.ip_forward
# net.ipv4.ip_forward = 0
Тэг нь оношийг батална. Утга нь зангилааны ажиллах үеийн тохиргооноос өвлөгддөггүй: контейнер үүсгэх бүрт образын анхдагчаас эхэлдэг. Тиймээс kubectl exec ... sysctl -w-ээр гараар хэрэглэсэн засвар дараагийн дахин эхлүүлэлтэд алга болж, хааяа харагддаг гэмтэл болж буцаж ирдэг.
Манифест хадгалахын тулд идэвхжүүлэх
Тогтвортой хувилбар нь ижил pod sandbox-д ажиллаж, VPN контейнер эхлэхээс өмнө утгыг бичдэг init контейнер юм. Под дахь контейнерууд сүлжээний 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-д ямар ч контейнерт эрх мэдэл өгөхгүйгээр namespace-т sysctl хэрэглэх боломжийг олгодог. Энэ нь зөвхөн кластерын зөвшөөрөгдсөн жагсаалт дахь нэрсийг хамардаг. net.ipv4.ip_forward тэр жагсаалтад байгаа эсэх нь kubelet хэрхэн тохируулагдсанаас хамаарна, мөн түүнээс гадна sysctl хүссэн под admission-д татгалзагдах эсвэл sandbox дахин оролдох хооронд CreateContainerConfigError-д гацах болно. Талбарыг эвдэрсэн гэж үзэхээс өмнө зөвшөөрөгдсөн жагсаалтыг шалгана уу.
Хоёр аргын аль нэгийг гараар бүтээхээс өмнө chart унтраалгыг аль хэдийн илрүүлж байгаа эсэхийг харна уу, ихэвчлэн ipForwardInitContainer: true гэх мэт зүйл хэлбэрээр. Chart-ын утгыг ашиглах нь таны override файлыг жижиг байлгаж, дараагийн шинэчлэлтийг даван туулдаг бол гараар нөхсөн Deployment өөрчлөлтүүд тэгдэггүй.
Хоёр дахь хагас: буцах зам ба бодлого
Дамжуулалт асаалттай байх нь зайлшгүй боловч хангалттай биш. Хэрэв клиентүүд кластерын сүлжээнд маршрутгүй хувийн сан ашиглавал хариултууд туннель рүү буцах зам олж чадахгүй бөгөөд под тэр урсгалыг зорьсон газар руу нь маск хийх ёстой.
Бодлого үүн дээр суудаг. NetworkPolicy объектууд болон үүлэн firewall-ын дүрмүүд нь пакетын хөрвүүлэлтийн дараа авч явдаг эх хаягийн эсрэг үнэлэгддэг тул клиентийн санд зориулж бичсэн дүрэм маск хийх идэвхжсэний дараа чимээгүй эвлэрэхээ болих боломжтой.
Клиентүүд зөвхөн кластерын доторх үйлчилгээнд хүрэх шаардлагатай үед VPN-ийг үйлчилгээний VIP дээр дуусгах нь подын сүлжээ рүү чиглүүлэхээс жижиг загвар юм. Энэ нь мөн клиентийн саныг CNI-ийн чиглүүлэлтийн хүснэгтээс бүрэн гаргаж байдаг.
Бүтэлгүйтсэн үсрэлтийг клиентээс тусгаарлах
Гадагшаа ажиллаж, эхний чимээгүй алхамд зогсо. VPN peer-ээс эхэлж, дараа нь аль нэг подын хаяг, дараа нь үйлчилгээний VIP, түүний дараа л нийтийн очих газрыг турш. Амжилт бүр хил хязгаарыг нэг үсрэлтээр зөөж, бүтэлгүйтэл бүр шалгах нь зүйтэй давхаргыг нэрлэдэг. Аливаа нэвтрүүлгийн дараа exec-ээр орж sysctl-ийг дахин унш, учир нь солигдсон под образын анхдагчаас эхэлдэг бөгөөд манифестэд хэзээ ч байгаагүй засвар аль хэдийн явсан байдаг.
Kubernetes-ийн баримт бичиг кластерт sysctl ашиглах тухай аль нэрсийг подын аюулгүй байдлын контекстээр тохируулж болохыг жагсаасан бөгөөд admission өөрчлөлтийг татгалзах үед хамгийн түрүүнд харах газар нь тэр юм.