چرا پادهای GKE از طریق VPN به میزبانهای محلی نمیرسند
گره به شبکه محلی میرسد، پاد نه. استثناهای masquerade در GKE آدرس پادها را برای مقصدهای 10.x ترجمهنشده رها میکند.
پینگ از گره کار میکند و از پاد شکست میخورد، و هیچ چیز به سمت محلی نمیرسد. تونل و مسیر درستاند؛ آدرس مبدأ روی سیم درست نیست. چیزی که این دو حالت را متمایز میکند این است که بسته هنگام خروج از خوشه خود را چه مینامد، و GKE در این باره نظر دارد. سازوکار یک فهرست استثنای masquerade است، و خواندنش فقط یک فرمان میخواهد.
پیش از تغییر هر چیز، فهرست معتبر را بخوانید
GKE عاملی عرضه میکند که برای هر بازه مقصد تصمیم میگیرد آیا ترافیک پادها هنگام خروج به آدرس گره بازنویسی شود یا نه. پیکربندی ارائهشدهاش سه بلوک RFC1918، 10.0.0.0/8، 172.16.0.0/12 و 192.168.0.0/16، را مقصدهای معاف مینامد. بنابراین هر چیزی که از پاد به میزبان محلی 10.x بفرستید گره را با آدرس خود پاد همچنان چسبیده ترک میکند. ترافیک خود گره بازنویسی نمیشود، و دقیقاً به همین دلیل پینگ آن کار میکند.
پیکربندی موردنظر و قواعد نصبشده را بخوانید، چون ممکن است همخوان نباشند. 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.
آن را با چیزی که طرف مقابل گزارش میکند مقایسه کنید. ضبطی در سمت محلی که آدرس پاد را نشان میدهد و پاسخی ندارد حلقه را میبندد: فهرست استثناها عدم تقارن را بدون هیچ نقص تونل توضیح میدهد. دو مشاهده از یک آدرس مبدأ برای دست کشیدن از گمانهزنی درباره CNI کافی است.
استثنا را به CIDR پادها محدود کنید
تعمیر پشتیبانیشده بهجای حذف استثنا آن را محدود میکند: CIDR پادها را معاف نگه دارید و بقیه فضای 10.x را کنار بگذارید. آن فهرست در ConfigMap عامل زیر nonMasqueradeCIDRs زندگی میکند، و تغییرش یک ویرایش و سپس انتشار است. ورودی گسترده را با بازه واقعی پادهای خوشه جایگزین کنید، اگر ترافیک داخل خوشه هنوز به بلوکهای خصوصی دیگر نیاز دارد آنها را نگه دارید، و بیدلیل resyncInterval را دست نزنید. اعمالش کنید، تأیید کنید پادهای عامل دوباره راهاندازی شدهاند و تأیید کنید قواعد هسته تغییر کردهاند.
این تغییری در کل خوشه با شعاع اثر واقعی است. پس از اعمال، ترافیکی که پیشتر مبدأ پاد خود را حفظ میکرد اکنون بازنویسیشده به گره میرسد، پس هر چیزی که به آن آدرسهای پاد وابسته بود فرستنده متفاوتی میبیند. قربانیان گزارشها، فهرستهای مجاز و قواعد دیوار آتش محلی هستند که آدرس پادها را نام میبرند، و بیصدا شکست میخورند. تغییر را بهعنوان تغییر رفتار اعلام کنید نه تعمیر.
در خوشهای با چند استخر گره بررسی کنید عامل روی گرههایی زمانبندی شده که پادهای متأثر واقعاً روی آنها اجرا میشوند. استخری بدون DaemonSet قواعد قدیمی خود را نگه میدارد، و هیچ چیز در ConfigMap آن را نشان نخواهد داد.
گزینه جایگزین و هزینهاش
گزینه دیگر آدرس پادها را دستنخورده نگه میدارد و مسیر را درباره آنها آموزش میدهد. CIDR پادها به انتخابگرهای ترافیک Cloud VPN میرود، و سمت محلی برای پاسخها به مسیر بازگشت نیاز دارد تا بدانند کجا بروند. این هویت پاد را که برخی مدلهای امنیتی میخواهند حفظ میکند، و هم گستره مسیریابی و هم گستره دیوار آتش را که طرف مقابل باید بپذیرد گسترش میدهد.
معامله خوانایی در برابر گستره است. ترجمه باعث میشود سمت محلی برای هر گره یک آدرس ببیند، که افزودنش به فهرست مجاز آسان است و پنهان میکند کدام پاد چه فرستاده. بدون ترجمه آدرس پاد از سر تا ته حفظ میشود، که برای انتساب بهتر و برای هر دستگاهی در مسیر که باید بازه جدید را بیاموزد بدتر است. هیچکدام نقص Docker یا CNI نیست؛ هر دو تصمیم مسیریابی با صورتحساب عملیاتیاند. آن را انتخاب کنید که تیمتان توان پرداخت صورتحسابش را دارد، و دلیلش را بنویسید.
تأیید و بازگردانی
همان ضبط را دوباره اجرا کنید. اگر ضبط در سطح گره پس از ویرایش شما هنوز آدرس پاد را چاپ میکند، یعنی قواعد هرگز تغییر نکردهاند، هر چه ConfigMap بگوید. سیم واقعیت است؛ بقیه استنتاج.
سپس جهت مخالف را بررسی کنید، چون نیمی از این تغییرات فقط در جهت خروج تأیید میشوند. تأیید کنید پاسخ به گره یا پادی میرسد که درخواست را فرستاده، و تأیید کنید برنامه تمام شده نه اینکه فقط SYN گرفته باشد. ضبطی که درخواست بدون پاسخ را نشان میدهد مشکل مسیریابی در طرف مقابل است، نه مشکل masquerade در این طرف.
بازگردانی یعنی ConfigMap قبلی، با همان روش اعمال شود، با همان تأیید که عامل دوباره راهاندازی شده و قواعد تغییر کردهاند. آدرس مبدأ پیش و پس از یک درخواست معلوم را در سابقه تغییر نگه دارید، چون همان یک خط ثابت میکند تغییر همان کاری را کرد که گفتید. راهنمای عامل IP masquerade در GKE مقادیر پیشفرض و فیلدهای ConfigMap را مستند میکند. اگر آدرس مبدأ پس از انتشار تغییر نکرده باشد، عامل روی آن گره اجرا نمیشود و هیچ ویرایش YAML آن را درست نمیکند.