پاد OpenVPN در Kubernetes هیچ چیز را هدایت نمیکند؟ ip_forward را بررسی کنید
کلاینتها پاد VPN را پینگ میکنند و بعد از آن هیچ چیز نیست. فضای نام، ارسال را خاموش دارد و اصلاح باید از admission، راهاندازیهای مجدد و مسیر بازگشت جان سالم به در ببرد.
لپتاپ شما تونل سبزی نشان میدهد، گزارش کلاینت میگوید مسیرها فرستاده شدهاند، و تنها آدرسی که پاسخ میدهد IP تونل خود سرور VPN است. پینگهای بعد از آن هر چه را هدف بگیرید میمیرند، چه ClusterIP باشد، چه آدرس پاد دیگری، چه یک نام میزبان عمومی. این ترکیب مبهم نیست، تشخیصی است: بازگشایی بسته کار میکند و پرش دوم نه.
این را روی یک نود Debian با ایمیج OpenVPN نصبشده با chart دیدم، و تونل بخش آسان بود. کلاینت اجاره 10.8.0.x گرفت، 10.8.0.1 پاسخ داد، و 10.96.0.10، سرویس DNS خوشه، به تایماوت خورد. هیچ چیز در گزارش سرور ناسالم به نظر نمیرسید، و دقیقاً به همین دلیل است که مردم شروع به بازنویسی قواعد iptables میکنند که هرگز نیازی به دست زدن به آنها نداشتند.
پاد VPN یک روتر است، و ارزش دارد که این را صریح گفت. بستههای رمزنگاریشده میرسند، در فضای نام شبکه خود پاد باز پیچیده میشوند، و سپس باید از رابط دیگری خارج شوند. لینوکس این گام دوم را رد میکند مگر اینکه ارسال درون همان فضای نام فعال باشد.
کلاینت به چه چیزی میرسد و به چه چیزی نه
آدرسی که پاسخ میدهد به نقطه پایانی تونل تعلق دارد و فرآیند VPN آن را بهصورت محلی در اختیار دارد، پس هیچ ارسالی در کار نیست. هر چیز دیگری، از جمله پاد دیگر، VIP سرویس یا اینترنت، به کرنل نیاز دارد تا بستهای را از tun0 به eth0 منتقل کند. وقتی این انتقال رد میشود، نشانه سکوت یکنواخت است نه رد شدن، چون هیچ چیز خطای ICMP را به پایین تونل برنمیگرداند. تایماوت میگیرید، نه پیام غیرقابلدسترس، و این همان سرنخی است که هیچکس اصلاً مسیریابی نمیکند.
دو دقیقه طبقهبندی لایه را باریک میکند. اگر نامهای DNS شکست بخورند در حالی که پینگ خام به IP سرویس موفق شود، مشکل در لولهکشی DNS است، نه در ارسال. اگر هر مقصدی فراتر از آدرس همتا تایماوت شود، از جمله IP خالی، از فضای نام شروع کنید.
تنظیم را درون فضای نام بخوانید
هر پاد فضای نام شبکه خودش را میگیرد، و net.ipv4.ip_forward یک sysctl برای هر فضای نام است. تغییر آن روی نود هیچ چیزی درباره کانتینر نمیگوید، و راهی مطمئن برای گذراندن یک بعدازظهر روی ماشین اشتباه است.
kubectl exec -it deploy/openvpn -- sysctl net.ipv4.ip_forward
# net.ipv4.ip_forward = 0
صفر تشخیص را تأیید میکند. مقدار از پیکربندی زمان اجرای نود هم به ارث نمیرسد: هر بار که کانتینری ساخته میشود از پیشفرض ایمیج شروع میکند. بنابراین اصلاحی که دستی با kubectl exec ... sysctl -w اعمال شده در راهاندازی مجدد بعدی ناپدید میشود و بهصورت نقصی که متناوب به نظر میرسد برمیگردد.
فعال کردنش تا مانیفست آن را نگه دارد
گزینه پایدار یک کانتینر init است که در همان sandbox پاد اجرا میشود و مقدار را قبل از شروع کانتینر VPN مینویسد. کانتینرهای یک پاد فضای نام شبکه را شریک میشوند، پس تنظیم به کانتینر اصلی منتقل میشود.
initContainers:
- name: enable-forwarding
image: busybox:1.36
command: ["sysctl", "-w", "net.ipv4.ip_forward=1"]
securityContext:
privileged: true
همان privileged: true خطی است که بازبینها به آن اعتراض میکنند، و حق دارند. نوشتن یک sysctl یا به امتیاز نیاز دارد یا به توانایی محدود، و خوشهای که استاندارد Pod Security محدود را اجرا میکند ممکن است کانتینر init ممتاز را یکسره رد کند. اگر admission پاد را رد کند، در زمان ساخت میفهمید، که حداقل صادقانه و آسان برای خواندن است.
جایگزین تمیزتر فهرست securityContext.sysctls در سطح پاد است که به kubelet اجازه میدهد sysctlهای فضای نام را بدون دادن امتیاز به هیچ کانتینری اعمال کند. فقط نامهای فهرست مجاز خوشه را پوشش میدهد. اینکه net.ipv4.ip_forward در آن فهرست باشد به نحوه پیکربندی kubelet بستگی دارد، و پادی که sysctl خارج از آن بخواهد در admission رد میشود یا در CreateContainerConfigError گیر میکند تا sandbox دوباره تلاش شود. قبل از اینکه فرض کنید فیلد خراب است، فهرست مجاز را بررسی کنید.
قبل از اینکه هر یک از این دو رویکرد را دستی بسازید، ببینید آیا chart کلید را از قبل ارائه میدهد، اغلب چیزی مثل ipForwardInitContainer: true. استفاده از مقدار chart فایل override شما را کوچک نگه میدارد و از ارتقای بعدی جان سالم به در میبرد، کاری که ویرایشهای دستی Deployment نمیکنند.
نیمه دوم: مسیر بازگشت و سیاست
ارسال فعال لازم است، نه کافی. اگر کلاینتها از استخری خصوصی استفاده کنند که شبکه خوشه مسیری به آن ندارد، پاسخها راهی به تونل پیدا نمیکنند، و پاد باید آن ترافیک را به سمت مقصدش ماسک کند.
سیاست روی این سوار است. اشیای NetworkPolicy و قواعد فایروال ابری بر اساس آدرس مبدأیی که بسته پس از ترجمه حمل میکند ارزیابی میشوند، بنابراین قاعدهای که برای استخر کلاینت نوشته شده میتواند وقتی ماسک کردن فعال میشود بیصدا از تطابق بماند.
وقتی کلاینتها فقط باید به سرویسهای درون خوشه برسند، پایان دادن VPN در VIP سرویس طراحی کوچکتری از مسیریابی به شبکه پادهاست. همچنین استخر کلاینت را کاملاً از جدول مسیریابی CNI بیرون نگه میدارد.
جدا کردن پرش خراب از کلاینت
به سمت بیرون کار کنید و در اولین گام بیصدا بایستید. با همتای VPN شروع کنید، سپس آدرس یک پاد را امتحان کنید، بعد یک VIP سرویس، و تنها پس از آن یک مقصد عمومی. هر موفقیت مرز را یک پرش جابهجا میکند و هر شکست لایهای را نام میبرد که ارزش بررسی دارد. پس از هر استقرار، با exec وارد شوید و sysctl را دوباره بخوانید، چون پاد جایگزینشده از پیشفرض ایمیج شروع میکند و اصلاحی که هرگز در مانیفست نبوده از قبل رفته است.
مستندات Kubernetes درباره استفاده از sysctlها در یک خوشه فهرست میکند کدام نامها را میتوان از طریق زمینه امنیتی پاد تنظیم کرد، و همان اولین جایی است که وقتی admission تغییر را رد میکند باید نگاه کنید.