1. نظرة عامة
Jenkins هو أحد أكثر حلول الدمج المستمر شيوعًا. ويتم استخدامه لأتمتة الأجزاء الأساسية غير البشرية من عملية تطوير البرامج. من خلال نشر Jenkins في Kubenetes على Google Cloud واستخدام المكوّن الإضافي GKE، يمكننا توسيع نطاق مشغّلي عمليات الإنشاء بسرعة وتلقائيًا حسب الحاجة. وباستخدام Cloud Storage، يمكننا إنشاء تطبيق واختباره بأقل مجهود.
المهام التي ستنفّذها
- نشر Jenkins في مجموعة Kubernetes
- نشر مكوّن GKE الإضافي في Jenkins وضبطه لتفعيل Jenkins لإنشاء وحدات pod وإزالتها كنواة تنفيذ
- إنشاء نموذج لتطبيق SpringBoot واختباره
- إنشاء حاوية ونشرها في Google Container Registry
- نشر نموذج التطبيق في بيئة GKE الرئيسية والاختبارية
المتطلبات
- مشروع على Google Cloud تم إعداد الفوترة له إذا لم يكن لديك حساب، عليك إنشاء حساب.
2. الإعداد
يمكن تشغيل هذا الإصدار التجريبي من الرمز البرمجي بالكامل على Google Cloud Platform بدون أي تثبيت أو ضبط على الجهاز.
Cloud Shell
خلال هذا الدرس التطبيقي حول رموز البرامج، سنوفّر خدمات وموارد مختلفة في السحابة الإلكترونية ونديرها باستخدام سطر الأوامر من خلال Cloud Shell.
تفعيل واجهات برمجة التطبيقات
في ما يلي واجهات برمجة التطبيقات التي سنحتاج إلى تفعيلها في مشروعنا:
- Compute Engine API: لإنشاء الأجهزة الافتراضية وتشغيلها
- Kubernetes Engine API: لإنشاء التطبيقات المستندة إلى حاويات وإدارتها
- Cloud Build API: منصة الدمج والتسليم المستمرَين من Google Cloud
- Service Management API: تتيح لمطوّري الخدمات نشر الخدمات على Google Cloud Platform.
- Cloud Resource Manager API: لإنشاء البيانات الوصفية لحاويات موارد Google Cloud وقراءتها وتعديلها
فعِّل واجهات برمجة التطبيقات المطلوبة باستخدام أمر gcloud التالي:
gcloud services enable compute.googleapis.com \ container.googleapis.com \ cloudbuild.googleapis.com \ servicemanagement.googleapis.com \ cloudresourcemanager.googleapis.com \ --project ${GOOGLE_CLOUD_PROJECT}
إنشاء حزمة GCS
سنحتاج إلى حزمة GCS لتحميل عملنا التجريبي. لننشئ حزمة باستخدام معرّف المشروع في الاسم لضمان تفرد الحزمة:
gsutil mb gs://${GOOGLE_CLOUD_PROJECT}-jenkins-test-bucket/
3- إنشاء مجموعات Kubernetes
إنشاء المجموعة
بعد ذلك، سننشئ مجموعة GKE ستستضيف نظام Jenkins، بما في ذلك مجموعات التطبيقات التي سيتم إرسالها كنوى عامل. سيسمح النطاق الإضافي الذي يشير إليه الرمز --scopes
لـ Jenkins بالوصول إلى "مستودعات مصادر Cloud" و"سجلّ الحاويات". في Cloud Console، نفِّذ ما يلي:
gcloud container clusters create jenkins-cd \ --machine-type n1-standard-2 --num-nodes 1 \ --zone us-east1-d \ --scopes "https://www.googleapis.com/auth/source.read_write,cloud-platform" \ --cluster-version latest
لننشر أيضًا مجموعتَين لاستضافة إصدارَي الإصدار التجريبي والإصدار العلني من نموذج التطبيق:
gcloud container clusters create staging \ --machine-type n1-standard-2 --num-nodes 1 \ --zone us-east1-d \ --cluster-version latest
gcloud container clusters create prod \ --machine-type n1-standard-2 --num-nodes 2 \ --zone us-east1-d \ --cluster-version latest
التحقّق من الملكية
بعد إنشاء المجموعات، يمكننا التأكّد من أنّها تعمل باستخدام gcloud container clusters list
.
يجب أن تحتوي النتيجة على RUNNING
في عمود STATUS
:
NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS jenkins-cd us-east1-d 1.15.9-gke.9 34.74.77.124 n1-standard-2 1.15.9-gke.9 2 RUNNING prod us-east1-d 1.15.9-gke.9 35.229.98.12 n1-standard-2 1.15.9-gke.9 2 RUNNING staging us-east1-d 1.15.9-gke.9 34.73.92.228 n1-standard-2 1.15.9-gke.9 2 RUNNING
4. نشر Jenkins باستخدام Helm
تثبيت Helm
سنستخدم Helm، وهو مدير حِزم تطبيقات Kubernetes، لتثبيت Jenkins على مجموعتنا. للبدء، نزِّل المشروع الذي يتضمّن ملفات Kubernetes التي سنستخدمها لنشر Jenkins:
git clone https://github.com/GoogleCloudPlatform/continuous-deployment-on-kubernetes.git ~/continuous-deployment-on-kubernetes
غيِّر دليل العمل الحالي إلى دليل المشروع:
cd ~/continuous-deployment-on-kubernetes/
أنشئ عملية ربط دور مجمع لمنح نفسك أذونات دور مشرف المجمع:
kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin --user=$(gcloud config get-value account)
يمكنك الاتصال بمجموعة jenkins من خلال الحصول على بيانات اعتمادها:
gcloud container clusters get-credentials jenkins-cd --zone us-east1-d --project ${GOOGLE_CLOUD_PROJECT}
نزِّل ملف Helm الثنائي إلى Cloud Console:
wget https://storage.googleapis.com/kubernetes-helm/helm-v2.14.1-linux-amd64.tar.gz
فكِّ ضغط الملف وانسخ ملف helm المضمّن إلى دليل العمل الحالي:
tar zxfv helm-v2.14.1-linux-amd64.tar.gz && \ cp linux-amd64/helm .
Tiller هو الجانب الخادم من Helm الذي يعمل على مجموعة Kubernetes. لننشئ حساب خدمة باسم tiller
:
kubectl create serviceaccount tiller \ --namespace kube-system
واربطه بدور مجموعة cluster-admin
حتى يتمكّن من إجراء تغييرات:
kubectl create clusterrolebinding tiller-admin-binding \ --clusterrole=cluster-admin \ --serviceaccount=kube-system:tiller
يمكننا الآن إعداد Helm وتعديل المستودع:
./helm init --service-account=tiller && \ ./helm repo update
إثبات الملكية
تأكَّد من أنّ Helm جاهز للاستخدام مع ./helm version
، ومن المفترض أن يعرض هذا الإجراء أرقام إصدارات العميل والخادم:
Client: &version.Version{SemVer:"v2.14.1", GitCommit:"5270352a09c7e8b6e8c9593002a73535276507c0", GitTreeState:"clean"} Server: &version.Version{SemVer:"v2.14.1", GitCommit:"5270352a09c7e8b6e8c9593002a73535276507c0", GitTreeState:"clean"}
تثبيت Jenkins
بعد تثبيت Helm على مجموعتنا، أصبحنا جاهزين لتثبيت Jenkins:
./helm install stable/jenkins -n cd \ -f jenkins/values.yaml \ --version 1.2.2 --wait
التحقّق من الملكية
لنطّلِع على وحدات pod:
kubectl get pods
من المفترض أن يعرض الإخراج مجموعة Jenkins مع حالة "جارٍ":
NAME READY STATUS RESTARTS AGE cd-jenkins-7c786475dd-vbhg4 1/1 Running 0 1m
تأكَّد من أنّه تم إنشاء خدمة Jenkins بشكل صحيح:
kubectl get svc
من المفترض أن تظهر النتيجة على النحو التالي:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE cd-jenkins ClusterIP 10.35.241.170 <none> 8080/TCP 2m27s cd-jenkins-agent ClusterIP 10.35.250.57 <none> 50000/TCP 2m27s kubernetes ClusterIP 10.35.240.1 <none> 443/TCP 75m
سيستخدم تثبيت Jenkins مكوّن Kubernetes الإضافي لإنشاء وكلاء أدوات الإنشاء. وسيتم إطلاقها تلقائيًا من خلال Jenkins master حسب الحاجة. وعند الانتهاء من عملها، يتم إنهاء عملها تلقائيًا وتتم إضافة مواردها مرة أخرى إلى مجموعة موارد المجموعة.
الاتصال بخدمة Jenkins
يعمل Jenkins على مجموعتنا، ولكن للوصول إلى واجهة المستخدم، لنعدّ إعدادات إعادة توجيه المنفذ من Cloud Shell:
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/component=jenkins-master" -l "app.kubernetes.io/instance=cd" -o jsonpath="{.items[0].metadata.name}") && kubectl port-forward $POD_NAME 8080:8080 >> /dev/null &
تم إنشاء كلمة مرور مشرف أثناء عملية التثبيت. لنسترِده:
printf $(kubectl get secret cd-jenkins -o jsonpath="{.data.jenkins-admin-password}" | base64 --decode);echo
في أعلى Cloud Shell، انقر على رمز معاينة الويب واختَر "معاينة على المنفذ 8080".
من المفترض أن تظهر لنا شاشة تسجيل الدخول إلى Jenkins حيث يمكننا إدخال admin
لاسم المستخدم وكلمة المرور التي تم عرضها في الخطوة السابقة:
عند النقر على تسجيل الدخول، من المفترض أن يتم توجيهنا إلى الصفحة الرئيسية لخدمة Jenkins.
5- تثبيت المكوّن الإضافي لـ GKE وضبطه
يتيح لنا مكوّن Google Kubernetes Engine الإضافي نشر عمليات النشر التي تم إنشاؤها في Jenkins إلى مجموعات Kubernetes التي تعمل ضمن GKE. هناك بعض الإعدادات التي يجب إجراؤها باستخدام أذونات إدارة الهوية وإمكانية الوصول في مشروعك. سننشر هذه الإعدادات باستخدام Terraform.
أولاً، نزِّل مشروع المكوّن الإضافي لـ GKE:
git clone https://github.com/jenkinsci/google-kubernetes-engine-plugin.git ~/google-kubernetes-engine-plugin
ضبط أذونات إدارة الهوية وإمكانية الوصول التلقائية
غيِّر دليل العمل الحالي إلى دليل rbac في مشروع GKE الذي نسخناه سابقًا:
cd ~/google-kubernetes-engine-plugin/docs/rbac/
gcp-sa-setup.tf
هو ملف إعدادات Terraform سينشئ دورًا مخصّصًا في "إدارة الهوية وإمكانية الوصول" في Google Cloud Platform (IAM) مع أذونات مفروض عليها قيود، بالإضافة إلى حساب خدمة على Google Cloud Platform لمنح هذا الدور. يتطلب الملف قيمًا لمتغيّرات اسم المشروع والمنطقة وحساب الخدمة. نقدّم هذه القيم من خلال تحديد متغيّرات البيئة التالية أولاً:
export TF_VAR_project=${GOOGLE_CLOUD_PROJECT} export TF_VAR_region=us-east1-d export TF_VAR_sa_name=kaniko-role
ابدأ استخدام Terraform وأنشئ خطة وطبِّقها:
terraform init terraform plan -out /tmp/tf.plan terraform apply /tmp/tf.plan && rm /tmp/tf.plan
سيحتاج حساب الخدمة إلى أذونات مشرف مساحة التخزين للحفظ في حزمة Cloud Storage:
gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \ --member serviceAccount:kaniko-role@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com \ --role 'roles/storage.admin'
ستحتاج أيضًا إلى أذونات الحاوية لمراحل النشر في مسار الإحالة الناجحة:
gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} --member \ serviceAccount:kaniko-role@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com --role 'roles/container.developer'
يمكننا الآن استخدام Helm لإعداد أذونات المجموعة لمكوّن GKE الإضافي باستخدام أداة نشر الروبوت gke. غيِّر دليل العمل إلى دليل Helm الخاص بمشروع GKE:
cd ~/google-kubernetes-engine-plugin/docs/helm/
ويمكنك التثبيت باستخدام مخطّط Helm المقدَّم:
export TARGET_NAMESPACE=kube-system && \ envsubst < gke-robot-deployer/values.yaml | helm install ./gke-robot-deployer --name gke-robot-deployer -f -
6- إعداد Jenkins
مفاتيح حسابات الخدمة
لكي يعمل حساب الخدمة بشكل صحيح، سنحتاج إلى إنشاء ملف مفتاح خاص وإضافته كسرّ Kubernetes. أولاً، أنشئ الملف باستخدام الأمر gcloud التالي:
gcloud iam service-accounts keys create /tmp/kaniko-secret.json --iam-account kaniko-role@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com
سننشئ مفتاحًا سريًا في ملف تخزين الأسرار في Kubernetes باستخدام هذا الملف:
kubectl create secret generic jenkins-int-samples-kaniko-secret --from-file=/tmp/kaniko-secret.json
نزِّل ملف json إلى القرص المحلي من خلال الوصول إلى عنصر "تنزيل الملف" من قائمة النقاط الثلاث في Cloud Shell:
أدخِل مسار الملف /tmp/kaniko-secret.json
وانقر على "تنزيل".
في صفحة Jenkins، على يمين الصفحة، انقر على الاعتمادات، ثم على النظام.
ضمن قسم الصفحة بعنوان النظام، انقر على "بيانات الاعتماد الشاملة" ثم على "إضافة بيانات اعتماد" على يمين الصفحة:
في القائمة المنسدلة "النوع"، اختَر حساب خدمة Google من المفتاح الخاص. أدخِل "kaniko-role" كاسم، ثم حمِّل مفتاح JSON الذي تم إنشاؤه في الخطوات السابقة وانقر على "حسنًا".
متغيّرات البيئة
هناك بعض متغيّرات البيئة التي سنحتاج إلى تحديدها في Jenkins قبل إنشاء مسار الإدراج المتعدّد الفروع. وهذه الأنواع الفرعية هي:
- JENK_INT_IT_ZONE: منطقة مجموعة Kubernetes. في حالتنا
us-east1-d
- JENK_INT_IT_PROJECT_ID: يشير إلى رقم تعريف مشروع GCP الذي يستضيف هذا المثيل من Jenkins
- JENK_INT_IT_STAGING: اسم مجموعة "مرحلة الإعداد"، ويكون
staging
لأغراض العرض. - JENK_INT_IT_PROD: اسم مجموعة "prod". لأغراض توضيحية، تكون القيمة
prod
. - JENK_INT_IT_BUCKET: حزمة Google Cloud Storage التي تم إنشاؤها في الخطوة السابقة
- JENK_INT_IT_CRED_ID: يشير إلى بيانات الاعتماد التي تم إنشاؤها باستخدام ملف json في الخطوة السابقة. يجب أن تتطابق القيمة مع الاسم الذي منحناه،
kaniko-role
.
لإضافة هذه العناصر، انتقِل إلى إدارة Jenkins:
بعد ذلك، ضبط النظام:
سيظهر قسم بعنوان الخصائص الشاملة، وعند وضع علامة في المربّع بجانب متغيّرات البيئة، سيظهر زر إضافة يمكننا النقر عليه لإضافة المتغيّرات أعلاه كأزواج مفتاح/قيمة:
انقر على الزر حفظ في أسفل الصفحة لتطبيق التغييرات.
7- إعداد مسار إحالة ناجحة
في Jenkins، انقر على "عنصر جديد":
أدخِل jenkins-integration-sample للاسم واختَر Multibranch Pipeline كنوع المشروع، ثم انقر على "حسنًا":
ستتم إعادة توجيهنا إلى صفحة إعدادات مسار الإحالة الناجحة. ضمن مصادر الفروع، أدخِل https://github.com/GoogleCloudPlatform/jenkins-integration-samples.git كـ مستودع المشروع. ضمن إعدادات الإصدار، أدخِل gke/Jenkinsfile كـ مسار النص البرمجي.
انقر على حفظ لتطبيق هذه الإعدادات. عند الحفظ، سيبدأ Jenkins عملية فحص للمستودع وإنشاء لاحق لكل فرع. أثناء التقدّم، سترى وحدات pod يتم إنشاؤها وتشغيلها وإزالتها مع تقدّم عمليات الإنشاء في صفحة "أحمال Kubernetes".
عند اكتمال عمليات الإنشاء، سيظهر لك عنصران في صفحة "أحمال عمل Kubernetes" باسم jenkins-integration-samples-gke، يتوافق كل منهما مع المجموعة الاختبارية أو مجموعة الإنتاج. ستظهر الحالة "حسنًا":
باستخدام الأمر gcloud التالي، سنرى أنّنا حمّلنا صورة حاوية إلى "مستودع حاويات Google" المرتبط بمسار الإرسال:
gcloud container images list
للاطّلاع على حجم العمل في المتصفّح، احصل على بيانات الاعتماد الخاصة بمجموعة الإنتاج:
gcloud container clusters get-credentials prod --zone us-east1-d --project ${GOOGLE_CLOUD_PROJECT}
وشغِّل ما يلي لإعداد إعادة توجيه منفذ من منفذ shell 8081 إلى منفذ 8080 لوحدة العمل:
export POD_NAME=$(kubectl get pods -o jsonpath="{.items[0].metadata.name}") && kubectl port-forward $POD_NAME 8081:8080 >> /dev/null &
في أعلى Cloud Shell، انقر على رمز معاينة الويب واختَر "معاينة على المنفذ 8081".
8. تنظيف
لقد استكشَفنا كيفية نشر Jenkins ونموذج مسار عمل متعدد الفروع على Kubernetes. حان الآن وقت إزالة أيّ موارد أنشأناها من مشروعنا.
حذف المشروع
يمكنك أيضًا حذف المشروع بأكمله. في وحدة تحكّم Google Cloud Platform، انتقِل إلى صفحة Cloud Resource Manager:
في قائمة المشاريع، اختَر المشروع الذي كنا نعمل عليه وانقر على حذف. سيُطلب منك كتابة رقم تعريف المشروع. أدخِل كلمة المرور وانقر على إيقاف.
بدلاً من ذلك، يمكنك حذف المشروع بأكمله مباشرةً من Cloud Shell باستخدام gcloud:
gcloud projects delete $GOOGLE_CLOUD_PROJECT
إذا كنت تفضّل حذف المكوّنات المختلفة القابلة للفوترة واحدًا تلو الآخر، انتقِل إلى القسم التالي.
مجموعة Kubernetes
يمكنك حذف مجموعة Kubernetes بأكملها باستخدام gcloud:
gcloud container clusters delete jenkins-cd --zone=us-east1-d
حِزم التخزين
أزِل جميع الملفات المحمَّلة واحذِف حزمة التخزين باستخدام gsutil:
gsutil rm -r gs://${GOOGLE_CLOUD_PROJECT}-jenkins-test-bucket
صور Google Container Registry
سنحذف صور Google Container Registry باستخدام ملخّصات الصور. أولاً، استرجع الملخّصات باستخدام الأمر التالي:
gcloud container images list-tags gcr.io/${GOOGLE_CLOUD_PROJECT}/jenkins-integration-samples-gke --format="value(digest)"
بعد ذلك، لكل خلاصة يتم عرضها:
gcloud container images delete gcr.io/${GOOGLE_CLOUD_PROJECT}/jenkins-integration-samples-gke@sha256:<DIGEST>
9. تهانينا!
رائع! أحسنت. لقد تعلّمت كيفية نشر Jenkins على GKE وإرسال المهام إلى مجموعات Kubernetes.
المواضيع التي تناولناها
- لقد نفّذنا مجموعة Kubernetes واستخدمنا Helm لتثبيت Jenkins.
- لقد ثبَّتنا مكوّن GKE الإضافي وضبطناه لتفعيل Jenkins من أجل نشر عناصر الإنشاء في مجموعات Kubernetes.
- لقد أعددنا Jenkins لإعداد مسار عمل متعدد الفروع يرسل العمل إلى مجموعات GKE.