Ενδεικτική λύση: Kubernetes Assessment 02 – Intermediate
Επίπεδο δυσκολίας: Intermediate
Γλώσσα: Ελληνικά
Τύπος: ενδεικτική λύση / οδηγός αναμενόμενων απαντήσεων
Αυτό το αρχείο είναι η αντίστοιχη λύση του Assessment 02 Intermediate. Τα Manifests αποτελούν παραδείγματα για Lab. Εξαρτήσεις από Tools και Cluster, όπως StorageClass, Ingress Controller, Gateway API ή υποστήριξη NetworkPolicy, πρέπει να ελέγχονται στο αντίστοιχο Lab.
1. Οδηγίες χρήσης
Προτεινόμενο Namespace:
export NS=exam-intermediate
Μια πλήρης λύση δεν χρειάζεται να χρησιμοποιεί ακριβώς τα ίδια Images, εφόσον αυτά είναι ασφαλή, δείχνουν τις απαιτούμενες έννοιες Kubernetes και μπορούν να επαληθευτούν με επαναλήψιμο τρόπο. Όπου ένα Tool δεν είναι διαθέσιμο, γίνεται δεκτή μια τεχνικά σωστή εναλλακτική αξιολόγηση.
2. Μέρος A: Ενδεικτικές απαντήσεις στις ερωτήσεις γνώσεων
1. Deployment, StatefulSet, Job και CronJob
| Resource | Περίπτωση χρήσης |
|---|---|
| Deployment | Stateless Services που εκτελούνται συνεχώς, με Rollout και Rollback. |
| StatefulSet | Workloads με σταθερή ταυτότητα και σταθερή αντιστοίχιση PVC. |
| Job | Εργασία που εκτελείται μία φορά ή έχει πεπερασμένη διάρκεια, όπως ένα Migration. |
| CronJob | Προγραμματισμένες επαναλαμβανόμενες εργασίες. |
Ένα Deployment δεν είναι κατάλληλο για Migration που εκτελείται μία φορά, επειδή προσπαθεί να διατηρεί συνεχώς ενεργή τη διεργασία.
2. Init Containers, Sidecars και Ephemeral Containers
Τα Init Containers εκτελούνται πριν από τα Containers της εφαρμογής και πρέπει να ολοκληρωθούν επιτυχώς. Τα Sidecars εκτελούνται παράλληλα με την εφαρμογή και μοιράζονται Network, Volumes και τον κύκλο ζωής του Pod. Τα Ephemeral Containers προστίθενται εκ των υστέρων για Debugging και δεν αποτελούν μέρος του κανονικού μοντέλου Deployment.
3. Startup, Readiness και Liveness Probe
| Probe | Επίδραση |
|---|---|
| Startup Probe | Προστατεύει τις αργές εκκινήσεις· τα Readiness και Liveness περιμένουν μέχρι να επιτύχει. |
| Readiness Probe | Καθορίζει αν το Pod λαμβάνει κυκλοφορία από Service. |
| Liveness Probe | Καθορίζει αν το kubelet επανεκκινεί το Container. |
4. Κίνδυνος από υπερβολικά επιθετικά Liveness Probes
Ένα υπερβολικά επιθετικό Liveness Probe μπορεί να επανεκκινεί υγιή Containers υπό φόρτο ή κατά την αργή εκκίνηση. Αυτό μπορεί να προκαλέσει Crash Loops, περιττές διακοπές λειτουργίας και αυξημένο φόρτο.
5. Επίδραση των Requests στο Scheduling και στο HPA
Τα CPU και Memory Requests είναι τιμές σχεδιασμού για τον Scheduler. Τα CPU Requests αποτελούν επίσης βάση για το CPU-Based HPA Utilization. Requests που λείπουν ή δεν ανταποκρίνονται στην πραγματικότητα οδηγούν σε κακή τοποθέτηση Pods, παραπλανητικό Autoscaling και προβλήματα Noisy Neighbor.
6. QoS Classes
| QoS | Συνθήκη | Επίδραση |
|---|---|---|
| Guaranteed | Τα CPU και Memory Requests ισούνται με τα Limits για όλα τα Containers. | Μεγαλύτερη σταθερότητα υπό πίεση Resources. |
| Burstable | Υπάρχουν Requests, αλλά δεν είναι ίδια με τα Limits. | Ενδιάμεση προτεραιότητα. |
| BestEffort | Δεν υπάρχουν Requests ούτε Limits. | Απομακρύνεται πρώτο υπό πίεση Resources. |
7. LimitRange και ResourceQuota
Το LimitRange ορίζει προεπιλεγμένες τιμές και όρια για μεμονωμένα Pods ή Containers σε ένα Namespace. Το ResourceQuota περιορίζει τη συνολική χρήση του Namespace, για παράδειγμα σε Pods, CPU, Memory ή PVCs.
8. nodeSelector, Affinity, Taints και Tolerations
Το nodeSelector είναι απλή και υποχρεωτική επιλογή Node. Το Affinity προσφέρει περισσότερες δυνατότητες και μπορεί να ορίζει υποχρεωτικούς ή προτιμησιακούς κανόνες. Τα Taints σημαδεύουν Nodes ώστε Pods χωρίς αντίστοιχο Toleration να μην προγραμματίζονται εκεί. Τα Tolerations επιτρέπουν τοποθέτηση σε Nodes με Taint, αλλά από μόνα τους δεν την επιβάλλουν.
9. Γιατί ένα Pod μπορεί να παραμείνει Pending
Συνήθεις αιτίες είναι ανεπαρκή Resources, Node Selectors που δεν ταιριάζουν, κανόνες Affinity, ελλείποντα Tolerations για Taints, ελλείποντα PVCs ή προβλήματα StorageClass. Η διάγνωση γίνεται με kubectl describe pod και Events.
10. Service, EndpointSlice, Pod Readiness και DNS
Ένα Service ορίζει σταθερή διεύθυνση και Selector. Τα EndpointSlices περιέχουν τα πραγματικά προσβάσιμα Pod Endpoints. Συνήθως μόνο Ready Pods περιλαμβάνονται στην κυκλοφορία Service. Το CoreDNS επιλύει τα Service Names.
11. DNS Egress με Default Deny
Με Default Deny στο Egress, τα DNS Queries αποκλείονται αν δεν επιτραπούν ρητά. Χωρίς DNS Egress, τα Pods δεν μπορούν να επιλύσουν Service Names όπως backend.
12. Ingress Resource και Ingress Controller
Το Ingress Resource περιγράφει κανόνες HTTP Routing. Ένας Ingress Controller υλοποιεί αυτούς τους κανόνες ως Proxy ή Load Balancer Configuration. Χωρίς Controller, το Resource έχει μικρή πρακτική επίδραση.
13. PV, PVC, StorageClass και CSI
| Όρος | Ρόλος |
|---|---|
| PV | Storage Object που έχει διατεθεί στο Cluster. |
| PVC | Αίτημα Storage από Pod ή Workload. |
| StorageClass | Περιγράφει το Dynamic Provisioning και τις παραμέτρους του. |
| CSI | Διεπαφή/Plugin για Storage Systems. |
14. Γιατί το hostPath δεν είναι λύση Production
Το hostPath προσαρτά απευθείας το Filesystem ενός Node. Δεν είναι φορητό, δεσμεύει τα δεδομένα σε συγκεκριμένο Node και μπορεί να δημιουργήσει κινδύνους ασφαλείας. Είναι πρακτικό σε Labs, αλλά δεν αποτελεί γενικό μοντέλο Storage για Production.
15. Έλεγχοι για PVC Pending, Service χωρίς Endpoints και CreateContainerConfigError
| Μοτίβο σφάλματος | Έλεγχος |
|---|---|
| PVC Pending | kubectl describe pvc, StorageClass, Provisioner, Events. |
| Service χωρίς Endpoints | Pod Labels, Service Selector, Readiness, EndpointSlices. |
| CreateContainerConfigError | Ελλείπον ConfigMap/Secret, λανθασμένο Key ή μη έγκυρη αναφορά Env/Volume. |
3. Μέρος B: Απόφαση αρχιτεκτονικής
Πρότυπο για το architecture-decision.md:
# Απόφαση αρχιτεκτονικής – Shop Lab
| Απαίτηση | Απόφαση | Αιτιολόγηση |
| --- | --- | --- |
| Το HTTP Frontend εκτελείται συνεχώς και ενημερώνεται με Rolling Updates | Deployment | Stateless, Replicas, Rollout, Rollback. |
| Το Backend API χρειάζεται Health Checks και Resources | Deployment + Service | Εσωτερικό Service που εκτελείται συνεχώς· Readiness για κυκλοφορία, Liveness για πραγματικά σφάλματα. |
| Migration μία φορά ανά Release | Job | Η επιτυχής ολοκλήρωση είναι το Desired State. |
| Cleanup ανά ώρα χωρίς παράλληλα Jobs | CronJob με `concurrencyPolicy: Forbid` | Προγραμματισμένα Jobs χωρίς επικάλυψη. |
| Μικρό Stateful Workload με δεδομένα μετά την αναδημιουργία Pod | StatefulSet με `volumeClaimTemplates` | Σταθερή ταυτότητα Pod και αντιστοίχιση PVC. |
| Εξωτερική πρόσβαση | Ingress ή Gateway API | Το Resource απαιτεί αντίστοιχο Controller. |
| Προστασία Namespace από υπερβολική χρήση | LimitRange + ResourceQuota | Προεπιλεγμένες τιμές και συνολικά όρια. |
| Το Frontend συνδέεται μόνο με Backend και DNS | NetworkPolicy Default Deny + Allow Rules | Σκόπιμη άδεια για Ingress/Egress. |
4. Μέρος C: Πρακτική λύση
C1: Namespace, LimitRange και ResourceQuota
namespace.yml
apiVersion: v1
kind: Namespace
metadata:
name: exam-intermediate
labels:
environment: exam
level: intermediate
resources/limitrange.yml
apiVersion: v1
kind: LimitRange
metadata:
name: default-container-limits
namespace: exam-intermediate
spec:
limits:
- type: Container
defaultRequest:
cpu: 100m
memory: 128Mi
default:
cpu: 500m
memory: 512Mi
max:
cpu: "2"
memory: 2Gi
resources/resourcequota.yml
apiVersion: v1
kind: ResourceQuota
metadata:
name: exam-quota
namespace: exam-intermediate
spec:
hard:
pods: "10"
requests.cpu: "2"
requests.memory: 2Gi
limits.cpu: "4"
limits.memory: 4Gi
Εφαρμογή:
kubectl apply -f namespace.yml
kubectl apply -f resources/limitrange.yml
kubectl apply -f resources/resourcequota.yml
kubectl describe limitrange default-container-limits -n exam-intermediate
kubectl describe resourcequota exam-quota -n exam-intermediate
Παράδειγμα υπέρβασης Quota:
apiVersion: v1
kind: Pod
metadata:
name: too-large
namespace: exam-intermediate
spec:
containers:
- name: app
image: busybox:1.36
command: ["sh", "-c", "sleep 3600"]
resources:
requests:
cpu: "3"
memory: 3Gi
limits:
cpu: "3"
memory: 3Gi
Αναμενόμενο αποτέλεσμα: Ο API Server απορρίπτει το Pod λόγω του ResourceQuota.
C2: Frontend και Backend με Probes
workloads/backend.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
namespace: exam-intermediate
labels:
app: backend
component: api
environment: exam
spec:
replicas: 2
selector:
matchLabels:
app: backend
template:
metadata:
labels:
app: backend
component: api
environment: exam
spec:
containers:
- name: backend
image: registry.k8s.io/e2e-test-images/agnhost:2.53
args: ["netexec", "--http-port=8080"]
ports:
- name: http
containerPort: 8080
startupProbe:
httpGet:
path: /healthz
port: 8080
failureThreshold: 30
periodSeconds: 2
readinessProbe:
httpGet:
path: /healthz
port: 8080
periodSeconds: 5
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 15
periodSeconds: 10
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
workloads/frontend.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
namespace: exam-intermediate
labels:
app: frontend
component: web
environment: exam
spec:
replicas: 1
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
component: web
environment: exam
spec:
containers:
- name: frontend
image: curlimages/curl:8.8.0
command: ["sh", "-c", "sleep 3600"]
readinessProbe:
exec:
command: ["sh", "-c", "command -v curl >/dev/null"]
periodSeconds: 10
livenessProbe:
exec:
command: ["sh", "-c", "test -d /tmp"]
initialDelaySeconds: 10
periodSeconds: 20
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 200m
memory: 128Mi
networking/services.yml
apiVersion: v1
kind: Service
metadata:
name: backend
namespace: exam-intermediate
spec:
selector:
app: backend
ports:
- name: http
port: 8080
targetPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: frontend
namespace: exam-intermediate
spec:
selector:
app: frontend
ports:
- name: http
port: 80
targetPort: 8080
Εφαρμογή και έλεγχος:
kubectl apply -f workloads/backend.yml
kubectl apply -f workloads/frontend.yml
kubectl apply -f networking/services.yml
kubectl rollout status deployment/backend -n exam-intermediate
kubectl rollout status deployment/frontend -n exam-intermediate
kubectl get deploy,pod,svc,endpoints,endpointslices -n exam-intermediate
Διαφορά μεταξύ Readiness και Liveness:
- Το Readiness αφαιρεί Pods από την κυκλοφορία Service χωρίς να τα επανεκκινεί.
- Το Liveness επανεκκινεί Containers και πρέπει να εντοπίζει μόνο πραγματικά σφάλματα που δεν αποκαθίστανται από μόνα τους.
C3: Job και CronJob
workloads/migration-job.yml
apiVersion: batch/v1
kind: Job
metadata:
name: migration
namespace: exam-intermediate
spec:
backoffLimit: 2
template:
spec:
restartPolicy: OnFailure
containers:
- name: migration
image: busybox:1.36
command: ["sh", "-c", "echo Migration starts; sleep 3; echo Migration successful"]
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 200m
memory: 128Mi
workloads/cleanup-cronjob.yml
apiVersion: batch/v1
kind: CronJob
metadata:
name: cleanup
namespace: exam-intermediate
spec:
schedule: "0 * * * *"
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 1
jobTemplate:
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: cleanup
image: busybox:1.36
command: ["sh", "-c", "date; echo cleanup done"]
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 200m
memory: 128Mi
Έλεγχος:
kubectl apply -f workloads/migration-job.yml
kubectl apply -f workloads/cleanup-cronjob.yml
kubectl get job,cronjob,pod -n exam-intermediate
kubectl logs job/migration -n exam-intermediate
C4: Έλεγχος Scheduling
Προσθέστε Label σε ένα Node:
NODE=$(kubectl get nodes -o jsonpath='{.items[0].metadata.name}')
kubectl label node "$NODE" exam-role=apps
kubectl get nodes --show-labels | grep exam-role
Pod με Selector που ταιριάζει:
apiVersion: v1
kind: Pod
metadata:
name: scheduled-ok
namespace: exam-intermediate
spec:
nodeSelector:
exam-role: apps
containers:
- name: app
image: busybox:1.36
command: ["sh", "-c", "sleep 3600"]
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 100m
memory: 128Mi
Pod με Selector που δεν ταιριάζει:
apiVersion: v1
kind: Pod
metadata:
name: scheduled-pending
namespace: exam-intermediate
spec:
nodeSelector:
exam-role: does-not-exist
containers:
- name: app
image: busybox:1.36
command: ["sh", "-c", "sleep 3600"]
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 100m
memory: 128Mi
Taint και Toleration:
kubectl taint node "$NODE" dedicated=apps:NoSchedule
Pod με Toleration:
apiVersion: v1
kind: Pod
metadata:
name: tolerated
namespace: exam-intermediate
spec:
nodeSelector:
exam-role: apps
tolerations:
- key: dedicated
operator: Equal
value: apps
effect: NoSchedule
containers:
- name: app
image: busybox:1.36
command: ["sh", "-c", "sleep 3600"]
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 100m
memory: 128Mi
Επαλήθευση:
kubectl get pods -o wide -n exam-intermediate
kubectl describe pod scheduled-pending -n exam-intermediate
kubectl get events -n exam-intermediate --sort-by=.metadata.creationTimestamp
Rollback των αλλαγών στον Node:
kubectl taint node "$NODE" dedicated=apps:NoSchedule-
kubectl label node "$NODE" exam-role-
C5: NetworkPolicy με Default Deny και εξαιρέσεις
networking/networkpolicies.yml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
namespace: exam-intermediate
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns-egress
namespace: exam-intermediate
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-egress-to-backend
namespace: exam-intermediate
spec:
podSelector:
matchLabels:
app: frontend
policyTypes:
- Egress
egress:
- to:
- podSelector:
matchLabels:
app: backend
ports:
- protocol: TCP
port: 8080
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-backend-ingress-from-frontend
namespace: exam-intermediate
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
Έλεγχος:
kubectl apply -f networking/networkpolicies.yml
kubectl get networkpolicy -n exam-intermediate
FRONTEND=$(kubectl get pod -l app=frontend -n exam-intermediate -o jsonpath='{.items[0].metadata.name}')
kubectl exec "$FRONTEND" -n exam-intermediate -- nslookup backend
kubectl exec "$FRONTEND" -n exam-intermediate -- curl -s --max-time 5 http://backend:8080/hostname
Έλεγχος του CNI:
kubectl get pods -A | grep -Ei 'calico|cilium|weave|antrea|flannel|kindnet'
Μια καλή λύση τεκμηριώνει αν το συγκεκριμένο CNI επιβάλλει NetworkPolicies. Για παράδειγμα, το Flannel χωρίς επέκταση Policy αξιολογείται διαφορετικά από το Calico ή το Cilium.
C6: Ingress ή Gateway API
Ελέγξτε αν υπάρχει Controller:
kubectl get ingressclass
kubectl get gatewayclass 2>/dev/null || true
kubectl get pods -A | grep -Ei 'ingress|gateway|nginx|traefik|envoy|haproxy'
Παράδειγμα networking/ingress-or-gateway.yml ως Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: shop
namespace: exam-intermediate
spec:
rules:
- host: shop.localtest.me
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: backend
port:
number: 8080
Έλεγχος:
kubectl apply -f networking/ingress-or-gateway.yml
kubectl describe ingress shop -n exam-intermediate
kubectl get ingress shop -n exam-intermediate
Αν δεν υπάρχει Controller:
Στο Lab δεν είναι εγκατεστημένος Ingress ή Gateway Controller. Ο API Server μπορεί να δεχτεί το Resource, αλλά αυτό δεν δρομολογεί πρακτικά την κυκλοφορία, επειδή κανένας Controller δεν το μετατρέπει σε Proxy ή Load Balancer Configuration.
Παράδειγμα Gateway API, αν είναι διαθέσιμο
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: shop
namespace: exam-intermediate
spec:
parentRefs:
- name: shared-gateway
namespace: gateway-system
hostnames:
- shop.localtest.me
rules:
- backendRefs:
- name: backend
port: 8080
C7: PVC και StatefulSet
Ελέγξτε τα StorageClasses:
kubectl get storageclass
storage/statefulset.yml
apiVersion: v1
kind: Service
metadata:
name: data-demo
namespace: exam-intermediate
spec:
clusterIP: None
selector:
app: data-demo
ports:
- name: dummy
port: 80
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: data-demo
namespace: exam-intermediate
spec:
serviceName: data-demo
replicas: 1
selector:
matchLabels:
app: data-demo
template:
metadata:
labels:
app: data-demo
spec:
containers:
- name: app
image: busybox:1.36
command: ["sh", "-c", "while true; do sleep 3600; done"]
volumeMounts:
- name: data
mountPath: /data
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 100m
memory: 128Mi
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 1Gi
Εφαρμογή και επαλήθευση:
kubectl apply -f storage/statefulset.yml
kubectl rollout status statefulset/data-demo -n exam-intermediate
POD=data-demo-0
kubectl exec "$POD" -n exam-intermediate -- sh -c 'echo persistent > /data/test.txt'
kubectl delete pod "$POD" -n exam-intermediate
kubectl wait --for=condition=Ready pod/data-demo-0 -n exam-intermediate --timeout=90s
kubectl exec data-demo-0 -n exam-intermediate -- cat /data/test.txt
Αναμενόμενο αποτέλεσμα: Το αρχείο εξακολουθεί να υπάρχει μετά την αναδημιουργία του Pod, εφόσον το Dynamic Provisioning και η συμπεριφορά του Storage το υποστηρίζουν.
C8: Render με Helm και Kustomize
Παράδειγμα Kustomize:
packaging/kustomize/base/deployment.yml
packaging/kustomize/base/service.yml
packaging/kustomize/base/kustomization.yml
packaging/kustomize/overlays/dev/kustomization.yml
Render:
kubectl kustomize packaging/kustomize/overlays/dev > packaging/kustomize-output.md
Παράδειγμα Helm:
helm create packaging/shop-demo
helm template shop-demo packaging/shop-demo > packaging/helm-output.md
Σύγκριση:
| Κριτήριο | Kustomize | Helm |
|---|---|---|
| Μοντέλο | Patches και Overlays σε υπάρχον YAML. | Chart Package βασισμένο σε Templates. |
| Δυνατότητα Review | Το παραγόμενο YAML βρίσκεται συχνά κοντά στο Source. | Το παραγόμενο YAML χρειάζεται προσεκτικό Review. |
| Παραμετροποίηση | Overlays και Patches. | Values Files και Templates. |
| Κίνδυνος σφαλμάτων | Patch Drift και πολυπλοκότητα Overlays. | Σφάλματα στη λογική Templates και στις τιμές. |
5. Μέρος D: Διαδρομή Troubleshooting
| Μοτίβο σφάλματος | Σύμπτωμα | Διάγνωση | Αιτία | Διόρθωση | Επαλήθευση |
|---|---|---|---|---|---|
Λάθος nodeSelector |
Το Pod παραμένει Pending. |
kubectl describe pod, Events. |
Κανένα Node δεν ταιριάζει με τον Selector. | Διορθώστε τον Selector ή προσθέστε το σωστό Label στο Node. | Το Pod έχει προγραμματιστεί. |
| Λάθος Image Tag | ImagePullBackOff. |
Τα Pod Events δείχνουν αποτυχία Pull. | Το Tag ή το Image δεν υπάρχει. | Ορίστε έγκυρο Image Tag. | Το Pod εκτελείται. |
| Λάθος Startup Command | CrashLoopBackOff. |
kubectl logs --previous, Exit Code. |
Η διεργασία τερματίζεται. | Διορθώστε Command ή Configuration. | Οι επανεκκινήσεις σταματούν. |
| Λάθος StorageClass | Το PVC παραμένει Pending. |
kubectl describe pvc, Events. |
Δεν υπάρχει Provisioner ή StorageClass. | Χρησιμοποιήστε έγκυρο StorageClass ή παραλείψτε το αν υπάρχει προεπιλεγμένο. | Το PVC γίνεται Bound. |
| Λάθος Service Selector | Το Service δεν έχει Endpoints. | Labels, Selector, EndpointSlices. | Ο Selector δεν ταιριάζει. | Διορθώστε τον Selector. | Τα Endpoints συμπληρώνονται. |
6. Αναμενόμενη δομή υποβολής
02-intermediate-submission/
answers.md
architecture-decision.md
workloads/
frontend.yml
backend.yml
migration-job.yml
cleanup-cronjob.yml
resources/
limitrange.yml
resourcequota.yml
networking/
services.yml
networkpolicies.yml
ingress-or-gateway.yml
storage/
statefulset.yml
packaging/
kustomize-output.md
helm-output.md
troubleshooting.md
evidence.md
cleanup.md
7. Cleanup
Προτιμώμενο Cleanup:
kubectl delete namespace exam-intermediate
Αν αλλάξατε Node Labels ή Taints, αναιρέστε τα πάντοτε ρητά:
NODE=$(kubectl get nodes -o jsonpath='{.items[0].metadata.name}')
kubectl taint node "$NODE" dedicated=apps:NoSchedule- || true
kubectl label node "$NODE" exam-role- || true
Επαλήθευση:
kubectl get namespace exam-intermediate
kubectl get nodes --show-labels
kubectl describe node "$NODE" | grep -i taint -A2
8. Βαθμολόγηση και σημειώσεις εξεταστή
Μια ισχυρή λύση:
- επιλέγει Workload Resources βάσει κύκλου ζωής και λειτουργικού μοντέλου,
- διαχωρίζει καθαρά Readiness, Liveness και Startup Probe,
- ορίζει ουσιαστικά Requests και Limits,
- αποδεικνύει την απόρριψη λόγω Quota,
- διαγιγνώσκει το Scheduling με Events αντί για εικασίες,
- αντιμετωπίζει NetworkPolicy και DNS ως χωριστά θέματα,
- κατανοεί ότι το Ingress/Gateway χρειάζεται Controller,
- αποδεικνύει τη συμπεριφορά Persistent Storage ή περιγράφει σωστά τον περιορισμό,
- κάνει Render των Helm και Kustomize πριν εφαρμόσει Resources,
- τεκμηριώνει το Troubleshooting με σύμπτωμα, διάγνωση, αιτία, διόρθωση και επαλήθευση.
Συνήθεις αφαιρέσεις μονάδων:
| Πρόβλημα | Αφαίρεση μονάδων |
|---|---|
| Χρήση Deployment για Migration μίας εκτέλεσης | Μέτρια. |
| Περιγραφή των Readiness και Liveness ως ισοδύναμων | Μεγάλη. |
| NetworkPolicy χωρίς DNS Egress | Μέτρια έως μεγάλη. |
| Απουσιάζει σημείωση για το αν το CNI επιβάλλει Policies | Μέτρια. |
| Δεν αναιρείται το Node Taint | Μεγάλη. |
| Διατυπώνεται ισχυρισμός για τη συμπεριφορά PVC χωρίς Evidence | Μέτρια. |
| Δεν υπάρχει παραγόμενο Output Helm/Kustomize | Μικρή έως μέτρια. |