شما network_mode: service:vpn را به برنامه اضافه می‌کنید، پشته را دوباره راه‌اندازی می‌کنید و برنامه می‌میرد، چون db دیگر تفکیک نمی‌شود. در فایل compose هیچ چیز تغییر نام نداده است، بنابراین مظنونان واضح DNS و پایگاه داده هستند. تغییر واقعی کوچک‌تر و عجیب‌تر است: برنامه دیگر عضوی از شبکهٔ Compose که آن نام در آن وجود دارد نیست. تا زمانی که تصمیم نگیرید پایگاه داده باید از کدام فضای نام پاسخ دهد، هر اصلاح نام میزبان یک حدس است.

چرا نام میزبان db دیگر تفکیک نمی‌شود

سرویسی که از network_mode استفاده می‌کند در شبکهٔ Compose آدرس خودش را ندارد؛ فضای نام سرویس نام‌برده را قرض می‌گیرد. آن فضای نام رابط‌ها، مسیرها، فضای پورت و تفکیک‌کنندهٔ خودش را می‌آورد و اتصال برنامه به شبکهٔ backend را جایگزین می‌کند. نام db هرگز انتزاعی نبود: در همان شبکه زندگی می‌کرد و از طریق DNS تعبیه‌شدهٔ آن تفکیک می‌شد. اتصال را بردارید و نام جایی برای تفکیک شدن ندارد.

این را از درون کانتینرها تأیید کنید، نه از میزبان. جست‌وجویی که در برنامه شکست می‌خورد اما در کانتینر پایگاه داده موفق می‌شود یعنی نام درست است و عضویت نه. این نتیجه اصلاح را نیز در توپولوژی compose قرار می‌دهد، نه در تنظیمات تفکیک‌کنندهٔ برنامه.

سه پرسش پیش از ویرایش فایل

به ترتیب پاسخ دهید، زیرا هر کدام توپولوژی را محدود می‌کند. پایگاه داده باید به چه چیزی پاسخ دهد: نام میزبانی که کانتینرهای دیگر استفاده می‌کنند، یا فقط برنامه روی loopback؟ آیا برنامه باید پورتی را به میزبان منتشر کند، و کدام سرویس مالک آن خواهد بود؟ آیا پایگاه داده باید از میزبان یا از ماشین دیگری در دسترس باشد، یا فقط از درون تونل؟

اگر پایگاه داده به نام خودش نیاز دارد و برنامه چیزی منتشر نمی‌کند، آن‌ها را روی اتصال‌های جدا نگه دارید. اگر برنامه باید پورت منتشر کند و همه چیز از تونل می‌گذرد، پایگاه داده را در فضای نام VPN بگذارید و از loopback استفاده کنید. آمیختن این دو پشته‌ای می‌سازد که تمیز شروع می‌شود و در زمان اتصال شکست می‌خورد.

پایگاه داده را همان‌جا که هست بگذارید

تغییر کوچک‌تر مالک فضای نام را به شبکه‌ای متصل می‌کند که از قبل پایگاه داده را در خود دارد. برنامه آن اتصال را به ارث می‌برد چون پشتهٔ vpn را شریک است، و db دقیقاً مثل قبل تفکیک می‌شود.

services:
  vpn:
    networks:
      - backend
  app:
    network_mode: service:vpn
  db:
    networks:
      - backend
networks:
  backend:

networks را هم به برنامه اضافه نکنید. Compose آن ویژگی را در کنار network_mode در همان سرویس رد می‌کند، و خطا به فایل اشاره می‌کند نه به آن جفت. اگر کلاینت VPN مقصد backend را درون فضای نامش فیلتر می‌کند، سیاست شبکهٔ محلی پشتیبانی‌شدهٔ آن را هم تنظیم کنید؛ اتصال مشترک مسیری پیشنهاد می‌دهد اما آن فیلتر را لغو نمی‌کند.

پایگاه داده را به فضای نام منتقل کنید

تغییر بزرگ‌تر پایگاه داده را در همان فضای نام قرار می‌دهد و برنامه را با پورت واقعی به 127.0.0.1 اشاره می‌دهد. دو فرایند نمی‌توانند فقط به این دلیل که در کانتینرهای مختلف شروع شده‌اند هر دو یک آدرس و پورت را مقید کنند، پس پایگاه داده‌ای که روی آدرس wildcard هم گوش می‌دهد با هر چیز دیگری که چنین می‌کند برخورد خواهد کرد. پیش از جابه‌جایی شنونده را بررسی کنید.

پورت‌های منتشرشده به سرویس مالک فضای نام تعلق دارند. افزودن ports به برنامه در کنار network_mode رد می‌شود، و ساختن آدرس جداگانه برای برنامه رابطی را توصیف می‌کند که وجود ندارد.

آمادگی، مسدودسازی و تفکیک‌کننده

depends_on ترتیب شروع کانتینرها را تعیین می‌کند؛ این شاهد بالا بودن تونل نیست و وقتی تونل قطع می‌شود ترافیک را متوقف نمی‌کند. دسترس‌پذیری، آمادگی تونل و مسدودسازی خطا را سه نیاز جداگانه بدانید. پشته‌ای که فقط اولی را برآورده می‌کند در یک روز خوب در آزمون دستی قبول می‌شود و در یک روز بد نشت می‌کند. سه پاسخ را کنار فایل compose بنویسید، جایی که نفر بعدی نگاه خواهد کرد.

هم‌رسانی فضای نام همچنین یعنی برنامه تفکیک‌کنندهٔ کانتینر VPN را به ارث می‌برد، که وقتی تونل سرورهای DNS را تحمیل می‌کند کمک می‌کند و وقتی نمی‌کند گیج‌کننده است. بررسی کنید فضای نام واقعاً چه دارد، به جای اینکه فرض کنید تفکیک‌کنندهٔ میزبان اعمال می‌شود. مرجع سرویس‌های Compose در یک جا network_mode، ports و رفتار وابستگی‌ها را مستند می‌کند، از جمله اینکه چرا یک سرویس network_mode آدرس خودش را ندارد.

مقالات مرتبط