نسخه آنلاین در حال بارگذاری زمان... تهران: ۲۶°C
۲۸ کاربر آنلاین

PNo.30Light

نشریه تخصصی هوش مصنوعی، سیستم‌های سرور و مهندسی داده

تازه ترین‌ها
زیرساخت و سرور
زمان مطالعه: ۳۰ دقیقه ۰ بازدید

apiVersion در YAML کوبرنتیز: Deep Dive نسخه‌بندی API، Alpha/Beta/Stable و تفاوت رفتار

نویسنده: تحریریه فنی P30Light
apiVersion در YAML کوبرنتیز: Deep Dive نسخه‌بندی API، Alpha/Beta/Stable و تفاوت رفتار
✦ خلاصه نکات کلیدی مقاله
  • apiVersion = Group + Version؛ همراه Kind هویت شیء را می‌سازد (GVK) — نه نسخه نرم‌افزار اپ شما.
  • Alpha / Beta / Stable قواعد پشتیبانی، پیش‌فرض enable، و حذف کاملاً متفاوت دارند.
  • چند نسخه می‌توانند همزمان served باشند؛ فقط یک storage version در etcd می‌ماند.

تقریباً هر فایل YAML کوبرنتیز با دو خط شروع می‌شود:

apiVersion: apps/v1
kind: Deployment

این apiVersion نسخهٔ image اپ شما نیست، نسخهٔ chart هم نیست، و لزوماً برابر نسخهٔ cluster (1.29، 1.31، …) هم نیست. این فیلد می‌گوید: با کدام قرارداد API سرور این نوع شیء را بشناس و validate کن.

طبق API Overview رسمی: کل Kubernetes روی REST API بنا شده؛ هر چیزی که kubectl یا کنترلر لمس می‌کند یک API object است.

این مقاله deep dive است: معنی apiVersion، انواع سطح پایداری، گروه‌های API، تفاوت رفتار نسخه‌ها، deprecate/حذف، و نسخه‌بندی CRDها.


سه‌گانه هویت: Group · Version · Kind (GVK)

هر شیء با GVK شناخته می‌شود:

جزءمثالنقش
Groupapps، batch، networking.k8s.io، (خالی = core)خانواده API
Versionv1، v1beta1، v1alpha1سطح پایداری + شکل schema
KindDeployment، Job، Ingressنوع منبع

در YAML:

# Core group — Group در رشته نیست
apiVersion: v1
kind: Pod

# Named group — Group/Version
apiVersion: apps/v1
kind: Deployment

apiVersion: networking.k8s.io/v1
kind: Ingress

مسیر REST متناظر:

apiVersionمسیر تقریبی
v1/api/v1/...
batch/v1/apis/batch/v1/...
networking.k8s.io/v1/apis/networking.k8s.io/v1/...

علاوه بر GVK، GVR (Group / Version / Resource) برای URL جمع‌ها مهم است: deployments، pods، ingresses. Kind مفرد است؛ resource معمولاً جمع.

kubectl api-resources
kubectl api-versions
kubectl explain deployment --api-version=apps/v1

Core group در برابر Named groups

Core (legacy)Named groups
apiVersionفقط v1GROUP/VERSION
نمونه‌هاPod، Service، ConfigMap، Secret، Namespace، PersistentVolumeClaim، …Deployment (apps)، Job (batch)، Ingress (networking.k8s.io)، …
چرا جدا؟تاریخچه اولیه Kubernetesگسترش‌پذیری؛ جلوگیری از شلوغی یک namespace عظیم

بسیاری منابع امروز در named groupsاند چون از core/extensions مهاجرت کرده‌اند (مثلاً Ingress از extensions/v1beta1 به networking.k8s.io/v1).


سه سطح پایداری: Alpha · Beta · Stable

نام version خودش سیگنال پایداری است. رفتار عملیاتی‌شان عملاً فرق دارد.

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

موضوعAlpha (v1alpha1)Beta (v1beta1, v2beta3)Stable / GA (v1, v2)
نامشامل alphaشامل betaفقط vX عددی
پیش‌فرض روی apiserverمعمولاً غیرفعالمعمولاً غیرفعال (به‌جز betaهای قدیمی قبل از ~۱.۲۲)فعال
فعال‌سازی--runtime-config=...--runtime-config=...پیش‌فرض
باگ / ناپایداریمحتملکمتر؛ هنوز schema ممکن است عوض شودproduction-ready
تغییر ناسازگاربدون اخطار طولانیممکن در beta/stable بعدی + راهنمای مهاجرتدر major فعلی حذف نمی‌شود
عمر تا deprecate/حذفممکن است هر زمان حذف شودسقف تقریبی: ۹ ماه یا ۳ minor تا deprecate، سپس همان‌قدر تا حذفپایدار در سراسر major فعلی
توصیهفقط cluster آزمایشی کوتاه‌عمرآزمایش / بازخورد؛ production با احتیاطپیش‌فرض production

منبع قواعد: Kubernetes API Overview.

مثال نام‌گذاری

v1alpha1  →  اولین آزمایش feature
v1alpha2  →  تکرار alpha (شکست schema ممکن)
v1beta1   →  ورود به beta
v1beta2   →  اصلاحات ناسازگار در beta
v1        →  فارغ‌التحصیلی به stable
v2alpha1  →  نسل بعدی feature بزرگ (موازی با v1)

نکته مهم: v2 لزوماً «بهتر از v1 برای همان Kind» نیست — گاهی نسل API جدید برای مدل متفاوت است؛ v1 ممکن است هنوز preferred باشد.


نسخه‌های رایج که در YAML می‌بینید

apiVersionKindهای نمونهیادداشت
v1Pod، Service، ConfigMap، Secret، ServiceAccount، Namespace، PVC، …core
apps/v1Deployment، StatefulSet، DaemonSet، ReplicaSetپایدار
batch/v1Job، CronJobCronJob قبلاً batch/v1beta1 بود (حذف در مسیر ارتقا)
networking.k8s.io/v1Ingress، NetworkPolicy، IngressClassجایگزین extensions قدیمی
rbac.authorization.k8s.io/v1Role، ClusterRole، RoleBinding، …
storage.k8s.io/v1StorageClass، CSIDriver، …
apiextensions.k8s.io/v1CustomResourceDefinitionv1beta1 CRD حذف شده
policy/v1PodDisruptionBudgetقبلاً policy/v1beta1
autoscaling/v2HorizontalPodAutoscalerنسل متریک چندگانه
gateway.networking.k8s.io/v1Gateway، HTTPRoute، …Gateway API
cert-manager.io/v1Certificate، Issuerنمونه CRD محبوب — مقاله cert-manager
helm.toolkit.fluxcd.io/v2HelmReleaseنمونه GitOps — Flux / Helm

لیست کامل روی هر cluster:

kubectl api-resources -o wide

یک شیء، چند نسخه — چطور «متفاوت عمل می‌کنند»؟

فرض کنید Kind واحد CronJob زمانی هم batch/v1beta1 و هم batch/v1 را serve می‌کرد.

جنبهرفتار
Schema روی سیمفیلدها، نام‌ها، validation ممکن است فرق کند
ذخیره در etcdمعمولاً یک storage version — نه دو کپی کامل
درخواست با نسخه قدیمیapiserver تبدیل (conversion) به/از storage می‌کند
درخواست با نسخه جدیدممکن است فیلدهای تازه‌ای ببینید که در نسخه قدیمی وجود نداشتند
نوشتن با نسخه قدیمی پس از deprecatewarning در response header؛ بعداً ۴۰۴ / عدم serve

پس «تفاوت عمل» یعنی:

  1. Validation متفاوت — چیزی که در alpha قبول می‌شود در stable رد می‌شود (یا برعکس بعد از تغییر schema)
  2. Defaulting متفاوت — مقادیر پیش‌فرض ممکن است عوض شوند
  3. فیلدهای موجود/غایب — feature جدید فقط روی نسخه جدید
  4. Conversion lossy — خواندن با نسخه قدیمی ممکن است فیلد جدید را drop کند؛ نوشتن دوباره = از دست رفتن داده
  5. دسترسی — اگر نسخه روی apiserver disable باشد، YAML با آن apiVersion اصلاً apply نمی‌شود

مثال مفهومی تفاوت schema

# نسل قدیمی (ساده شده — تاریخی)
apiVersion: extensions/v1beta1
kind: Ingress
spec:
  rules: [...]
  # برخی فیلدها و annotation-محور بودن متفاوت بود

# نسل پایدار
apiVersion: networking.k8s.io/v1
kind: Ingress
spec:
  ingressClassName: nginx
  rules:
    - http:
        paths:
          - path: /
            pathType: Prefix          # اجباری‌تر / صریح‌تر
            backend:
              service:
                name: web
                port:
                  number: 80

همین «Ingress» است، اما قرارداد فیلدها و گروه API عوض شده — کلاینت قدیمی و جدید رفتار متفاوت می‌بینند.


Preferred, Served, Storage

روی منابع built-in و CRDها سه مفهوم جداست:

مفهوممعنی
Servedاین نسخه روی API در دسترس است؟
Storageکدام نسخه در etcd نوشته می‌شود؟ (معمولاً فقط یکی)
Preferredkubectl / discovery کدام را ترجیح می‌دهد؟

برای CRD:

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
spec:
  group: example.com
  names:
    kind: Widget
    plural: widgets
  scope: Namespaced
  versions:
    - name: v1alpha1
      served: true
      storage: false
      schema:
        openAPIV3Schema:
          type: object
          # ...
    - name: v1
      served: true
      storage: true   # تنها storage
      schema:
        openAPIV3Schema:
          type: object
          # ...

اولویت نام‌گذاری برای preferred تقریباً: GA > Beta > Alpha، سپس شماره بالاتر.


Conversion: None در برابر Webhook

وقتی چند نسخه served هستند:

استراتژیکیرفتار
Noneهمه نسخه‌ها شکل سیم یکسان (فقط فیلد اختیاری اضافه)بدون تبدیل واقعی؛ برچسب version عوض می‌شود
Webhookrename، split، merge، تو در تو شدن فیلدهاapiserver webhook را صدا می‌زند تا بین نسخه‌ها reshape کند

الگوی رایج در کنترلرها: hub-and-spoke — یک نسخه hub (معمولاً storage)، بقیه به hub تبدیل می‌شوند.

خطر: conversion یک‌طرفه یا lossy → کاربر با kubectl get widget.v1alpha1 می‌خواند، فیلد v1-only حذف می‌شود، بعد apply می‌کند و داده از بین می‌رود.

مهاجرت storage کامل نیست تا objectهای قدیمی در etcd rewrite شوند (StorageVersionMigration / ابزارهای migrator). فقط عوض کردن storage: true ردیف‌های قدیمی را بازنویسی نمی‌کند.


Deprecation و حذف — تقویم واقعی دردسر

سیاست تقریبی Kubernetes:

معرفی → (عمر) → deprecate (warning) → (عمر) → دیگر serve نمی‌شود
  • Alpha: ممکن است بدون مسیر طولانی حذف شود
  • Beta: حداقل حدود ۹ ماه یا ۳ minor تا deprecate، و همان‌قدر تا توقف serve
  • Stable: در major فعلی حذف نمی‌شود (ممکن است deprecate شود ولی بماند)

مهاجرت‌های معروفی که YAMLها را شکستند

ازبهیادداشت
extensions/v1beta1 Ingress/Deploymentnetworking.k8s.io/v1 / apps/v1
batch/v1beta1 CronJobbatch/v1حذف در مسیر ۱.۲۵
policy/v1beta1 PDBpolicy/v1
apiextensions.k8s.io/v1beta1 CRDapiextensions.k8s.io/v1schema اجباری‌تر
autoscaling/v2beta2 HPAautoscaling/v2

قبل از ارتقا cluster:

# هشدارهای deprecate در audit / kubectl
kubectl get --raw /metrics | head  # یا بررسی logs apiserver

# ابزارهای رایج جامعه
# pluto, kube-no-trouble (kubent), kubepug — مانیفست/Helm را اسکن می‌کنند

Helm charts قدیمی اغلب آخرین جایی هستند که apiVersion مرده را نگه می‌دارند — قبل از upgrade، chart را به‌روز کنید.


apiVersion ≠ این‌ها

مفهومچیستاشتباه رایج
نسخه Kubernetes (Server Version: v1.31)نسخه باینری/clusterفکر کردن apiVersion: v1 یعنی K8s v1
appVersion در Chart.yamlنسخه نرم‌افزار داخل بستهربط مستقیم به GVK ندارد
version در Chart.yamlنسخه بسته Helm
image tagنسخه کانتینر
Feature gateروشن/خاموش کردن رفتار در کامپوننت‌هابعضی featureها قبل از API جداگانه با gate می‌آیند
CRD spec.versions[].nameنسخه‌های منبع سفارشیباید با apiVersion: group/version در اشیاء CR جور باشد
# درست برای یک CR
apiVersion: example.com/v1
kind: Widget

اگر فقط v1alpha1 served باشد و شما example.com/v1 بفرستید → خطا.


فعال/غیرفعال کردن روی API Server

# مثال مفهومی روی kube-apiserver
--runtime-config=batch/v1=false
--runtime-config=batch/v2alpha1=true
--runtime-config=storage.k8s.io/v1beta1/csistoragecapacities=true

بعد از تغییر معمولاً restart apiserver (و گاه controller-manager) لازم است. روی سرویس‌های managed (EKS/GKE/AKS) این سطح کنترل محدودتر است — نسخه alpha/beta ممکن است اصلاً در دسترس نباشد.


کشف و دیباگ روزمره

# چه versionهایی زنده‌اند؟
kubectl api-versions | sort

# برای یک resource کدام نسخه؟
kubectl api-resources | grep -i ingress

# توضیح فیلدها روی نسخه مشخص
kubectl explain ingress.spec --api-version=networking.k8s.io/v1

# شیء ذخیره‌شده را با version صریح بخوانید
kubectl get ingress.v1.networking.k8s.io my-ing -o yaml

# تبدیل مانیفست (ابزارها/نسخه‌های مختلف kubectl)
kubectl convert -f old.yaml --output-version networking.k8s.io/v1

در GitOps (Flux / Argo) شکست reconcile اغلب از no matches for kind ... in version ... است = apiVersion روی آن cluster دیگر serve نمی‌شود.


تفاوت رفتار در عمل — سناریوها

۱. Apply با نسخه حذف‌شده

error: unable to recognize "ingress.yaml":
no matches for kind "Ingress" in version "extensions/v1beta1"

رفع: به‌روز کردن apiVersion و فیلدهای اجباری جدید (pathType، ingressClassName، …).

۲. Beta روی production بدون enable

YAML معتبر است؛ cluster آن version را advertise نمی‌کند → همان خطای بالا یا dry-run شکست.

۳. دو کلاینت، دو نسخه

Controller با v1 فیلد جدید می‌نویسد؛ انسان با v1beta1 get/edit می‌کند → فیلد گم می‌شود (lossy).

۴. CRD فقط storage را عوض کردید

Objectهای قدیمی هنوز با version قبلی در etcdاند تا migrate شوند؛ ابزارهای فرض‌کننده «همه v1 هستند» گیج می‌شوند.

۵. HPA v1 در برابر v2

autoscaling/v1 عمدتاً CPU؛ autoscaling/v2 متریک‌های چندگانه و رفتار غنی‌تر — Kind یکسان نیست از نظر قابلیت، هرچند هر دو «HPA»اند.


ارتباط با stack شما

YAML / Helm / Kustomize
    apiVersion + kind  →  GVK


   kube-apiserver  (served versions, conversion)


      etcd  (storage version)   ← مقاله etcd


 Controllers, Flux, Operators, cert-manager CRDs, Istio CRDs, ...

روی K3s همان مدل GVK برقرار است؛ فقط مجموعه APIهای enable‌شده را با kubectl api-versions چک کنید.


Best practices

  1. در مانیفست‌های production فقط stable بنویسید مگر feature مجبورتان کند
  2. قبل از upgrade cluster، مانیفست‌ها و Helm charts را با ابزار deprecate اسکن کنید
  3. در CI: kubeconform / kubeval با version هدف cluster
  4. برای CRD: همیشه OpenAPI schema؛ migration با conversion تست‌شده
  5. از kubectl explain نسخه صریح استفاده کنید — نه حافظه از آموزش قدیمی
  6. در مستندات تیم جدول «apiVersion ممنوع / اجباری» بگذارید
  7. Image/chart version را با apiVersion قاطی نکنید
  8. بعد از تغییر storage CRD، migration etcd را تمام کنید قبل از حذف version قدیمی
  9. Warningهای deprecate در CI و audit را جدی بگیرید — نه بعد از شکست upgrade
  10. برای Gateway / mesh / cert-manager نسخه CRD را با نسخه کنترلر هم‌تراز نگه دارید

جمع‌بندی

مفهومیک جمله
apiVersionGroup+Version قراردادی که schema و endpoint را تعیین می‌کند
GVKهویت نوع شیء
Alpha/Beta/Stableقواعد enable، پشتیبانی و حذف متفاوت
Served vs Storageچه چیزی دیده می‌شود در برابر چه چیزی در etcd می‌ماند
Conversionپل بین نسخه‌ها؛ ممکن است lossy باشد
Deprecateفرصت مهاجرت قبل از حذف از apiserver

apiVersion کوچک به‌نظر می‌رسد، اما مرز بین «YAML دیروز» و «cluster امروز» است. فهم تفاوت alpha/beta/stable و served/storage همان چیزی است که upgradeهای Kubernetes را قابل پیش‌بینی یا کابوس می‌کند.


قدم بعدی

  1. روی cluster خود: kubectl api-versions و kubectl api-resources
  2. یک Ingress/CronJob قدیمی را عمداً با apiVersion منسوخ dry-run کنید و خطا را ببینید
  3. مانیفست‌های Git را برای extensions/ و v1beta1 جستجو کنید
  4. یک CRD چندنسخه‌ای (مثلاً از cert-manager) را با kubectl get crd -o yaml نگاه کنید: served / storage
  5. قبل از ارتقا minor بعدی، Deprecation Guide نسخه هدف را بخوانید

منابع


منتشر شده در P30Light — بخش زیرساخت و سرور.

لینک گزارش با موفقیت کپی گردید!