يجمع هذا المشروع الختامي كل مفاهيم الدورة في إطار عملي متكامل من البداية إلى النهاية: تثبيت Istio على مجموعة Kubernetes حقيقية، وإدخال تطبيق متعدد الخدمات إلى الشبكة، وتطبيق TLS المتبادل على جميع الاتصالات، ثم نشر إصدار canary بتقسيم دقيق للحركة، وإضافة سياسات المرونة، وتأكيد كل شيء عبر منظومة الرصد. الهدف هو إجراء جاهز للإنتاج يمكن تشغيله حرفيًا أو تكييفه مع بيئتك.
التطبيق المستهدف: Online Boutique
يُعدّ تطبيق Online Boutique (microservices-demo) من Google التطبيق المرجعي القياسي لاختبار شبكات الخدمات: أحد عشر خدمة بلغات برمجية متعددة (Go، Python، C#، Java، Node.js)، وحركة gRPC وHTTP واقعية، وواجهة أمامية تختبر كل مسار. سنربطه بالشبكة، ونطبق mTLS، ثم ننفذ نشرًا تدريجيًا لخدمة productcatalogservice من v1 إلى v2.
تفترض جميع الأوامر استخدام Istio 1.22 وKubernetes 1.29+، مع توفر istioctl في PATH. تكفي مجموعة k3s بعقدة واحدة (4 أنوية / 8 GB) لتنفيذ هذا الدرس. ملفات Online Boutique متاحة على github.com/GoogleCloudPlatform/microservices-demo.
الخطوة 1 — تثبيت Istio باستخدام IstioOperator جاهز للإنتاج
استخدم ملف تعريف default مع تعديل ثلاثة إعدادات حرجة في الإنتاج: سجلات وصول بتنسيق JSON منظم لتسهيل تحليل الأنابيب بدون تعبيرات منتظمة، وأخذ عينات 5% من التتبع (ارفعها إلى 100% خلال الحوادث)، وطلبات موارد صريحة لـ istiod حتى لا تُطرد تحت الضغط.
فعّل حقن الـ sidecar التلقائي على namespace التطبيق، ثم انشر Online Boutique. سيبدأ كل pod بحاويتين: التطبيق وproxy Envoy.
kubectl create namespace boutique
kubectl label namespace boutique istio-injection=enabled
kubectl apply -n boutique \
-f https://raw.githubusercontent.com/GoogleCloudPlatform/microservices-demo/main/release/kubernetes-manifests.yaml
# تحقق من 2/2 READY لكل pod (التطبيق + istio-proxy)
kubectl get pods -n boutique
kubectl get pod -n boutique -l app=frontend -o jsonpath='{.items[0].spec.containers[*].name}'
# الناتج المتوقع: server istio-proxy
الخطوة 3 — تطبيق mTLS الصارم على الـ Namespace
يعمل Istio افتراضيًا في وضع PERMISSIVE الذي يقبل الاتصالات النصية العادية واتصالات mTLS معًا. هذا مفيد أثناء الإعداد، لكن يجب تشديده قبل الادعاء بأن الـ namespace آمن. يحول مورد PeerAuthentication المحدد للـ namespace كل الخدمات إلى وضع STRICT: تُرفض الاتصالات النصية العادية عند الـ sidecar وليس عند التطبيق.
وضع mTLS الصارم: يقدم كلا الـ sidecar شهادات X.509 من نوع SPIFFE صادرة عن istiod؛ يُسقط proxy الاستقبال أي حركة نصية عادية.
# قفل الـ namespace بأكمله على وضع mTLS الصارم
kubectl apply -n boutique -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: boutique
spec:
mtls:
mode: STRICT
EOF
# تحقق: حاول الاتصال بخدمة بدون sidecar (يحاكي pod مارق)
kubectl run test-no-mesh --image=curlimages/curl --restart=Never \
--command -- curl -s http://productcatalogservice.boutique:3550/
# متوقع: curl: (56) Recv failure: Connection reset by peer
# تحقق من نشاط mTLS من داخل الشبكة
kubectl exec -n boutique deploy/frontend -c istio-proxy -- \
curl -s http://productcatalogservice:3550/ -v 2>&1 | grep "TLS"
نفّذ istioctl authn tls-check <pod> productcatalogservice.boutique.svc.cluster.local لمعرفة ما إذا كان زوج عميل-خادم محدد يستخدم mTLS. يُظهر الناتج وضع PeerAuthentication، ووضع TLS في DestinationRule، وما إذا كانا متوافقَين — أسرع بكثير من قراءة إعداد Envoy الخام.
الخطوة 4 — تقسيم حركة Canary لخدمة productcatalogservice
ضع تسمية version: v1 على Deployment الحالي، ثم انشر Deployment جديدًا للإصدار v2. يعرّف DestinationRule مجموعتين فرعيتين. يبدأ VirtualService بنسبة 95/5 وتزيد وزن v2 تدريجيًا عبر مراحل النشر.
في الإنتاج، تُدار تغييرات الأوزان عبر CI/CD (Argo Rollouts أو Flux مع تصحيح Kustomize) بدلًا من أوامر kubectl patch اليدوية. راقب معدل الخطأ والتأخر في Grafana أو Kiali بعد كل تحويل قبل المتابعة.
لا تحذف Deployment الخاص بـ v1 حتى يعمل VirtualService بنسبة 100% على v2 لمدة نافذة SLO كاملة على الأقل (عادةً 30 دقيقة إلى ساعة). حذف v1 مبكرًا يعني أن التراجع يتطلب دفع صورة جديدة — مما يُلغي خاصية التراجع السريع التي تجعل نشرات canary آمنة.
الخطوة 6 — تطبيق سياسات المرونة
mTLS وتقسيم canary في مكانهما. طبّق الآن طبقة المرونة: قطع الدائرة عبر outlierDetection (موجود مسبقًا في DestinationRule)، وتحديد معدل للواجهة الأمامية باستخدام EnvoyFilter، وإضافة مهلة لـ checkoutservice.
ثبّت لوحتي Kiali وGrafana في دليل الاستجابة للحوادث. خلال حادثة canary، اللوحة الأكثر قيمة هي Request Success Rate by Version — تعرض v1 وv2 جنبًا إلى جنب في الوقت الفعلي، مما يجعل نطاق التأثير مرئيًا فورًا دون الحاجة لتصفح السجلات.
الخطوة 7 — AuthorizationPolicy: ثقة صفرية في الاتصالات الداخلية
يُثبت mTLS الهوية لكن لا يقيّد أي هويات مسموح لها بالتواصل مع أي خدمات. أضف موارد AuthorizationPolicy لتطبيق مبدأ الصلاحية الأدنى: فقط الخدمات التي تحتاج فعليًا إلى استدعاء productcatalogservice مسموح لها بذلك، وكل المتصلين الآخرين يتلقون HTTP 403.
# السماح فقط للواجهة الأمامية وخدمة التوصية بالوصول إلى catalog
kubectl apply -n boutique -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: productcatalogservice-allow
namespace: boutique
spec:
selector:
matchLabels:
app: productcatalogservice
action: ALLOW
rules:
- from:
- source:
principals:
- cluster.local/ns/boutique/sa/frontend
- cluster.local/ns/boutique/sa/recommendationservice
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: deny-all
namespace: boutique
spec:
{}
EOF
# اختبار: الواجهة الأمامية تصل إلى catalog (يجب أن تحصل على 200)
kubectl exec -n boutique deploy/frontend -c server -- \
wget -qO- http://productcatalogservice:3550/ | head -1
# اختبار: cartservice لا تستطيع الوصول إلى catalog (يجب أن تحصل على 403)
kubectl exec -n boutique deploy/cartservice -c server -- \
wget -qO- http://productcatalogservice:3550/ 2>&1 | head -1
# متوقع: wget: server returned error: HTTP/1.1 403 Forbidden
دروس إنتاجية مستخلصة من هذا المشروع
يكشف تطبيق شبكة الخدمات على تطبيق حقيقي عن عدة دروس لا تظهر في الوثائق:
حقن الـ Sidecar أولًا ثم تشديد الأمان. حوّل الـ namespaces إلى PERMISSIVE أولًا، تحقق من تدفق الحركة مع الـ sidecars المحقونة، ثم انتقل إلى STRICT. التحويل إلى STRICT قبل اكتمال الحقن يكسر استدعاءات الخدمات بصمت.
يجب أن يسبق DestinationRule أي VirtualService يشير إليه. طبّق DestinationRule أولًا؛ وإلا فلن يجد Envoy مجموعة فرعية للتوجيه إليها ويُرجع 503.
يجب أن يكون التراجع عن canary عملية من أمر واحد. ينبغي أن يحتوي خط CI/CD على هدف make rollback يضبط أوزان VirtualService على 100/0 في أقل من 30 ثانية.
سياسة deny-all تكسر Jobs وInit Containers. طبّق deny-all للـ namespace تدريجيًا، وتحقق دائمًا من Kubernetes Jobs وCronJobs — غالبًا ما تستخدم service accounts غائبة عن قواعد السماح.
ميزانية موارد الـ Sidecar. على نطاق Google (آلاف الـ pods)، يستهلك كل Envoy sidecar 50-100 MB ذاكرة وصول عشوائي و0.1-0.2 نواة CPU في وضع الخمول. ادرج هذا في نموذج سعة المجموعة قبل تفعيل الحقن على مستوى الشبكة.
على هذا النطاق — آلاف الـ pods وعشرات الخدمات — يصبح سطح إعداد الشبكة مخاطرة موثوقية بحد ذاته. اجعل istioctl analyze خطوة إلزامية في CI على كل تغيير لإعداد الشبكة. يكتشف DestinationRules المفقودة، وVirtualServices المتعارضة، وAuthorizationPolicies غير الصالحة قبل وصولها إلى المجموعة.
لقد أكملت الآن دورة شبكة الخدمات بالكامل: من المبادئ الأساسية عبر المعمارية وإدارة الحركة وmTLS والمرونة والرصد وLinkerd والتشغيل وهذا المشروع الختامي. الأنماط هنا — حقن sidecar، والهوية المستندة إلى SPIFFE، وتوجيه الحركة التصريحي، والتفويض على مبدأ الثقة الصفرية — هي الخط الأساسي لأي منصة خدمات مصغّرة جادة في عام 2025 وما بعده.
نستخدم ملفات تعريف الارتباط لتشغيل هذا الموقع وتحليل الزيارات وعرض إعلانات مخصّصة. يمكنك قبول كل ملفات تعريف الارتباط أو رفض غير الأساسية منها.
سياسة الخصوصية