آموزش کوبرنتیز؛ شب ششم: YAML اعلانی¶
در شب پایانی، وضعیت مطلوب را با Manifestهای قابل نگهداری در Git ایجاد، بررسی، مقایسه و بهروزرسانی میکنیم.
ساختار یک Object¶
هر Object کوبرنتیز چهار بخش مهم در سطح بالا دارد:
apiVersion: apps/v1 # گروه و نسخهٔ API
kind: Deployment # نوع منبع
metadata: {} # هویت، Labelها و Annotationها
spec: {} # وضعیت مطلوب
API Server و Controllerها بخش status را با وضعیت مشاهدهشده پر میکنند. فیلدهای تولیدشدهای مانند status، resourceVersion، uid و managedFields را در Manifest دستنویس کپی نکنید.
Manifest برنامه¶
فایل app.yaml را بسازید:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: course-night-6
labels:
app.kubernetes.io/name: web
app.kubernetes.io/part-of: night-school
annotations:
course.example/owner: student
spec:
replicas: 2
selector:
matchLabels:
app.kubernetes.io/name: web
template:
metadata:
labels:
app.kubernetes.io/name: web
app.kubernetes.io/part-of: night-school
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- name: http
containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: web
namespace: course-night-6
labels:
app.kubernetes.io/name: web
app.kubernetes.io/part-of: night-school
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: web
ports:
- name: http
port: 80
targetPort: http
اعتبارسنجی پیش از Apply¶
kubectl create namespace course-night-6
kubectl apply --dry-run=server -f app.yaml
kubectl diff -f app.yaml
kubectl apply -f app.yaml
kubectl rollout status deployment/web --namespace course-night-6
وقتی kubectl diff تفاوتی پیدا میکند، معمولاً با Exit Code برابر 1 خارج میشود. این نتیجه بهتنهایی به معنی خرابی فرمان نیست.
فایل نوشتهشده را با Object زنده مقایسه کنید:
kubectl get deployment web --namespace course-night-6 -o yaml
kubectl get deployment web --namespace course-night-6 \
-o jsonpath='{.metadata.generation}{" desired; observed="}{.status.observedGeneration}{"\n"}'
kubectl get pods --namespace course-night-6 --show-labels
Label، Selector و Annotation¶
- Label برای شناسایی و گروهبندی Objectهاست.
- Selector کنترلرها و Serviceها را به Podها متصل میکند.
- Annotation برای Metadataای است که نقش شناسایی ندارد.
- Selector یک Deployment باید با Labelهای Pod Template هماهنگ باشد و پس از ایجاد عملاً تغییرناپذیر است.
Label و Annotation تعریفشده را Query کنید:
kubectl get all --namespace course-night-6 \
-l app.kubernetes.io/name=web
kubectl get deployment web --namespace course-night-6 \
-o jsonpath='{.metadata.annotations.course\\.example/owner}{"\n"}'
بهروزرسانی Declarative و امن¶
در app.yaml تعداد Replica را از ۲ به ۳ تغییر دهید:
سپس تغییر را پیشنمایش، مقایسه و اعمال کنید:
kubectl apply --dry-run=server -f app.yaml
kubectl diff -f app.yaml
kubectl apply -f app.yaml
kubectl get deployment,pods --namespace course-night-6
اکنون Image را از nginx:alpine به nginx:1.27-alpine تغییر دهید:
kubectl diff -f app.yaml
kubectl apply -f app.yaml
kubectl rollout status deployment/web --namespace course-night-6
kubectl rollout history deployment/web --namespace course-night-6
تغییر Replica، Pod Template را تغییر نمیدهد؛ اما تغییر Image آن را عوض میکند و در نتیجه Revision تازهای از ReplicaSet میسازد.
تمرین خطای Schema¶
یک کپی موقت از Manifest بگیرید:
تمام بلوک spec.selector مربوط به Deployment را از broken-app.yaml حذف و نسخهٔ خراب را فقط اعتبارسنجی کنید:
پیام اعتبارسنجی API را بخوانید، فایل را تعمیر و دوباره بررسی کنید. فایل خراب را روی کلاستر Apply نکنید.
چکلیست پایان¶
-
apiVersion،kind،metadata،specوstatusرا توضیح میدهم. - پیش از Apply از Dry-run سمت سرور و Diff استفاده کردهام.
- با Label جستوجو و یک Annotation را خواندهام.
- تعداد Replica و Image را بهشکل Declarative تغییر دادهام.
- خطای Schema ساخته و آن را رفع کردهام.
- فیلدهای تولیدشده یا اطلاعات محرمانه را Commit نکردهام.
Objectهای کلاستر را پاک کنید، اما Manifest را بهعنوان محتوای دوره نگه دارید: