سی آر دی و اُپراتور (قسمت شانزدهم)

توی این قسمت میریم به سراغ اینکه بررسی کنیم چطوری می‌تونیم ریسورس‌های خودمون رو به صورت کاستوم شده توی کوبرنتیز تعریف کنیم و بعدش هم در مورد اُپراتورها توی کوبرنتیز توضیح می‌دیم.

خب یه مروری کنیم پست‌های قبلی رو:

توصیه می‌کنم که حتما این پست‌ها رو هم مطالعه کنید. بریم که ادامه بدیم.

CRD
CRD

تعریف منابع سفارشی (Custom Resource Definitions – CRDs)

در دنیای کوبرنتیز، انعطاف‌پذیری و قابلیت گسترش از اهمیت بالایی برخوردار است. کوبرنتیز یک API قدرتمند برای مدیریت منابعی مانند Pod، Deployment و Service ارائه می‌دهد. اما اگر بخواهید منابعی را مدیریت کنید که به‌صورت پیش‌فرض توسط کوبرنتیز پشتیبانی نمی‌شوند، چه باید کرد؟ اینجاست که CRDs وارد عمل می‌شوند.

توی کوبرنتیز CRDها به شما این امکان را می‌دهند که منابع سفارشی خود را تعریف کرده و API کوبرنتیز را مطابق نیازهای خود گسترش دهید. در این مطلب، یک مثال عملی از کار با CRDها را بررسی می‌کنیم، جایی که یک کنترلر سفارشی ConfigMapها را بر اساس منابع سفارشی مدیریت می‌کند.

چرا از CRDها استفاده کنیم؟

توی کوبرنتیز CRDها بسیار قدرتمند هستند، زیرا به شما این امکان را می‌دهند که منابع مربوط به برنامه‌های خاص خود را به شیوه‌ای بومی (Native) در کوبرنتیز مدیریت کنید. دلایل استفاده از CRDها:

  1. انتزاع (Abstraction): با استفاده از CRDها می‌توانید منطق پیچیده را در منابع سفارشی پنهان کنید و مدیریت برنامه‌ها را ساده‌تر کنید و از امکانات کوبرنتیز برای مدیریت منابع خود استفاده کنید.
  2. یکپارچگی (Consistency): تعریف منابع سفارشی به شما کمک می‌کند تا برنامه‌های خود را در محیط‌های مختلف به‌صورت یکپارچه مدیریت کنید.
  3. خودکارسازی (Automation): CRDها امکان خودکارسازی را فراهم می‌کنند و به شما اجازه می‌دهند کنترلرهای سفارشی ایجاد کنید که وضعیت منابع را نظارت و اصلاح کنند.

در ادامه این مبحث نحوه نصب یک منبع سفارشی در API کوبرنتیز از طریق ایجاد CustomResourceDefinition را بررسی می‌کنیم.

مطالب این پست نیاز به نسخه سرور کوبرنتیز ۱.۱۶ یا بالاتر دارد. برای بررسی نسخه، از دستور زیر استفاده کنید:

kubectl version

ایجاد یک CustomResourceDefinition

وقتی یک CustomResourceDefinition (CRD) جدید ایجاد می‌کنید، API Server کوبرنتیز یک مسیر RESTful جدید برای هر نسخه‌ای که مشخص می‌کنید ایجاد می‌کند. منبع سفارشی ایجاد شده می‌تواند در محدوده فضای نام (Namespace) یا سراسری (Cluster-scoped) باشد. حذف فضای نام، تمام آبجکت‌های CRD داخل آن را نیز حذف می‌کند. اما خود CRDها غیرمحدوده‌ای (Non-namespaced) هستند.

مثال:

فایل زیر را در resourcedefinition.yaml ذخیره کنید:

				
					apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: crontabs.stable.example.com
spec:
  group: stable.example.com
  versions:
    - name: v1
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                cronSpec:
                  type: string
                image:
                  type: string
                replicas:
                  type: integer
  scope: Namespaced
  names:
    plural: crontabs
    singular: crontab
    kind: CronTab
    shortNames:
    - ct
				
			

ایجاد CRD:

				
					kubectl apply -f resourcedefinition.yaml
				
			

یک مسیر API جدید مانند زیر ایجاد می‌شود:

				
					/apis/stable.example.com/v1/namespaces/*/crontabs/...
				
			

ایجاد آبجکت‌های سفارشی

پس از ایجاد CRD، می‌توانید آبجکت‌های سفارشی را ایجاد کنید. به‌عنوان مثال، فایل زیر را در my-crontab.yaml ذخیره کنید:

				
					apiVersion: &quotstable.example.com/v1&quot
kind: CronTab
metadata:
  name: my-new-cron-object
spec:
  cronSpec: &quot* * * * */5&quot
  image: my-awesome-cron-image
				
			

ایجاد آبجکت سفارشی:

				
					kubectl apply -f my-crontab.yaml
				
			

مشاهده آبجکت‌های ایجاد شده:

				
					kubectl get crontab
				
			

حذف یک CustomResourceDefinition

برای حذف CRD و تمام آبحکت‌های مرتبط:

				
					kubectl delete -f resourcedefinition.yaml
				
			

مشخص کردن ساختار اسکیما (Schema)

با نسخه apiextensions.k8s.io/v1، تعریف یک اسکیما ساختاری (Structural Schema) برای CRD الزامی است. این اسکیما برای موارد زیر استفاده می‌شود:

  1. اعتبارسنجی داده‌های ورودی.
  2. جلوگیری از ذخیره فیلدهای ناشناخته (Pruning).

مثال اسکیما ساختاری:

				
					type: object
properties:
  spec:
    type: object
    properties:
      cronSpec:
        type: string
      image:
        type: string
				
			

کنترل حذف فیلدهای ناشناخته:

				
					type: object
properties:
  json:
    x-kubernetes-preserve-unknown-fields: true
				
			

بررسی یک مثال دیگه:

در این مثال، یک CRD ریسورسی به نام CustomConfigMap ایجاد خواهیم کرد. هر زمان که نمونه‌ای از این منبع ایجاد یا حذف شود، یک کنترلر سفارشی به ترتیب یک ConfigMap را ایجاد یا حذف می‌کند.

CRD

مراحل مثال عملی

۱. ایجاد Custom Resource Definition (CRD)

ابتدا CRD خود را تعریف می‌کنیم. فایل زیر را به نام CCM_CRD.yaml ایجاد کنید:

				
					apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: customconfigmaps.anvesh.com
spec:
  group: anvesh.com
  names:
    plural: customconfigmaps
    singular: customconfigmap
    kind: CustomConfigMap
  scope: Namespaced
  versions:
    - name: v1
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                my-own-property:
                  type: string
				
			

سپس دستور زیر را اجرا کنید:

				
					kubectl apply -f CCM_CRD.yaml
				
			

۲. ایجاد Custom Resource (CR)

یک نمونه از منبع سفارشی ایجاد کنید. فایل زیر را به نام CCM_CR.yaml ذخیره کنید:

				
					apiVersion: anvesh.com/v1
kind: CustomConfigMap
metadata:
  name: my-custom-resource-instance
spec:
  my-own-property: &quotexample-value&quot
				
			

و دستور زیر را اجرا کنید:

				
					kubectl apply -f CCM_CR.yaml
				
			

۳. نوشتن کنترلر سفارشی

یک فایل به نام custom_controller.py ایجاد کرده و محتوای زیر را در آن قرار دهید:

				
					from kubernetes import client, config, watch

def create_configmap(namespace, name, data):
    core_v1_api = client.CoreV1Api()
    configmap = client.V1ConfigMap(
        metadata=client.V1ObjectMeta(namespace=namespace, name=name),
        data=data
    )
    core_v1_api.create_namespaced_config_map(namespace=namespace, body=configmap)

def delete_configmap(namespace, name):
    core_v1_api = client.CoreV1Api()
    core_v1_api.delete_namespaced_config_map(name=name, namespace=namespace)

def main():
    config.load_incluster_config()
    api_instance = client.CustomObjectsApi()
    group = &quotanvesh.com&quot
    version = &quotv1&quot
    namespace = &quotdefault&quot
    plural = &quotcustomconfigmaps&quot

    resource_version = &quot&quot
    while True:
        stream = watch.Watch().stream(
            api_instance.list_namespaced_custom_object,
            group, version, namespace, plural,
            resource_version=resource_version
        )
        for event in stream:
            custom_resource = event['object']
            event_type = event['type']
            resource_name = custom_resource['metadata']['name']
            resource_data = custom_resource.get('spec', {})
            if event_type == &quotADDED&quot:
                create_configmap(namespace, resource_name, resource_data)
            elif event_type == &quotDELETED&quot:
                delete_configmap(namespace, resource_name)
				
			

۴. ایجاد Docker Image برای کنترلر

یک فایل Dockerfile ایجاد کنید:

				
					FROM python:3.8
ADD custom_controller.py /
RUN pip install kubernetes
CMD [&quotpython&quot, &quot/custom_controller.py&quot]
				
			

سپس تصویر را بسازید:

				
					docker build -t custom-controller:v1 .
				
			

۵. راه‌اندازی کنترلر

یک فایل به نام controller_deployment.yaml ایجاد کنید و محتوای زیر را در آن قرار دهید:

				
					apiVersion: apps/v1
kind: Deployment
metadata:
  name: custom-controller
spec:
  replicas: 1
  selector:
    matchLabels:
      app: custom-controller
  template:
    metadata:
      labels:
        app: custom-controller
    spec:
      containers:
      - name: custom-controller
        image: custom-controller:v1
				
			

دستور زیر را اجرا کنید:

				
					kubectl apply -f controller_deployment.yaml
				
			

۱. بررسی کنید که کنترلر در حال اجرا باشد:

kubectl get pods

۲. بررسی کنید که ConfigMap ایجاد شده است:

kubectl get configmaps

۳. منبع سفارشی را ویرایش کنید:

kubectl edit customconfigmaps my-custom-resource-instance

۴. منبع سفارشی را حذف کنید و بررسی کنید که ConfigMap حذف شده است:

kubectl delete customconfigmaps my-custom-resource-instance

در این آموزش یاد گرفتید چگونه از CRDها برای گسترش API کوبرنتیز استفاده کنید. با ترکیب CRDها و کنترلرها می‌توانید کوبرنتیز را برای نیازهای خاص خود سفارشی کنید و قدرت بیشتری به فرآیند مدیریت کانتینرها بدهید.

Kubernetes Operator

اپراتورهای کوبرنتیز چیستند؟

اپراتور یک افزونه برای کوبرنتیز است که فرآیند استقرار یک برنامه را خودکار می‌کند. اپراتورها معمولاً شامل کنترلرها و Custom Resource Definitions (CRDs) هستند که به شما این امکان را می‌دهند نمونه‌های جدید برنامه‌ها را بدون نیاز به دانش عمیق از نیازها یا نحوه عملکرد آنها، به‌سرعت مستقر کنید.

اپراتورها هدف اصلی مدیران انسانی را منعکس می‌کنند. استقرار دستی سیستم‌های پیچیده در یک کلاستر کوبرنتیز معمولاً نیازمند تلاش زیادی است، زیرا باید Pods، StatefulSets، Services، ConfigMaps و Volumes مورد نیاز برنامه را ایجاد و متصل کنید. اپراتورها به شما این امکان را می‌دهند که از انواع آبجکت‌های سفارشی مانند postgresql استفاده کنید تا پیکربندی زیرساخت کوبرنتیز به‌طور خودکار انجام شود.

اپراتور با ارائه CRDs و کنترلرهای مرتبط، این قابلیت را فراهم می‌کند.

برای مثال شما می‌خواهید دیتابیس از سرویس بدید. می‌تونید برای دیتابیس خود CRD و اپراتور تعریف کنید و تمام کانفیگ‌ها و الزامات مورد نیاز رو اونجا ایجاد کنید و هر زمان که درخواست ساخت کلاستر جدید دیتابیس بدید یه کلاستر کامل همانند کانفیگ‌هایی که لازم دارید می‌تونید ایجاد کنید.

اپراتور کوبرنتیز در مقابل کنترلر

معماری کوبرنتیز شامل اجزا و مفاهیم متعددی است، اما یک ویژگی همه آنها را به هم مرتبط می‌کند: مدل حالت اعلامی (Declarative State Model) که با استفاده از حلقه‌های کنترلی (Control Loops) به‌طور خودکار اقدامات لازم را برای همسان‌سازی وضعیت واقعی کلاستر با وضعیت مطلوب شما انجام می‌دهد.

کنترلرهای داخلی مانند Deployments و ReplicaSets، آبجکت‌های کلاستر شما را دنبال کرده و چرخه حیات وابسته‌های آنها را مدیریت می‌کنند. به‌عنوان مثال، وقتی یک آبجکت Deployment با ۳ کپی (Replica) ایجاد می‌کنید، کنترلر Deployment به‌طور خودکار یک ReplicaSet با سه Pod راه‌اندازی می‌کند و تمام تلاش خودش رو با استفاده از کنترلر رپلیکیشن انجام می‌دهد که همواره ۳ رپلیکا رو برای سرویس شما ایجاد کند.

کنترلرها یک الگوی عمومی هستند که در سراسر کوبرنتیز استفاده می‌شوند و اغلب بخشی از اپراتورها هستند. اپراتورها کدی سفارشی را توصیف می‌کنند که برنامه‌های خاص را با کوبرنتیز ادغام می‌کند.

چرا از اپراتورها استفاده کنیم؟

۱. تسهیل استقرار و نگهداری برنامه‌های پیچیده

اپراتورها آبجکت‌های موردنیاز برنامه را بر اساس پیکربندی منابع سفارشی شما فراهم می‌کنند. این امر به شما اجازه می‌دهد تا بدون نیاز به دانش عمیق در مورد آبجکت‌های کوبرنتیز، برنامه‌های جدید را مستقر کنید.

۲. مدیریت چرخه حیات برنامه

اپراتورها معمولاً چرخه حیات کامل برنامه را شامل ارتقاها، پشتیبان‌گیری‌ها و ادغام‌های نظارتی مدیریت می‌کنند. اپراتور به جای شما برنامه را اجرا می‌کند و لایه‌هایی از خودکارسازی را اضافه می‌کند که به مدیران انسانی کمک می‌کند وظایف خسته‌کننده یا مستعد خطا را انجام دهند. مثل این می‌مونه که تمام کانفیگ‌ها و الزامات مورد نیاز رو یه بار سر حوصله و صبر و با دقت زیاد ایجاد کنید و هر زمان که نیاز داشتید به راحتی از آن‌ها استفاده کنید.

۳. ساده‌سازی استقرار پایگاه‌های داده

اپراتورها به‌طور چشمگیری فرآیند استقرار پایگاه‌های داده را در کوبرنتیز ساده می‌کنند، اما برای برنامه‌های ساده و بدون وضعیت (Stateless) مانند وب‌سرورها ضروری نیستند.

۴. استقرار در چندین کلاستر

اگر یک برنامه عمومی را در چندین کلاستر مستقر می‌کنید، اپراتورها بسیار مفید هستند. اما برای کدهای اختصاصی خود بهتر است از جایگزین‌هایی مانند Helm Chart استفاده کنید.

مثال‌هایی از اپراتورهای کوبرنتیز

Postgres Operator

۱. اپراتور Postgres

این اپراتور به شما امکان می‌دهد با استفاده از یک مانیفست YAML ساده، یک نمونه از Postgres با ذخیره‌سازی پایدار و تنظیمات از پیش پیکربندی‌شده ایجاد کنید:

				
					apiVersion: acid.zalan.do/v1
kind: postgresql
metadata:
  name: postgres-cluster
spec:
  volume:
    size: 1Gi
  numberOfInstances: 3
  users:
    demo-user:
      - superuser
      - createdb
  databases:
    demo-user: demo-db
  postgresql:
    version: &quot15&quot
				
			

۲. اپراتور MySQL

اپراتور MySQL فرآیند استقرار نمونه‌های MySQL را ساده می‌کند. با ایجاد آبجکت InnoDBCluster، اپراتور مدیریت پایگاه داده، کشف شبکه و مسیر‌یابی ترافیک را خودکار می‌کند.

				
					apiVersion: mysql.oracle.com/v2
kind: InnoDBCluster
metadata:
  name: demo-db
spec:
  secretName: mysql-creds
  tlsUseSelfSigned: true
  instances: 3
  router:
    instances: 1
				
			

۳. اپراتور Prometheus

این اپراتور استقرار و مدیریت Prometheus را که یک دیتابیس time series برای مانیتورینگ است، خودکار می‌کند.

۴. اپراتور Istio

اپراتور Istio مدیریت و پیکربندی سرویس مش را ساده می‌کند. با ایجاد یک آبجکت IstioOperator، می‌توانید تنظیمات سرویس مش را مدیریت کنید.

چگونه یک اپراتور کوبرنتیز ایجاد کنیم؟

اپراتورها را می‌توان با استفاده از هر زبان برنامه‌نویسی که با API کوبرنتیز تعامل دارد، ایجاد کرد. کتابخانه‌های رسمی برای زبان‌هایی مانند Go، Python، Java و Ruby موجود هستند.

۱. Operator Framework

ابزار Operator Framework یک کیت اوپن سورس است که به شما در نوشتن اپراتورهای پایدار کمک می‌کند. این ابزار شامل یک SDK است که فرآیند ساخت، آزمایش و بسته‌بندی اپراتورها را تسهیل می‌کند.

۲. Operator SDK

موردی بعدی Operator SDK هست که یک ابزار توسعه اپراتور است که از زبان‌های زیر پشتیبانی می‌کند:

  • Go:

برای توسعه‌دهندگانی که به اکوسیستم Go تسلط دارند.

  • Ansible:

برای کاربرانی که با اتوماسیون Ansible آشنا هستند.

  • Helm:

برای ساخت اپراتورها بر اساس Helm Chart های موجود.

دیدیم که اپراتورها قابلیت‌های خاص برنامه را به کوبرنتیز اضافه می‌کنند، اونها پیچیدگی استقرار برنامه‌های پیشرفته را کاهش داده و به کاربران اجازه می‌دهند روی پیکربندی برنامه تمرکز کنند همچنین ابزارهایی مانند Operator SDK و Helm فرآیند ایجاد اپراتورها را تسهیل می‌کنند.

توی بلاگ پست‌های بعدی مطالب مربوط به کوبرنتیز رو ادامه میدیم و بیشتر با هم یاد می‌گیریم.

مراقب خودتون باشید. 🌹🐳🌹

دیدگاه‌ خود را بنویسید

مقاله های داکرمی

Kubernetes

نصب کلاستر با kubespray (قسمت هجدهم)

توی این قسمت میریم سراغ اینکه بررسی کنیم چطوری می‌تونیم یه کلاستر کوبرنتیز رو با استفاده از kubespray ستاپ کنیم و بیاریم بالا. روشی که می‌تونیم باهاش کلاستر پروداکش رو ستاپ و نگهداری کنیم. خب یه مروری کنیم پست‌های قبلی

توضیحات بیشتر »
Kubernetes

نصب کلاستر با kubeadm (قسمت هفدهم)

توی این قسمت میریم به سراغ اینکه بررسی کنیم چطوری می‌تونیم یه کلاستر کوبرنتیز رو با استفاده از kubeadm ستاپ کنیم و بیاریم بالا. خب یه مروری کنیم پست‌های قبلی رو: دواپس چیه و چرا لازمه؟ اینجا در مورد دواپس و

توضیحات بیشتر »
Kubernetes

سی آر دی و اُپراتور (قسمت شانزدهم)

توی این قسمت میریم به سراغ اینکه بررسی کنیم چطوری می‌تونیم ریسورس‌های خودمون رو به صورت کاستوم شده توی کوبرنتیز تعریف کنیم و بعدش هم در مورد اُپراتورها توی کوبرنتیز توضیح می‌دیم. خب یه مروری کنیم پست‌های قبلی رو: دواپس

توضیحات بیشتر »
پیمایش به بالا