نشر تطبيق ASP.NET Core على Google Kubernetes Engine باستخدام Istio (الجزء 1)

1. نظرة عامة

ASP.NET Core هو إطار عمل مفتوح المصدر ومتعدد الأنظمة الأساسية لإنشاء تطبيقات حديثة مستندة إلى السحابة الإلكترونية ومتصلة بالإنترنت باستخدام لغة البرمجة C# .

Kubernetes هو نظام مفتوح المصدر يعمل على التشغيل الآلي للتطبيقات وتوسيع نطاقها وإدارتها. Istio هو إطار عمل مفتوح لربط الخدمات وتأمينها وإدارتها ومراقبتها.

في هذا الجزء الأول من التمرين المعملي، يمكنك نشر تطبيق ASP.NET Core بسيط على Kubernetes قيد التشغيل على Google Kubernetes Engine (GKE) وتهيئته ليُدار بواسطة Istio.

في الجزء الثاني من التمرين، يمكنك استكشاف ميزات Istio أيضًا، مثل المقاييس والتتبّع والإدارة الديناميكية لعدد الزيارات وإدخال الأخطاء وإدخال أخطاء وغير ذلك.

ما ستتعرَّف عليه

  • كيفية إنشاء تطبيق ASP.NET Core بسيط وتجميعه في حاوية Docker.
  • كيفية إنشاء مجموعة Kubernetes باستخدام Google Kubernetes Engine (GKE)
  • كيفية تثبيت Istio على مجموعة Kubernetes على GKE
  • كيفية تفعيل تطبيق ASP.NET Core وضبط عدد زياراته لتتم إدارته من خلال Istio

المتطلبات

كيف ستستخدم هذا البرنامج التعليمي؟

القراءة فقط اقرأها وأكمِل التمارين

ما هو تقييمك لتجربتك مع Google Cloud Platform؟

حديث متوسط بارع

2. الإعداد والمتطلبات

إعداد بيئة ذاتية

  1. سجِّل الدخول إلى Cloud Console وأنشِئ مشروعًا جديدًا أو أعِد استخدام مشروع حالي. إذا لم يكن لديك حساب على Gmail أو Google Workspace، عليك إنشاء حساب.

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

يُرجى تذكُّر رقم تعريف المشروع، وهو اسم فريد في جميع مشاريع Google Cloud (سبق أن تم استخدام الاسم أعلاه ولن يكون مناسبًا لك). ستتم الإشارة إليها لاحقًا في هذا الدرس التطبيقي حول الترميز باسم PROJECT_ID.

  1. بعد ذلك، عليك تفعيل الفوترة في Cloud Console لاستخدام موارد Google Cloud.

إنّ تنفيذ هذا الدرس التطبيقي حول الترميز لن يكون مكلفًا أو مكلفًا على الإطلاق. احرص على اتّباع أي تعليمات في قسم "الحذف سريعًا". الذي يقدم لك نصائح حول كيفية إيقاف تشغيل الموارد حتى لا تتكبّد أي فواتير خارج نطاق هذا البرنامج التعليمي. يكون مستخدمو Google Cloud الجدد مؤهَّلون للانضمام إلى برنامج فترة تجريبية مجانية بقيمة 300 دولار أمريكي.

بدء Cloud Shell

يمكن إدارة Google Cloud عن بُعد من الكمبيوتر المحمول، إلا أنّك تستخدم في هذا الدرس التطبيقي Google Cloud Shell، وهي بيئة سطر أوامر يتم تشغيلها في Google Cloud.

تفعيل Cloud Shell

  1. من Cloud Console، انقر على تفعيل Cloud Shell 4292cbf4971c9786.png.

bce75f34b2c53987.png

إذا لم يسبق لك بدء تشغيل Cloud Shell، ستظهر لك شاشة وسيطة (الجزء السفلي غير المرئي من الصفحة) تصف ماهيتها. إذا كان الأمر كذلك، فانقر على متابعة (ولن تراه مرة أخرى مطلقًا). إليك ما تبدو عليه هذه الشاشة التي تُستخدم لمرة واحدة:

70f315d7b402b476.png

من المفترَض أن تستغرق عملية إدارة الحسابات والاتصال بخدمة Cloud Shell بضع دقائق فقط.

fbe3a0674c982259.png

يتم تحميل هذا الجهاز الافتراضي مع جميع أدوات التطوير التي تحتاجها. وتوفّر هذه الشبكة دليلاً رئيسيًا دائمًا بسعة 5 غيغابايت ويتم تشغيله في Google Cloud، ما يحسّن بشكل كبير من أداء الشبكة والمصادقة. يمكنك تنفيذ معظم عملك، إن لم يكن كلّه، في هذا الدرس التطبيقي حول الترميز باستخدام متصفّح أو جهاز Chromebook.

بعد الربط بخدمة Cloud Shell، من المفترض أن ترى أنّه قد تمت مصادقتك وأنّ المشروع معيّن سبق أن تم ضبطه على رقم تعريف مشروعك.

  1. شغِّل الأمر التالي في Cloud Shell لتأكيد مصادقتك:
gcloud auth list

مخرجات الأمر

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. شغّل الأمر التالي في Cloud Shell للتأكد من معرفة الأمر gcloud بمشروعك:
gcloud config list project

مخرجات الأمر

[core]
project = <PROJECT_ID>

إذا لم يكن كذلك، يمكنك تعيينه من خلال هذا الأمر:

gcloud config set project <PROJECT_ID>

مخرجات الأمر

Updated property [core/project].

3- إنشاء تطبيق ASP.NET Core في Cloud Shell

في موجه Cloud Shell، يمكنك التحقق من تثبيت أداة سطر أوامر dotnet من قبل عن طريق التحقق من إصدارها. من المفترض أن يؤدي ذلك إلى طباعة إصدار أداة سطر أوامر dotnet المثبتة:

dotnet --version

بعد ذلك، قم بإنشاء تطبيق ويب ASP.NET Core جديد.

dotnet new mvc -o HelloWorldAspNetCore

سيؤدي هذا إلى إنشاء مشروع واستعادة تبعياته. من المفترض أن تظهر لك رسالة مشابهة لما يلي.

Restore completed in 11.44 sec for HelloWorldAspNetCore.csproj.

Restore succeeded.

4. تشغيل تطبيق ASP.NET Core

نحن جاهزون تقريبًا لتشغيل تطبيقنا. انتقِل إلى مجلد التطبيق.

cd HelloWorldAspNetCore

وأخيرًا، شغِّل التطبيق.

dotnet run --urls=http://localhost:8080

يبدأ التطبيق الاستماع عبر المنفذ 8080.

Hosting environment: Production
Content root path: /home/atameldev/HelloWorldAspNetCore
Now listening on: http://[::]:8080
Application started. Press Ctrl+C to shut down.

للتحقق من أن التطبيق يعمل، انقر على زر معاينة الويب في أعلى اليسار واختر "معاينة على المنفذ 8080".

Capture.PNG

ستظهر لك صفحة الويب الافتراضية ASP.NET Core:

f579a9baedc108a9.png

بعد التحقق من أن التطبيق يعمل، اضغط على Ctrl+C لإيقاف التطبيق.

5- تجميع تطبيق ASP.NET Core في حاوية Docker

بعد ذلك، يمكنك إعداد تطبيقك لتشغيله كحاوية. الخطوة الأولى هي تحديد الحاوية ومحتوياتها.

في الدليل الأساسي للتطبيق، أنشِئ Dockerfile لتحديد صورة Docker.

touch Dockerfile

يمكنك إضافة ما يلي إلى "Dockerfile" باستخدام المحرِّر المفضّل لديك ("vim, nano,emacs" أو أداة تعديل الرموز في Cloud Shell).

# Use Microsoft's official build .NET image.
# https://hub.docker.com/_/microsoft-dotnet-core-sdk/
FROM mcr.microsoft.com/dotnet/sdk:5.0-alpine AS build
WORKDIR /app

# Install production dependencies.
# Copy csproj and restore as distinct layers.
COPY *.csproj ./
RUN dotnet restore

# Copy local code to the container image.
COPY . ./
WORKDIR /app

# Build a release artifact.
RUN dotnet publish -c Release -o out

# Use Microsoft's official runtime .NET image.
# https://hub.docker.com/_/microsoft-dotnet-core-aspnet/
FROM mcr.microsoft.com/dotnet/aspnet:5.0-alpine AS runtime
WORKDIR /app
COPY --from=build /app/out ./

# Make sure the app binds to port 8080
ENV ASPNETCORE_URLS http://*:8080

# Run the web service on container startup.
ENTRYPOINT ["dotnet", "HelloWorldAspNetCore.dll"]

من بين الإعدادات المهمة المضمنة في ملف Dockerfile هو المنفذ الذي ينتظر التطبيق من خلاله استقبال حركة البيانات الواردة (8080). يتم تحقيق ذلك من خلال ضبط متغيّر البيئة ASPNETCORE_URLS، الذي تستخدمه تطبيقات ASP.NET Core لتحديد المنفذ الذي يجب الاستماع إليه.

حفظ Dockerfile الآن، لنقم بإنشاء الصورة:

docker build -t gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-dotnet:v1 .

بعد اكتمال هذا (سيستغرق تنزيل كل البيانات واستخراجها بعض الوقت)، يمكنك رؤية أنّه تم إنشاء الصورة وحفظها على الجهاز:

docker images

REPOSITORY                             TAG   
gcr.io/yourproject-XXXX/hello-dotnet   v1            

اختبِر الصورة محليًا باستخدام الأمر التالي الذي سيشغِّل حاوية Docker محليًا على المنفذ 8080 من صورة الحاوية التي تمّ إنشاؤها حديثًا:

docker run -p 8080:8080 gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-dotnet:v1

ومرة أخرى، استفد من ميزة معاينة الويب في CloudShell :

لقطة شاشة من 2015-11-03 17:20:22.png

ستظهر لك صفحة الويب التلقائية الخاصة بـ ASP.NET Core في علامة تبويب جديدة.

f579a9baedc108a9.png

بعد التأكّد من أنّ التطبيق يعمل بشكل جيد محليًا في حاوية Docker، يمكنك إيقاف الحاوية قيد التشغيل بحلول Ctrl-> C.

والآن بعد أن أصبحت الصورة تعمل على النحو المطلوب، يمكنك إرسالها إلى Google Container Registry، وهو مستودع خاص لصور Docker يمكن الوصول إليها من كل مشروع على Google Cloud (ولكن أيضًا من خارج Google Cloud Platform) :

docker push gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-dotnet:v1

وإذا سارت الأمور على ما يرام وبعد فترة وجيزة، من المفترض أن تتمكن من الاطّلاع على صورة الحاوية مُدرجة في القسم Container Registry. في هذه المرحلة، لديك الآن صورة Docker على مستوى المشروع يمكن لـ Kubernetes الوصول إليها وتنسيقها كما سيصلك بعد بضع دقائق.

73558f3a54ce1c0c.png

إذا كنت مهتمًا، يمكنك الاطّلاع على صور الحاويات أثناء تخزينها في Google Cloud Storage من خلال اتّباع هذا الرابط: https://console.cloud.google.com/storage/browser/ (يجب أن يكون الرابط الكامل الناتج بهذا النموذج: https://console.cloud.google.com/project/PROJECT_ID/storage/browser/).

6- إنشاء مجموعة Kubernetes/GKE باستخدام Istio

أولاً، تأكَّد من تفعيل واجهة برمجة تطبيقات Kubernetes Engine باتّباع الخطوات التالية:

gcloud services enable container.googleapis.com

أنشئ مجموعة Kubernetes. يمكنك تغيير المنطقة إلى مكان قريب منك، إذا كنت ترغب في ذلك:

gcloud container clusters create hello-istio \
  --cluster-version=latest \
  --machine-type=n1-standard-2 \
  --num-nodes=4 \
  --region europe-west1

يُرجى الانتظار قليلاً ريثما يتم إعداد المجموعة نيابةً عنك. وسيظهر هذا الاسم في قسم Kubernetes Engine في وحدة تحكّم Google Cloud Platform.

e46fd9c6ee82bcc4.png

في هذا الدرس التطبيقي، سننزِّل Istio ونُثبِّته من istio.io. وتتوفّر خيارات تثبيت أخرى، بما في ذلك إضافة Istio لنظام GKE وAnthos Service Mesh. ستعمل خطوات التطبيق بعد هذه الخطوة على أي عملية تثبيت لـ Istio.

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

curl -L https://istio.io/downloadIstio | sh -

سيخبرك النص البرمجي بإصدار Istio الذي تم تنزيله:

Istio has been successfully downloaded into the istio-1.8.1 folder on your system.

يحتوي دليل التثبيت على نموذج تطبيقات والبرنامج الثنائي لعميل "istioctl". التغيير إلى هذا الدليل:

cd istio-1.8.1

انسخ الأمر المتوفّر والصقه لإضافة الدليل bin إلى PATH، كي تتمكّن من استخدام istioctl:

export PATH="$PATH:/home/<YOURHOMEID>/istio-1.8.1/bin"

تأكَّد من أنّ المجموعة istioctl متاحة من خلال التأكّد من أنّ مجموعتك جاهزة للاستخدام في Istio:

istioctl x precheck

من المفترض أن تظهر رسالة مفادها Install Pre-Check passed! The cluster is ready for Istio installation..

تثبيت Istio باستخدام الملف الشخصي للعرض التوضيحي:

istioctl install --set profile=demo

تم تثبيت Istio الآن في مجموعتك.

الحقن الجانبي تلقائيًا

لبدء استخدام Istio، لن تحتاج إلى إجراء أي تغييرات على التطبيق. عند إعداد الخدمات وتشغيلها، يتم إدخال الصور الجانبية لـ Envoy تلقائيًا في كل لوحة للخدمة.

ولكي ينجح ذلك، يجب تفعيل ميزة "إدخال ملف جانبي" لمساحة الاسم ("التلقائية") التي تستخدمها في خدماتك المصغّرة. يمكنك القيام بذلك عن طريق تطبيق تصنيف:

kubectl label namespace default istio-injection=enabled

للتأكّد من تطبيق التصنيف بنجاح، شغِّل الأمر التالي:

kubectl get namespace -L istio-injection

وتؤكِّد النتائج أنّه تم تفعيل ميزة "إدخال ملف جانبي" لمساحة الاسم التلقائية:

NAME              STATUS   AGE    ISTIO-INJECTION
default           Active   3m     enabled
istio-system      Active   63s    disabled
...

7. التحقّق من التثبيت

يوفّر Istio ثلاث خدمات: مستوى التحكّم istiod ومدخلَي الدخول والخروج (الذي يمكن اعتبارهما "خوادم وكيلة للسيارات الجانبية لبقية مستخدمي الإنترنت")، واسمهما istio-ingressgateway وistio-egressgateway على التوالي.

kubectl get svc -n istio-system

يجب أن تبدو مخرجاتك على هذا النحو:

NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP                                                                     AGE
istio-egressgateway    ClusterIP      10.55.252.182   <none>
istio-ingressgateway   LoadBalancer   10.55.250.185   35.233.118.42
istiod                 ClusterIP      10.55.253.217   <none>

إن بوابة الدخول هي من نوع LoadBalancer بحيث يمكن الوصول إليها من الإنترنت. ينبغي الوصول إلى باقي المجموعات العنقودية فقط من داخل المجموعة العنقودية.

بعد ذلك، يجب التأكّد من نشر مجموعات Kubernetes المقابلة ومن أنّ جميع الحاويات تعمل بشكل صحيح:

kubectl get pods -n istio-system

عندما تكون جميع اللوحات قيد التشغيل، يمكنك المتابعة.

NAME                                    READY   STATUS
istio-egressgateway-674988f895-m6tk4    1/1     Running
istio-ingressgateway-6996f7dcc8-7lvm2   1/1     Running
istiod-6bf5fc8b64-j79hj                 1/1     Running
  • istiod: مستوى التحكّم في Istio يشير إلى عملية إعداد وبرمجة الأجهزة الجانبية للخادم الوكيل واكتشاف الخدمة وتوزيع الشهادات وإدخال الرموز الجانبية.
  • ingress gateway: تتم معالجة الطلبات الواردة من خارج مجموعتك.
  • egress gateway: يعالج الطلبات الصادرة إلى نقاط نهاية خارج مجموعتك.

8. نشر التطبيق

بعد أن تحقّقت من تثبيت تطبيق Istio وتشغيله، يمكنك نشر تطبيق ASP.NET Core.

النشر والخدمة

أولاً، أنشِئ ملف aspnetcore.yaml باستخدام المحرِّر المفضّل لديك (vim, nano,emacs أو أداة تعديل الرموز في Cloud Shell) وحدِّد طريقة نشر وخدمة Kubernetes للتطبيق:

apiVersion: v1
kind: Service
metadata:
  name: aspnetcore-service
  labels:
    app: aspnetcore
spec:
  ports:
  - port: 8080
    name: http
  selector:
    app: aspnetcore
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: aspnetcore-v1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: aspnetcore
      version: v1
  template:
    metadata:
      labels:
        app: aspnetcore
        version: v1
    spec:
      containers:
      - name: aspnetcore
        image: gcr.io/YOUR-PROJECT-ID/hello-dotnet:v1
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080

محتوى الملف هو "عمليات نشر وخدمات" عادية لنشر التطبيق ولا تحتوي على أي شيء خاص بـ Istio.

نشر الخدمات إلى مساحة الاسم التلقائية باستخدام kubectl:

kubectl apply -f aspnetcore.yaml
service "aspnetcore-service" created
deployment.extensions "aspnetcore-v1" created

تأكَّد من أنّ اللوحات قيد التشغيل:

kubectl get pods
NAME                          READY     STATUS    RESTARTS   AGE
aspnetcore-v1-6cf64748-mddb   2/2       Running   0          34s

البوابة وخدمة VirtualService

للسماح بوصول الزيارات الواردة إلى الشبكة المتداخلة، عليك إنشاء Gateway وVirtualService.

تهيئ البوابة جهاز موازنة حمل لحركة بيانات HTTP/TCP، وغالبًا ما يعمل على حافة الشبكة المتداخلة لتمكين حركة البيانات الواردة إلى أحد التطبيقات. تحدِّد VirtualService القواعد التي تتحكّم في كيفية توجيه طلبات الخدمة ضمن شبكة خدمة Istio.

أنشئ ملف aspnetcore-gateway.yaml لتحديد المدخل:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: aspnetcore-gateway
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"

أنشِئ ملف aspnetcore-virtualservice.yaml لتحديد VirtualService:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: aspnetcore-virtualservice
spec:
  hosts:
  - "*"
  gateways:
  - aspnetcore-gateway
  http:
  - route:
    - destination:
        host: aspnetcore-service

يمكنك تشغيل أمر kubectl لنشر البوابة باستخدام:

kubectl apply -f aspnetcore-gateway.yaml

ينتج عن الأمر الإخراج التالي:

gateway.networking.istio.io "aspnetcore-gateway" created

بعد ذلك، شغِّل الأمر التالي لنشر VirtualService:

kubectl apply -f aspnetcore-virtualservice.yaml

ينتج عن الأمر الإخراج التالي:

virtualservice.networking.istio.io "aspnetcore-virtualservice" created

تأكَّد من أنّ كل شيء يعمل:

kubectl get gateway
NAME                      AGE
aspnetcore-gateway   28s
kubectl get virtualservice
NAME                             AGE
aspnetcore-virtualservice   33s

تهانينا! لقد نشرت للتو تطبيقًا متوافقًا مع Istio. بعد ذلك، سترى التطبيق قيد الاستخدام.

9. اختبار التطبيق

يمكنك أخيرًا الاطّلاع على التطبيق أثناء تشغيله. ستحتاج إلى الحصول على عنوان IP الخارجي ومنفذ المدخل. وتم إدراجها ضمن EXTERNAL-IP:

kubectl get svc istio-ingressgateway -n istio-system

تصدير عنوان IP الخارجي والمنفذ إلى متغيّر GATEWAY_URL:

export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')

export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')

export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT

يمكنك استخدام curl لاختبار التطبيق. من المفترض أن تستجيب الخدمة برمز استجابة 200:

curl -o /dev/null -s -w "%{http_code}\n" http://${GATEWAY_URL}/

يمكنك بدلاً من ذلك فتح المتصفّح والانتقال إلى http://<gatewayurl> لعرض التطبيق:

f579a9baedc108a9.png

10. تهانينا!

لقد نشرت للتو تطبيق ASP.NET Core بسيطًا على Kubernetes والذي يتم تشغيله على Google Kubernetes Engine (GKE) وضبطته ليديره بواسطة Istio.

قد تتساءل عن فائدة استخدام Istio. هذا سؤال رائع. حتى الآن، ما مِن فائدة من تكليف Istio بإدارة هذا التطبيق. وفي الجزء الثاني من التمرين المعملي، سنستكشف بشكل أكبر ميزات Istio، مثل المقاييس والتتبع والإدارة الديناميكية للزيارات ومؤثرات عرض الخدمة وإدخال الأخطاء.

الخطوات التالية

الترخيص

هذا العمل مرخّص بموجب رخصة المشاع الإبداعي 2.0 مع نسب العمل إلى مؤلف عام.

11. تنظيف

إذا كنت لا تنتقل إلى الجزء الثاني من التمرين المعملي، يمكنك حذف التطبيق وإلغاء تثبيت Istio أو يمكنك ببساطة حذف مجموعة Kubernetes.

حذف التطبيق

لحذف التطبيق:

kubectl delete -f aspnetcore-gateway.yaml
Kubectl delete -f aspnetcore-virtualservice.yaml
kubectl delete -f aspnetcore.yaml

للتأكد من إيقاف التطبيق:

kubectl get gateway 
kubectl get virtualservices 
kubectl get pods

إلغاء تثبيت Istio

لحذف Istio، يُرجى اتّباع الخطوات التالية:

kubectl delete -f install/kubernetes/istio-demo-auth.yaml

للتأكّد من إيقاف Istio، اتّبِع الخطوات التالية:

kubectl get pods -n istio-system

حذف مجموعة Kubernetes

gcloud container clusters delete hello-istio