تجاوز إلى المحتوى
← المدونة

ما بعد Ingress NGINX

المتحكّم الذي يستقبل حركة المرور في نحو نصف البيئات السحابية الأصيلة أصبح مؤرشفًا منذ مارس 2026. دليل ترحيل عملي: ما ينكسر فعليًا، وما لا تحوّله أداة ingress2gateway، وخطة تبديل يمكن التراجع عنها.

·قراءة 15 دقيقة
  • Kubernetes
  • Gateway API
  • Ingress
  • المنصات
  • الترحيل

إذا كان عنقودك لا يزال يمرّر حركة المرور عبر ingress-nginx، فأنت تشغّل برمجية لم يعد أحد مسؤولًا عن إصلاحها. أُرشِف المستودع في 24 مارس 2026. لن تصدر إصدارات جديدة، ولا إصلاحات للعلل، والأهم من ذلك: لن تصدر أي ترقيعات أمنية، لأي ثغرة، على الإطلاق. لم ينكسر شيء في ذلك اليوم، وهذه هي المشكلة بالضبط: مدخلك ما زال يعمل، فلم يجبرك شيء على التحرّك.

رسم يقارن مورد Ingress في كوبرنيتس يوجّه حركة المرور إلى خدمتين، مقابل كائنات Gateway API المكافئة: Gateway و HTTPRoute
الترحيل ليس عملية بحث واستبدال. مورد Ingress واحد يصبح Gateway واحدًا، إضافة إلى HTTPRoute لكل سلوك كنت تحصل عليه ضمنيًا.

هذا دليل ترحيل مكتوب بعد الموعد النهائي لا قبله. يغطي كيفية قياس حجم تعرّضك بأربعة أوامر، وكيفية اختيار الوجهة بناءً على أدلة لا انطباعات، وسلوكيات ingress-nginx التي يتغيّر معناها بصمت عند الترجمة، وتسلسل إطلاق يتيح لك إعادة حركة المرور إن أساء مستوى البيانات الجديد التصرّف.

ما الذي حدث فعلًا — وما الذي لم يحدث

التسلسل الزمني قصير ويستحق الدقة، لأن كثيرًا من النقل الثانوي شوّهه. أعلنت مجموعة SIG Network في كوبرنيتس ولجنة الاستجابة الأمنية (SRC) الإيقاف في 11 نوفمبر 2025. وفي 29 يناير 2026 صعّدت لجنة التوجيه (Steering Committee) مع الـ SRC ببيان مشترك بالغ الصراحة: البقاء على Ingress NGINX بعد إيقافه يترككم وأنتم ومستخدموكم عرضة للهجوم، ولا يوجد من بين البدائل المتاحة بديل مباشر يحلّ محلّه كما هو.[retire][steering]

السؤالالإجابة بتاريخ 15 أغسطس 2026
هل لا يزال ingress-nginx مصانًا؟لا. الإصدار الأخير هو controller-v1.15.1 بتاريخ 19 مارس 2026 (مخطط Helm 4.15.1، و NGINX 1.27.1، ومختبر مقابل Kubernetes من 1.31 إلى 1.35).[lastrel]
هل اختفى المستودع؟لا — أُرشِف في 24 مارس 2026 وصار للقراءة فقط. المسائل وطلبات السحب مجمّدة، وموقع الوثائق ما زال متاحًا.[repo]
هل سينكسر عنقودي؟لا. عمليات النشر القائمة تواصل العمل، وتبقى مخرجات التثبيت — مخططات Helm وصور الحاويات — متاحة. وهذا بالضبط ما يجعل الأمر خطيرًا.[retire]
هل واجهة Ingress API مهجورة؟لا. هي متاحة بشكل عام ومجمّدة: لا تغييرات لاحقة، ولا خطة لإزالتها من كوبرنيتس.[ingressdoc]
هل يوجد متحكّم بديل رسمي؟لا. مشروع كوبرنيتس يدعم ويصون متحكّمَي Ingress الخاصين بـ AWS و GCE فقط. أما InGate، الخَلَف المفترض، فلم يصدر أي إصدار وأُرشِف هو نفسه في 30 يونيو 2026.[ctrldoc][retire]

السطر الأخير هو الأكثر إساءة فهم. واجهة Ingress API ليست مهجورة. تنص الوثائق على أنها متاحة بشكل عام (GA)، وأن المشروع لا يخطط لإزالتها، وأنها ببساطة مجمّدة — لا تغييرات ولا تحديثات لاحقة. كائنات Ingress لديك تحت networking.k8s.io/v1 صالحة في كوبرنيتس وستظل كذلك. ما انتهى هو متحكّم بعينه يقرأها.[ingressdoc]

ما الذي ترثه إن بقيت

أوضح طريقة لتقدير حجم المخاطرة هي النظر في الإصلاحات الأمنية التي أصدرها المشروع في أسابيعه الأخيرة. في 2 فبراير 2026 — بعد أربعة أيام من بيان لجنة التوجيه، وقبل سبعة أسابيع من تحويل المستودع إلى وضع القراءة فقط — كشفت الـ SRC عن أربع ثغرات في ingress-nginx: CVE-2026-1580 و CVE-2026-24512 و CVE-2026-24513 و CVE-2026-24514. صُنّفت أخطرها بدرجة HIGH بقيمة 8.8، وأُصلحت في v1.13.7 و v1.14.3.[advisory]

الثغرة الجديرة بالاستيعاب هي CVE-2026-24512. كان يمكن استخدام حقل rules.http.paths.path في مورد Ingress لحقن إعدادات داخل NGINX، ما يؤدي إلى تنفيذ شيفرة اعتباطية ضمن سياق المتحكّم، وإلى كشف كل الأسرار (Secrets) التي يستطيع المتحكّم قراءتها — وهي، في التثبيت الافتراضي، كل أسرار العنقود. كان التخفيف المؤقت هو استخدام validating admission controller يرفض موارد Ingress التي تستعمل نوع المسار ImplementationSpecific. لاحظ ما يتطلّبه هذا الصنف من الثغرات من المهاجم: القدرة على إنشاء مورد Ingress. أي شخص يملك صلاحية كتابة على مستوى فضاء أسماء واحد يستوفي الشرط.[cve24512]

ثم تلتهما ثغرتان أخريان، وهما اللتان تكملان الحجّة. CVE-2026-3288، كُشِف عنها في 9 مارس 2026 وصُنّفت HIGH بقيمة 8.8، كانت حقن إعدادات عبر التعليقة التوضيحية rewrite-target — وهي نفسها التي يحذّر منها جدول الدلالات أدناه — وأُصلحت في v1.13.8 و v1.14.4 و v1.15.0. ثم CVE-2026-4342، كُشِف عنها في 19 مارس 2026 بقيمة 8.8 وبالمتّجه نفسه: حقن إعدادات عبر التعليقات البرمجية، يؤدي مرة أخرى إلى تنفيذ شيفرة في المتحكّم وكشف الأسرار على مستوى العنقود كله. أُصلحت في v1.13.9 و v1.14.5 و controller-v1.15.1 — أي في الإصدار الأخير. آخر ما أصدره هذا المشروع على الإطلاق كان ترقيعًا أمنيًا، قبل خمسة أيام من تحويل المستودع إلى وضع القراءة فقط. أما ما سيأتي بعد ذلك فلن يحصل على شيء.[cve3288][cve4342][lastrel]

وإن أردت الحدّ الأعلى، فالسابقة هي CVE-2025-1974 — المعروفة باسم «IngressNightmare»، مارس 2025، بدرجة CVSS تساوي 9.8. وصفها مشروع كوبرنيتس بلغة مباشرة: أي شيء على شبكة الحاويات (Pod network) كانت لديه فرصة جيدة للاستيلاء على العنقود، دون أي بيانات اعتماد. تلك حصلت على ترقيع. التالية لن تحصل.[nightmare]

ستستمر عمليات النشر القائمة في العمل، لذا ما لم تتحقّق بنفسك ومبادرةً منك، قد لا تعرف أنك متأثر إلا بعد اختراقك.[steering]

أما عن الحجم: تذكر لجنة التوجيه ولجنة الاستجابة الأمنية أن نحو 50% من البيئات السحابية الأصيلة تعتمد على هذا المتحكّم، استنادًا إلى بحث داخلي لشركة Datadog. تعامل مع الرقم بوصفه مؤشرًا لا قياسًا دقيقًا — فمجموعة البيانات غير منشورة وتعكس البيئات التي تراقبها Datadog — لكن رتبة الحجم يؤكّدها رقم المشروع نفسه في 2025: «أكثر من 40% من عناقيد كوبرنيتس». في الحالتين، هذه ليست مهمة تنظيف هامشية.

اكتشف ما إذا كنت متأثرًا

قبل أي تخطيط، قِس. الأمر الأول هو ما ينشره مشروع كوبرنيتس نفسه؛ أما الثلاثة الباقية فتخبرك بحجم العمل الحقيقي، لأن كلفة هذا الترحيل ليست عدد كائنات Ingress، بل عدد التعليقات التوضيحية (annotations) المختلفة خلفها.

# 1. The check the Kubernetes project itself publishes
kubectl get pods --all-namespaces \
  --selector app.kubernetes.io/name=ingress-nginx

# 2. Which controller image, and therefore which version, is actually running
kubectl get deploy -A -l app.kubernetes.io/name=ingress-nginx \
  -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.spec.template.spec.containers[0].image}{"\n"}{end}'

# 3. How much surface you have to translate: every Ingress bound to it
kubectl get ingress -A \
  -o jsonpath='{range .items[*]}{.metadata.namespace}/{.metadata.name}{"\t"}{.spec.ingressClassName}{"\n"}{end}'

# 4. The real cost driver - the annotations, ranked by how often you use them
kubectl get ingress -A -o json \
  | jq -r '.items[].metadata.annotations // {} | keys[]' \
  | grep -F 'nginx.ingress.kubernetes.io/' | sort | uniq -c | sort -rn

الأمر الرابع هو التقدير بعينه. عنقود فيه ستون مورد Ingress وأربع تعليقات توضيحية يعني بعد ظهر واحد. عنقود فيه اثنا عشر موردًا واثنتان وعشرون تعليقة توضيحية — من بينها configuration-snippet — يعني مشروعًا كاملًا، وقد عرفت للتو السبب.

حدّد الوجهة قبل أن تلمس أي ملف YAML

هناك ثلاثة خيارات صادقة، والصحيح منها يعتمد على مدى اعتمادك الفعلي على سلوك ingress-nginx. ومما يجدر معرفته قبل وضع قائمة مختصرة: متحكّمات Ingress الوحيدة التي يدعمها ويصونها مشروع كوبرنيتس هي متحكّما AWS و GCE. أما كل ما عداهما في القائمة الموثّقة — Traefik و HAProxy و Contour و Kong و APISIX و Cilium و Higress و Istio وغيرها — فهي أطراف ثالثة. ولاحظ أيضًا أن kubernetes/ingress-nginx لم يعد مدرجًا في تلك الصفحة إطلاقًا.[ctrldoc]

الوجهةاخترها حينما تكلّفك
تنفيذ لـ Gateway API
NGINX Gateway Fabric، Envoy Gateway، Traefik، Cilium، kgateway، Istio، agentgateway…
تريد الواجهة التي يجري تطويرها فعلًا، أو لديك أكثر من فريق يربط مسارات بحافة مشتركة، أو تحتاج فصلًا للأدوار بين المنصة وأصحاب التطبيقات.أكبر قدر من إعادة الكتابة. تتحوّل كائنات Ingress إلى Gateway و HTTPRoute، وتتحوّل التعليقات التوضيحية إلى مرشّحات أو سياسات أو لا شيء على الإطلاق.
متحكّم Ingress آخر
Traefik، HAProxy، Contour، Kong، APISIX، Istio…
لديك عدد كبير من موارد Ingress البسيطة، وميزانية ترحيل محدودة، وتريد أقصر طريق للخروج من متحكّم غير مصان.تبقى كائنات networking.k8s.io/v1 كما هي، لكن كل تعليقة nginx.ingress.kubernetes.io/* يجب إعادة التعبير عنها بلهجة المتحكّم الجديد. كما أنك تحطّ على واجهة مجمّدة، فخطّط لتكرار العملية لاحقًا.
متحكّم أو بوابة مزوّدك السحابي
AWS Load Balancer Controller، GKE Gateway، AGIC، بوابات API المدارة…
أنت على منصة مُدارة واحدة، وتقدّر وجود جهة تتصل بها، ومستعدّ لمبادلة قابلية النقل بقابلية الدعم.ارتباط بالمورّد، ومستوى بيانات لا يمكنك فحص سلوكه بالكامل. راجع تقرير المطابقة قبل افتراض تكافؤ الميزات — عدة تنفيذات مُدارة تجتاز عددًا أقل بوضوح من الميزات الموسّعة.

إن سلكت طريق Gateway API، فالإصدار الحالي هو v1.6.0، وُسِم في أواخر يونيو 2026 وأُعلن عنه في 3 أغسطس 2026. في هذا الإصدار ترقّى TCPRoute و UDPRoute من قناة Experimental إلى Standard تحت v1، لينضمّا إلى Gateway و GatewayClass و HTTPRoute و GRPCRoute و TLSRoute و ListenerSet و ReferenceGrant و BackendTLSPolicy. أما نسختا v1alpha2 من TCPRoute و UDPRoute فأصبحتا مهجورتين اعتبارًا من v1.6 وستُزالان. ثبّت إصدار الترقيع الحالي، v1.6.1 الصادر في 16 يوليو 2026، لا v1.6.0. وبخصوص إصدارات العنقود، لا ينشر المشروع حدًّا أدنى ثابتًا؛ سياسته المعلنة هي دعم أحدث خمسة إصدارات فرعية من كوبرنيتس، فقارن هذه السياسة بعنقودك بدل الاعتماد على رقم قرأته في تدوينة.[gw16][gw16rel][gw161][versioning]

ثمة تغيير بنيوي في v1.6 يستحق التخطيط له: الموارد التجريبية الجديدة صارت في مجموعة واجهات منفصلة، gateway.networking.x-k8s.io، مع بادئة X في اسم النوع — مثل XBackend و XMesh. وعند ترقّي أحدها يُعاد تسميته داخل gateway.networking.k8s.io وتُحذف البادئة. هذه إشارة مقصودة: إن كان النوع الذي تنوي الاعتماد عليه يبدأ بحرف X، فهو ليس التزامًا صالحًا للإنتاج.[gw16]

اختر بناءً على الأدلة. ينشر مشروع Gateway API تقارير مطابقة (conformance) لكل إصدار، تبيّن بالضبط كم ميزة موسّعة يجتازها كل تنفيذ، ولكل نوع مسار. هذا الجدول أداة فرز أفضل من أي صفحة مقارنة من مورّد، بما في ذلك هذا المقال — راجع صف الإصدار الذي تنوي تشغيله فعلًا، لا صف العام الماضي. وانتبه إلى أن ليس كل تنفيذ يقدّم تقريرًا مع كل إصدار؛ فغياب الصف يعني «لا يوجد تقرير لهذا الإصدار»، لا «غير مطابق».[conform]

ملاحظة عملية للفرق التي تعمل في المنطقة: إن كنت على منصة كوبرنيتس مُدارة لدى مزوّد سحابي إقليمي أو عالمي، فابدأ بالسؤال الذي يقيّد كل ما عداه — أي متحكّم يوفّره المزوّد، وعلى أي إصدار من Gateway API هو معتمد؟ في الممارسة العملية، دورة تحديث المنصة هي التي تحدّد إيقاع الترحيل، لا قائمة أعمالك. وإن كنت خاضعًا لمتطلبات إقامة بيانات أو ضوابط أمنية وطنية، فإن تشغيل مكوّن مكشوف على الإنترنت أُعلن صراحةً أنه لن يتلقّى ترقيعات أمنية هو ملاحظة تدقيق قابلة للتوثيق، لا مجرد دَين تقني. من المفيد توثيق إجراءات التخفيف المؤقتة كتابةً لا تطبيقها فحسب.

خمسة سلوكيات لا تنجو من الترجمة

هنا تنحرف عمليات الترحيل، ويستحق هذا القسم القراءة حتى لو كنت قد حسمت وجهتك. راكم ingress-nginx سلوكيات لم تكن يومًا جزءًا من مواصفة Ingress، وصارت تطبيقاتك تعتمد عليها بصمت، ولا يعيد إنتاجها أي تنفيذ مطابق لـ Gateway API. وقد وثّق مشروع كوبرنيتس خمسة منها تحديدًا ليوفّر على الناس اكتشافها بأنفسهم.[gotchas]

سلوك ingress-nginxما يتغيّر بعد الترحيلما العمل
مطابقات التعابير النمطية تعتمد البادئة ولا تميّز حالة الأحرفتترك Gateway API دلالات RegularExpression للتنفيذ نفسه، والتنفيذات الشائعة القائمة على Envoy — Istio و Envoy Gateway و kgateway — تُجري مطابقة كاملة تميّز حالة الأحرف، فتتوقّف مسارات كانت تُطابَق عن المطابقة.ترجمها صراحةً إلى (?i)/pattern.*. وأداة ingress2gateway تُخرج هذه الصيغة نيابةً عنك.
use-regex يتسرّب إلى كل موارد Ingress على المضيف نفسهتفعيل التعابير النمطية على مورد واحد كان يغيّر مطابقة المسارات في موارد Ingress أخرى لا علاقة لها به على اسم المضيف نفسه. هذا الاقتران يختفي بصمت.احصر الجرد حسب اسم المضيف لا حسب مورد Ingress. المسارات التي كانت تعمل فقط بفضل تعليقة «جار» ستفشل.
rewrite-target يفعّل ضمنيًا use-regexقد تكون دلالات التعابير النمطية مفعّلة على موارد Ingress لم تعلنها قط.عند التدقيق، عامِل كل مورد Ingress يحمل rewrite-target كأنه مورد بتعابير نمطية.
غياب الشرطة المائلة الأخيرة يولّد 301 تلقائيًاالتنفيذات المطابقة لـ Gateway API لا تضيف إعادة التوجيه هذه. العملاء الذين اعتمدوا عليها يحصلون على 404 من تطبيقك بدلًا منها.إما أن تضيف مرشّح RequestRedirect صراحةً، أو تصلح المسارات داخل التطبيق. اختبر /path و/path/ معًا.
تُطبَّع عناوين URL قبل المطابقة (RFC 3986 §6.2)معظم التنفيذات تُطبّع أيضًا المقاطع . و.. افتراضيًا، لكن السلوك الدقيق يختلف بينها، لذا قد تصل الشرطات المكرّرة والحالات الحدّية إلى خدمتك بصيغة مختلفة عمّا اعتدته.غير قابل للضبط عبر Gateway API القياسي. تحقّق من كل تنفيذ على حدة، وتحقّق من صحة المسارات داخل التطبيق.

أكثرها إيلامًا عمليًا هو إعادة التوجيه المرتبطة بالشرطة المائلة الأخيرة، لأنها لا تفشل بصوت عالٍ. الطلبات إلى /api التي كانت تُعاد توجيهها إلى /api/ صارت تُرجع 404 من التطبيق، ويظهر الخطأ في سجلات خدمتك لا عند الحافة — فتكون الفرضية الأولى وجود علة في الخدمة، لا الترحيل الذي نفّذته الليلة الماضية.

‏ingress2gateway: ما الذي يحوّله وما الذي يرفضه

توجد أداة تحويل رسمية، وقد تحسّنت كثيرًا. بلغت ingress2gateway الإصدار 1.0 في 20 مارس 2026 بوصفها مشروعًا فرعيًا ضمن SIG Network. التغيير الأبرز: ارتفعت تغطية تعليقات ingress-nginx التوضيحية من ثلاث إلى أكثر من ثلاثين، تشمل CORS وTLS نحو الواجهة الخلفية ومطابقة التعابير النمطية وإعادة كتابة المسارات. كما أضاف الإصدار 1.0 اختبارات تكامل على مستوى المتحكّم، تُشغّل ingress-nginx حقيقيًا ومتحكّم Gateway API حقيقيًا داخل عناقيد حيّة وتقارن سلوكهما أثناء التشغيل، بدل الاكتفاء بمقارنة ملفات YAML.[i2gblog]

# Install the official converter (Go 1.25.5 or newer to build from source)
go install github.com/kubernetes-sigs/ingress2gateway@v1.0.0
# or: brew install ingress2gateway

# Convert a manifest on disk, without touching the cluster
ingress2gateway print --input-file ingress.yaml \
  --providers=ingress-nginx > gwapi.yaml

# Convert one namespace from a live cluster
ingress2gateway print --namespace shop \
  --providers=ingress-nginx > gwapi.yaml

# Convert everything, and keep the warnings - they are the migration backlog
ingress2gateway print --all-namespaces \
  --providers=ingress-nginx > gwapi.yaml 2> unsupported.log

تدعم الأداة تسعة مزوّدين — ingress-nginx وnginx وtraefik وkong وistio وapisix وcilium وgce وopenapi — مع ستة مُصدِرات إخراج (emitters) من بينها envoy-gateway وkgateway. ومخرجاتها تستهدف Gateway API v1.5.0. أما ما لن تقوم به نيابةً عنك:[i2g]

  • configuration-snippet وserver-snippet — غير مدعومتين، ولا يوجد مقابل لهما. فتوجيهات NGINX الاعتباطية هي بالضبط قرار التصميم الذي سمّاه مشروع كوبرنيتس مصدرًا لـ«دَين تقني لا يمكن تجاوزه». وإن كانت مقتطفاتك تحمل منطق عمل، فذلك المنطق يجب أن ينتقل إلى التطبيق، أو إلى مرشّح (filter)، أو إلى مورد سياسة CRD خاص بالتنفيذ.[retire]
  • proxy-body-size — لا مقابل له في Gateway API. اضبطه على مستوى البيانات بدلًا من ذلك، ما يعني أنه يصبح خاصًا بالتنفيذ ويفقد قابلية النقل.
  • proxy-read-timeout وproxy-send-timeout — تعيين بأفضل جهد إلى timeouts.request، وهو ليس الشيء نفسه. أعد القياس تحت الحمل بدل افتراض التكافؤ.
  • تطبيع عناوين URL — غير قابل للضبط عبر Gateway API القياسي إطلاقًا. إن كنت تعتمد عليه فأنت تعتمد على مستوى البيانات، ويلزمك التحقّق من كل تنفيذ على حدة.

اقرأ تحذيرات الأداة بوصفها قائمة أعمال الترحيل لا ضجيجًا. كل ما تطبعه على stderr هو سلوك لم تستطع نقله، وكل واحد من تلك السلوكيات حادثُ إنتاجٍ ينتظر تغيير الـ DNS.

‏Ingress و Gateway API جنبًا إلى جنب

مثال بسيط لكنه واقعي: اسم مضيف واحد، و TLS، ومسار مقسوم بين واجهة برمجية وواجهة ويب أمامية. الفائدة من وضعهما جنبًا إلى جنب أن نسخة Gateway API أطول، وهذا الطول الإضافي ليس شكليات — بل هو السلوك الذي كان ingress-nginx يمنحك إياه ضمنيًا، مكتوبًا صراحةً الآن.

قبل — مورد Ingress واحد

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: shop-ingress
  namespace: shop
spec:
  ingressClassName: nginx
  tls:
    - hosts: [shop.example.com]
      secretName: shop-example-com-tls
  rules:
    - host: shop.example.com
      http:
        paths:
          - path: /api
            pathType: Prefix
            backend:
              service:
                name: api-service
                port:
                  number: 8080
          - path: /
            pathType: Prefix
            backend:
              service:
                name: web-service
                port:
                  number: 80

بعد — Gateway واحد و HTTPRoute اثنان

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: shop-gateway
  namespace: shop
spec:
  gatewayClassName: nginx          # must match an installed GatewayClass
  listeners:
    - name: http
      protocol: HTTP
      port: 80
      hostname: shop.example.com
      allowedRoutes:
        namespaces:
          from: Same
    - name: https
      protocol: HTTPS
      port: 443
      hostname: shop.example.com
      tls:
        mode: Terminate
        certificateRefs:
          - group: ""              # empty string = core API group
            kind: Secret
            name: shop-example-com-tls
      allowedRoutes:
        namespaces:
          from: Same
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: shop-route
  namespace: shop
spec:
  parentRefs:
    - name: shop-gateway
      sectionName: https
  hostnames: [shop.example.com]
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /api
      backendRefs:
        - name: api-service
          port: 8080
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: web-service
          port: 80
---
# ingress-nginx redirected HTTP to HTTPS for you. Gateway API does not.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: shop-route-ssl-redirect
  namespace: shop
spec:
  parentRefs:
    - name: shop-gateway
      sectionName: http
  hostnames: [shop.example.com]
  rules:
    - filters:
        - type: RequestRedirect
          requestRedirect:
            scheme: https
            statusCode: 308

ثلاثة أمور تستحق الانتباه. sectionName يربط المسار بمستمع (listener) بعينه، وبه تفصل بين سلوك HTTP وسلوك HTTPS. وallowedRoutes هو الفصل بين الأدوار الذي لم تملكه واجهة Ingress قط: فريق المنصة يملك الـ Gateway ويقرّر أي فضاءات أسماء يُسمح لها بالارتباط به، بينما تملك فرق التطبيقات مسارات HTTPRoute الخاصة بها. أما الكائن الثالث فوجوده لمجرد إعادة إنتاج إعادة توجيه كان ingress-nginx ينفّذها افتراضيًا — وهذا في ذاته تلخيص منصف للترحيل كله.[gwapi]

تبديل يمكنك التراجع عنه فعلًا

أنفع خاصية في هذا الترحيل أن المتحكّمَين يمكن أن يعملا في الوقت نفسه. فهما كائنان مختلفان، يراقبان موارد مختلفة، خلف موازنَي تحميل مختلفين. لا شيء يفرض تبديلًا دفعة واحدة، فلا تفعل ذلك.

  1. ثبّت المتحكّم الجديد بجوار القديم. GatewayClass مستقل، وفضاء أسماء مستقل، وخدمة LoadBalancer خاصة به وعنوان خارجي خاص به. حركة المرور ما زالت تذهب إلى ingress-nginx.
  2. حوّل ثم راجع. شغّل ingress2gateway على فضاء أسماء واحد، واقرأ التحذيرات، وأصلح يدويًا التعليقات التوضيحية التي عجز عن ترجمتها. لا تطبّق المخرجات دون قراءتها.
  3. طبّق كائنات Gateway API بالأسماء المضيفة نفسها. لا شيء يتغيّر للمستخدمين بعد — فللمتحكّم الجديد عنوان IP خاص به ولا يشير إليه أي سجل DNS.
  4. قارن الحافتين مباشرة باستخدام --resolve، طلبًا بطلب: رموز الحالة، وأهداف إعادة التوجيه، والترويسات، وتحديدًا حالات الشرطة المائلة الأخيرة والتعابير النمطية. هذه هي الخطوة التي تلتقط السلوكيات الخمسة أعلاه.
  5. انقل الـ DNS تدريجيًا — سجل بقيمة TTL منخفضة، أو سياسة موزونة، أو اسم مضيف غير حرج أولًا. أبقِ ingress-nginx يخدم حتى تتحمّل الحافة الجديدة حركة مرور حقيقية عبر ذروة كاملة.
  6. فكّك التركيب عن قصد. احذف Deployment الخاص بـ ingress-nginx وخدمته وIngressClass وValidatingWebhookConfiguration. ترك خطّاف القبول (admission webhook) وراءك هو الطريق إلى عنقود معطوب بعد أسابيع.
# Install the Standard channel CRDs (server-side apply, as the project documents)
kubectl apply --server-side -f \
  https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.6.1/standard-install.yaml

# The Gateway must be Programmed before you move any traffic to it
kubectl get gateway shop-gateway -n shop \
  -o jsonpath='{.status.conditions[?(@.type=="Programmed")].status}{"\n"}'

# Every parentRef must be Accepted, and every backendRef ResolvedRefs.
# Nested ranges keep each condition paired with its own status.
kubectl get httproute shop-route -n shop -o jsonpath='{range .status.parents[*]}{.controllerName}{"\t"}{range .conditions[*]}{.type}={.status}{" "}{end}{"\n"}{end}'

# Compare old and new on the same request, before DNS moves.
# A cloud load balancer publishes either .ip or .hostname - AWS uses .hostname,
# so --connect-to is used instead of --resolve: it accepts both.
OLD=$(kubectl get svc -n ingress-nginx ingress-nginx-controller \
  -o jsonpath='{.status.loadBalancer.ingress[0].ip}{.status.loadBalancer.ingress[0].hostname}')
NEW=$(kubectl get gateway shop-gateway -n shop \
  -o jsonpath='{.status.addresses[0].value}')
for edge in "$OLD" "$NEW"; do
  curl -sS -o /dev/null -w "$edge  %{http_code}  %{redirect_url}\n" \
    --connect-to "shop.example.com:443:$edge:443" https://shop.example.com/api
done

انتبه إلى الحالة Programmed في الأمر الثاني. وجود Gateway لا يعني أنه يخدم؛ فشروط الحالة (status conditions) هي العقد، والتحقّق منها أرخص من اكتشاف الفارق أثناء تغيير الـ DNS.

‏ingress-nginx و NGINX Ingress و NGINX Gateway Fabric

ثلاثة مشاريع منفصلة بأسماء متشابهة، ومصدر حقيقي لقرارات خاطئة أثناء هذا الترحيل بالذات. فمنهم من ينتقل من ingress-nginx إلى «NGINX Ingress» ظنًّا أنه غيّر شيئًا، ثم يُفاجأ لاحقًا — ومنهم من يستبعد NGINX كليًا افتراضًا أن الثلاثة ماتت معًا.

المشروعمن يصونهالحالة
kubernetes/ingress-nginx
«Ingress NGINX Controller»
مجتمع كوبرنيتس (SIG Network)متوقّف. أُرشِف للقراءة فقط في 24 مارس 2026. وهذا هو الذي ترحل عنه.[repo]
nginx/kubernetes-ingress
«NGINX Ingress Controller»
F5 / NGINXقيد التطوير النشط. يدعم Ingress إضافة إلى موارد CRD خاصة به — VirtualServer وVirtualServerRoute وTransportServer — فوق NGINX OSS أو NGINX Plus.[f5]
nginx/nginx-gateway-fabric
«NGINX Gateway Fabric»
F5 / NGINXقيد التطوير النشط. تنفيذ لـ Gateway API يستخدم NGINX مستوىً للبيانات — مشروع ثالث مختلف، ومطابق للمواصفة.[ngf]

رأى مشروع كوبرنيتس نفسه ضرورة توضيح ذلك صراحةً: كلاهما يستخدم NGINX مستوىً للبيانات، لكن لا علاقة بينهما فيما عدا ذلك. الانتقال من متحكّم المجتمع إلى متحكّم F5 ترحيلٌ حقيقي له عمل ترجمة تعليقات توضيحية خاص به — وليس تغيير اسم.[gotchas]

ما الذي سأفعله هذا الأسبوع

إن لم تكن قد بدأت: نفّذ أوامر الاكتشاف الأربعة اليوم، لأن عدد التعليقات التوضيحية هو الرقم الوحيد الذي يخبرك إن كانت هذه مهمة بعد ظهر أم مهمة ربع سنة. إن كان الجواب «بعد ظهر»، فأنجزها هذا الأسبوع وتوقّف عن حمل المخاطرة. وإن كان «ربع سنة»، فالخطوة المفيدة تبقى نفسها: ثبّت متحكّمًا ثانيًا بالتوازي الآن ورحّل اسم مضيف واحدًا منخفض المخاطر، لأن الترحيل الأول هو حيث تكتشف أي افتراضاتك كانت في الحقيقة سلوكيات لـ ingress-nginx.

الدرس الأوسع سبق أن كتبت عنه في معماريات السحابة المملّة: المكوّنات الأرجح أن تؤذيك هي تلك التي لا يفكّر فيها أحد، وذلك تحديدًا لأنها ظلّت تعمل سنوات. متحكّم Ingress يصونه متطوّع أو اثنان ويقف أمام نصف العالم السحابي الأصيل كان تركيزًا للمخاطر قبل أرشفته بوقت طويل. يستحق الأمر مراجعة ما الذي يشبهه في بقية منظومتك التقنية — وأن تسأل، كما في متى لا تستخدم كوبرنيتس، هل تستحق المنصة المساحة التشغيلية التي تكلّفك إياها.

أسئلة شائعة

هل من الآمن إبقاء ingress-nginx يعمل في الوقت الحالي؟

هو يعمل، وسيستمر في العمل. لكنه لن يتلقّى ترقيعًا أمنيًا آخر أبدًا — ويجدر النظر في ماهية الإصدار الأخير فعلًا: controller-v1.15.1 كان إصلاح CVE-2026-4342، وهو حقن إعدادات يصل إلى تنفيذ شيفرة داخل المتحكّم وكشف أسرار على مستوى العنقود كله، صدر في اليوم نفسه الذي صدر فيه التنبيه وقبل خمسة أيام من تحويل المستودع إلى القراءة فقط. كان ذلك الخلل السادس من نوعه خلال سبعة أسابيع. والخلل التالي لن يكون له إصلاح. وإن اضطررت لتشغيله بضعة أسابيع إضافية، فقيّد على الأقل من يستطيع إنشاء موارد Ingress، واسحب من المتحكّم صلاحية الوصول إلى الأسرار على مستوى العنقود إن كان تثبيتك يمنحها له، ولا تعرّض خطّاف القبول للإنترنت.

هل واجهة Ingress API في كوبرنيتس مهجورة هي الأخرى؟

لا، وهذا أشيع سوء فهم. واجهة Ingress متاحة بشكل عام وتخضع لضمانات الاستقرار المعتادة لواجهات GA، وقد صرّح مشروع كوبرنيتس بأنه لا يخطط لإزالتها. هي مجمّدة فقط: لا تطوير لاحق. المتوقّف هو متحكّم NGINX المجتمعي وحده، لا الواجهة التي ينفّذها.

ما الفرق بين ingress-nginx و nginx-ingress؟

مشروعان مختلفان من جهتين مختلفتين. kubernetes/ingress-nginx كان يصونه مجتمع كوبرنيتس وهو الآن مؤرشف. أما nginx/kubernetes-ingress فهو NGINX Ingress Controller من F5 وما زال قيد التطوير النشط. وبتعبير مشروع كوبرنيتس نفسه: كلاهما يستخدم NGINX مستوىً للبيانات، لكن لا علاقة بينهما فيما عدا ذلك. الانتقال من أحدهما إلى الآخر ترحيلٌ حقيقي لا تغيير اسم.

هل تستطيع ingress2gateway ترحيل عنقودي تلقائيًا؟

جزئيًا. يغطّي الإصدار 1.0 أكثر من ثلاثين تعليقة توضيحية لـ ingress-nginx بعد أن كانت ثلاثًا، وهو نقطة الانطلاق الصحيحة. لكن configuration-snippet لا مقابل لها وغير مدعومة، وproxy-body-size لا مقابل لها في Gateway API، ومهلات الوسيط تُعيَّن بأفضل جهد فحسب، وتطبيع عناوين URL غير قابل للتعبير عنه إطلاقًا. اقرأ كل ما تطبعه على stderr — تلك المخرجات هي عملك اليدوي المتبقّي.

هل أنتقل إلى Gateway API أم أكتفي بتبديل متحكّم Ingress؟

تبديل المتحكّم أسرع ويحافظ على كائناتك الحالية، لكنك تحطّ على واجهة مجمّدة وتظل مضطرًا لإعادة التعبير عن كل تعليقة توضيحية بلهجة جديدة — أي أنك على الأرجح ستكرّر العملية. أما Gateway API فإعادة كتابة أكبر، لكنه المكان الذي يجري فيه التطوير، ويمنحك فصلًا للأدوار بين فريق المنصة الذي يملك الـ Gateway وفرق التطبيقات التي تملك مساراتها. الأعداد الكبيرة من موارد Ingress البسيطة تميل نحو تبديل المتحكّم؛ والحواف المشتركة بين عدة فرق تميل نحو Gateway API.

أي تنفيذ لـ Gateway API ينبغي أن أختار؟

اختر انطلاقًا من تقارير المطابقة المنشورة لا من صفحات التسويق. يُدرج مشروع Gateway API، لكل إصدار، عدد الميزات الموسّعة التي يجتازها كل تنفيذ لـ HTTPRoute و GRPCRoute و TLSRoute بالضبط. راجع تقرير الإصدار الذي تنوي تشغيله فعلًا، وتأكّد أن التنفيذ يدعم تحديدًا الميزات التي تُرجمت إليها تعليقاتك التوضيحية، وأنه مدعوم على منصتك.

هل يلزم ترقية كوبرنيتس قبل تثبيت Gateway API؟

لا ينشر المشروع حدًّا أدنى ثابتًا لإصدار كوبرنيتس؛ سياسته المعلنة هي دعم أحدث خمسة إصدارات فرعية، فقارن هذه السياسة بعنقودك بدل الاعتماد على رقم قرأته في تدوينة. ثبّت موارد CRD الخاصة بقناة Standard من إصدار الترقيع الحالي — v1.6.1 الصادر في 16 يوليو 2026 — باستخدام server-side apply، وهو ما يوثّقه المشروع. وإن ثبّت قناة Experimental بدلًا من ذلك، فموارد CRD الخاصة بها أكبر من أن يعالجها kubectl apply من جهة العميل على أي حال، كما أن الأنواع التجريبية تحمل الآن بادئة X في مجموعة واجهات منفصلة، تحديدًا كي لا تبني الإنتاج فوقها عن غير قصد.

وينطبق المبدأ نفسه على طبقة التشفير الأدنى: راجع SSH وTLS بعد الكم لمعرفة ما ينبغي التحقق منه في الاتصالات التي تعتمد عليها هذه الأنظمة.

المصادر

كل ما ورد أعلاه قابل للتتبّع إلى أحد هذه المصادر. مصادر أولية ورسمية فقط: مدوّنة مشروع كوبرنيتس ووثائقه، وحالة المستودعات، والتنبيهات الأمنية، ومواصفة Gateway API.

  1. Kubernetes blog — Ingress NGINX Retirement: What You Need to Know (11 Nov 2025)
  2. Kubernetes blog — Ingress NGINX: Statement from the Steering and Security Response Committees (29 Jan 2026)
  3. Kubernetes blog — Before You Migrate: Five Surprising Ingress-NGINX Behaviors You Need to Know (27 Feb 2026)
  4. GitHub — kubernetes/ingress-nginx (public archive, read-only since 24 Mar 2026)
  5. GitHub — ingress-nginx controller-v1.15.1, the final release (19 Mar 2026)
  6. Kubernetes Security Response Committee — [Security Advisory] Multiple issues in ingress-nginx (2 Feb 2026)
  7. kubernetes/kubernetes#136678 — CVE-2026-24512, configuration injection via the Ingress path field
  8. kubernetes/kubernetes#137560 — CVE-2026-3288, configuration injection via the rewrite-target annotation
  9. kubernetes/kubernetes#137893 — CVE-2026-4342, comment-based configuration injection (fixed by the final release)
  10. Kubernetes blog — Ingress-nginx CVE-2025-1974: What You Need to Know (24 Mar 2025)
  11. Kubernetes documentation — Ingress (the API is generally available and frozen)
  12. Kubernetes documentation — Ingress Controllers
  13. Gateway API — API overview and channel status
  14. Kubernetes blog — Gateway API v1.6: TCPRoute and UDPRoute Graduate to Standard (3 Aug 2026)
  15. GitHub — Gateway API v1.6.0 release notes
  16. GitHub — Gateway API v1.6.1, the current patch release (16 July 2026)
  17. Gateway API — v1.6 conformance reports by implementation
  18. GitHub — kubernetes-sigs/ingress2gateway
  19. Kubernetes blog — Announcing Ingress2Gateway 1.0: Your Path to Gateway API (20 Mar 2026)
  20. GitHub — nginx/kubernetes-ingress, the F5 NGINX Ingress Controller (a different project)
  21. GitHub — nginx/nginx-gateway-fabric, F5's Gateway API implementation
  22. Gateway API — versioning, release channels and graduation criteria

Was this useful?