پرش به محتویات

آموزش کوبرنتیز؛ شب هفتم: بازبینی و تمرین خرابی

امشب آموخته‌های شش شب نخست را به یک روش عیب‌یابی منسجم تبدیل می‌کنیم و سه خرابی مستقل را تعمیر می‌کنیم: Image نامعتبر، Selectorای که هیچ Podی را انتخاب نمی‌کند و targetPortای که با برنامه هماهنگ نیست.

مدل ذهنی اصلی ما چنین است:

Deployment → ReplicaSet → Pod → container
client → Service → EndpointSlice

خرابی در مسیر بالایی، ساخت Workload را مختل می‌کند؛ خرابی در مسیر پایینی حتی وقتی همهٔ Podها Running هستند، ترافیک را از کار می‌اندازد.

روش مبتنی بر شواهد

از نشانه‌های کلی به‌سمت لایهٔ خراب حرکت کنید:

  1. get وضعیت مطلوب و مشاهده‌شده را خلاصه می‌کند.
  2. describe شرط‌ها و Eventهای مرتبط را نشان می‌دهد.
  3. logs گزارش Processای را نشان می‌دهد که اجرا شده است.
  4. Eventها خرابی‌های Scheduling، دریافت Image، Mount و Probe را توضیح می‌دهند.
  5. EndpointSliceها ثابت می‌کنند که Service، Backendهای آماده را انتخاب کرده است یا نه.

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

Manifest پایه

فایل app.yaml یک Deployment دونمونه‌ای و Service متناظر آن را تعریف می‌کند:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
  namespace: course-night-7
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: nginx
          image: nginx:1.27-alpine
          ports:
            - name: http
              containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: web
  namespace: course-night-7
spec:
  selector:
    app: web
  ports:
    - name: http
      port: 80
      targetPort: http

ایجاد وضعیت سالم اولیه

kubectl create namespace course-night-7
kubectl apply -f app.yaml
kubectl rollout status deployment/web --namespace course-night-7
kubectl get deployment,replicaset,pod,service,endpointslice \
  --namespace course-night-7 -o wide

kubectl run client --namespace course-night-7 --rm -it \
  --restart=Never --image=curlimages/curl \
  -- curl --fail --max-time 5 http://web

نام ReplicaSet، آدرس‌های IP مربوط به Podها، ClusterIP سرویس و آدرس Endpointها را یادداشت کنید.

خرابی اول: Image نامعتبر

kubectl set image deployment/web --namespace course-night-7 \
  nginx=nginx:this-tag-does-not-exist
kubectl rollout status deployment/web --namespace course-night-7 --timeout=45s
kubectl get pods --namespace course-night-7
kubectl describe deployment web --namespace course-night-7
kubectl describe pod <new-pod-name> --namespace course-night-7
kubectl get events --namespace course-night-7 \
  --sort-by=.metadata.creationTimestamp

ImagePullBackOff دلیل انتظار یک Container است. این وضعیت یعنی Kubelet نتوانسته Image را دریافت کند و با فاصله‌ای افزایشی دوباره تلاش می‌کند. ممکن است Replicaهای قدیمی همچنان در دسترس بمانند، زیرا راهبرد Rolling نمونه‌های سالم را بلافاصله حذف نمی‌کند.

خرابی را تعمیر و نتیجه را بررسی کنید:

kubectl set image deployment/web --namespace course-night-7 \
  nginx=nginx:1.27-alpine
kubectl rollout status deployment/web --namespace course-night-7

خرابی دوم: Selector نادرست

kubectl patch service web --namespace course-night-7 --type merge \
  --patch '{"spec":{"selector":{"app":"wrong"}}}'
kubectl get pods --namespace course-night-7 --show-labels
kubectl describe service web --namespace course-night-7
kubectl get endpointslices --namespace course-night-7 \
  -l kubernetes.io/service-name=web -o yaml

Service هنوز نام DNS و ClusterIP دارد، اما EndpointSlice آن Endpoint قابل استفاده‌ای ندارد؛ زیرا Labelها یک قرارداد تطبیق دقیق هستند.

kubectl patch service web --namespace course-night-7 --type merge \
  --patch '{"spec":{"selector":{"app":"web"}}}'
kubectl get endpointslices --namespace course-night-7 \
  -l kubernetes.io/service-name=web

خرابی سوم: Target Port نادرست

kubectl patch service web --namespace course-night-7 --type merge \
  --patch '{"spec":{"ports":[{"name":"http","port":80,"targetPort":8080}]}}'
kubectl describe service web --namespace course-night-7
kubectl run client --namespace course-night-7 --rm -it \
  --restart=Never --image=curlimages/curl \
  -- curl --max-time 5 http://web

Endpointها هنوز وجود دارند، پس انتخاب درست انجام شده است. ترافیک شکست می‌خورد چون Service آن را به درگاه ۸۰۸۰ می‌فرستد، درحالی‌که NGINX روی درگاه ۸۰ گوش می‌دهد. containerPort قرارداد Container را مستند می‌کند، اما Process را وادار نمی‌کند روی آن درگاه گوش دهد.

kubectl patch service web --namespace course-night-7 --type merge \
  --patch '{"spec":{"ports":[{"name":"http","port":80,"targetPort":"http"}]}}'
kubectl run client --namespace course-night-7 --rm -it \
  --restart=Never --image=curlimages/curl \
  -- curl --fail --max-time 5 http://web

چک‌لیست پایان

  • خرابی ساخت Workload را از خرابی مسیر ترافیک تشخیص داده‌ام.
  • پیش از هر تعمیر از شواهد استفاده کرده‌ام.
  • هر سه خرابی را تعمیر و دوباره از طریق Service آزمایش کرده‌ام.
  • مسیر Objectها و ترافیک را از حفظ رسم کرده‌ام.
  • در یک جمله نوشته‌ام که هر فرمان عیب‌یابی دقیقاً چه چیزی را ثابت می‌کند.
kubectl delete namespace course-night-7