الاتصال بـ Private CloudSQL من خلال Cloud Run

1. نظرة عامة

في هذا الدرس التطبيقي، ستنشئ خدمة قائمة الطعام في Cymbal Eats، وستعرض واجهات برمجة تطبيقات RESTful لإضافة عناصر القائمة وتعديلها وحذفها وإدراجها. ستنشئ قاعدة بيانات Cloud SQL كقاعدة بيانات خلفية لخدمة القائمة، والتي سيتم تشغيلها في Cloud Run. بما أنّ Cloud Run لا يقع في شبكة VPC نفسها التي تقع فيها قاعدة بيانات Cloud SQL، عليك ضبط موصِّل "الوصول إلى شبكة VPC بدون خادم" للسماح لـ Cloud Run بالتواصل مع Cloud SQL عبر عنوان IP خاص.

19c7b05f35789fda.png

ما ستتعلمه

في هذه الميزة الاختبارية، ستتعرّف على كيفية تنفيذ ما يلي:

  • ضبط إعدادات شبكة VPC الخاصة
  • إنشاء قاعدة بيانات خاصة على Cloud SQL باستخدام Postgres
  • ربط CloudRun بشبكة VPC خاصة
  • نشر خدمة على Cloud Run تتصل بقاعدة بيانات Cloud SQL

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

إعداد البيئة بوتيرة ذاتية

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

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • اسم المشروع هو الاسم المعروض للمشاركين في هذا المشروع. وهي سلسلة أحرف لا تستخدمها Google APIs. ويمكنك تعديله في أي وقت.
  • رقم تعريف المشروع هو معرّف فريد في جميع مشاريع Google Cloud ولا يمكن تغييره بعد ضبطه. تنشئ Cloud Console تلقائيًا سلسلة فريدة، ولا يهمّك عادةً ما هي. في معظم دروس البرمجة، عليك الرجوع إلى رقم تعريف المشروع (يتم تحديده عادةً على أنّه PROJECT_ID). إذا لم يعجبك رقم التعريف الذي تم إنشاؤه، يمكنك إنشاء رقم تعريف عشوائي آخر. يمكنك بدلاً من ذلك تجربة اسم مستخدم من اختيارك لمعرفة ما إذا كان متاحًا. لا يمكن تغيير هذا الخيار بعد هذه الخطوة وسيظل ساريًا طوال مدة المشروع.
  • للعلم، هناك قيمة ثالثة، وهي رقم المشروع الذي تستخدمه بعض واجهات برمجة التطبيقات. يمكنك الاطّلاع على مزيد من المعلومات عن كل هذه القيم الثلاث في المستندات.
  1. بعد ذلك، عليك تفعيل الفوترة في Cloud Console لاستخدام موارد/واجهات برمجة تطبيقات Cloud. لن تكلفك تجربة هذا الدرس التطبيقي حول الترميز الكثير من المال، إن لم تكلفك شيئًا على الإطلاق. لإيقاف الموارد كي لا يتم تحصيل رسوم منك بعد هذا البرنامج التعليمي، يمكنك حذف الموارد التي أنشأتها أو حذف المشروع بأكمله. يمكن لمستخدمي Google Cloud الجدد الاستفادة من برنامج الفترة التجريبية المجانية بقيمة 300 دولار أمريكي.

إعداد البيئة

  1. إنشاء متغيرات بيئية مرتبطة بالمشروع والموارد
export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
export PROJECT_NAME=$(gcloud projects describe $PROJECT_ID --format='value(name)')
export REGION=us-east1
export MENU_SERVICE_NAME=menu-service

export SERVERLESS_VPC_CONNECTOR=cymbalconnector
export DB_INSTANCE_NAME=menu-catalog
export DB_INSTANCE_PASSWORD=password123
export DB_DATABASE=menu-db
export DB_USER=menu-user
export DB_PASSWORD=menupassword123
  1. استنساخ المستودع والانتقال إلى الدليل
git clone https://github.com/GoogleCloudPlatform/cymbal-eats.git && cd cymbal-eats/menu-service
  1. تفعيل الخدمات
gcloud services enable \
    sqladmin.googleapis.com \
    run.googleapis.com \
    vpcaccess.googleapis.com \
    servicenetworking.googleapis.com

3- ضبط "الوصول الخاص"

يتم توفير الوصول إلى الخدمات الخاصة كرابط تبادل معلومات بين شبكتَي VPC، أي بين شبكة VPC وشبكة VPC الأساسية في Google Cloud التي يقع فيها مثيل Cloud SQL. يتيح الاتصال الخاص لآلات VM في شبكة السحابة الإلكترونية الخاصة الافتراضية (VPC) والخدمات التي تستخدمها التواصل فقط من خلال عناوين IP داخلية. للوصول إلى الخدمات المتاحة من خلال ميزة "الوصول إلى الخدمات الخاصة"، لا تتطلّب مثيلات الأجهزة الافتراضية الاتصال بالإنترنت أو عناوين IP خارجية.

  1. تخصيص نطاق عناوين IP
gcloud compute addresses create google-managed-services-default \
    --global \
    --purpose=VPC_PEERING \
    --prefix-length=20 \
    --network=projects/$PROJECT_ID/global/networks/default

مثال على الناتج

Created [https://www.googleapis.com/compute/v1/projects/cymbal-eats-2-348215/global/addresses/google-managed-services-default].
  1. إنشاء اتصال خاص
gcloud services vpc-peerings connect \
    --service=servicenetworking.googleapis.com \
    --ranges=google-managed-services-default \
    --network=default \
    --project=$PROJECT_ID

مثال على الناتج

Operation "operations/pssn.p24-528514492617-2f2b507f-e4e5-4d53-a4de-9ddaceb4e92f" finished successfully.

4. إعداد Cloud SQL

‫Cloud SQL هي خدمة قواعد بيانات مُدارة بالكامل تسهّل إعداد قواعد البيانات الارتباطية PostgreSQL وMySQL وصيانتها وإدارتها والتحكّم فيها على السحابة الإلكترونية. يتم تشغيل كل مثيل من Cloud SQL بواسطة جهاز افتراضي (VM) يعمل على خادم مضيف في Google Cloud. يتضمّن خيار التوفّر العالي أيضًا آلة افتراضية (VM) احتياطية في منطقة أخرى تتضمّن الإعداد نفسه للآلة الافتراضية الأساسية. يتم الاحتفاظ بقاعدة البيانات على جهاز تخزين شبكي قابل للتوسع ويدوم طويلاً يُعرف باسم القرص الدائم، وهو متصل بالجهاز الافتراضي. يتم تخصيص عنوان IP ثابت لكل جهاز افتراضي لضمان بقاء عنوان IP الذي يتصل به التطبيق ثابتًا طوال مدة عمل مثيل Cloud SQL.

219cb722c2dd1b82.png

ستنشئ قاعدة بيانات Postgres Cloud SQL باستخدام عنوان IP خاص.

إنشاء قاعدة بيانات ومستخدم

  1. إنشاء مثيل Postgres Cloud SQL لاستخدام عنوان IP خاص
gcloud sql instances create $DB_INSTANCE_NAME \
    --project=$PROJECT_ID \
    --network=projects/$PROJECT_ID/global/networks/default \
    --no-assign-ip \
    --database-version=POSTGRES_12 \
    --cpu=2 \
    --memory=4GB \
    --region=$REGION \
    --root-password=${DB_INSTANCE_PASSWORD}

مثال على الناتج

Created [https://sqladmin.googleapis.com/sql/v1beta4/projects/cymbal1/instances/menu-instance].
NAME: menu-instance
DATABASE_VERSION: POSTGRES_12
LOCATION: us-east1-a
TIER: db-custom-2-4096
PRIMARY_ADDRESS: -
PRIVATE_ADDRESS: 10.8.80.5
STATUS: RUNNABLE
  1. إضافة قاعدة بيانات إلى مثيل قاعدة البيانات
gcloud sql databases create $DB_DATABASE --instance=$DB_INSTANCE_NAME

مثال على الناتج

Created database [menu-db].
instance: menu-catalog
name: menu-db
project: cymbal1
  1. إنشاء مستخدم SQL
gcloud sql users create ${DB_USER} \
    --password=$DB_PASSWORD \
    --instance=$DB_INSTANCE_NAME

مثال على الناتج

Created user [menu-user].
  1. تخزين عنوان IP لقاعدة البيانات
export DB_INSTANCE_IP=$(gcloud sql instances describe $DB_INSTANCE_NAME \
    --format=json | jq \
    --raw-output ".ipAddresses[].ipAddress")
  1. إضافة دور "عميل Cloud SQL" إلى حساب خدمة Compute Engine
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com" \
--role="roles/cloudsql.client"

مثال على الناتج

Updated IAM policy for project [cymbal1].
[...]

5- شبكة VPC بدون خادم

تتيح لك خدمة "الوصول إلى شبكة VPC بدون خادم" الاتصال مباشرةً بشبكة السحابة الإلكترونية الخاصة الافتراضية من بيئات بدون خادم، مثل Cloud Run أو App Engine أو Cloud Functions. يسمح ضبط الاتصال بشبكة VPC بدون خادم لبيئتك التي لا تتضمّن خادمًا بإرسال طلبات إلى شبكة VPC باستخدام نظام أسماء النطاقات الداخلي وعناوين IP الداخلية (على النحو المحدّد في RFC 1918 وRFC 6598). تستخدم الردود على هذه الطلبات أيضًا شبكتك الداخلية.

ستنشئ موصِّل "إمكانية الوصول إلى VPC بدون خادم" لربط خدمة Cloud Run بـ Cloud SQL.

19c7b05f35789fda.png

  1. أنشئ موصِّل "إمكانية الوصول إلى VPC بدون خادم" في شبكة VPC نفسها التي يتوفّر فيها مثيل Cloud SQL.
gcloud compute networks vpc-access connectors create ${SERVERLESS_VPC_CONNECTOR} \
    --region=${REGION} \
    --range=10.8.0.0/28

مثال على الناتج

Created connector [cymbalconnector].

6. النشر على Cloud Run

ستنشئ صورة Docker وتنشرها على Cloud Run، ثم تربط Cloud Run بموصّل Serverless VPC للوصول إلى قاعدة بيانات Cloud SQL.

  1. تجميع التطبيق باستخدام Maven
./mvnw package -DskipTests

مثال على الناتج

[...]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  42.864 s
[INFO] Finished at: 2022-04-28T16:15:33Z
[INFO] ------------------------------------------------------------------------
  1. إنشاء صورة Docker:
docker build -f src/main/docker/Dockerfile.jvm \
    --tag gcr.io/$PROJECT_NAME/menu-service .

مثال على الناتج

[...]
Successfully built 4ef5d7a3befc
Successfully tagged gcr.io/cymbal1/menu-service:latest
  1. إرسال صورة Docker إلى سجلّ الحاويات:
docker push gcr.io/$PROJECT_NAME/menu-service

مثال على الناتج

Using default tag: latest
The push refers to repository [gcr.io/cymbalsql/menu-service]
17b374963800: Pushed
d9a51c06430d: Pushed
fff5d2a2cfc9: Pushed
f21fceb558c6: Pushed
5ffbbbf218dd: Pushed
60609ec85f86: Layer already exists
f2c4302f03b8: Layer already exists
latest: digest: sha256:f64cb7c288dbf4ad9b12bd210c23c5aec1048dee040450ff2d9dbdf96e83a426 size: 1789
  1. تفعيل خدمة "القائمة":
gcloud run deploy $MENU_SERVICE_NAME \
    --image=gcr.io/$PROJECT_NAME/menu-service:latest \
    --region $REGION \
    --allow-unauthenticated \
    --set-env-vars DB_USER=$DB_USER \
    --set-env-vars DB_PASS=$DB_PASSWORD \
    --set-env-vars DB_DATABASE=$DB_DATABASE \
    --set-env-vars DB_HOST=$DB_INSTANCE_IP \
    --vpc-connector $SERVERLESS_VPC_CONNECTOR \
    --project=$PROJECT_ID \
    --quiet

مثال على الناتج

[...]
Done.
Service [menu-service] revision [menu-service-00002-xox] has been deployed and is serving 100 percent of traffic.
Service URL: https://menu-service-g2mfphytdq-uk.a.run.app

تنصح Google باستخدام خدمة Secret Manager لتخزين المعلومات الحسّاسة، مثل بيانات اعتماد SQL. يمكنك تمرير الأسرار كمتغيرات بيئية أو تركيبها كوحدة تخزين باستخدام Cloud Run.

  1. عنوان URL الخاص بخدمة قائمة المتجر:
MENU_SERVICE_URL=$(gcloud run services describe menu-service \
  --platform managed \
  --region $REGION \
  --format=json | jq \
  --raw-output ".status.url")
  1. التحقّق من عنوان URL الخاص بخدمة القائمة
echo $MENU_SERVICE_URL

مثال على الناتج

https://menu-service-g2mfphytdq-uk.a.run.app

7. اختبار الخدمة

  1. أنشئ عنصر قائمة جديدًا عن طريق إرسال طلب POST:
curl -X POST "${MENU_SERVICE_URL}/menu" \
  -H 'Content-Type: application/json' \
  -d '{
       "itemImageURL": "https://images.unsplash.com/photo-1631452180519-c014fe946bc7?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1587&q=80",
       "itemName": "Curry Plate",
       "itemPrice": 12.5,
       "itemThumbnailURL": "https://images.unsplash.com/photo-1631452180519-c014fe946bc7?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1587&q=80",
       "spiceLevel": 3,
       "status": "Ready",
       "tagLine": "Spicy touch for your taste buds!!"
   }'

مثال على الناتج

{
    "id": 16,
    "createDateTime": "2022-04-28T18:14:04.17225",
    "itemImageURL": "https://images.unsplash.com/photo-1631452180519-c014fe946bc7?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1587&q=80",
    "itemName": "Curry Plate",
    "itemPrice": 12.5,
    "itemThumbnailURL": "https://images.unsplash.com/photo-1631452180519-c014fe946bc7?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1587&q=80",
    "spiceLevel": 3,
    "status": "Processing",
    "tagLine": "Spicy touch for your taste buds!!",
    "updateDateTime": "2022-04-28T18:14:04.172298"
}
  1. غيِّر حالة عنصر القائمة عن طريق إرسال طلب PUT:
curl -X PUT "${MENU_SERVICE_URL}/menu/1" \
  -H 'Content-Type: application/json' \
  -d '{"status": "Ready"}'

مثال على الناتج

{
    "id": 1,
    "createDateTime": "2022-04-28T17:21:02.369093",
    "itemImageURL": "https://images.unsplash.com/photo-1631452180519-c014fe946bc7?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1587&q=80",
    "itemName": "Curry Plate",
    "itemPrice": 12.50,
    "itemThumbnailURL": "https://images.unsplash.com/photo-1631452180519-c014fe946bc7?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1587&q=80",
    "spiceLevel": 0,
    "status": "Ready",
    "tagLine": "Spicy touch for your taste buds!!",
    "updateDateTime": "2022-04-28T17:21:02.657636"
}

8. تهانينا!

تهانينا، لقد أكملت درس البرمجة.

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

استكشِف دروسًا تطبيقية أخرى حول Cymbal Eats:

تَنظيم

لتجنُّب تحمّل رسوم في حسابك على Google Cloud مقابل الموارد المستخدَمة في هذا البرنامج التعليمي، احذف المشروع الذي يحتوي على الموارد أو احتفظ بالمشروع واحذف الموارد الفردية.

حذف المشروع

أسهل طريقة لإيقاف الفوترة هي حذف المشروع الذي أنشأته لتنفيذ البرنامج التعليمي.