استفاده از Kubernetes در Gitlab - بخش دوم

در آموزش قبلی به مبحث اتصال کلاستر K8s به سرور Gitlab پرداختیم تا از مزایایی مانند استقرار خودکار پروژه ها استفاده کنیم. حالا در این پست به یک نمونه از چنین استقراری میپردازیم.

استفاده از Kubernetes در Gitlab - بخش دوم

اگر آموزش قبلی رو مشاهده کرده باشید ٬ یاد گرفتیم که چطور یک کلاستر Kubernetes رو به سرور Gitlab خودمون متصل کنیم.

استفاده از Kubernetes در Gitlab - بخش اول
خیلی از شما ها از Gitlab استفاده می کنید. یکی از بهترین ویژگی هاش امکان اتصال به کلاستر Kubernetes و استقرار پروژه هاست که در این پست به اون می پردازیم.

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

Auto DevOps چیست ؟

یکی از بهترین ویژگی هایی که Gitlab در اختیار شما میذاره گزینه Auto DevOps که احتمالا اون رو در بخش CI/CD تنظیمات ریپازیتوری های خودتون مشاهده کردید.

این ویژگی به صورت خودکار تمامی مراحل Build, Test, Deploy, Performance check, Security check, ... رو انجام میده و با اتصال به کلاستری مناسب ٬ میتونید عملیات استقرار هم انجام بدید. وقتی از این گزینه استفاده کنید Gitlab با استفاده از یک CI Template مراحل بالا رو انجام میده که چنین محتوایی داره :

image: alpine:latest

variables:
  KUBE_INGRESS_BASE_DOMAIN: domain.example.com
  POSTGRES_USER: user
  POSTGRES_PASSWORD: testing-password
  POSTGRES_ENABLED: "true"
  POSTGRES_DB: $CI_ENVIRONMENT_SLUG
  DOCKER_DRIVER: overlay2
  ROLLOUT_RESOURCE_TYPE: deployment
  DOCKER_TLS_CERTDIR: ""

stages:
  - build
  - test
  - deploy
  - review
  - dast
  - staging
  - canary
  - production
  - incremental rollout 10%
  - incremental rollout 25%
  - incremental rollout 50%
  - incremental rollout 100%
  - performance
  - cleanup

workflow:
  rules:
    - if: '$BUILDPACK_URL || $AUTO_DEVOPS_EXPLICITLY_ENABLED == "1" || $DOCKERFILE_PATH'

    - exists:
        - Dockerfile

    - exists:
        - project.clj

    - exists:
        - go.mod
        - Gopkg.mod
        - Godeps/Godeps.json
        - vendor/vendor.json
        - glide.yaml
        - src/**/*.go

    - exists:
        - gradlew
        - build.gradle
        - settings.gradle

    - exists:
        - pom.xml
        - pom.atom
        - pom.clj
        - pom.groovy
        - pom.rb
        - pom.scala
        - pom.yaml
        - pom.yml

    - exists:
        - .buildpacks

    - exists:
        - package.json

    - exists:
        - composer.json
        - index.php

    - exists:
        - '**/conf/application.conf'

    - exists:
        - requirements.txt
        - setup.py
        - Pipfile

    - exists:
        - Gemfile

    - exists:
        - '*.sbt'
        - project/*.scala
        - .sbt/*.scala
        - project/build.properties

    - exists:
        - .static

include:
  - template: Jobs/Build.gitlab-ci.yml  
  - template: Jobs/Test.gitlab-ci.yml  
  - template: Jobs/Code-Quality.gitlab-ci.yml  
  - template: Jobs/Deploy.gitlab-ci.yml
  - template: Jobs/Deploy/ECS.gitlab-ci.yml
  - template: Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml  
  - template: Jobs/Browser-Performance-Testing.gitlab-ci.yml  
  - template: Security/DAST.gitlab-ci.yml
  - template: Security/Container-Scanning.gitlab-ci.yml  
  - template: Security/Dependency-Scanning.gitlab-ci.yml  
  - template: Security/License-Scanning.gitlab-ci.yml
  - template: Security/SAST.gitlab-ci.yml
  - template: Security/Secret-Detection.gitlab-ci.yml

همینطور که مشاهده می کنید با استفاده از rule هایی که تعریف شده رنج وسیعی از پروژه ها پشتیبانی میشه از جمله :

  • Clojure
  • GO
  • Gradle
  • Java
  • NodeJs
  • PHP
  • Python
  • Ruby
  • ...

و در نهایت با استفاده از قالب های متفاوت برای هر Job تمامی مراحل برای یک پروژه تعریف و اجرا میشه. در اینجا Gitlab با استفاده از Heroku تمامی روند CI/CD رو انجام میده که میتونید لیست کاملشون رو در این آدرس مشاهده کنید :

Heroku
Heroku has 821 repositories available. Follow their code on GitHub.

شروع به کار

قبل از اینکه ادامه بدیم توجه کنید که این موارد انجام شده باشه :

نکته خیلی مهم : برای کلاستر و گیتلب حتما از دامنه به همراه SSL استفاده کنید. در غیر اینصورت با مشکلات زیادی مواجه میشید. حتی استفاده از گواهینامه های self-signed هم کار شما رو دشوار میکنه.
حرف من رو قبول کنید :)) قبلا تجربه کردم ٬ شدنی هست ولی خیلی اذیت میشید.

مسلما نیاز به یک پروژه نمونه داریم. در محیط گیتلب New project بزنید و تب Create from template رو انتخاب کنید :

اینجا لیست کاملی از نمونه پروژه های آماده رو مشاهده می کنید که بسته به نیازتون میتونید ازشون استفاده کنید. سه مورد اول مثال های خوبی برای استفاده با Auto DevOps هستند که من از Spring استفاده می کنم. اطلاعات مورد نیاز رو وارد کنید و پروژه رو بسازید.

وقتی به صفحه اصلی ریپازیتوری مراجعه کنید گزینه ای با عنوان Auto DevOps enabled مشاهده می کنید.

با کلیک روی این دکمه یا رفتن به مسیر Settings > CI/CD > Auto DevOps تنظیمات مربوطه برای شما نمایش داده میشه :

در قسمت Deployment strategy باید روند مد نظرتون جهت استقرار رو انتخاب کنید. به صورت پیشفرض ۳ گزینه در اختیار شما قرار گرفته :

  • استفاده از CD برای استقرار مستقیم نسخه Production
  • استفاده از CD برای استقرار مستقیم نسخه Production به صورت زمان دار. در این حالت استقرار پروژه با تاخیر های 5 دقیقه ای بین هر مرحله اعمال میشه.
  • استقرار خودکار روی محیط Staging و استقرار دستی روی محیط Production.

بسته به نیازتون یکی از گزینه های بالا رو انتخاب کنید و تنظیمات رو ذخیره کنید ( اینجا برای تست همون گزینه اول کفایت میکنه )

به محض ذخیره کردن ٬ یک Pipeline برای پروژه ایجاد میشه و تمامی Job هایی که در ابتدای این پست ذکر شد در صف اجرا قرار میگیره. البته توجه کنید که این Job ها با توجه به هر پروژه اعمال میشه و ممکنه باهم تفاوت داشته باشن.

کمی که صبر کنید Runner تمام مراحل رو اجرا کرده و استقرار به اتمام میرسه. اینجا من فقط Job های لازم رو اجرا کردم و بقیه Skip شدن. البته تست کارایی هم با خطا به اتمام رسید که مشکل از sitespeed.io بود.

اگر Job های اصلی رو در نظر بگیریم به ترتیب پروژه Build و سپس تست شد و در نهایت استقرار انجام میشه. بیاید نگاهی به مرحله استقرار داشته باشیم :

همون اول پیغامی رو مشاهده می کنید که میگه با اجرای این Job یک نسخه از پروژه روی محیط production در کلاستر با نام Local و فضانام spring-7-production ساخته میشه. برای محیط های استقرار توضیحاتی در آموزش قبلی داده شد. همچنین مشاهده می کنید که گیتلب برای پروژه شما یک namespace هم در نظر میگیره تا تمام اجزای پروژه به صورت مستقل در کلاستر قرار بگیرن.

ساختار فضا نام به این صورت شکل میگیره :

<project-name> - <project-id> - <environment>

در ادامه مشاهده می کنیم که منابع مورد نیاز برای Helm ساخته میشه و به ترتیب :

  • یک namespace ساخته میشه
  • تنظیمات Tiller انجام میشه
  • برای استفاده از Container registry یک Secret ساخته میشه.

در ادامه مشاهده میکنید که یک دیتابیس برای این پروژه در نظر گرفته میشه. گیتلب از PostgreSQL استفاده میکنه و در نهایت اطلاعات لازم جهت دسترسی به دیتابیس هم در اختیار شما گذاشته میشه.

و در آخر عملیات استقرار خود پروژه انجام میشه که در انتها دامنه ای هم به اون اختصاص داده میشه ( این دامنه با استفاده از ENV Variable ها قابل تنظیمه ).

نیم نگاهی به کلاستر

حالا که Pipeline اجرا شد نگاهی به کلاستر داشته باشیم و نتیجه رو ببینیم.

در اینجا ما دو namespace داریم. گزینه اول مربوط به همین پروژه و گزینه دوم مربوط به برنامه هایی میشه که گیتلب روی کلاستر نصب میکنه مانند Prometheus, Knative و غیره.

اینجا یک Deployment برای پروژه اصلی داریم.

همچنین Pod های مربوطه رو مشاهده می کنید. یکی برای پروژه و دیگری برای دیتابیس.

همچنین Service هایی هم برای پروژه و دیتابیس در نظر گرفته شده.

در نهایت تمام Secret های مورد نظر هم مشاهده می کنید.


تمامی مراحل استقرار خودکار انجام شد و از این به بعد با هر Commit مراحل بالا انجام شده و آخرین تغییرات روی کلاستر اعمال میشه. به این نکات دقت داشته باشید :

  • این مورد روی یک پروژه آماده پیاده سازی شد. در بخش بعدی آموزش روی پروژه ی خودمون این کار رو انجام میدیم.
  • برای مدیریت بهتر مسیریابی ها میتونید از بخش Applications برای کلاستر خودتون Ingress را نصب نمایید.
  • جهت استفاده از Let's Encrypt برای دامنه کلاستر میتونید در بخش قبلی Cert-Manager رو نصب کنید.
  • جهت شخصی سازی دامنه از متغیری با نام KUBE_INGRESS_BASE_DOMAIN استفاده کنید.
  • استفاده از Auto DevOps فقط وقتی امکان پذیره که هیچ CI دیگه ای وجود نداشته باشه. برای مثال اگه در پروژه یک فایل gitlab-ci.yml. داشته باشید این قابلیت کار نمیکنه.