۱. مرور کلی
جنکینز یکی از محبوبترین راهحلهای ادغام مداوم موجود است. از آن برای خودکارسازی بخشهای ضروری غیرانسانی فرآیند توسعه نرمافزار استفاده میشود. با استقرار جنکینز در Kubenetes در Google Cloud و استفاده از افزونه GKE، میتوانیم به سرعت و به طور خودکار اجراکنندههای ساخت را در صورت نیاز مقیاسبندی کنیم. با ترکیب با Cloud Storage، میتوانیم یک برنامه را با حداقل تلاش بسازیم و آزمایش کنیم.
کاری که انجام خواهید داد
- جنکینز را در یک کلاستر Kubernetes مستقر کنید
- افزونه Jenkins GKE را مستقر و پیکربندی کنید تا Jenkins بتواند پادها را به عنوان گرههای اجراکننده ایجاد و از بین ببرد.
- ساخت و آزمایش یک برنامه SpringBoot نمونه
- ساخت و انتشار یک کانتینر در رجیستری کانتینر گوگل
- استقرار برنامه نمونه در محیط GKE مرحلهبندی و تولید
آنچه نیاز دارید
- یک پروژه گوگل کلود با تنظیمات صورتحساب. اگر ندارید، باید یکی ایجاد کنید .
۲. راهاندازی
این آزمایشگاه کد میتواند بدون هیچ گونه نصب یا پیکربندی محلی، به طور کامل روی پلتفرم ابری گوگل اجرا شود.
پوسته ابری
در طول این آزمایشگاه کد، ما منابع و سرویسهای ابری مختلف را با استفاده از خط فرمان از طریق Cloud Shell فراهم و مدیریت خواهیم کرد.
فعال کردن APIها
APIهایی که باید در پروژه خود فعال کنیم عبارتند از:
- رابط برنامهنویسی کاربردی موتور محاسبات - ایجاد و اجرای ماشینهای مجازی
- Kubernetes Engine API - ساخت و مدیریت برنامههای مبتنی بر کانتینر
- Cloud Build API - پلتفرم ادغام مداوم و تحویل مداوم Google Cloud
- API مدیریت خدمات - به تولیدکنندگان خدمات اجازه میدهد تا خدمات را در پلتفرم ابری گوگل منتشر کنند.
- رابط برنامهنویسی کاربردی مدیریت منابع ابری - ایجاد، خواندن و بهروزرسانی فراداده برای کانتینرهای منابع گوگل کلود
API های مورد نیاز را با دستور 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/
۳. ایجاد خوشههای Kubernetes
ایجاد خوشه
در مرحله بعد، یک کلاستر GKE ایجاد خواهیم کرد که میزبان سیستم Jenkins ما، از جمله پادهایی که به عنوان گرههای کارگر ارسال میشوند، خواهد بود. محدوده اضافی که با پرچم --scopes مشخص شده است، به Jenkins اجازه میدهد تا به مخازن منبع ابر و رجیستری کانتینر دسترسی داشته باشد. در کنسول ابر، دستور زیر را اجرا کنید:
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 اجرا میشوند.
خروجی باید در ستون STATUS RUNNING داشته باشد:
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
۴. جنکینز را با 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 را در کنسول ابری خود دانلود کنید:
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 .
تیلر سمت سرور 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"}
نصب جنکینز
اکنون که Helm روی کلاستر ما نصب شده است، آماده نصب Jenkins هستیم:
./helm install stable/jenkins -n cd \ -f jenkins/values.yaml \ --version 1.2.2 --wait
تأیید
بیایید غلافها را بررسی کنیم:
kubectl get pods
خروجی باید غلاف Jenkins ما را با وضعیت RUNNING نشان دهد:
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 راهاندازی میشوند. پس از اتمام کار، به طور خودکار خاتمه مییابند و منابع آنها به مجموعه منابع کلاستر اضافه میشود.
اتصال به جنکینز
جنکینز روی کلاستر ما اجرا میشود، اما برای دسترسی به رابط کاربری، باید پورت فورواردینگ را از 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، روی آیکون پیشنمایش وب کلیک کنید
و گزینه «پیشنمایش روی پورت ۸۰۸۰» را انتخاب کنید.

باید یک صفحه ورود به سیستم برای Jenkins ببینیم که در آن میتوانیم admin به عنوان نام کاربری و رمز عبوری که در مرحله قبل برگردانده شده است، وارد کنیم:

وقتی روی ورود کلیک میکنیم، باید به صفحه اصلی جنکینز هدایت شویم.

۵. نصب و پیکربندی افزونه GKE
افزونهی موتور کوبرنتیز گوگل به ما این امکان را میدهد که پیادهسازیهای ساختهشده در جنکینز را در کلاسترهای کوبرنتیز خود که در GKE اجرا میشوند، منتشر کنیم. پیکربندیهایی وجود دارد که باید با مجوزهای IAM در پروژه شما انجام شود. ما این پیکربندی را با استفاده از Terraform پیادهسازی خواهیم کرد.
ابتدا، پروژه افزونه GKE را دانلود کنید:
git clone https://github.com/jenkinsci/google-kubernetes-engine-plugin.git ~/google-kubernetes-engine-plugin
پیکربندی خودکار مجوزهای IAM
دایرکتوری کاری فعلی خود را به دایرکتوری rbac پروژه GKE که قبلاً کلون کردیم تغییر دهید:
cd ~/google-kubernetes-engine-plugin/docs/rbac/
gcp-sa-setup.tf یک فایل پیکربندی Terraform است که یک نقش سفارشی GCP IAM با مجوزهای محدود به همراه یک حساب سرویس GCP برای اعطای آن نقش ایجاد میکند. این فایل به مقادیری برای متغیرهای نام حساب پروژه، منطقه و سرویس نیاز دارد. ما این مقادیر را ابتدا با اعلام متغیرهای محیطی زیر ارائه میدهیم:
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
حساب کاربری سرویس برای ذخیره در مخزن ذخیرهسازی ابری ما به مجوزهای ادمین ذخیرهسازی نیاز دارد:
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 robot deployer استفاده کنیم. دایرکتوری کاری خود را به دایرکتوری 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 -
۶. پیکربندی جنکینز
کلیدهای حساب سرویس
برای اینکه حساب کاربری سرویس به درستی کار کند، باید یک فایل کلید خصوصی ایجاد کنیم و آن را به عنوان یک راز 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
با دسترسی به گزینه دانلود فایل از منوی سه نقطهای Cloud Shell، فایل json را روی دیسک محلی خود دانلود کنید:

مسیر فایل /tmp/kaniko-secret.json را وارد کنید و روی دانلود کلیک کنید.
به صفحه Jenkins برگردید، در پنل سمت چپ، روی Credentials و سپس System کلیک کنید.


در زیر بخشی از صفحه با عنوان سیستم، روی اعتبارنامههای سراسری (Global credentials) کلیک کنید و سپس در سمت چپ، اعتبارنامهها را اضافه کنید (Add credentials).


در منوی کشویی Kind، گزینه Google Service Account را از private key انتخاب کنید. 'kaniko-role' را به عنوان نام وارد کنید، سپس کلید JSON خود را که در مراحل قبل ایجاد کردهاید، آپلود کنید و روی OK کلیک کنید.

متغیرهای محیطی
قبل از ایجاد خط لوله چند شاخهای، باید متغیرهای محیطی زیر را در Jenkins تعریف کنیم:
- JENK_INT_IT_ZONE - منطقهی کلاستر Kubernetes. در مورد ما
us-east1-d - JENK_INT_IT_PROJECT_ID - به شناسه پروژه GCP که میزبان این نمونه از Jenkins است اشاره دارد.
- JENK_INT_IT_STAGING - نام کلاستر «staging» ما، برای اهداف نمایشی
stagingاست. - JENK_INT_IT_PROD - نام کلاستر «prod» ما. برای نمایش، این
prodاست. - JENK_INT_IT_BUCKET - باکت ذخیرهسازی ابری گوگل که در مرحله قبل ایجاد شد
- JENK_INT_IT_CRED_ID - به اعتبارنامههایی که با استفاده از json در مرحله قبل ایجاد شدهاند اشاره دارد. مقدار آن باید با نامی که به آن دادیم،
kaniko-roleمطابقت داشته باشد.
برای افزودن این موارد، به مدیریت جنکینز بروید:

سپس سیستم را پیکربندی کنید:

بخشی به نام Global properties وجود خواهد داشت و وقتی کادر مربوط به Environment variables را علامت بزنیم، دکمهی Add ظاهر میشود که با کلیک روی آن میتوانیم متغیرهای بالا را به عنوان جفتهای کلید-مقدار اضافه کنیم:

برای اعمال تغییرات، روی دکمه ذخیره در پایین صفحه کلیک کنید.
۷. راهاندازی یک خط لوله
در Jenkins روی «مورد جدید» کلیک کنید:

برای نام، عبارت 'jenkins-integration-sample' را وارد کنید و نوع پروژه را 'Multibranch Pipeline' انتخاب کنید و روی تأیید کلیک کنید:

ما به صفحه پیکربندی خط لوله هدایت خواهیم شد. در قسمت منابع شاخه ، https://github.com/GoogleCloudPlatform/jenkins-integration-samples.git را به عنوان مخزن پروژه وارد کنید. در قسمت پیکربندی ساخت، 'gke/Jenkinsfile' را به عنوان مسیر اسکریپت وارد کنید.

برای اعمال این تنظیمات، روی ذخیره کلیک کنید. پس از ذخیره، جنکینز اسکن مخزن و ساخت بعدی برای هر شاخه را آغاز میکند. با پیشرفت کار، خواهید دید که پادها با پیشرفت ساختها در صفحه Kubernetes Workloads ایجاد، اجرا و از بین میروند.
وقتی ساختها تمام شد، دو مورد در صفحه Kubernetes Workloads با نام jenkins-integration-samples-gke خواهید یافت که هر کدام مربوط به کلاستر prod یا testing هستند. وضعیت OK خواهد بود:

با استفاده از دستور gcloud زیر، خواهیم دید که یک تصویر کانتینر را در رجیستری کانتینر گوگل مربوط به pipeline خود آپلود کردهایم:
gcloud container images list
برای مشاهده حجم کار در مرورگر خود، اعتبارنامههای مربوط به خوشه prod را دریافت کنید:
gcloud container clusters get-credentials prod --zone us-east1-d --project ${GOOGLE_CLOUD_PROJECT}
و برای تنظیم یک پورت فوروارد از پورت ۸۰۸۱ پوسته خود به پورت ۸۰۸۰ بار کاری خود، دستور زیر را اجرا کنید:
export POD_NAME=$(kubectl get pods -o jsonpath="{.items[0].metadata.name}") &&
kubectl port-forward $POD_NAME 8081:8080 >> /dev/null &
در بالای پوسته ابری، روی آیکون پیشنمایش وب کلیک کنید و گزینه «پیشنمایش روی پورت ۸۰۸۱» را انتخاب کنید.


۸. پاکسازی
ما نحوه استقرار یک Jenkins و یک نمونه خط لوله چندشاخهای روی Kubernetes را بررسی کردهایم. اکنون زمان آن رسیده است که پروژه خود را از هرگونه منبعی که ایجاد کردهایم، پاک کنیم.
حذف پروژه
اگر ترجیح میدهید، میتوانید کل پروژه را حذف کنید. در کنسول GCP، به صفحه 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
تصاویر رجیستری کانتینر گوگل
ما تصاویر رجیستری کانتینر گوگل را با استفاده از خلاصه تصاویر حذف خواهیم کرد. ابتدا خلاصهها را با دستور زیر بازیابی کنید:
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>
۹. تبریک میگویم!
هورا! شما موفق شدید. شما یاد گرفتید که چگونه Jenkins را روی GKE مستقر کنید و کارها را به کلاسترهای Kubernetes ارسال کنید.
آنچه ما پوشش دادهایم
- ما یک Kubernetes Cluster مستقر کردیم و از Helm برای نصب Jenkins استفاده کردیم.
- ما افزونه GKE را نصب و پیکربندی کردیم تا Jenkins بتواند مصنوعات ساخت را در خوشههای Kubernetes مستقر کند.
- ما Jenkins را طوری پیکربندی کردیم که یک خط لوله چندشاخهای راهاندازی کند که کار را به خوشههای GKE ارسال کند.