ساخت فایل Kubernetes با هوش مصنوعی؛ آموزش تولید، اعتبارسنجی و عیب‌یابی Manifestهای K8s

در این آموزش Manifestهای واقعی Kubernetes را با کمک هوش مصنوعی می‌سازیم، با قواعد قطعی و kubectl اعتبارسنجی می‌کنیم و خطاهای Deployment و Pod را تحلیل می‌کنیم.

Share
ساخت فایل Kubernetes با هوش مصنوعی؛ آموزش تولید، اعتبارسنجی و عیب‌یابی Manifestهای K8s

نوشتن فایل‌های Kubernetes در نگاه اول ساده است. یک Deployment، یک Service و چند مقدار YAML تعریف می‌کنیم و برنامه اجرا می‌شود. اما در پروژه واقعی، اشتباه کوچکی در Label، Selector، Port، Health Probe، Resource Request یا نام ConfigMap می‌تواند باعث شود برنامه:

  • اصلاً Deploy نشود.
  • در وضعیت Pending باقی بماند.
  • دائماً Restart شود.
  • ترافیک دریافت نکند.
  • Rollout را کامل نکند.
  • با خطای CrashLoopBackOff متوقف شود.
  • با وجود Running بودن، از طریق Service دردسترس نباشد.
  • در زمان افزایش بار رفتار نامناسبی داشته باشد.

مدل‌های هوش مصنوعی می‌توانند براساس توضیح پروژه، نسخه اولیه Kubernetes Manifest را تولید یا فایل‌های موجود را بازبینی کنند. بااین‌حال، خروجی مدل نباید مستقیماً روی Cluster اجرا شود.

معماری مناسب چنین است:

مشخصات قطعی برنامه
    ↓
تولید Manifest توسط مدل
    ↓
Parse کردن YAML
    ↓
اعتبارسنجی قواعد پروژه
    ↓
kubectl Dry Run
    ↓
مشاهده Diff
    ↓
Apply در محیط آزمایشی
    ↓
Rollout Status
    ↓
Smoke Test
    ↓
انتشار کنترل‌شده

در این مقاله یک پروژه واقعی برای استقرار FastAPI می‌سازیم و یاد می‌گیریم چگونه API هوش مصنوعی درواره را به ابزار بازبینی و عیب‌یابی Kubernetes متصل کنیم.

Kubernetes چیست؟

Kubernetes یا K8s یک پلتفرم مدیریت برنامه‌های Containerized است. Kubernetes وضعیت مطلوب برنامه را از Manifest دریافت می‌کند و تلاش می‌کند وضعیت واقعی Cluster را با آن هماهنگ نگه دارد.

برای مثال، اگر در Deployment تعداد Replicaها را سه قرار دهیم:

spec:
  replicas: 3

Kubernetes تلاش می‌کند سه Pod مطابق Pod Template ایجاد و نگهداری کند.

اگر یک Pod متوقف شود، Controller می‌تواند Pod جایگزین بسازد. اگر نسخه Image تغییر کند، Deployment می‌تواند Rollout جدیدی اجرا کند.

Manifest در Kubernetes چیست؟

Manifest یک فایل YAML یا JSON است که یک یا چند Kubernetes Object را تعریف می‌کند.

نمونه Pod:

apiVersion: v1
kind: Pod
metadata:
  name: example-api
spec:
  containers:
    - name: api
      image: registry.example.com/example-api:1.0.0
      ports:
        - containerPort: 8000

برای پروژه‌های واقعی معمولاً به‌جای ساخت مستقیم Pod از Resourceهایی مانند Deployment استفاده می‌شود.

Manifestهای رایج:

  • Namespace
  • Deployment
  • StatefulSet
  • DaemonSet
  • Service
  • ConfigMap
  • Job
  • CronJob
  • HorizontalPodAutoscaler
  • Ingress
  • PersistentVolumeClaim

هر Resource دارای apiVersion، kind، metadata و spec مخصوص خود است.

هوش مصنوعی در Kubernetes چه کاربردی دارد؟

هوش مصنوعی می‌تواند در کارهای زیر مفید باشد:

  • تولید نسخه اولیه Manifest
  • تبدیل مشخصات برنامه به Deployment
  • پیشنهاد Service
  • افزودن Readiness و Liveness Probe
  • بررسی هماهنگی Label و Selector
  • شناسایی Portهای ناسازگار
  • توضیح خطاهای Pod
  • تحلیل Events
  • تحلیل خروجی kubectl describe
  • خلاصه‌کردن Logهای طولانی
  • پیشنهاد مراحل تشخیصی
  • تولید Kustomize Overlay
  • تحلیل تفاوت دو Manifest
  • بررسی Resource Request و Limit
  • تولید مستندات استقرار

اما مدل نباید:

  • نام Image را حدس بزند.
  • Port برنامه را اختراع کند.
  • بدون داده واقعی مقدار منابع را قطعی اعلام کند.
  • نام ConfigMap یا Environment Variable جدید بسازد.
  • Command ناشناخته را جایگزین Entry Point کند.
  • Manifest را بدون Validation روی Cluster اعمال کند.

چرا Prompt ساده کافی نیست؟

این Prompt اطلاعات کافی ندارد:

برای برنامه من فایل Kubernetes بساز.

مدل مجبور می‌شود موارد زیر را حدس بزند:

  • نام برنامه
  • Image
  • Tag
  • Container Port
  • Replica Count
  • Health Endpoint
  • Environment Variableها
  • CPU و Memory
  • Namespace
  • نوع Service
  • دستور اجرای Container

Prompt باید از یک Application Manifest ساختاریافته تغذیه شود.

پروژه عملی

فرض می‌کنیم یک برنامه FastAPI داریم که قبلاً داخل Docker Image قرار گرفته است.

مشخصات برنامه:

{
  "applicationName": "catalog-api",
  "namespace": "catalog",
  "image": "registry.example.com/catalog-api:1.0.0",
  "containerPort": 8000,
  "replicas": 2,
  "healthEndpoints": {
    "startup": "/health/startup",
    "readiness": "/health/ready",
    "liveness": "/health/live"
  },
  "environmentVariables": {
    "APP_ENV": "production",
    "LOG_LEVEL": "info"
  },
  "resources": {
    "requests": {
      "cpu": "100m",
      "memory": "128Mi"
    },
    "limits": {
      "cpu": "500m",
      "memory": "512Mi"
    }
  }
}

این اطلاعات را در فایل application-manifest.json ذخیره می‌کنیم.

ساختار پروژه:

kubernetes-ai-assistant/
├── application-manifest.json
├── requirements.txt
├── .env
├── k8s/
│   ├── namespace.yaml
│   ├── configmap.yaml
│   ├── deployment.yaml
│   ├── service.yaml
│   └── hpa.yaml
├── scripts/
│   ├── validate_manifests.py
│   ├── review_manifests.py
│   └── analyze_kubernetes_failure.py
├── diagnostics/
└── ai-output/

پیش‌نیازها

برای انجام این آموزش به موارد زیر نیاز دارید:

  • Python 3.11 یا جدیدتر
  • Docker Image قابل اجرا
  • kubectl
  • دسترسی به Cluster آزمایشی یا محلی
  • کلید API درواره

برای تمرین محلی می‌توانید از یک Kubernetes Cluster محلی استفاده کنید. هدف این مقاله وابسته به ارائه‌دهنده خاصی نیست.

ساخت Namespace

فایل k8s/namespace.yaml:

apiVersion: v1
kind: Namespace
metadata:
  name: catalog
  labels:
    app.kubernetes.io/part-of: catalog-platform

Namespace منابع پروژه را از سایر برنامه‌های Cluster جدا می‌کند.

اعتبارسنجی اولیه:

kubectl apply \
  --dry-run=client \
  -f k8s/namespace.yaml

ساخت ConfigMap

فایل k8s/configmap.yaml:

apiVersion: v1
kind: ConfigMap
metadata:
  name: catalog-api-config
  namespace: catalog
  labels:
    app.kubernetes.io/name: catalog-api
    app.kubernetes.io/component: backend
data:
  APP_ENV: production
  LOG_LEVEL: info

ConfigMap برای تنظیمات غیرحساس برنامه مناسب است.

در Deployment می‌توان تمام مقادیر آن را وارد Environment کرد:

envFrom:
  - configMapRef:
      name: catalog-api-config

ساخت Deployment کامل

فایل k8s/deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: catalog-api
  namespace: catalog
  labels:
    app.kubernetes.io/name: catalog-api
    app.kubernetes.io/component: backend
    app.kubernetes.io/part-of: catalog-platform
spec:
  replicas: 2

  revisionHistoryLimit: 5

  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 0
      maxSurge: 1

  selector:
    matchLabels:
      app.kubernetes.io/name: catalog-api

  template:
    metadata:
      labels:
        app.kubernetes.io/name: catalog-api
        app.kubernetes.io/component: backend
        app.kubernetes.io/part-of: catalog-platform

    spec:
      terminationGracePeriodSeconds: 30

      containers:
        - name: catalog-api
          image: registry.example.com/catalog-api:1.0.0
          imagePullPolicy: IfNotPresent

          ports:
            - name: http
              containerPort: 8000
              protocol: TCP

          envFrom:
            - configMapRef:
                name: catalog-api-config

          startupProbe:
            httpGet:
              path: /health/startup
              port: http
            periodSeconds: 5
            timeoutSeconds: 2
            failureThreshold: 30

          readinessProbe:
            httpGet:
              path: /health/ready
              port: http
            periodSeconds: 5
            timeoutSeconds: 2
            failureThreshold: 3
            successThreshold: 1

          livenessProbe:
            httpGet:
              path: /health/live
              port: http
            periodSeconds: 10
            timeoutSeconds: 2
            failureThreshold: 3

          resources:
            requests:
              cpu: 100m
              memory: 128Mi
            limits:
              cpu: 500m
              memory: 512Mi

هماهنگی Selector و Label

این بخش Deployment:

selector:
  matchLabels:
    app.kubernetes.io/name: catalog-api

باید با Label موجود در Pod Template هماهنگ باشد:

template:
  metadata:
    labels:
      app.kubernetes.io/name: catalog-api

اگر مدل یکی از مقادیر را متفاوت تولید کند، Deployment معتبر نخواهد بود یا Resourceهای مرتبط Podهای موردنظر را پیدا نمی‌کنند.

تفاوت Startup، Readiness و Liveness Probe

Kubernetes سه Probe مهم دارد.

Startup Probe

بررسی می‌کند برنامه فرایند راه‌اندازی را کامل کرده است یا نه. تا زمانی که Startup Probe موفق نشده باشد، Liveness و Readiness Probe آغاز نمی‌شوند.

Readiness Probe

مشخص می‌کند Pod آماده دریافت ترافیک است یا خیر. اگر Readiness ناموفق باشد، Pod از Endpointهای Service کنار گذاشته می‌شود.

Liveness Probe

مشخص می‌کند Container هنوز سالم و قادر به ادامه کار است یا باید Restart شود.

براساس مستندات رسمی Probeهای Kubernetes، Readiness برای آمادگی دریافت ترافیک و Liveness برای تشخیص نیاز به Restart استفاده می‌شود. Startup Probe نیز برای برنامه‌هایی مفید است که زمان بیشتری برای شروع نیاز دارند.

نباید هر سه Probe را بدون توجه به رفتار واقعی برنامه روی یک Endpoint نامناسب قرار داد.

محاسبه زمان مجاز Startup

در نمونه ما:

startupProbe:
  periodSeconds: 5
  failureThreshold: 30

حداکثر زمان تقریبی مجاز:

startup_window = periodSeconds × failureThreshold

در این مثال:

startup_window = 5 × 30 = 150 seconds

این فرمول با متن ساده نوشته شده تا در ویرایشگر Ghost درست نمایش داده شود.

ساخت Health Endpointهای FastAPI

برنامه باید Endpointهای تعریف‌شده در Manifest را واقعاً داشته باشد.

نمونه:

from fastapi import FastAPI


app = FastAPI()


@app.get("/health/startup")
def startup_health() -> dict[str, str]:
    return {
        "status": "started"
    }


@app.get("/health/live")
def liveness_health() -> dict[str, str]:
    return {
        "status": "alive"
    }


@app.get("/health/ready")
def readiness_health() -> dict[str, str]:
    dependencies_ready = True

    if not dependencies_ready:
        return {
            "status": "not_ready"
        }

    return {
        "status": "ready"
    }

در پیاده‌سازی واقعی، Endpoint آمادگی باید وضعیت Dependencyهایی را بررسی کند که برای پاسخ‌دادن برنامه ضروری‌اند. Liveness نباید صرفاً به‌دلیل اختلال موقت یک سرویس خارجی باعث Restart پی‌درپی Container شود.

تنظیم Resource Request و Limit

در Deployment:

resources:
  requests:
    cpu: 100m
    memory: 128Mi
  limits:
    cpu: 500m
    memory: 512Mi

Request

مقداری است که Scheduler برای قرار‌دادن Pod روی Node در نظر می‌گیرد.

Limit

حد بالایی است که Container برای Resource مشخص می‌تواند مصرف کند.

طبق مستندات رسمی مدیریت منابع Kubernetes، Requestها در زمان Scheduling استفاده می‌شوند و CPU و Memory دارای واحدهای متفاوت هستند.

نمونه CPU:

100m = 0.1 CPU
500m = 0.5 CPU

نمونه Memory:

128Mi
512Mi
1Gi

به حروف کوچک و بزرگ توجه کنید:

400Mi

با مقدار زیر یکسان نیست:

400m

مقادیر نهایی باید براساس اندازه‌گیری مصرف واقعی برنامه تعیین شوند، نه حدس مدل.

ساخت Service

فایل k8s/service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: catalog-api
  namespace: catalog
  labels:
    app.kubernetes.io/name: catalog-api
    app.kubernetes.io/component: backend
spec:
  type: ClusterIP

  selector:
    app.kubernetes.io/name: catalog-api

  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: http

Service روی Port داخلی 80 درخواست دریافت می‌کند و آن را به Port نام‌گذاری‌شده http در Container می‌فرستد:

ports:
  - name: http
    containerPort: 8000

مزیت استفاده از نام Port این است که Service به عدد تکرارشده وابسته نیست:

targetPort: http

مشکل رایج Selector در Service

اگر Deployment دارای این Label باشد:

app.kubernetes.io/name: catalog-api

اما Service چنین Selectorی داشته باشد:

selector:
  app.kubernetes.io/name: catalog-service

Service هیچ Podی پیدا نمی‌کند.

بررسی Endpointها:

kubectl get endpoints \
  catalog-api \
  --namespace catalog

یا:

kubectl get endpointslices \
  --namespace catalog \
  --selector=kubernetes.io/service-name=catalog-api

اگر Endpointی وجود نداشته باشد، اولین بررسی باید هماهنگی Selector و Label باشد.

ساخت HorizontalPodAutoscaler

فایل k8s/hpa.yaml:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: catalog-api
  namespace: catalog
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: catalog-api

  minReplicas: 2
  maxReplicas: 8

  behavior:
    scaleDown:
      stabilizationWindowSeconds: 300

  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70

این HPA برای کارکردن به زیرساخت Metrics سازگار نیاز دارد.

مقدار averageUtilization نسبت به CPU Request محاسبه می‌شود. به همین دلیل تعریف Request در Deployment اهمیت دارد.

هوش مصنوعی می‌تواند فایل HPA پیشنهاد دهد، اما مقدارهای minReplicas، maxReplicas و Target باید براساس الگوی بار و ظرفیت سیستم انتخاب شوند.

اعتبارسنجی قطعی Manifestها با Python

پیش از استفاده از مدل، چند خطای پرتکرار را با کد قطعی بررسی می‌کنیم.

فایل requirements.txt:

PyYAML
openai
python-dotenv
pydantic

نصب:

python -m pip install \
  -r requirements.txt

فایل scripts/validate_manifests.py:

from __future__ import annotations

from pathlib import Path
from typing import Any

import yaml


ALLOWED_KINDS = {
    "Namespace",
    "ConfigMap",
    "Deployment",
    "Service",
    "HorizontalPodAutoscaler",
}


def load_documents() -> list[dict[str, Any]]:
    documents: list[dict[str, Any]] = []

    for path in sorted(
        Path("k8s").glob("*.yaml")
    ):
        content = path.read_text(
            encoding="utf-8"
        )

        for index, document in enumerate(
            yaml.safe_load_all(content)
        ):
            if document is None:
                continue

            if not isinstance(document, dict):
                raise ValueError(
                    f"{path}:{index + 1} "
                    "must contain an object"
                )

            document["_sourceFile"] = str(path)
            documents.append(document)

    return documents


def resource_key(
    document: dict[str, Any],
) -> tuple[str, str, str]:
    metadata = document.get(
        "metadata",
        {},
    )

    return (
        document.get("kind", ""),
        metadata.get("namespace", "default"),
        metadata.get("name", ""),
    )


def get_resource(
    documents: list[dict[str, Any]],
    kind: str,
    name: str,
    namespace: str,
) -> dict[str, Any] | None:
    for document in documents:
        if resource_key(document) == (
            kind,
            namespace,
            name,
        ):
            return document

    return None


def validate_deployment(
    deployment: dict[str, Any],
) -> list[str]:
    errors: list[str] = []

    spec = deployment.get("spec", {})
    selector = (
        spec.get("selector", {})
        .get("matchLabels", {})
    )
    pod_labels = (
        spec.get("template", {})
        .get("metadata", {})
        .get("labels", {})
    )

    for key, value in selector.items():
        if pod_labels.get(key) != value:
            errors.append(
                "Deployment selector does not "
                f"match pod label: {key}={value}"
            )

    containers = (
        spec.get("template", {})
        .get("spec", {})
        .get("containers", [])
    )

    if not containers:
        errors.append(
            "Deployment has no containers"
        )
        return errors

    for container in containers:
        name = container.get(
            "name",
            "<unnamed>",
        )

        image = container.get("image", "")

        if not image:
            errors.append(
                f"Container {name} has no image"
            )
        elif image.endswith(":latest"):
            errors.append(
                f"Container {name} uses latest tag"
            )

        if "readinessProbe" not in container:
            errors.append(
                f"Container {name} has no "
                "readinessProbe"
            )

        if "livenessProbe" not in container:
            errors.append(
                f"Container {name} has no "
                "livenessProbe"
            )

        resources = container.get(
            "resources",
            {},
        )

        if not resources.get("requests"):
            errors.append(
                f"Container {name} has no "
                "resource requests"
            )

        if not resources.get("limits"):
            errors.append(
                f"Container {name} has no "
                "resource limits"
            )

    return errors


def validate_service(
    service: dict[str, Any],
    deployments: list[dict[str, Any]],
) -> list[str]:
    errors: list[str] = []

    selector = service.get(
        "spec",
        {},
    ).get("selector", {})

    if not selector:
        errors.append(
            "Service has no selector"
        )
        return errors

    matched_deployment = False
    available_port_names: set[str] = set()

    for deployment in deployments:
        pod_labels = (
            deployment.get("spec", {})
            .get("template", {})
            .get("metadata", {})
            .get("labels", {})
        )

        matches = all(
            pod_labels.get(key) == value
            for key, value in selector.items()
        )

        if not matches:
            continue

        matched_deployment = True

        containers = (
            deployment.get("spec", {})
            .get("template", {})
            .get("spec", {})
            .get("containers", [])
        )

        for container in containers:
            for port in container.get(
                "ports",
                [],
            ):
                port_name = port.get("name")

                if port_name:
                    available_port_names.add(
                        port_name
                    )

    if not matched_deployment:
        errors.append(
            "Service selector does not match "
            "any Deployment pod template"
        )

    service_ports = (
        service.get("spec", {})
        .get("ports", [])
    )

    for port in service_ports:
        target_port = port.get(
            "targetPort"
        )

        if (
            isinstance(target_port, str)
            and target_port
            not in available_port_names
        ):
            errors.append(
                "Service targetPort references "
                f"unknown named port: {target_port}"
            )

    return errors


def main() -> None:
    documents = load_documents()
    errors: list[str] = []

    for document in documents:
        kind = document.get("kind")
        source_file = document.get(
            "_sourceFile",
            "<unknown>",
        )

        if kind not in ALLOWED_KINDS:
            errors.append(
                f"{source_file}: "
                f"kind {kind} is not allowed"
            )

        metadata = document.get(
            "metadata",
            {},
        )

        if not metadata.get("name"):
            errors.append(
                f"{source_file}: "
                "metadata.name is required"
            )

    deployments = [
        document
        for document in documents
        if document.get("kind")
        == "Deployment"
    ]

    services = [
        document
        for document in documents
        if document.get("kind")
        == "Service"
    ]

    for deployment in deployments:
        errors.extend(
            validate_deployment(
                deployment
            )
        )

    for service in services:
        errors.extend(
            validate_service(
                service,
                deployments,
            )
        )

    config_map = get_resource(
        documents,
        kind="ConfigMap",
        name="catalog-api-config",
        namespace="catalog",
    )

    if config_map is None:
        errors.append(
            "Required ConfigMap "
            "catalog/catalog-api-config "
            "was not found"
        )

    if errors:
        print("Manifest validation failed:")

        for error in errors:
            print(f"- {error}")

        raise SystemExit(1)

    print(
        f"Validated {len(documents)} "
        "Kubernetes resources"
    )


if __name__ == "__main__":
    main()

اجرا:

python scripts/validate_manifests.py

این Validator چه چیزهایی را بررسی می‌کند؟

  • YAML قابل Parse است.
  • Resource Kind مجاز است.
  • هر Resource نام دارد.
  • Selector مربوط به Deployment با Pod Label هماهنگ است.
  • Deployment دارای Container است.
  • Image مشخص است.
  • از Tag مبهم latest استفاده نشده است.
  • Readiness و Liveness Probe وجود دارند.
  • Resource Request و Limit تعریف شده‌اند.
  • Selector مربوط به Service حداقل یک Deployment را پیدا می‌کند.
  • targetPort نام‌گذاری‌شده در Container وجود دارد.
  • ConfigMap موردنیاز تعریف شده است.

این بررسی‌ها کامل نیستند، اما بسیاری از خطاهای پرتکرار را پیش از اتصال به Cluster پیدا می‌کنند.

اعتبارسنجی با kubectl

ابتدا Dry Run سمت Client:

kubectl apply \
  --dry-run=client \
  --validate=strict \
  -f k8s/

اگر به Cluster آزمایشی متصل هستید، Server-side Dry Run دقیق‌تر است:

kubectl apply \
  --dry-run=server \
  --validate=strict \
  -f k8s/

طبق مرجع رسمی kubectl apply، حالت client شیء قابل ارسال را بدون ارسال واقعی تولید می‌کند و حالت server درخواست را به‌شکل Dry Run به API Server می‌فرستد، بدون اینکه Resource ذخیره شود.

مشاهده Diff پیش از Apply

kubectl diff -f k8s/

kubectl diff تفاوت میان Manifest جدید و وضعیت موجود Cluster را نشان می‌دهد. مستندات Kubernetes نیز استفاده از Diff پیش از Apply را در مدیریت Declarative توضیح می‌دهد. مدیریت Declarative منابع Kubernetes

کد خروجی غیرصفر kubectl diff همیشه به معنی خطا نیست؛ وجود تفاوت نیز می‌تواند Exit Code متفاوتی ایجاد کند. در CI باید تفاوت و خطای واقعی از هم جدا شوند.

اعمال Manifestها

ترتیب مناسب:

kubectl apply \
  -f k8s/namespace.yaml

kubectl apply \
  -f k8s/configmap.yaml

kubectl apply \
  -f k8s/deployment.yaml

kubectl apply \
  -f k8s/service.yaml

kubectl apply \
  -f k8s/hpa.yaml

یا:

kubectl apply -f k8s/

اگر میان Resourceها وابستگی ترتیبی مهمی دارید، اجرای صریح فایل‌ها قابل‌فهم‌تر است.

بررسی Rollout

kubectl rollout status \
  deployment/catalog-api \
  --namespace catalog \
  --timeout=180s

طبق مستندات رسمی kubectl rollout status، این دستور وضعیت جدیدترین Rollout را دنبال می‌کند تا کامل شود یا Timeout رخ دهد.

مشاهده Deployment:

kubectl get deployment \
  catalog-api \
  --namespace catalog

مشاهده Podها:

kubectl get pods \
  --namespace catalog \
  --selector=app.kubernetes.io/name=catalog-api

مشاهده Service:

kubectl get service \
  catalog-api \
  --namespace catalog

تست محلی Service با Port Forward

kubectl port-forward \
  --namespace catalog \
  service/catalog-api \
  8080:80

سپس:

curl http://localhost:8080/health/ready

خروجی:

{
  "status": "ready"
}

اتصال هوش مصنوعی به فرایند Review

مدل باید Manifest، Application Manifest و نتیجه Validator را دریافت کند و یک گزارش ساختاریافته بسازد.

فایل .env:

DARVAREH_API_KEY=YOUR_DARVAREH_API_KEY
DARVAREH_MODEL=MODEL_ID_DARVAREH

برای دریافت کلید، در درواره ثبت‌نام کنید. Model ID و قیمت به‌روز را در صفحه مدل‌ها ببینید.

ساخت Kubernetes Manifest Reviewer

فایل scripts/review_manifests.py:

from __future__ import annotations

import json
import os
from pathlib import Path
from typing import Literal

from openai import OpenAI
from pydantic import BaseModel, Field


class Finding(BaseModel):
    file: str
    resource_kind: str
    resource_name: str
    severity: Literal[
        "low",
        "medium",
        "high",
    ]
    category: str
    explanation: str
    evidence: list[str] = Field(
        default_factory=list
    )
    recommendation: str
    needs_measurement: bool = False


class ManifestReview(BaseModel):
    valid_for_application: bool
    summary: str
    findings: list[Finding] = Field(
        default_factory=list
    )
    missing_information: list[str] = Field(
        default_factory=list
    )
    invented_assumptions: list[str] = Field(
        default_factory=list
    )


def read_text(path: Path) -> str:
    return path.read_text(
        encoding="utf-8"
    )


def load_manifests() -> dict[str, str]:
    return {
        str(path): read_text(path)
        for path in sorted(
            Path("k8s").glob("*.yaml")
        )
    }


def strip_code_fence(value: str) -> str:
    text = value.strip()

    if not text.startswith("```"):
        return text

    lines = text.splitlines()
    content = "\n".join(
        lines[1:-1]
    ).strip()

    if content.startswith("json"):
        content = content[4:].lstrip()

    return content


def main() -> None:
    application_manifest = json.loads(
        read_text(
            Path(
                "application-manifest.json"
            )
        )
    )

    manifests = load_manifests()
    allowed_files = set(manifests)

    client = OpenAI(
        api_key=os.environ[
            "DARVAREH_API_KEY"
        ],
        base_url="https://api.darvareh.ir/v1",
    )

    model_id = os.environ.get(
        "DARVAREH_MODEL",
        "MODEL_ID_DARVAREH",
    )

    response = client.chat.completions.create(
        model=model_id,
        temperature=0.1,
        messages=[
            {
                "role": "system",
                "content": (
                    "You are a Kubernetes manifest "
                    "reviewer. The application manifest "
                    "is the only source of application "
                    "facts. Do not invent images, tags, "
                    "ports, health endpoints, environment "
                    "variables, namespaces, commands, "
                    "dependencies, or resource usage. "
                    "Return valid JSON only."
                ),
            },
            {
                "role": "user",
                "content": json.dumps(
                    {
                        "task": (
                            "Review these Kubernetes "
                            "manifests for consistency "
                            "with the application manifest, "
                            "selector and label alignment, "
                            "ports, probes, resources, "
                            "rollout behavior, and "
                            "maintainability."
                        ),
                        "rules": [
                            (
                                "Do not claim resource "
                                "values are correct without "
                                "runtime measurements."
                            ),
                            (
                                "Reference only files "
                                "provided in the input."
                            ),
                            (
                                "Cite exact YAML evidence "
                                "for every finding."
                            ),
                            (
                                "Do not generate kubectl "
                                "apply commands."
                            ),
                        ],
                        "requiredOutput": {
                            "valid_for_application": (
                                "boolean"
                            ),
                            "summary": "string",
                            "findings": [
                                {
                                    "file": "string",
                                    "resource_kind": "string",
                                    "resource_name": "string",
                                    "severity": (
                                        "low | medium | high"
                                    ),
                                    "category": "string",
                                    "explanation": "string",
                                    "evidence": ["string"],
                                    "recommendation": "string",
                                    "needs_measurement": (
                                        "boolean"
                                    )
                                }
                            ],
                            "missing_information": [
                                "string"
                            ],
                            "invented_assumptions": [
                                "string"
                            ]
                        },
                        "applicationManifest": (
                            application_manifest
                        ),
                        "kubernetesManifests": manifests,
                    },
                    ensure_ascii=False,
                ),
            },
        ],
    )

    content = response.choices[0].message.content

    if not content:
        raise RuntimeError(
            "Model returned an empty response"
        )

    parsed = json.loads(
        strip_code_fence(content)
    )

    review = ManifestReview.model_validate(
        parsed
    )

    invalid_files = {
        finding.file
        for finding in review.findings
        if finding.file not in allowed_files
    }

    if invalid_files:
        raise ValueError(
            "Model referenced unknown files: "
            + ", ".join(
                sorted(invalid_files)
            )
        )

    output_path = Path(
        "ai-output/manifest-review.json"
    )
    output_path.parent.mkdir(
        parents=True,
        exist_ok=True,
    )

    output_path.write_text(
        json.dumps(
            review.model_dump(),
            ensure_ascii=False,
            indent=2,
        ),
        encoding="utf-8",
    )

    print(
        f"Review saved to {output_path}"
    )


if __name__ == "__main__":
    main()

اجرا:

python scripts/review_manifests.py

نمونه گزارش هوش مصنوعی

{
  "valid_for_application": true,
  "summary": "The Deployment, Service and ConfigMap match the supplied application manifest.",
  "findings": [
    {
      "file": "k8s/deployment.yaml",
      "resource_kind": "Deployment",
      "resource_name": "catalog-api",
      "severity": "medium",
      "category": "resource-sizing",
      "explanation": "CPU and memory values match the application manifest, but their operational suitability cannot be confirmed from configuration alone.",
      "evidence": [
        "requests.cpu is 100m",
        "limits.memory is 512Mi"
      ],
      "recommendation": "Measure CPU and memory usage under representative load before finalizing these values.",
      "needs_measurement": true
    }
  ],
  "missing_information": [
    "Representative runtime resource measurements"
  ],
  "invented_assumptions": []
}

این خروجی نمی‌گوید مقدار 512Mi حتماً مناسب است؛ زیرا بدون داده مصرف واقعی چنین ادعایی قابل تأیید نیست.

تولید Manifest با هوش مصنوعی

اگر فایل Kubernetes ندارید، ابتدا از مدل بخواهید یک Plan بسازد:

{
  "resources": [
    {
      "kind": "Namespace",
      "name": "catalog"
    },
    {
      "kind": "ConfigMap",
      "name": "catalog-api-config"
    },
    {
      "kind": "Deployment",
      "name": "catalog-api"
    },
    {
      "kind": "Service",
      "name": "catalog-api"
    }
  ]
}

Plan را اعتبارسنجی کنید و سپس برای هر Resource فایل بسازید.

Prompt پیشنهادی:

براساس Application Manifest، فایل‌های Kubernetes تولید کن.

قوانین:
1. فقط Resource Kindهای Namespace، ConfigMap، Deployment و Service مجازند.
2. نام Image و Tag را دقیقاً از Manifest بردار.
3. Port جدید نساز.
4. Environment Variable جدید نساز.
5. نام Health Endpointها را تغییر نده.
6. Label اصلی تمام Resourceها app.kubernetes.io/name باشد.
7. Service Selector باید دقیقاً با Pod Label مطابقت داشته باشد.
8. targetPort باید از نام Port داخل Container استفاده کند.
9. از latest استفاده نکن.
10. هر فایل را در یک فیلد JSON جدا برگردان.
11. هیچ Resource دیگری تولید نکن.

بعد از تولید:

JSON Validation
    ↓
YAML Parse
    ↓
Project Validator
    ↓
kubectl Dry Run
    ↓
Human Review

عیب‌یابی CrashLoopBackOff

ابتدا وضعیت Podها:

kubectl get pods \
  --namespace catalog

جزئیات Pod:

kubectl describe pod \
  POD_NAME \
  --namespace catalog

Log اجرای فعلی:

kubectl logs \
  POD_NAME \
  --namespace catalog

اگر Container Restart شده است، Log اجرای قبلی:

kubectl logs \
  POD_NAME \
  --namespace catalog \
  --previous

اطلاعات مناسب برای مدل:

{
  "namespace": "catalog",
  "workload": "deployment/catalog-api",
  "podStatus": "CrashLoopBackOff",
  "containerName": "catalog-api",
  "restartCount": 6,
  "lastTermination": {
    "reason": "Error",
    "exitCode": 1
  },
  "events": [
    "Back-off restarting failed container"
  ],
  "recentLogs": [
    "RuntimeError: required configuration is missing"
  ]
}

اطلاعات حساس و نامرتبط را پیش از ارسال حذف کنید.

ساخت تحلیل‌گر خطای Kubernetes

فایل scripts/analyze_kubernetes_failure.py:

from __future__ import annotations

import json
import os
from pathlib import Path
from typing import Literal

from openai import OpenAI
from pydantic import BaseModel, Field


class Cause(BaseModel):
    cause: str
    confidence: Literal[
        "low",
        "medium",
        "high",
    ]
    evidence: list[str] = Field(
        default_factory=list
    )
    diagnostic_commands: list[str] = Field(
        default_factory=list
    )
    suggested_change: str | None = None


class FailureAnalysis(BaseModel):
    summary: str
    likely_layer: str
    causes: list[Cause] = Field(
        default_factory=list
    )
    missing_information: list[str] = Field(
        default_factory=list
    )


ALLOWED_COMMAND_PREFIXES = (
    "kubectl get ",
    "kubectl describe ",
    "kubectl logs ",
    "kubectl rollout status ",
)


def read_json(path: str) -> dict:
    return json.loads(
        Path(path).read_text(
            encoding="utf-8"
        )
    )


def strip_code_fence(value: str) -> str:
    text = value.strip()

    if not text.startswith("```"):
        return text

    lines = text.splitlines()
    content = "\n".join(
        lines[1:-1]
    ).strip()

    if content.startswith("json"):
        content = content[4:].lstrip()

    return content


def main() -> None:
    diagnostic = read_json(
        "diagnostics/failure.json"
    )
    application_manifest = read_json(
        "application-manifest.json"
    )

    client = OpenAI(
        api_key=os.environ[
            "DARVAREH_API_KEY"
        ],
        base_url="https://api.darvareh.ir/v1",
    )

    response = client.chat.completions.create(
        model=os.environ.get(
            "DARVAREH_MODEL",
            "MODEL_ID_DARVAREH",
        ),
        temperature=0.1,
        messages=[
            {
                "role": "system",
                "content": (
                    "You are a Kubernetes failure "
                    "analyst. Use only supplied status, "
                    "events, logs, and application facts. "
                    "Do not invent cluster state, files, "
                    "containers, environment variables, "
                    "commands, or log lines. Return valid "
                    "JSON only."
                ),
            },
            {
                "role": "user",
                "content": json.dumps(
                    {
                        "task": (
                            "Rank the likely causes of this "
                            "Kubernetes failure. Cite exact "
                            "evidence and suggest read-only "
                            "diagnostic commands."
                        ),
                        "allowedCommandPrefixes": list(
                            ALLOWED_COMMAND_PREFIXES
                        ),
                        "requiredOutput": {
                            "summary": "string",
                            "likely_layer": "string",
                            "causes": [
                                {
                                    "cause": "string",
                                    "confidence": (
                                        "low | medium | high"
                                    ),
                                    "evidence": ["string"],
                                    "diagnostic_commands": [
                                        "string"
                                    ],
                                    "suggested_change": (
                                        "string or null"
                                    )
                                }
                            ],
                            "missing_information": [
                                "string"
                            ]
                        },
                        "application": (
                            application_manifest
                        ),
                        "diagnostic": diagnostic,
                    },
                    ensure_ascii=False,
                ),
            },
        ],
    )

    content = response.choices[0].message.content

    if not content:
        raise RuntimeError(
            "Model returned an empty response"
        )

    parsed = json.loads(
        strip_code_fence(content)
    )

    analysis = (
        FailureAnalysis.model_validate(
            parsed
        )
    )

    for cause in analysis.causes:
        for command in (
            cause.diagnostic_commands
        ):
            if not command.startswith(
                ALLOWED_COMMAND_PREFIXES
            ):
                raise ValueError(
                    "Model suggested a command "
                    f"outside the allowlist: {command}"
                )

    output_path = Path(
        "ai-output/failure-analysis.json"
    )
    output_path.parent.mkdir(
        parents=True,
        exist_ok=True,
    )

    output_path.write_text(
        json.dumps(
            analysis.model_dump(),
            ensure_ascii=False,
            indent=2,
        ),
        encoding="utf-8",
    )


if __name__ == "__main__":
    main()

تشخیص چند خطای رایج Kubernetes

ImagePullBackOff

بررسی:

kubectl describe pod \
  POD_NAME \
  --namespace catalog

موارد احتمالی:

  • نام Image اشتباه است.
  • Tag موردنظر وجود ندارد.
  • Registry دردسترس نیست.
  • تنظیم موردنیاز برای دریافت Image کامل نیست.

مدل باید دقیقاً از Eventها برای انتخاب علت استفاده کند.

CrashLoopBackOff

بررسی:

kubectl logs \
  POD_NAME \
  --namespace catalog \
  --previous

موارد احتمالی:

  • برنامه بلافاصله Exit می‌کند.
  • تنظیم موردنیاز وجود ندارد.
  • Entry Point اشتباه است.
  • Liveness Probe نامناسب است.
  • Dependency برنامه آماده نیست.

Pending

بررسی:

kubectl describe pod \
  POD_NAME \
  --namespace catalog

موارد احتمالی:

  • Resource Request قابل تأمین نیست.
  • محدودیت Scheduling وجود دارد.
  • Volume موردنیاز آماده نیست.
  • Node مناسب پیدا نمی‌شود.

Running ولی بدون ترافیک

بررسی:

kubectl get endpointslices \
  --namespace catalog \
  --selector=kubernetes.io/service-name=catalog-api

موارد احتمالی:

  • Selector سرویس اشتباه است.
  • Readiness Probe موفق نمی‌شود.
  • targetPort نادرست است.
  • برنامه روی Interface یا Port متفاوت گوش می‌دهد.

Rollout متوقف‌شده

بررسی:

kubectl rollout status \
  deployment/catalog-api \
  --namespace catalog \
  --timeout=180s

سپس:

kubectl get replicasets \
  --namespace catalog

و:

kubectl describe deployment \
  catalog-api \
  --namespace catalog

تحلیل Events

دریافت Eventهای Namespace:

kubectl get events \
  --namespace catalog \
  --sort-by=.metadata.creationTimestamp

برای مدل بهتر است فقط Eventهای مرتبط با Resource شکست‌خورده ارسال شوند.

نمونه ورودی:

{
  "kind": "Pod",
  "name": "catalog-api-example",
  "namespace": "catalog",
  "events": [
    {
      "type": "Warning",
      "reason": "Unhealthy",
      "message": "Readiness probe failed: HTTP probe failed with statuscode: 503"
    }
  ]
}

مدل در این حالت می‌تواند با اطمینان بیشتری مشکل را در مسیر Readiness بررسی کند.

Rollback کنترل‌شده

مشاهده تاریخچه:

kubectl rollout history \
  deployment/catalog-api \
  --namespace catalog

بازگشت به Revision قبلی:

kubectl rollout undo \
  deployment/catalog-api \
  --namespace catalog

بعد از Rollback:

kubectl rollout status \
  deployment/catalog-api \
  --namespace catalog \
  --timeout=180s

Rollback جای رفع علت اصلی را نمی‌گیرد. پس از پایدارشدن سرویس، تفاوت Manifest و علت شکست باید بررسی شود.

استفاده از Kustomize برای محیط‌ها

ساختار:

k8s/
├── base/
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── configmap.yaml
│   └── kustomization.yaml
└── overlays/
    ├── staging/
    │   └── kustomization.yaml
    └── production/
        └── kustomization.yaml

فایل k8s/base/kustomization.yaml:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
  - deployment.yaml
  - service.yaml
  - configmap.yaml

Overlay مربوط به Staging:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace: catalog-staging

resources:
  - ../../base

images:
  - name: registry.example.com/catalog-api
    newTag: 1.1.0-rc.1

replicas:
  - name: catalog-api
    count: 1

مشاهده خروجی:

kubectl kustomize \
  k8s/overlays/staging

Dry Run:

kubectl apply \
  --dry-run=client \
  -k k8s/overlays/staging

هوش مصنوعی می‌تواند Overlay پیشنهاد دهد، اما Base و Overlay نهایی باید Render و اعتبارسنجی شوند.

تست Manifest در CI

نمونه GitHub Actions:

name: Kubernetes manifests

on:
  pull_request:
    paths:
      - "k8s/**"
      - "scripts/validate_manifests.py"
      - "application-manifest.json"

  push:
    branches:
      - main
    paths:
      - "k8s/**"
      - "scripts/validate_manifests.py"
      - "application-manifest.json"

permissions:
  contents: read

jobs:
  validate:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v6

      - name: Set up Python
        uses: actions/setup-python@v6
        with:
          python-version: "3.13"
          cache: pip

      - name: Install dependencies
        run: |
          python -m pip install \
            -r requirements.txt

      - name: Validate project rules
        run: |
          python scripts/validate_manifests.py

      - name: Run kubectl client dry-run
        run: |
          kubectl apply \
            --dry-run=client \
            --validate=strict \
            -f k8s/

Server-side Validation باید روی Cluster آزمایشی انجام شود:

kubectl apply \
  --dry-run=server \
  --validate=strict \
  -f k8s/

افزودن AI Review به CI

      - name: Review manifests with AI
        env:
          DARVAREH_API_KEY: >-
            ${{ secrets.DARVAREH_API_KEY }}
          DARVAREH_MODEL: MODEL_ID_DARVAREH
        run: |
          python scripts/review_manifests.py

      - name: Upload AI review
        uses: actions/upload-artifact@v6
        with:
          name: kubernetes-ai-review
          path: ai-output/manifest-review.json
          retention-days: 14

بهتر است AI Review مانع جایگزینی Validation واقعی نشود. ابتدا بررسی‌های قطعی اجرا شوند و سپس مدل درباره کیفیت و ناسازگاری‌های معنایی گزارش دهد.

بهینه‌سازی هزینه فراخوانی مدل

برای هر Commit تمام Manifestها را ارسال نکنید.

روش‌های کاهش مصرف:

  • فقط فایل‌های تغییرکرده را ارسال کنید.
  • Application Manifest را Cache کنید.
  • YAML را Parse و فیلدهای غیرضروری را حذف کنید.
  • فقط Diff را همراه Context مرتبط ارسال کنید.
  • گزارش‌های قبلی را دوباره ارسال نکنید.
  • AI Review را فقط هنگام تغییر Deployment، Service یا HPA اجرا کنید.
  • برای Manifestهای ساده از مدل اقتصادی استفاده کنید.
  • خروجی را کوتاه و JSON نگه دارید.

ارزیابی کیفیت Kubernetes Reviewer

Dataset:

[
  {
    "id": "service-selector-mismatch",
    "input": {
      "deploymentLabel": "catalog-api",
      "serviceSelector": "catalog-service"
    },
    "expectedFindings": [
      "service-selector-mismatch"
    ]
  },
  {
    "id": "missing-readiness",
    "input": {
      "readinessProbe": null
    },
    "expectedFindings": [
      "missing-readiness-probe"
    ]
  },
  {
    "id": "unknown-target-port",
    "input": {
      "containerPortName": "http",
      "serviceTargetPort": "web"
    },
    "expectedFindings": [
      "unknown-named-port"
    ]
  }
]

معیارها:

  • نرخ تشخیص خطای واقعی
  • نرخ هشدار اشتباه
  • نرخ ارجاع به فایل ناموجود
  • نرخ ساخت Resource خیالی
  • دقت استناد به YAML
  • درصد خروجی JSON معتبر
  • هزینه متوسط هر Review
  • زمان پاسخ
  • درصد پیشنهادهایی که Validator تأیید می‌کند

اشتباهات رایج تولید Kubernetes YAML با AI

ندادن Application Manifest

بدون Image، Port، Probe و Environment Variable دقیق، مدل ناچار به حدس است.

استفاده مستقیم از خروجی مدل

خروجی باید Parse، Validate، Dry Run و Review شود.

استفاده از latest

این مقدار مبهم است:

image: example/app:latest

از Tag مشخص و قابل ردیابی استفاده کنید:

image: example/app:1.4.2

ناهماهنگی Labelها

Deployment، Service و ابزارهای Monitoring باید از Labelهای پایدار و هماهنگ استفاده کنند.

یکسان‌دانستن Readiness و Liveness

عدم آمادگی موقت همیشه به معنی نیاز به Restart نیست.

انتخاب Resource براساس حدس

مقدار منابع باید براساس مشاهده و Load Test تنظیم شود.

نبود Timeout برای Rollout

این دستور ممکن است مدت نامحدودی منتظر بماند:

kubectl rollout status deployment/catalog-api

نسخه بهتر:

kubectl rollout status \
  deployment/catalog-api \
  --timeout=180s

ارسال تمام خروجی Cluster به مدل

فقط Namespace، Resource و Log مرتبط را ارسال کنید. خروجی بزرگ و نامرتبط کیفیت تحلیل را کاهش می‌دهد.

اجرای Command پیشنهادی مدل بدون Allowlist

در ابزار عیب‌یابی، Commandها را به دستورات Read-only محدود و پیش از اجرا بررسی کنید.

چک‌لیست Deployment

  • apiVersion و kind درست‌اند.
  • Namespace مشخص است.
  • نام Resource پایدار است.
  • Image و Tag دقیق‌اند.
  • latest استفاده نشده است.
  • Container Port با برنامه هماهنگ است.
  • Selector با Pod Label تطابق دارد.
  • Replica Count مشخص است.
  • Rolling Update تعریف شده است.
  • Startup Probe متناسب با زمان شروع است.
  • Readiness Probe آمادگی واقعی را می‌سنجد.
  • Liveness Probe فقط خرابی واقعی را تشخیص می‌دهد.
  • Resource Request تعریف شده است.
  • Resource Limit تعریف شده است.
  • Graceful Shutdown با برنامه هماهنگ است.
  • ConfigMapهای ارجاع‌شده وجود دارند.
  • Dry Run موفق است.
  • Diff بررسی شده است.
  • Rollout Status کنترل می‌شود.
  • Smoke Test وجود دارد.

چک‌لیست Service

  • Namespace با Deployment یکسان است.
  • Selector حداقل یک Pod را پیدا می‌کند.
  • Port و Target Port درست‌اند.
  • Named Port در Container تعریف شده است.
  • نوع Service با معماری هماهنگ است.
  • EndpointSlice ایجاد می‌شود.
  • Podهای Not Ready ترافیک دریافت نمی‌کنند.
  • Port Forward و Smoke Test موفق‌اند.

چک‌لیست عیب‌یابی

  • وضعیت Deployment بررسی شده است.
  • وضعیت ReplicaSet بررسی شده است.
  • Podهای مرتبط فهرست شده‌اند.
  • kubectl describe بررسی شده است.
  • Eventهای جدید مرتب شده‌اند.
  • Log اجرای فعلی دیده شده است.
  • Log اجرای قبلی بررسی شده است.
  • Restart Count مشخص است.
  • Last Termination State بررسی شده است.
  • Readiness و Liveness جداگانه بررسی شده‌اند.
  • Service Selector بررسی شده است.
  • EndpointSlice بررسی شده است.
  • Image و Tag تأیید شده‌اند.
  • Resource Request با ظرفیت Cluster مقایسه شده است.
  • تحلیل مدل همراه شواهد است.
  • هیچ فرض مدل بدون بررسی پذیرفته نشده است.

انتخاب مدل مناسب

مدل مناسب برای Kubernetes باید:

  • YAML و JSON را دقیق درک کند.
  • با Deployment، Service و Probe آشنا باشد.
  • بتواند Log و Event را تحلیل کند.
  • خروجی ساختاریافته تولید کند.
  • به Application Manifest پایبند بماند.
  • میان حدس و شواهد تفاوت قائل شود.
  • فایل و Resource خیالی نسازد.
  • Context کافی برای چند Manifest داشته باشد.
  • برای Reviewهای پرتکرار هزینه مناسبی داشته باشد.

برای Manifestهای کوچک، یک مدل سریع کافی است. برای مجموعه بزرگ Manifestها، Kustomize Overlay یا Logهای طولانی، مدلی با Context و توان استدلال بیشتر مناسب خواهد بود.

Model ID و قیمت به‌روز را از صفحه مدل‌های درواره دریافت کنید.

چرا API درواره برای این پروژه مناسب است؟

Kubernetes Reviewer باید از داخل Script، CI/CD، پنل داخلی یا ابزار DevOps فراخوانی شود.

با API درواره می‌توانید:

  • Manifestها را بازبینی کنید.
  • خطاهای YAML و Kubernetes را توضیح دهید.
  • Event و Log را تحلیل کنید.
  • خروجی JSON قابل اعتبارسنجی بگیرید.
  • مدل مناسب هر مرحله را انتخاب کنید.
  • تحلیل را به CI اضافه کنید.
  • گزارش را در Artifact نگهداری کنید.
  • مدل را بدون بازنویسی معماری ابزار تغییر دهید.

برای شروع:

  1. در درواره ثبت‌نام کنید.
  2. کلید API بسازید.
  3. مدل مناسب را از صفحه مدل‌ها انتخاب کنید.
  4. از Base URL زیر استفاده کنید:
https://api.darvareh.ir/v1

پرسش‌های متداول

آیا هوش مصنوعی می‌تواند Kubernetes YAML بسازد؟

بله. مدل می‌تواند براساس مشخصات دقیق برنامه Deployment، Service، ConfigMap و Resourceهای دیگر تولید کند؛ اما فایل نهایی باید با Validator و kubectl بررسی شود.

چگونه Kubernetes Manifest را قبل از اجرا تست کنیم؟

ابتدا:

kubectl apply \
  --dry-run=client \
  --validate=strict \
  -f k8s/

و در صورت دسترسی به Cluster آزمایشی:

kubectl apply \
  --dry-run=server \
  --validate=strict \
  -f k8s/

تفاوت Readiness و Liveness چیست؟

Readiness مشخص می‌کند Pod آماده دریافت ترافیک است یا نه. Liveness مشخص می‌کند Container باید Restart شود یا نه.

چرا Service به Pod وصل نمی‌شود؟

یکی از رایج‌ترین دلایل، ناهماهنگی spec.selector در Service با Labelهای Pod است. Target Port و Readiness نیز باید بررسی شوند.

علت CrashLoopBackOff چیست؟

CrashLoopBackOff یک علت واحد نیست. Log فعلی، Log قبلی، Exit Code، Eventها، Probeها و تنظیمات برنامه باید بررسی شوند.

چگونه بفهمیم Deployment کامل شده است؟

kubectl rollout status \
  deployment/DEPLOYMENT_NAME \
  --namespace NAMESPACE \
  --timeout=180s

آیا هوش مصنوعی می‌تواند مقدار CPU و Memory را تعیین کند؟

مدل می‌تواند مقدار اولیه پیشنهاد دهد، اما مقدار نهایی باید با Monitoring و Load Test تعیین شود.

آیا باید کل Cluster را برای مدل ارسال کنیم؟

خیر. فقط Resource، Event، Log و وضعیت مرتبط را ارسال کنید.

آیا درواره خودش Kubernetes Cluster ارائه می‌کند؟

درواره زیرساخت دسترسی API به مدل‌های هوش مصنوعی را فراهم می‌کند. ساخت Cluster، اجرای kubectl و استقرار برنامه در زیرساخت Kubernetes شما انجام می‌شود.

Model ID درواره را از کجا بگیریم؟

Model ID، مشخصات و قیمت مدل‌ها را در صفحه مدل‌های درواره مشاهده کنید.

جمع‌بندی

هوش مصنوعی می‌تواند تولید و عیب‌یابی Kubernetes Manifest را سریع‌تر کند، اما نباید تنها لایه کنترل استقرار باشد.

در یک فرایند حرفه‌ای:

  1. مشخصات برنامه در Application Manifest ثبت می‌شود.
  2. مدل فقط براساس همان اطلاعات Manifest پیشنهاد می‌دهد.
  3. YAML با Parser واقعی خوانده می‌شود.
  4. قواعد پروژه به‌صورت قطعی بررسی می‌شوند.
  5. Selector، Label، Port و Probeها تطبیق داده می‌شوند.
  6. kubectl اعتبارسنجی Client و Server را انجام می‌دهد.
  7. Diff پیش از Apply بررسی می‌شود.
  8. Rollout دارای Timeout است.
  9. Smoke Test پس از استقرار اجرا می‌شود.
  10. Log و Event فقط برای تحلیل به مدل داده می‌شوند.
  11. پیشنهادهای مدل با شواهد واقعی بررسی می‌شوند.

برای ساخت Kubernetes Reviewer یا دستیار عیب‌یابی K8s، در درواره ثبت‌نام کنید، کلید API بگیرید و مدل مناسب برنامه‌نویسی و تحلیل Log را از صفحه مدل‌ها انتخاب کنید.

مقالات مرتبط

برای مطالعه شرایط استفاده و محدودیت‌های مسئولیت، صفحه «سلب مسئولیت» را مشاهده کنید.

Read more

اتوماسیون هوش مصنوعی چیست؟ کاربردها و آموزش ساخت AI Automation

اتوماسیون هوش مصنوعی چیست؟ کاربردها و آموزش ساخت AI Automation

اتوماسیون هوش مصنوعی با ترکیب گردش‌کارهای خودکار و مدل‌های هوش مصنوعی، پردازش متن، دسته‌بندی، استخراج اطلاعات و تصمیم‌های پیشنهادی را خودکار می‌کند. در این راهنما، معماری و ساخت نمونه عملی آن با API درواره را می‌آموزید.

Agentic Commerce چیست؟ آینده خرید با ایجنت هوش مصنوعی

Agentic Commerce چیست؟ آینده خرید با ایجنت هوش مصنوعی

Agentic Commerce شیوه‌ای جدید برای خرید اینترنتی است که در آن ایجنت هوش مصنوعی می‌تواند نیاز کاربر را بفهمد، محصولات را جست‌وجو و مقایسه کند و فرایند خرید را پیش ببرد. در این راهنما با معماری، UCP، ACP و پیاده‌سازی آن با API درواره آشنا می‌شوید.