From 343a2ebe7924d92e5d4d996541a687b29d92aa18 Mon Sep 17 00:00:00 2001 From: Translator Date: Sat, 4 Jul 2026 11:45:43 +0000 Subject: [PATCH] Translated ['src/pentesting-cloud/kubernetes-security/kubernetes-basics. --- .../exposing-services-in-kubernetes.md | 74 ++++---- .../kubernetes-security/kubernetes-basics.md | 160 ++++++++++-------- .../kubernetes-securitycontext-s.md | 78 +++++---- 3 files changed, 171 insertions(+), 141 deletions(-) diff --git a/src/pentesting-cloud/kubernetes-security/exposing-services-in-kubernetes.md b/src/pentesting-cloud/kubernetes-security/exposing-services-in-kubernetes.md index cd648393b..0af844801 100644 --- a/src/pentesting-cloud/kubernetes-security/exposing-services-in-kubernetes.md +++ b/src/pentesting-cloud/kubernetes-security/exposing-services-in-kubernetes.md @@ -2,11 +2,11 @@ {{#include ../../banners/hacktricks-training.md}} -Υπάρχουν **διαφορετικοί τρόποι να expose services** στο Kubernetes, ώστε τόσο τα **internal** endpoints όσο και τα **external** endpoints να μπορούν να τα access. Αυτή η ρύθμιση του Kubernetes είναι αρκετά κρίσιμη, καθώς ο administrator θα μπορούσε να δώσει access σε **attackers σε services στα οποία δεν θα έπρεπε να μπορούν να access**. +Υπάρχουν **διάφοροι τρόποι να expose services** στο Kubernetes, ώστε τόσο τα **internal** endpoints όσο και τα **external** endpoints να μπορούν να τα προσπελάσουν. Αυτή η διαμόρφωση του Kubernetes είναι αρκετά κρίσιμη, καθώς ο administrator θα μπορούσε να δώσει πρόσβαση σε **attackers σε services στα οποία δεν θα έπρεπε να μπορούν να έχουν πρόσβαση**. ### Automatic Enumeration -Πριν ξεκινήσετε να enumerating τους τρόπους που το K8s προσφέρει για να expose services στο public, να ξέρετε ότι αν μπορείτε να list namespaces, services και ingresses, μπορείτε να βρείτε όλα τα exposed στο public με: +Πριν ξεκινήσεις να enumerating τους τρόπους που το K8s προσφέρει για να expose services στο public, να ξέρεις ότι αν μπορείς να list namespaces, services και ingresses, μπορείς να βρεις όλα όσα είναι exposed to the public με: ```bash kubectl get namespace -o custom-columns='NAME:.metadata.name' | grep -v NAME | while IFS='' read -r ns; do echo "Namespace: $ns" @@ -20,13 +20,13 @@ done | grep -v "ClusterIP" ``` ### ClusterIP -Ένα **ClusterIP** service είναι το **default** Kubernetes **service**. Σου δίνει ένα **service inside** το cluster σου που άλλες apps μέσα στο cluster σου μπορούν να προσπελάσουν. Δεν υπάρχει **external access**. +Ένα **ClusterIP** service είναι το **προεπιλεγμένο** Kubernetes **service**. Σου δίνει ένα **service μέσα** στο cluster σου, στο οποίο μπορούν να έχουν πρόσβαση άλλες εφαρμογές μέσα στο cluster σου. Δεν υπάρχει **εξωτερική πρόσβαση**. Ωστόσο, αυτό μπορεί να προσπελαστεί χρησιμοποιώντας το Kubernetes Proxy: ```bash kubectl proxy --port=8080 ``` -Τώρα, μπορείτε να πλοηγηθείτε μέσω του Kubernetes API για να αποκτήσετε πρόσβαση σε services χρησιμοποιώντας αυτό το scheme: +Τώρα, μπορείτε να πλοηγηθείτε μέσω του Kubernetes API για να έχετε πρόσβαση σε services χρησιμοποιώντας αυτό το σχήμα: `http://localhost:8080/api/v1/proxy/namespaces//services/:/` @@ -34,7 +34,7 @@ kubectl proxy --port=8080 `http://localhost:8080/api/v1/proxy/namespaces/default/services/my-internal-service:http/` -για να αποκτήσετε πρόσβαση σε αυτό το service: +για να έχετε πρόσβαση σε αυτό το service: ```yaml apiVersion: v1 kind: Service @@ -50,15 +50,15 @@ port: 80 targetPort: 80 protocol: TCP ``` -_Αυτή η μέθοδος απαιτεί να εκτελέσεις το `kubectl` ως **πιστοποιημένος χρήστης**._ +_Αυτή η μέθοδος απαιτεί να εκτελέσετε το `kubectl` ως **authenticated user**._ -Λίστα όλων των ClusterIPs: +List all ClusterIPs: ```bash kubectl get services --all-namespaces -o=custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,TYPE:.spec.type,CLUSTER-IP:.spec.clusterIP,PORT(S):.spec.ports[*].port,TARGETPORT(S):.spec.ports[*].targetPort,SELECTOR:.spec.selector' | grep ClusterIP ``` ### NodePort -Όταν χρησιμοποιείται το **NodePort**, μια καθορισμένη θύρα γίνεται διαθέσιμη σε όλα τα Nodes (που αντιπροσωπεύουν τα Virtual Machines). Η **κίνηση** που κατευθύνεται σε αυτή τη συγκεκριμένη θύρα στη συνέχεια **δρομολογείται προς το service**. Συνήθως, αυτή η μέθοδος δεν συνιστάται λόγω των μειονεκτημάτων της. +Όταν χρησιμοποιείται το **NodePort**, μια καθορισμένη πόρτα γίνεται διαθέσιμη σε όλους τους Nodes (που αντιπροσωπεύουν τις Virtual Machines). Η **Traffic** που κατευθύνεται σε αυτή τη συγκεκριμένη πόρτα στη συνέχεια **δρομολογείται προς το service**. Συνήθως, αυτή η μέθοδος δεν συνιστάται λόγω των μειονεκτημάτων της. List all NodePorts: ```bash @@ -81,30 +81,41 @@ targetPort: 80 nodePort: 30036 protocol: TCP ``` -Αν **δεν καθορίσεις** το **nodePort** στο yaml (είναι η θύρα που θα ανοίξει), θα χρησιμοποιηθεί μια θύρα στο **εύρος 30000–32767**. +Αν **δεν ορίσεις** το **nodePort** στο yaml (είναι η θύρα που θα ανοίξει), θα χρησιμοποιηθεί μια θύρα στο **εύρος 30000–32767**. + +Όταν ελέγχεις NodePort ή LoadBalancer Services, εξέτασε επίσης τα traffic-policy fields, επειδή αλλάζουν ποιοι nodes και backends είναι χρήσιμοι από μια δεδομένη source: +```bash +kubectl get services --all-namespaces \ +-o custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,TYPE:.spec.type,ETP:.spec.externalTrafficPolicy,ITP:.spec.internalTrafficPolicy,AFFINITY:.spec.sessionAffinity,DIST:.spec.trafficDistribution,NODEPORTS:.spec.ports[*].nodePort' +``` +- `externalTrafficPolicy: Local` διατηρεί το αρχικό client source IP για NodePort/LoadBalancer traffic και αποφεύγει το forwarding σε endpoints σε άλλους nodes. Ένα node χωρίς local ready endpoint μπορεί να απορρίψει το traffic ακόμα κι αν το Service έχει endpoints αλλού. +- `externalTrafficPolicy: Cluster` είναι το default και μπορεί να κάνει forward μέσω οποιουδήποτε node, αλλά τα backend logs μπορεί να βλέπουν node IPs αντί για το πραγματικό external client IP. +- `internalTrafficPolicy: Local` περιορίζει το in-cluster Service traffic σε endpoints που είναι local στο source node. Αυτό είναι locality routing, όχι authorization boundary. +- `sessionAffinity: ClientIP` μπορεί να κάνει επαναλαμβανόμενα tests από έναν client να χτυπούν το ίδιο backend, κρύβοντας άλλα ready endpoints κατά τη διάρκεια manual checks. +- `trafficDistribution` και EndpointSlice topology hints μπορούν να προτιμούν same-zone ή same-node endpoints σε νεότερα clusters· να τα αντιμετωπίζεις ως routing preferences και όχι ως αυστηρό security policy. ### LoadBalancer -Εκθέτει το Service εξωτερικά **χρησιμοποιώντας το load balancer ενός cloud provider**. Στο GKE, αυτό θα δημιουργήσει ένα [Network Load Balancer](https://cloud.google.com/compute/docs/load-balancing/network/) που θα σου δώσει μία μοναδική IP διεύθυνση η οποία θα προωθεί όλη την κίνηση στο service σου. Στο AWS θα εκκινήσει ένα Load Balancer. +Exposes the Service externally **using a cloud provider's load balancer**. On GKE, this will spin up a [Network Load Balancer](https://cloud.google.com/compute/docs/load-balancing/network/) that will give you a single IP address that will forward all traffic to your service. In AWS it will launch a Load Balancer. -Πρέπει να πληρώνεις για ένα LoadBalancer ανά εκτεθειμένο service, κάτι που μπορεί να είναι ακριβό. +You have to pay for a LoadBalancer per exposed service, which can be expensive. -Λίστα όλων των LoadBalancers: +List all LoadBalancers: ```bash kubectl get services --all-namespaces -o=custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,TYPE:.spec.type,CLUSTER-IP:.spec.clusterIP,EXTERNAL-IP:.status.loadBalancer.ingress[*],PORT(S):.spec.ports[*].port,NODEPORT(S):.spec.ports[*].nodePort,TARGETPORT(S):.spec.ports[*].targetPort,SELECTOR:.spec.selector' | grep LoadBalancer ``` ### External IPs > [!TIP] -> Τα External IPs εκτίθενται από services τύπου Load Balancers και χρησιμοποιούνται γενικά όταν αξιοποιείται ένα εξωτερικό Cloud Provider Load Balancer. +> Τα External IPs εκτίθενται από services τύπου Load Balancers και γενικά χρησιμοποιούνται όταν γίνεται χρήση ενός εξωτερικού Cloud Provider Load Balancer. > -> Για να τα βρείτε, ελέγξτε για load balancers με τιμές στο πεδίο `EXTERNAL-IP`. +> Για να τα βρεις, έλεγξε για load balancers με τιμές στο πεδίο `EXTERNAL-IP`. -Η κίνηση που εισέρχεται στο cluster με το **external IP** (ως **destination IP**), στο Service port, θα **δρομολογηθεί σε ένα από τα Service endpoints**. Τα `externalIPs` δεν διαχειρίζονται από το Kubernetes και αποτελούν ευθύνη του cluster administrator. +Η κίνηση που εισέρχεται στο cluster με το **external IP** (ως **destination IP**), στο Service port, θα **δρομολογείται σε ένα από τα Service endpoints**. Τα `externalIPs` δεν διαχειρίζονται από το Kubernetes και αποτελούν ευθύνη του cluster administrator. -Τα `externalIPs` είναι ένα ευαίσθητο πεδίο route-control επειδή ένας user που μπορεί να το ορίσει ίσως διεκδικήσει traffic για μια IP address που ο Service owner δεν θα έπρεπε να ελέγχει, αν το surrounding network routes αυτή την IP στο cluster. Το Kubernetes ανακοίνωσε την deprecation και το planned removal των Service `externalIPs` στο v1.36, οπότε προτιμήστε controller-owned exposure mechanisms όπως LoadBalancer integrations ή Gateway API όπου είναι δυνατό, και περιορίστε/επιτρέψτε αυτό το πεδίο προσεκτικά όσο ακόμη υπάρχει. +Το `externalIPs` είναι ένα ευαίσθητο πεδίο route-control επειδή ένας χρήστης που μπορεί να το ορίσει ίσως διεκδικήσει traffic για μια IP address που ο Service owner δεν θα έπρεπε να ελέγχει, αν το surrounding network δρομολογεί αυτή την IP προς το cluster. Το Kubernetes ανακοίνωσε την deprecation και την προγραμματισμένη αφαίρεση του Service `externalIPs` στο v1.36, οπότε προτίμησε controller-owned exposure mechanisms όπως LoadBalancer integrations ή Gateway API όπου είναι δυνατό, και περιόρισε/επέτρεψε αυτό το πεδίο προσεκτικά όσο ακόμη υπάρχει. -Στο Service spec, τα `externalIPs` μπορούν να οριστούν μαζί με οποιονδήποτε από τους `ServiceTypes`. Στο παρακάτω παράδειγμα, το "`my-service`" μπορεί να προσπελαστεί από clients στο "`80.11.12.10:80`" (`externalIP:port`) +Στο Service spec, το `externalIPs` μπορεί να καθοριστεί μαζί με οποιονδήποτε από τους `ServiceTypes`. Στο παρακάτω παράδειγμα, το "`my-service`" μπορεί να προσπελαστεί από clients στο "`80.11.12.10:80`" (`externalIP:port`) ```yaml apiVersion: v1 kind: Service @@ -123,9 +134,9 @@ externalIPs: ``` ### ExternalName -[**Από τα docs:**](https://kubernetes.io/docs/concepts/services-networking/service/#externalname) Τα Services τύπου ExternalName **αντιστοιχίζουν ένα Service σε ένα DNS name**, όχι σε έναν τυπικό selector όπως `my-service` ή `cassandra`. Ορίζετε αυτά τα Services με την παράμετρο `spec.externalName`. +[**Από τα docs:**](https://kubernetes.io/docs/concepts/services-networking/service/#externalname) Τα Services τύπου ExternalName **αντιστοιχίζουν ένα Service σε ένα DNS name**, όχι σε έναν τυπικό selector όπως `my-service` ή `cassandra`. Καθορίζεις αυτά τα Services με την παράμετρο `spec.externalName`. -Αυτό το Service definition, για παράδειγμα, αντιστοιχίζει το Service `my-service` στο namespace `prod` στο `my.database.example.com`: +Αυτό το Service definition, για παράδειγμα, αντιστοιχίζει το `my-service` Service στο namespace `prod` στο `my.database.example.com`: ```yaml apiVersion: v1 kind: Service @@ -136,7 +147,7 @@ spec: type: ExternalName externalName: my.database.example.com ``` -Όταν αναζητάς τον host `my-service.prod.svc.cluster.local`, το cluster DNS Service επιστρέφει ένα `CNAME` record με τιμή `my.database.example.com`. Η πρόσβαση στο `my-service` λειτουργεί με τον ίδιο τρόπο όπως σε άλλα Services, αλλά με τη σημαντική διαφορά ότι η **redirection συμβαίνει σε επίπεδο DNS** και όχι μέσω proxying ή forwarding. +Όταν αναζητάς το host `my-service.prod.svc.cluster.local`, το cluster DNS Service επιστρέφει μια εγγραφή `CNAME` με τιμή `my.database.example.com`. Η πρόσβαση στο `my-service` λειτουργεί με τον ίδιο τρόπο όπως σε άλλες Services, αλλά με τη σημαντική διαφορά ότι η **ανακατεύθυνση γίνεται σε επίπεδο DNS** αντί μέσω proxying ή forwarding. List all ExternalNames: ```bash @@ -144,24 +155,24 @@ kubectl get services --all-namespaces | grep ExternalName ``` ### EndpointSlices -Τα EndpointSlices δείχνουν τις συγκεκριμένες backend διευθύνσεις και ports προς τα οποία δρομολογεί ένα Service αυτή τη στιγμή. Είναι ιδιαίτερα χρήσιμα όταν ένα Service δεν έχει selector, όταν τα labels δεν εξηγούν το traffic path, ή όταν μόνο μερικά backends είναι ready. +Τα EndpointSlices δείχνουν τις συγκεκριμένες backend διευθύνσεις και ports προς τα οποία δρομολογεί αυτή τη στιγμή ένα Service. Είναι ιδιαίτερα χρήσιμα όταν ένα Service δεν έχει selector, όταν τα labels δεν εξηγούν τη διαδρομή της κίνησης, ή όταν μόνο κάποια backends είναι έτοιμα. -Λίστα EndpointSlices που σχετίζονται με Services: +List EndpointSlices associated with Services: ```bash kubectl get endpointslices --all-namespaces kubectl get endpointslice -n -l kubernetes.io/service-name= -o yaml kubectl get endpointslice -n -l kubernetes.io/service-name= \ -o custom-columns='NAME:.metadata.name,ADDR:.endpoints[*].addresses,READY:.endpoints[*].conditions.ready,PORTS:.ports[*].port' ``` -Κατά την εξέταση της έκθεσης, σύγκρινε το Service selector με το EndpointSlice `targetRef`, τις διευθύνσεις endpoint, τις συνθήκες readiness και τις θύρες. Ένα selectorless Service μπορεί να συνδυαστεί με χειροκίνητα διαχειριζόμενα EndpointSlices και να δρομολογήσει traffic σε non-Pod ή απροσδόκητους προορισμούς. +Κατά τον έλεγχο της έκθεσης, σύγκρινε τον Service selector με το EndpointSlice `targetRef`, τις endpoint addresses, τις readiness conditions και τα ports. Ένα selectorless Service μπορεί να συνδυαστεί με EndpointSlices που διαχειρίζονται χειροκίνητα και να δρομολογεί traffic σε μη-Pod ή απρόσμενους προορισμούς. ### Ingress -Σε αντίθεση με όλα τα παραπάνω παραδείγματα, το **Ingress ΔΕΝ είναι τύπος service**. Αντίθετα, βρίσκεται **μπροστά από πολλά services και λειτουργεί ως “smart router”** ή entrypoint στο cluster σου. +Σε αντίθεση με όλα τα παραπάνω παραδείγματα, το **Ingress ΔΕΝ είναι τύπος service**. Αντίθετα, βρίσκεται **μπροστά από πολλαπλά services και λειτουργεί ως “smart router”** ή entrypoint στο cluster σου. -Μπορείς να κάνεις πολλά διαφορετικά πράγματα με ένα Ingress, και υπάρχουν **πολλοί τύποι από Ingress controllers που έχουν διαφορετικές δυνατότητες**. +Μπορείς να κάνεις πολλά διαφορετικά πράγματα με ένα Ingress, και υπάρχουν **πολλοί τύποι Ingress controllers που έχουν διαφορετικές δυνατότητες**. -Ο default GKE ingress controller θα εκκινήσει ένα [HTTP(S) Load Balancer](https://cloud.google.com/compute/docs/load-balancing/http/) για εσένα. Αυτό θα σου επιτρέψει να κάνεις routing τόσο βάσει path όσο και βάσει subdomain προς backend services. Για παράδειγμα, μπορείς να στείλεις τα πάντα στο foo.yourdomain.com στο foo service, και τα πάντα κάτω από το path yourdomain.com/bar/ στο bar service. +Ο default GKE ingress controller θα εκκινήσει για εσένα ένα [HTTP(S) Load Balancer](https://cloud.google.com/compute/docs/load-balancing/http/). Αυτό θα σου επιτρέψει να κάνεις τόσο path based όσο και subdomain based routing προς backend services. Για παράδειγμα, μπορείς να στείλεις τα πάντα στο foo.yourdomain.com στο foo service, και τα πάντα κάτω από το path yourdomain.com/bar/ στο bar service. Το YAML για ένα Ingress object στο GKE με ένα [L7 HTTP Load Balancer](https://cloud.google.com/compute/docs/load-balancing/http/) μπορεί να μοιάζει κάπως έτσι: ```yaml @@ -201,15 +212,15 @@ number: 8080 ```bash kubectl get ingresses --all-namespaces -o=custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,RULES:spec.rules[*],STATUS:status' ``` -Αν και σε αυτήν την περίπτωση είναι καλύτερα να πάρεις τις πληροφορίες του καθενός μία-μία για να τις διαβάσεις καλύτερα: +Αν και σε αυτή την περίπτωση είναι καλύτερο να πάρεις τις πληροφορίες του καθενός ξεχωριστά για να τις διαβάσεις καλύτερα: ```bash kubectl get ingresses --all-namespaces -o=yaml ``` ### Gateway API -Το Gateway API είναι το νεότερο Kubernetes API για την έκθεση Services. Διαχωρίζει τα αντικείμενα Gateway που ανήκουν στην υποδομή από τα αντικείμενα Route που ανήκουν στην εφαρμογή, όπως το HTTPRoute. Αυτό είναι χρήσιμο για delegation, αλλά σημαίνει επίσης ότι η έκθεση μπορεί να μοιραστεί across namespaces. +Το Gateway API είναι το νεότερο Kubernetes API για την έκθεση Services. Διαχωρίζει τα Gateway objects που ανήκουν στην υποδομή από τα Route objects που ανήκουν στην εφαρμογή, όπως το HTTPRoute. Αυτό είναι χρήσιμο για delegation, αλλά σημαίνει επίσης ότι η έκθεση μπορεί να είναι κατανεμημένη across namespaces. -Καταγράψτε τα αντικείμενα έκθεσης Gateway API: +List Gateway API exposure objects: ```bash kubectl get gatewayclasses kubectl get gateways --all-namespaces @@ -217,13 +228,16 @@ kubectl get httproutes --all-namespaces kubectl get gateway -n -o yaml kubectl get httproute -n -o yaml ``` -Έλεγξε Gateway listeners, allowed route namespaces, Route `parentRefs`, hostnames, filters, backend references και status conditions όπως το αν το route έγινε accepted. Ένα Route που γίνεται accepted από ένα shared Gateway μπορεί να εκθέσει ένα backend ακόμα κι όταν δεν υπάρχει legacy Ingress object. +Έλεγξε Gateway listeners, allowed route namespaces, Route `parentRefs`, hostnames, filters, backend references, και status conditions όπως αν το route έγινε accepted. Ένα Route που γίνεται accepted από ένα shared Gateway μπορεί να expose ένα backend ακόμα και όταν δεν υπάρχει legacy Ingress object. ### References - [https://medium.com/google-cloud/kubernetes-nodeport-vs-loadbalancer-vs-ingress-when-should-i-use-what-922f010849e0](https://medium.com/google-cloud/kubernetes-nodeport-vs-loadbalancer-vs-ingress-when-should-i-use-what-922f010849e0) - [https://kubernetes.io/docs/concepts/services-networking/service/](https://kubernetes.io/docs/concepts/services-networking/service/) - [https://kubernetes.io/blog/2026/05/14/kubernetes-v1-36-deprecation-and-removal-of-service-externalips/](https://kubernetes.io/blog/2026/05/14/kubernetes-v1-36-deprecation-and-removal-of-service-externalips/) +- [https://kubernetes.io/docs/concepts/services-networking/service-traffic-policy/](https://kubernetes.io/docs/concepts/services-networking/service-traffic-policy/) +- [https://kubernetes.io/docs/tutorials/services/source-ip/](https://kubernetes.io/docs/tutorials/services/source-ip/) +- [https://kubernetes.io/docs/concepts/services-networking/topology-aware-routing/](https://kubernetes.io/docs/concepts/services-networking/topology-aware-routing/) - [https://kubernetes.io/docs/concepts/services-networking/endpoint-slices/](https://kubernetes.io/docs/concepts/services-networking/endpoint-slices/) - [https://gateway-api.sigs.k8s.io/](https://gateway-api.sigs.k8s.io/) diff --git a/src/pentesting-cloud/kubernetes-security/kubernetes-basics.md b/src/pentesting-cloud/kubernetes-security/kubernetes-basics.md index c26fce231..296b84c07 100644 --- a/src/pentesting-cloud/kubernetes-security/kubernetes-basics.md +++ b/src/pentesting-cloud/kubernetes-security/kubernetes-basics.md @@ -2,62 +2,64 @@ {{#include ../../banners/hacktricks-training.md}} -**Ο αρχικός συγγραφέας αυτής της σελίδας είναι** [**Jorge**](https://www.linkedin.com/in/jorge-belmonte-a924b616b/) **(διάβασε το αρχικό του post** [**εδώ**](https://sickrov.github.io)**)** +**Ο αρχικός συγγραφέας αυτής της σελίδας είναι** [**Jorge**](https://www.linkedin.com/in/jorge-belmonte-a924b616b/) **(διάβασε το αρχικό του post [**εδώ**](https://sickrov.github.io)**)** ## Architecture & Basics -### What does Kubernetes do? +### Τι κάνει το Kubernetes; -- Επιτρέπει την εκτέλεση container/s σε έναν container engine. -- Το schedule επιτρέπει στα containers να έχουν efficient αποστολή. -- Κρατά τα containers ζωντανά. -- Επιτρέπει τις communications μεταξύ containers. +- Επιτρέπει την εκτέλεση container/s σε ένα container engine. +- Το schedule επιτρέπει στα containers να χρησιμοποιούν τους πόρους αποδοτικά. +- Διατηρεί τα containers ζωντανά. +- Επιτρέπει επικοινωνίες μεταξύ containers. - Επιτρέπει deployment techniques. -- Διαχειρίζεται volumes of information. +- Διαχειρίζεται volumes πληροφοριών. ### Architecture ![Kubernetes architecture diagram showing control plane components, API server, kubelet, kube-proxy, pods, and worker nodes](https://sickrov.github.io/media/Screenshot-68.jpg) -- **Node**: operating system με pod ή pods. -- **Pod**: Wrapper γύρω από ένα container ή multiple containers με. Ένα pod θα πρέπει να περιέχει μόνο μία application (οπότε συνήθως, ένα pod εκτελεί μόνο 1 container). Το pod είναι ο τρόπος με τον οποίο το kubernetes abstract το container technology που εκτελείται. -- **Service**: Κάθε pod έχει 1 εσωτερική **IP address** από το εσωτερικό range του node. Ωστόσο, μπορεί επίσης να εκτεθεί μέσω ενός service. Το **service έχει επίσης ένα IP address** και ο στόχος του είναι να διατηρεί την communication μεταξύ pods, ώστε αν ένα πεθάνει το **νέο replacement** (με διαφορετικό εσωτερικό IP) **θα είναι προσβάσιμο** εκτεθειμένο στο **ίδιο IP του service**. Μπορεί να ρυθμιστεί ως internal ή external. Το service λειτουργεί επίσης ως **load balancer όταν 2 pods είναι συνδεδεμένα** στο ίδιο service.\ -Όταν ένα **service** **δημιουργείται** μπορείς να βρεις τα endpoints κάθε service τρέχοντας `kubectl get endpoints` -- **Kubelet**: Primary node agent. Το component που καθιερώνει communication μεταξύ node και kubectl, και μπορεί να εκτελέσει μόνο pods (μέσω API server). Το kubelet δεν διαχειρίζεται containers που δεν δημιουργήθηκαν από Kubernetes. -- **Kube-proxy**: είναι το service που είναι υπεύθυνο για τις communications (services) μεταξύ του apiserver και του node. Η βάση είναι ένα IPtables για nodes. Πιο έμπειροι χρήστες θα μπορούσαν να εγκαταστήσουν άλλα kube-proxies από άλλους vendors. -- **Sidecar container**: Τα Sidecar containers είναι τα containers που θα πρέπει να εκτελούνται μαζί με το main container στο pod. Αυτό το sidecar pattern επεκτείνει και ενισχύει τη functionality των current containers χωρίς να τα αλλάζει. Σήμερα, ξέρουμε ότι χρησιμοποιούμε container technology για να τυλίγουμε όλες τις dependencies ώστε η application να τρέχει παντού. Ένα container κάνει μόνο ένα πράγμα και το κάνει πολύ καλά. +- **Node**: λειτουργικό σύστημα με pod ή pods. +- **Pod**: Wrapper γύρω από ένα container ή πολλαπλά containers μαζί. Ένα pod θα πρέπει να περιέχει μόνο μία εφαρμογή (άρα συνήθως, ένα pod εκτελεί μόνο 1 container). Το pod είναι ο τρόπος με τον οποίο το kubernetes abstract το container technology που εκτελείται. +- **Service**: Κάθε pod έχει 1 εσωτερική **IP address** από το εσωτερικό range του node. Ωστόσο, μπορεί επίσης να εκτεθεί μέσω ενός service. Το **service έχει επίσης μια IP address** και ο στόχος του είναι να διατηρεί την επικοινωνία μεταξύ pods, ώστε αν ένα πεθάνει το **νέο replacement** (με διαφορετική εσωτερική IP) **να είναι προσβάσιμο** εκτεθειμένο στην **ίδια IP του service**. Μπορεί να ρυθμιστεί ως internal ή external. Το service λειτουργεί επίσης ως **load balancer όταν 2 pods είναι συνδεδεμένα** στο ίδιο service.\ +Όταν ένα **service** **δημιουργείται** μπορείς να βρεις τα endpoints κάθε service εκτελώντας `kubectl get endpoints` +- **Kubelet**: Primary node agent. Το component που δημιουργεί επικοινωνία μεταξύ node και kubectl, και μπορεί να εκτελέσει μόνο pods (μέσω API server). Το kubelet δεν διαχειρίζεται containers που δεν δημιουργήθηκαν από το Kubernetes. +- **Kube-proxy**: είναι το service που είναι υπεύθυνο για τις επικοινωνίες (services) μεταξύ του apiserver και του node. Η βάση είναι ένα IPtables για nodes. Πιο έμπειροι χρήστες θα μπορούσαν να εγκαταστήσουν άλλα kube-proxies από άλλους vendors. +- **Sidecar container**: Τα Sidecar containers είναι τα containers που πρέπει να εκτελούνται μαζί με το main container στο pod. Αυτό το sidecar pattern επεκτείνει και ενισχύει τη λειτουργικότητα των current containers χωρίς να τα αλλάζει. Σήμερα, ξέρουμε ότι χρησιμοποιούμε container technology για να τυλίξουμε όλες τις dependencies της εφαρμογής ώστε να τρέχει οπουδήποτε. Ένα container κάνει μόνο ένα πράγμα και το κάνει πολύ καλά. - **Master process:** - **Api Server:** Είναι ο τρόπος με τον οποίο οι users και τα pods χρησιμοποιούν για να επικοινωνούν με το master process. Μόνο authenticated request θα πρέπει να επιτρέπονται. -- **Scheduler**: Το Scheduling αναφέρεται στο να διασφαλίζεται ότι τα Pods ταιριάζουν με Nodes ώστε το Kubelet να μπορεί να τα εκτελέσει. Έχει αρκετή intelligence για να αποφασίσει ποιο node έχει περισσότερους διαθέσιμους resources και να αναθέσει το νέο pod σε αυτό. Σημείωσε ότι ο scheduler δεν ξεκινά νέα pods, απλώς επικοινωνεί με το Kubelet process που τρέχει μέσα στο node, το οποίο θα εκκινήσει το νέο pod. -- **Kube Controller manager**: Ελέγχει resources όπως replica sets ή deployments για να δει αν, για παράδειγμα, εκτελείται ο σωστός αριθμός pods ή nodes. Σε περίπτωση που λείπει ένα pod, θα επικοινωνήσει με το scheduler για να ξεκινήσει ένα νέο. Ελέγχει replication, tokens, και account services προς το API. -- **etcd**: Data storage, persistent, consistent, και distributed. Είναι η database του Kubernetes και το key-value storage όπου κρατά το πλήρες state των clusters (κάθε αλλαγή καταγράφεται εδώ). Components όπως ο Scheduler ή ο Controller manager εξαρτώνται από αυτά τα data για να ξέρουν ποιες αλλαγές έχουν συμβεί (available resourced of the nodes, number of pods running...) -- **Cloud controller manager**: Είναι ο συγκεκριμένος controller για flow controls και applications, δηλαδή: αν έχεις clusters σε AWS ή OpenStack. +- **Scheduler**: Το Scheduling αναφέρεται στο να διασφαλίζει ότι τα Pods αντιστοιχίζονται σε Nodes ώστε το Kubelet να μπορεί να τα εκτελέσει. Έχει αρκετή intelligence για να αποφασίσει ποιο node έχει περισσότερους διαθέσιμους πόρους και να αναθέσει το νέο pod σε αυτό. Σημείωσε ότι ο scheduler δεν ξεκινά νέα pods, απλώς επικοινωνεί με το Kubelet process που τρέχει μέσα στο node, το οποίο θα εκκινήσει το νέο pod. +- **Kube Controller manager**: Ελέγχει resources όπως replica sets ή deployments για να δει αν, για παράδειγμα, εκτελείται ο σωστός αριθμός από pods ή nodes. Σε περίπτωση που λείπει ένα pod, θα επικοινωνήσει με τον scheduler για να ξεκινήσει ένα νέο. Ελέγχει replication, tokens και account services προς το API. +- **etcd**: Data storage, persistent, consistent και distributed. Είναι η βάση δεδομένων του Kubernetes και το key-value storage όπου κρατά την πλήρη κατάσταση των clusters (κάθε αλλαγή καταγράφεται εδώ). Components όπως ο Scheduler ή ο Controller manager εξαρτώνται από αυτά τα date για να ξέρουν ποιες αλλαγές έχουν συμβεί (available resourced of the nodes, number of pods running...) +- **Cloud controller manager**: Είναι ο συγκεκριμένος controller για flow controls και applications, δηλ.: αν έχεις clusters σε AWS ή OpenStack. -Σημείωσε ότι καθώς μπορεί να υπάρχουν αρκετά nodes (που εκτελούν αρκετά pods), μπορεί επίσης να υπάρχουν αρκετά master processes, των οποίων η πρόσβαση στο Api server είναι load balanced και το etcd τους synchronized. +Σημείωσε ότι καθώς μπορεί να υπάρχουν several nodes (που εκτελούν several pods), μπορεί επίσης να υπάρχουν several master processes των οποίων η πρόσβαση στο Api server είναι load balanced και το etcd τους συγχρονισμένο. **Volumes:** -Όταν ένα pod δημιουργεί data που δεν θα πρέπει να χαθούν όταν το pod εξαφανιστεί, θα πρέπει να αποθηκεύεται σε ένα physical volume. **Το Kubernetes επιτρέπει να attach ένα volume σε ένα pod για να persist τα data**. Το volume μπορεί να βρίσκεται στο local machine ή σε ένα **remote storage**. Αν εκτελείς pods σε διαφορετικά physical nodes, θα πρέπει να χρησιμοποιήσεις remote storage ώστε όλα τα pods να μπορούν να το προσπελάσουν. +Όταν ένα pod δημιουργεί data που δεν πρέπει να χαθούν όταν το pod εξαφανιστεί, θα πρέπει να αποθηκεύονται σε ένα physical volume. Το **Kubernetes επιτρέπει να συνδέσεις ένα volume σε ένα pod για να διατηρήσεις τα data**. Το volume μπορεί να είναι στο local machine ή σε ένα **remote storage**. Αν εκτελείς pods σε διαφορετικά physical nodes θα πρέπει να χρησιμοποιήσεις ένα remote storage ώστε όλα τα pods να μπορούν να το προσπελάσουν. + +Το Kubernetes υποστηρίζει επίσης **image volumes** σε πρόσφατες εκδόσεις. Ένα `image` volume κάνει mount ένα OCI image ή artifact ως **read-only** filesystem source μέσα στο Pod, χρησιμοποιώντας πεδία όπως `volumes[].image.reference` και `volumes[].image.pullPolicy`. Το kubelet κάνει pull το artifact με τις ίδιες credential sources που χρησιμοποιούνται για container images, συμπεριλαμβανομένων των node credentials, Pod `imagePullSecrets`, και ServiceAccount `imagePullSecrets`. Κατά τη διάρκεια ενός security review, αντιμετώπισε τα image volumes ως runtime inputs και supply-chain dependencies: έλεγξε αν το reference είναι pinned by digest, ποια registry credentials μπορούν να το fetch, πού γίνεται mount, και αν το `subPath` περιορίζει τον ορατό κατάλογο. **Other configurations:** -- **ConfigMap**: Μπορείς να ρυθμίσεις **URLs** για πρόσβαση σε services. Το pod θα πάρει data από εδώ για να ξέρει πώς να επικοινωνεί με το υπόλοιπο των services (pods). Σημείωσε ότι αυτό δεν είναι το recommended place για να αποθηκεύεις credentials! -- **Secret**: Αυτό είναι το μέρος για να **store secret data** όπως passwords, API keys... encoded σε B64. Το pod θα μπορεί να προσπελάσει αυτά τα data για να χρησιμοποιήσει τα required credentials. -- **Deployments**: Εδώ υποδεικνύονται τα components που θα εκτελεστούν από kubernetes. Ένας user συνήθως δεν θα δουλεύει απευθείας με pods, τα pods abstract σε **ReplicaSets** (αριθμός ίδιων pods replicated), τα οποία εκτελούνται μέσω deployments. Σημείωσε ότι τα deployments είναι για **stateless** applications. Η ελάχιστη διαμόρφωση για ένα deployment είναι το name και το image που θα εκτελεστεί. -- **StatefulSet**: Αυτό το component προορίζεται συγκεκριμένα για applications όπως **databases** που χρειάζονται να **access the same storage**. -- **Ingress**: Αυτή είναι η ρύθμιση που χρησιμοποιείται για να **expose the application publicly with an URL**. Σημείωσε ότι αυτό μπορεί επίσης να γίνει χρησιμοποιώντας external services, αλλά αυτός είναι ο σωστός τρόπος για να εκθέσεις την application. -- Αν υλοποιήσεις ένα Ingress θα χρειαστεί να δημιουργήσεις **Ingress Controllers**. Ο Ingress Controller είναι ένα **pod** που θα είναι το endpoint που θα δέχεται τα requests και θα τα ελέγχει και θα τα load balance προς τα services. ο ingress controller θα **send the request based on the ingress rules configured**. Σημείωσε ότι τα ingress rules μπορούν να δείχνουν σε διαφορετικά paths ή ακόμα και subdomains προς διαφορετικά internal kubernetes services. +- **ConfigMap**: Μπορείς να ρυθμίσεις **URLs** για πρόσβαση σε services. Το pod θα λάβει data από εδώ για να ξέρει πώς να επικοινωνεί με τα υπόλοιπα services (pods). Σημείωσε ότι αυτό δεν είναι το recommended place για να αποθηκεύεις credentials! +- **Secret**: Αυτό είναι το μέρος για να **αποθηκεύεις secret data** όπως passwords, API keys... encoded σε B64. Το pod θα μπορεί να προσπελάσει αυτά τα data για να χρησιμοποιήσει τα απαιτούμενα credentials. +- **Deployments**: Εδώ καθορίζονται τα components που θα εκτελεστούν από το kubernetes. Ένας user συνήθως δεν δουλεύει απευθείας με pods, τα pods abstract σε **ReplicaSets** (number of same pods replicated), τα οποία εκτελούνται μέσω deployments. Σημείωσε ότι τα deployments είναι για **stateless** applications. Η ελάχιστη ρύθμιση για ένα deployment είναι το name και το image που θα εκτελεστεί. +- **StatefulSet**: Αυτό το component προορίζεται ειδικά για εφαρμογές όπως **databases** που χρειάζονται να **προσπελάζουν το ίδιο storage**. +- **Ingress**: Αυτή είναι η configuration που χρησιμοποιείται για να **εκθέσει την εφαρμογή publicly με ένα URL**. Σημείωσε ότι αυτό μπορεί επίσης να γίνει χρησιμοποιώντας external services, αλλά αυτός είναι ο σωστός τρόπος για να εκθέσεις την εφαρμογή. +- Αν υλοποιήσεις ένα Ingress θα χρειαστεί να δημιουργήσεις **Ingress Controllers**. Ο Ingress Controller είναι ένα **pod** που θα είναι το endpoint που θα λαμβάνει τα requests και θα τα ελέγχει και θα τα load balance προς τα services. ο ingress controller θα **στέλνει το request βάσει των ingress rules που έχουν ρυθμιστεί**. Σημείωσε ότι τα ingress rules μπορούν να δείχνουν σε διαφορετικά paths ή ακόμη και subdomains προς διαφορετικά internal kubernetes services. - Μια καλύτερη security practice θα ήταν να χρησιμοποιήσεις ένα cloud load balancer ή έναν proxy server ως entrypoint ώστε να μην υπάρχει κανένα μέρος του Kubernetes cluster exposed. -- Όταν λαμβάνεται request που δεν ταιριάζει με κανένα ingress rule, ο ingress controller θα το κατευθύνει στο "**Default backend**". Μπορείς να κάνεις `describe` τον ingress controller για να πάρεις τη διεύθυνση αυτής της παραμέτρου. +- Όταν λαμβάνεται request που δεν ταιριάζει με κανένα ingress rule, ο ingress controller θα το κατευθύνει στο "**Default backend**". Μπορείς να `describe` τον ingress controller για να πάρεις τη διεύθυνση αυτής της παραμέτρου. - `minikube addons enable ingress` ### PKI infrastructure - Certificate Authority CA: ![Kubernetes CA and PKI diagram showing API server certificates between clients, scheduler, controller manager, kubelet, and etcd](https://sickrov.github.io/media/Screenshot-66.jpg) -- CA is το trusted root για όλα τα certificates μέσα στο cluster. +- Η CA είναι το trusted root για όλα τα certificates μέσα στο cluster. - Επιτρέπει στα components να κάνουν validate το ένα το άλλο. -- Όλα τα cluster certificates είναι signed by the CA. +- Όλα τα cluster certificates υπογράφονται από την CA. - Το ETCd έχει το δικό του certificate. - types: - apiserver cert. @@ -68,7 +70,7 @@ ### Minikube -Το **Minikube** μπορεί να χρησιμοποιηθεί για να πραγματοποιήσεις μερικά **quick tests** στο kubernetes χωρίς να χρειάζεται να deploy ολόκληρο kubernetes environment. Θα εκτελέσει τα **master and node processes σε ένα machine**. Το Minikube θα χρησιμοποιήσει virtualbox για να εκτελέσει το node. Δες [**εδώ πώς να το εγκαταστήσεις**](https://minikube.sigs.k8s.io/docs/start/). +Το **Minikube** μπορεί να χρησιμοποιηθεί για να εκτελέσει μερικά **quick tests** στο kubernetes χωρίς να χρειάζεται να αναπτυχθεί ολόκληρο kubernetes environment. Θα εκτελεί τα **master και node processes σε ένα μηχάνημα**. Το Minikube θα χρησιμοποιήσει το virtualbox για να εκτελέσει το node. Δες [**εδώ πώς να το εγκαταστήσεις**](https://minikube.sigs.k8s.io/docs/start/). ``` $ minikube start 😄 minikube v1.19.0 on Ubuntu 20.04 @@ -105,7 +107,7 @@ $ minikube delete ``` ### Kubectl Basics -**`Kubectl`** είναι το command line tool για τα kubernetes clusters. Επικοινωνεί με τον Api server της master process για να εκτελεί actions στο kubernetes ή για να ζητά δεδομένα. +**`Kubectl`** είναι το command line tool για kubernetes clusters. Επικοινωνεί με το Api server της master process για να εκτελεί actions στο kubernetes ή για να ζητά δεδομένα. ```bash kubectl version #Get client and server version kubectl get pod @@ -138,7 +140,7 @@ kubectl apply -f deployment.yml ``` ### Minikube Dashboard -Το dashboard σάς επιτρέπει να βλέπετε πιο εύκολα τι εκτελεί το minikube, μπορείτε να βρείτε το URL για να το προσπελάσετε στο: +Το dashboard σάς επιτρέπει να δείτε πιο εύκολα τι εκτελεί το minikube, μπορείτε να βρείτε το URL για να το προσπελάσετε στο: ``` minikube dashboard --url @@ -151,14 +153,14 @@ minikube dashboard --url 🤔 Verifying proxy health ... http://127.0.0.1:50034/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/ ``` -### Παραδείγματα αρχείων ρύθμισης YAML +### YAML configuration files examples -Κάθε αρχείο ρύθμισης έχει 3 μέρη: **metadata**, **specification** (τι πρέπει να εκκινηθεί), **status** (επιθυμητή κατάσταση).\ -Μέσα στο specification του deployment configuration file μπορείς να βρεις το template που ορίζεται με μια νέα configuration structure που καθορίζει το image που θα εκτελεστεί: +Κάθε configuration file έχει 3 μέρη: **metadata**, **specification** (τι χρειάζεται να ξεκινήσει), **status** (desired state).\ +Μέσα στη specification του deployment configuration file μπορείς να βρεις το template ορισμένο με μια νέα configuration structure που καθορίζει το image to run: -**Παράδειγμα Deployment + Service που δηλώνονται στο ίδιο configuration file (from** [**here**](https://gitlab.com/nanuchi/youtube-tutorial-series/-/blob/master/demo-kubernetes-components/mongo.yaml)**)** +**Example of Deployment + Service declared in the same configuration file (from** [**here**](https://gitlab.com/nanuchi/youtube-tutorial-series/-/blob/master/demo-kubernetes-components/mongo.yaml)**)** -Εφόσον ένα service συνήθως σχετίζεται με ένα deployment, είναι δυνατό να δηλώσεις και τα δύο στο ίδιο configuration file (το service που δηλώνεται σε αυτό το config είναι προσβάσιμο μόνο εσωτερικά): +Καθώς ένα service συνήθως σχετίζεται με ένα deployment, είναι δυνατό να δηλώσεις και τα δύο στο ίδιο configuration file (το service που δηλώνεται σε αυτό το config είναι προσβάσιμο μόνο εσωτερικά): ```yaml apiVersion: apps/v1 kind: Deployment @@ -225,11 +227,11 @@ targetPort: 8081 nodePort: 30000 ``` > [!NOTE] -> Αυτό είναι χρήσιμο για testing, αλλά για production θα πρέπει να έχετε μόνο internal services και ένα Ingress για να εκθέσετε την application. +> Αυτό είναι χρήσιμο για testing, αλλά για production θα πρέπει να έχετε μόνο internal services και ένα Ingress για να εκθέσετε την εφαρμογή. **Example of Ingress config file** -Αυτό θα εκθέσει την application στο `http://dashboard.com`. +Αυτό θα εκθέσει την εφαρμογή στο `http://dashboard.com`. ```yaml apiVersion: networking.k8s.io/v1 kind: Ingress @@ -245,9 +247,9 @@ paths: serviceName: kubernetes-dashboard servicePort: 80 ``` -**Παράδειγμα αρχείου secrets config** +**Παράδειγμα αρχείου ρυθμίσεων μυστικών** -Παρατήρησε πώς οι κωδικοί πρόσβασης είναι encoded σε B64 (το οποίο δεν είναι secure!) +Δες πώς οι κωδικοί πρόσβασης είναι κωδικοποιημένοι σε B64 (που δεν είναι ασφαλές!) ```yaml apiVersion: v1 kind: Secret @@ -269,7 +271,7 @@ name: mongodb-configmap data: database_url: mongodb-service ``` -Στη συνέχεια, μέσα σε ένα **deployment config** αυτή η διεύθυνση μπορεί να καθοριστεί με τον ακόλουθο τρόπο, ώστε να φορτωθεί μέσα στο env του pod: +Στη συνέχεια, μέσα σε ένα **deployment config** αυτή η διεύθυνση μπορεί να καθοριστεί με τον ακόλουθο τρόπο ώστε να φορτωθεί μέσα στο env του pod: ```yaml [...] spec: @@ -290,16 +292,16 @@ name: mongodb-configmap key: database_url [...] ``` -**Παράδειγμα volume config** +**Example of volume config** -Μπορείτε να βρείτε διαφορετικά παραδείγματα αρχείων yaml storage configuration στο [https://gitlab.com/nanuchi/youtube-tutorial-series/-/tree/master/kubernetes-volumes](https://gitlab.com/nanuchi/youtube-tutorial-series/-/tree/master/kubernetes-volumes).\ +Μπορείτε να βρείτε διαφορετικά examples από storage configuration yaml files στο [https://gitlab.com/nanuchi/youtube-tutorial-series/-/tree/master/kubernetes-volumes](https://gitlab.com/nanuchi/youtube-tutorial-series/-/tree/master/kubernetes-volumes).\ **Σημειώστε ότι τα volumes δεν βρίσκονται μέσα σε namespaces** ### Namespaces -Το Kubernetes υποστηρίζει **πολλαπλά virtual clusters** που υποστηρίζονται από το ίδιο physical cluster. Αυτά τα virtual clusters ονομάζονται **namespaces**. Προορίζονται για χρήση σε περιβάλλοντα με πολλούς χρήστες που είναι διασκορπισμένοι σε πολλαπλές ομάδες ή projects. Για clusters με λίγους έως δεκάδες χρήστες, δεν θα πρέπει να χρειάζεται να δημιουργείτε ή να σκέφτεστε καθόλου namespaces. Θα πρέπει να αρχίσετε να χρησιμοποιείτε namespaces μόνο για να έχετε καλύτερο έλεγχο και οργάνωση κάθε μέρους της application που έχει deployed στο kubernetes. +Το Kubernetes υποστηρίζει **multiple virtual clusters** που υποστηρίζονται από το ίδιο physical cluster. Αυτά τα virtual clusters ονομάζονται **namespaces**. Προορίζονται για χρήση σε environments με πολλούς users που είναι κατανεμημένοι σε multiple teams ή projects. Για clusters με λίγους έως δεκάδες users, δεν θα πρέπει να χρειάζεται να δημιουργήσετε ή να σκέφτεστε καθόλου τα namespaces. Θα πρέπει να αρχίσετε να χρησιμοποιείτε namespaces μόνο για να έχετε καλύτερο control και organization κάθε μέρους της application που έχει deployed στο kubernetes. -Τα Namespaces παρέχουν ένα scope για τα names. Τα names των resources πρέπει να είναι μοναδικά μέσα σε ένα namespace, αλλά όχι σε όλα τα namespaces. Τα Namespaces δεν μπορούν να είναι nested το ένα μέσα στο άλλο και κάθε Kubernetes **resource** μπορεί να βρίσκεται μόνο σε ένα namespace. +Τα namespaces παρέχουν ένα scope για names. Τα names των resources πρέπει να είναι μοναδικά μέσα σε ένα namespace, αλλά όχι across namespaces. Τα namespaces δεν μπορούν να είναι nested το ένα μέσα στο άλλο και **κάθε** Kubernetes **resource** μπορεί να είναι μόνο **σε** **ένα** namespace. Υπάρχουν 4 namespaces by default αν χρησιμοποιείτε minikube: ``` @@ -310,39 +312,39 @@ kube-node-lease Active 1d kube-public Active 1d kube-system Active 1d ``` -- **kube-system**: Δεν προορίζεται για χρήση από τους χρήστες και δεν πρέπει να το αγγίζεις. Είναι για master και kubectl processes. -- **kube-public**: Publicly accessible date. Περιέχει ένα configmap που περιέχει πληροφορίες του cluster +- **kube-system**: Δεν προορίζεται για χρήση από τους χρήστες και δεν θα πρέπει να το αγγίξεις. Είναι για τις διεργασίες master και kubectl. +- **kube-public**: Δημόσια προσβάσιμα δεδομένα. Περιέχει ένα configmap που περιέχει πληροφορίες για το cluster - **kube-node-lease**: Καθορίζει τη διαθεσιμότητα ενός node -- **default**: Το namespace που ο χρήστης θα χρησιμοποιεί για να δημιουργεί resources +- **default**: Το namespace που θα χρησιμοποιήσει ο χρήστης για να δημιουργήσει resources ```bash #Create namespace kubectl create namespace my-namespace ``` > [!NOTE] -> Σημειώστε ότι οι περισσότερες Kubernetes resources (π.χ. pods, services, replication controllers, και άλλα) βρίσκονται σε κάποια namespaces. Ωστόσο, άλλες resources όπως namespace resources και low-level resources, όπως nodes και persistenVolumes δεν βρίσκονται σε ένα namespace. Για να δείτε ποια Kubernetes resources είναι και ποια δεν είναι σε ένα namespace: +> Σημειώστε ότι οι περισσότερες Kubernetes resources (π.χ. pods, services, replication controllers και άλλα) βρίσκονται σε κάποια namespaces. Ωστόσο, άλλες resources όπως namespace resources και low-level resources, όπως nodes και persistenVolumes, δεν βρίσκονται σε namespace. Για να δείτε ποιες Kubernetes resources είναι και ποιες δεν είναι σε namespace: > > ```bash > kubectl api-resources --namespaced=true #In a namespace > kubectl api-resources --namespaced=false #Not in a namespace > ``` -Μπορείτε να αποθηκεύσετε το namespace για όλες τις επόμενες kubectl commands σε αυτό το context. +Μπορείτε να αποθηκεύσετε το namespace για όλες τις επόμενες kubectl commands σε εκείνο το context. ```bash kubectl config set-context --current --namespace= ``` ### Helm -Το Helm είναι ο **package manager** για το Kubernetes. Επιτρέπει τη συσκευασία αρχείων YAML και τη διανομή τους σε δημόσια και ιδιωτικά repositories. Αυτά τα packages ονομάζονται **Helm Charts**. +Το Helm είναι ο **package manager** για το Kubernetes. Επιτρέπει τη συσκευασία αρχείων YAML και τη διανομή τους σε public και private repositories. Αυτά τα packages ονομάζονται **Helm Charts**. ``` helm search ``` -Το Helm είναι επίσης ένα template engine που επιτρέπει τη δημιουργία config files με variables: +Helm είναι επίσης ένα template engine που επιτρέπει τη δημιουργία config files με variables: ## Kubernetes secrets -Ένα **Secret** είναι ένα object που **περιέχει sensitive data** όπως ένα password, ένα token ή ένα key. Τέτοιες πληροφορίες διαφορετικά θα μπορούσαν να τοποθετηθούν σε ένα Pod specification ή σε ένα image. Οι χρήστες μπορούν να δημιουργούν Secrets και το σύστημα επίσης δημιουργεί Secrets. Το όνομα ενός Secret object πρέπει να είναι έγκυρο **DNS subdomain name**. Διαβάστε εδώ [the official documentation](https://kubernetes.io/docs/concepts/configuration/secret/). +Ένα **Secret** είναι ένα object που **περιέχει ευαίσθητα δεδομένα** όπως ένα password, ένα token ή ένα key. Τέτοιες πληροφορίες διαφορετικά θα μπορούσαν να μπουν σε ένα Pod specification ή σε ένα image. Οι χρήστες μπορούν να δημιουργούν Secrets και το σύστημα επίσης δημιουργεί Secrets. Το όνομα ενός Secret object πρέπει να είναι ένα έγκυρο **DNS subdomain name**. Διάβασε εδώ [την επίσημη τεκμηρίωση](https://kubernetes.io/docs/concepts/configuration/secret/). -Secrets μπορεί να είναι πράγματα όπως: +Τα Secrets μπορεί να είναι πράγματα όπως: - API, SSH Keys. - OAuth tokens. @@ -366,11 +368,11 @@ Secrets μπορεί να είναι πράγματα όπως: > [!NOTE] > **Ο τύπος Opaque είναι ο προεπιλεγμένος, το τυπικό key-value pair που ορίζεται από τους χρήστες.** -**Πώς λειτουργούν τα secrets:** +**How secrets works:** ![Kubernetes secrets diagram showing secret data reaching the API server and being consumed by a pod](https://sickrov.github.io/media/Screenshot-164.jpg) -Το ακόλουθο configuration file ορίζει ένα **secret** με όνομα `mysecret` με 2 key-value pairs `username: YWRtaW4=` και `password: MWYyZDFlMmU2N2Rm`. Ορίζει επίσης ένα **pod** με όνομα `secretpod` που θα έχει τα `username` και `password` που ορίζονται στο `mysecret` εκτεθειμένα στις **environment variables** `SECRET_USERNAME` \_\_ και \_\_ `SECRET_PASSWOR`. Θα επίσης **mount** το secret `username` μέσα στο `mysecret` στο path `/etc/foo/my-group/my-username` με δικαιώματα `0640`. +Το παρακάτω configuration file ορίζει ένα **secret** με όνομα `mysecret` με 2 key-value pairs `username: YWRtaW4=` και `password: MWYyZDFlMmU2N2Rm`. Ορίζει επίσης ένα **pod** με όνομα `secretpod` που θα έχει τα `username` και `password` που ορίζονται στο `mysecret` εκτεθειμένα στις **environment variables** `SECRET_USERNAME` \_\_ και \_\_ `SECRET_PASSWOR`. Θα κάνει επίσης **mount** το secret `username` μέσα στο `mysecret` στο path `/etc/foo/my-group/my-username` με δικαιώματα `0640`. ```yaml:secretpod.yaml apiVersion: v1 kind: Secret @@ -422,25 +424,25 @@ env | grep SECRET && cat /etc/foo/my-group/my-username && echo ``` ### Μυστικά στο etcd -**etcd** είναι ένα συνεπές και υψηλής διαθεσιμότητας **key-value store** που χρησιμοποιείται ως backing store του Kubernetes για όλα τα δεδομένα του cluster. Ας αποκτήσουμε πρόσβαση στα secrets που είναι αποθηκευμένα στο etcd: +**etcd** είναι ένα συνεπές και ιδιαίτερα διαθέσιμο **key-value store** που χρησιμοποιείται ως backing store του Kubernetes για όλα τα δεδομένα του cluster. Ας αποκτήσουμε πρόσβαση στα secrets που είναι αποθηκευμένα στο etcd: ```bash cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep etcd ``` -Θα δείτε certs, keys και url’s που βρίσκονται στο FS. Μόλις τα αποκτήσετε, θα μπορείτε να συνδεθείτε στο etcd. +Θα δείτε ότι τα certs, keys και τα url’s βρίσκονται στο FS. Μόλις τα αποκτήσετε, θα μπορείτε να συνδεθείτε στο etcd. ```bash #ETCDCTL_API=3 etcdctl --cert --key --cacert endpoint=[] health ETCDCTL_API=3 etcdctl --cert /etc/kubernetes/pki/apiserver-etcd-client.crt --key /etc/kubernetes/pki/apiserver-etcd-client.key --cacert /etc/kubernetes/pki/etcd/etcd/ca.cert endpoint=[127.0.0.1:1234] health ``` -Μόλις καταφέρεις να εγκαθιδρύσεις επικοινωνία, θα μπορείς να αποκτήσεις τα secrets: +Μόλις επιτύχεις να establish communication, θα μπορείς να αποκτήσεις τα secrets: ```bash #ETCDCTL_API=3 etcdctl --cert --key --cacert endpoint=[] get ETCDCTL_API=3 etcdctl --cert /etc/kubernetes/pki/apiserver-etcd-client.crt --key /etc/kubernetes/pki/apiserver-etcd-client.key --cacert /etc/kubernetes/pki/etcd/etcd/ca.cert endpoint=[127.0.0.1:1234] get /registry/secrets/default/secret_02 ``` -**Προσθέτοντας encryption στο ETCD** +**Προσθήκη encryption στο ETCD** -By default all the secrets are **stored in plain** text inside etcd unless you apply an encryption layer. The following example is based on [https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/) +By default όλα τα secrets είναι **stored in plain** text μέσα στο etcd εκτός αν εφαρμόσεις ένα encryption layer. Το ακόλουθο παράδειγμα βασίζεται στο [https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/) ```yaml:encryption.yaml apiVersion: apiserver.config.k8s.io/v1 kind: EncryptionConfiguration @@ -454,20 +456,20 @@ keys: secret: cjjPMcWpTPKhAdieVtd+KhG4NN+N6e3NmBPMXJvbfrY= #Any random key - identity: {} ``` -Μετά από αυτό, πρέπει να ορίσετε το flag `--encryption-provider-config` στο `kube-apiserver` ώστε να δείχνει στη θέση του δημιουργημένου config file. Μπορείτε να τροποποιήσετε το `/etc/kubernetes/manifest/kube-apiserver.yaml` και να προσθέσετε τις ακόλουθες γραμμές: +Μετά από αυτό, πρέπει να ορίσετε το flag `--encryption-provider-config` στο `kube-apiserver` ώστε να δείχνει στη θέση του αρχείου ρύθμισης που δημιουργήθηκε. Μπορείτε να τροποποιήσετε το `/etc/kubernetes/manifest/kube-apiserver.yaml` και να προσθέσετε τις ακόλουθες γραμμές: ```yaml containers: - command: - kube-apiserver - --encriyption-provider-config=/etc/kubernetes/etcd/ ``` -Κάντε scroll down στο volumeMounts: +Κύλησε προς τα κάτω στο volumeMounts: ```yaml - mountPath: /etc/kubernetes/etcd name: etcd readOnly: true ``` -Κάνε scroll προς τα κάτω στο volumeMounts μέχρι το hostPath: +Κάνε scroll down στο `volumeMounts` μέχρι το `hostPath`: ```yaml - hostPath: path: /etc/kubernetes/etcd @@ -476,41 +478,41 @@ name: etcd ``` **Επαλήθευση ότι τα δεδομένα είναι κρυπτογραφημένα** -Τα δεδομένα κρυπτογραφούνται όταν γράφονται στο etcd. Μετά την επανεκκίνηση του `kube-apiserver`, κάθε νέο ή ενημερωμένο secret θα πρέπει να είναι κρυπτογραφημένο όταν αποθηκεύεται. Για να το ελέγξεις, μπορείς να χρησιμοποιήσεις το πρόγραμμα γραμμής εντολών `etcdctl` για να ανακτήσεις τα περιεχόμενα του secret σου. +Τα δεδομένα κρυπτογραφούνται όταν γράφονται στο etcd. Μετά την επανεκκίνηση του `kube-apiserver`, κάθε newly created ή updated secret θα πρέπει να είναι κρυπτογραφημένο όταν αποθηκεύεται. Για να το ελέγξεις, μπορείς να χρησιμοποιήσεις το `etcdctl` command line program για να ανακτήσεις τα περιεχόμενα του secret σου. -1. Δημιούργησε ένα νέο secret με όνομα `secret1` στο namespace `default`: +1. Δημιούργησε ένα νέο secret με όνομα `secret1` στο `default` namespace: ``` kubectl create secret generic secret1 -n default --from-literal=mykey=mydata ``` -2. Χρησιμοποιώντας το commandline `etcdctl`, διάβασε αυτό το secret από το etcd: +2. Χρησιμοποιώντας το etcdctl commandline, διάβασε αυτό το secret από το etcd: `ETCDCTL_API=3 etcdctl get /registry/secrets/default/secret1 [...] | hexdump -C` -όπου το `[...]` πρέπει να είναι τα επιπλέον arguments για τη σύνδεση στον etcd server. +όπου το `[...]` πρέπει να είναι τα additional arguments για σύνδεση στον etcd server. -3. Επαλήθευσε ότι το αποθηκευμένο secret έχει πρόθεμα `k8s:enc:aescbc:v1:` το οποίο δείχνει ότι ο provider `aescbc` έχει κρυπτογραφήσει τα παραγόμενα δεδομένα. +3. Επαλήθευσε ότι το αποθηκευμένο secret έχει πρόθεμα `k8s:enc:aescbc:v1:` το οποίο δείχνει ότι ο `aescbc` provider έχει κρυπτογραφήσει τα resulting data. 4. Επαλήθευσε ότι το secret αποκρυπτογραφείται σωστά όταν ανακτάται μέσω του API: ``` kubectl describe secret secret1 -n default ``` -θα πρέπει να ταιριάζει με `mykey: bXlkYXRh`, το mydata είναι encoded, έλεγξε [decoding a secret](https://kubernetes.io/docs/concepts/configuration/secret#decoding-a-secret) για να αποκωδικοποιήσεις πλήρως το secret. +θα πρέπει να ταιριάζει με `mykey: bXlkYXRh`, το mydata είναι encoded, έλεγξε το [decoding a secret](https://kubernetes.io/docs/concepts/configuration/secret#decoding-a-secret) για να αποκωδικοποιήσεις πλήρως το secret. -**Εφόσον τα secrets κρυπτογραφούνται κατά την εγγραφή, η πραγματοποίηση μιας ενημέρωσης σε ένα secret θα κρυπτογραφήσει εκείνο το περιεχόμενο:** +**Εφόσον τα secrets κρυπτογραφούνται κατά την εγγραφή, η εκτέλεση update σε ένα secret θα κρυπτογραφήσει αυτό το περιεχόμενο:** ``` kubectl get secrets --all-namespaces -o json | kubectl replace -f - ``` **Τελικές συμβουλές:** -- Προσπάθησε να μην κρατάς secrets στο FS, πάρε τα από άλλα μέρη. -- Δες το [https://www.vaultproject.io/](https://www.vaultproject.io) για να προσθέσεις περισσότερη προστασία στα secrets σου. +- Προσπαθήστε να μην κρατάτε secrets στο FS, πάρτε τα από άλλα μέρη. +- Δείτε το [https://www.vaultproject.io/](https://www.vaultproject.io) για να προσθέσετε περισσότερη προστασία στα secrets σας. - [https://kubernetes.io/docs/concepts/configuration/secret/#risks](https://kubernetes.io/docs/concepts/configuration/secret/#risks) - [https://docs.cyberark.com/Product-Doc/OnlineHelp/AAM-DAP/11.2/en/Content/Integrations/Kubernetes_deployApplicationsConjur-k8s-Secrets.htm](https://docs.cyberark.com/Product-Doc/OnlineHelp/AAM-DAP/11.2/en/Content/Integrations/Kubernetes_deployApplicationsConjur-k8s-Secrets.htm) -## Αναφορές +## References {{#ref}} https://sickrov.github.io/ @@ -520,4 +522,12 @@ https://sickrov.github.io/ https://www.youtube.com/watch?v=X48VuDVv0do {{#endref}} +{{#ref}} +https://kubernetes.io/docs/concepts/storage/volumes/#image +{{#endref}} + +{{#ref}} +https://kubernetes.io/docs/tasks/configure-pod-container/image-volumes/ +{{#endref}} + {{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-cloud/kubernetes-security/kubernetes-hardening/kubernetes-securitycontext-s.md b/src/pentesting-cloud/kubernetes-security/kubernetes-hardening/kubernetes-securitycontext-s.md index cf24e73ae..736b6fbd0 100644 --- a/src/pentesting-cloud/kubernetes-security/kubernetes-hardening/kubernetes-securitycontext-s.md +++ b/src/pentesting-cloud/kubernetes-security/kubernetes-hardening/kubernetes-securitycontext-s.md @@ -6,79 +6,85 @@ [**Από τα docs:**](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core) -Όταν καθορίζεις το security context ενός Pod, μπορείς να χρησιμοποιήσεις αρκετά attributes. Από αμυντική σκοπιά ασφάλειας, θα πρέπει να εξετάσεις: +Όταν καθορίζεις το security context ενός Pod μπορείς να χρησιμοποιήσεις αρκετά attributes. Από άποψη defensive security θα πρέπει να εξετάσεις: - Να έχεις το **runASNonRoot** ως **True** - Να ρυθμίσεις το **runAsUser** -- Αν είναι δυνατόν, να εξετάσεις τον **περιορισμό** των **permissions** δηλώνοντας **seLinuxOptions** και **seccompProfile** -- Να ΜΗΝ δίνεις access σε **privilege** **group** μέσω των **runAsGroup** και **supplementaryGroups** +- Αν είναι δυνατόν, να εξετάσεις τον **περιορισμό** των **permissions** καθορίζοντας **seLinuxOptions** και **seccompProfile** +- ΜΗΝ δίνεις πρόσβαση σε **privilege** **group** μέσω **runAsGroup** και **supplementaryGroups** | Parameter | Description | -|

fsGroup
integer

|

Ένα ειδικό supplemental group που εφαρμόζεται σε όλα τα containers σε ένα pod. Ορισμένοι τύποι volume επιτρέπουν στο Kubelet να αλλάξει το ownership αυτού του volume ώστε να ανήκει στο pod:
1. Το owning GID θα είναι το FSGroup
2. Το setgid bit ορίζεται (νέα αρχεία που δημιουργούνται στο volume θα ανήκουν στο FSGroup)
3. Τα permission bits γίνονται OR με rw-rw---- Αν δεν οριστεί, το Kubelet δεν θα τροποποιήσει το ownership και τα permissions κανενός volume

| +|

fsGroup
integer

|

Ένα ειδικό supplemental group που εφαρμόζεται σε όλα τα containers σε ένα pod. Ορισμένοι τύποι volumes επιτρέπουν στο Kubelet να αλλάξει το ownership αυτού του volume ώστε να ανήκει στο pod:
1. Το owning GID θα είναι το FSGroup
2. Το setgid bit ορίζεται (τα νέα files που δημιουργούνται στο volume θα ανήκουν στο FSGroup)
3. Τα permission bits γίνονται OR με rw-rw---- Αν δεν οριστεί, το Kubelet δεν θα τροποποιήσει το ownership και τα permissions κανενός volume

| |

fsGroupChangePolicy
string

| Αυτό καθορίζει τη συμπεριφορά της **αλλαγής ownership και permission του volume** πριν εκτεθεί μέσα στο Pod. | -|

runAsGroup
integer

| Το **GID για να εκτελεστεί το entrypoint της container process**. Χρησιμοποιεί το runtime default αν δεν οριστεί. Μπορεί επίσης να οριστεί στο SecurityContext. | -|

runAsNonRoot
boolean

| Δείχνει ότι το container πρέπει να εκτελείται ως non-root user. Αν είναι true, το Kubelet θα επαληθεύσει το image κατά το runtime ώστε να διασφαλίσει ότι δεν εκτελείται ως UID 0 (root) και θα αποτύχει να ξεκινήσει το container αν το κάνει. | -|

runAsUser
integer

| Το **UID για να εκτελεστεί το entrypoint της container process**. Προεπιλογή ο χρήστης που έχει οριστεί στα image metadata αν δεν καθοριστεί. | -|

seLinuxOptions
SELinuxOptions
More info about seLinux

| Το **SELinux context που θα εφαρμοστεί σε όλα τα containers**. Αν δεν οριστεί, το container runtime θα αποδώσει ένα τυχαίο SELinux context για κάθε container. | +|

runAsGroup
integer

| Το **GID για να εκτελεστεί το entrypoint του container process**. Χρησιμοποιεί το runtime default αν δεν οριστεί. Μπορεί επίσης να οριστεί στο SecurityContext. | +|

runAsNonRoot
boolean

| Δείχνει ότι το container πρέπει να εκτελείται ως non-root user. Αν είναι true, το Kubelet θα επαληθεύσει το image κατά το runtime ώστε να βεβαιωθεί ότι δεν εκτελείται ως UID 0 (root) και θα αποτύχει να ξεκινήσει το container αν το κάνει. | +|

runAsUser
integer

| Το **UID για να εκτελεστεί το entrypoint του container process**. Προεπιλογή είναι ο user που ορίζεται στα image metadata αν δεν καθοριστεί. | +|

seLinuxOptions
SELinuxOptions
More info about seLinux

| Το **SELinux context που θα εφαρμοστεί σε όλα τα containers**. Αν δεν καθοριστεί, το container runtime θα εκχωρήσει ένα τυχαίο SELinux context για κάθε container. | |

seccompProfile
SeccompProfile
More info about Seccomp

| Οι **seccomp options που θα χρησιμοποιηθούν από τα containers** σε αυτό το pod. | |

supplementalGroups
integer array

| Μια λίστα από **groups που εφαρμόζονται στο πρώτο process που εκτελείται σε κάθε container**, επιπλέον του primary GID του container. | |

sysctls
Sysctl array
More info about sysctls

| Τα Sysctls περιέχουν μια λίστα από **namespaced sysctls που χρησιμοποιούνται για το pod**. Pods με unsupported sysctls (από το container runtime) μπορεί να αποτύχουν να ξεκινήσουν. | -|

windowsOptions
WindowsSecurityContextOptions

| Οι Windows-specific ρυθμίσεις που εφαρμόζονται σε όλα τα containers. Αν δεν οριστούν, θα χρησιμοποιηθούν οι options μέσα στο SecurityContext ενός container. | +|

windowsOptions
WindowsSecurityContextOptions

| Οι ρυθμίσεις ειδικές για Windows που εφαρμόζονται σε όλα τα containers. Αν δεν καθοριστούν, θα χρησιμοποιηθούν οι options μέσα στο SecurityContext ενός container. | ## SecurityContext [**Από τα docs:**](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core) -Αυτό το context ορίζεται μέσα στα **containers definitions**. Από αμυντική σκοπιά ασφάλειας, θα πρέπει να εξετάσεις: +Αυτό το context ορίζεται μέσα στα **containers definitions**. Από άποψη defensive security θα πρέπει να εξετάσεις: -- **allowPrivilegeEscalation** ως **False** -- Μην προσθέτεις ευαίσθητα **capabilities** (και αφαίρεσε όσα δεν χρειάζεσαι) -- **privileged** ως **False** +- **allowPrivilegeEscalation** σε **False** +- Μην προσθέτεις sensitive **capabilities** (και αφαίρεσε όσες δεν χρειάζεσαι) +- **privileged** σε **False** - Αν είναι δυνατόν, όρισε το **readOnlyFilesystem** ως **True** -- Όρισε **runAsNonRoot** σε **True** και όρισε ένα **runAsUser** -- Αν είναι δυνατόν, να εξετάσεις τον **περιορισμό** των **permissions** δηλώνοντας **seLinuxOptions** και **seccompProfile** -- Να ΜΗΝ δίνεις access σε **privilege** **group** μέσω των **runAsGroup.** +- Όρισε το **runAsNonRoot** σε **True** και όρισε ένα **runAsUser** +- Αν είναι δυνατόν, εξέτασε τον **περιορισμό** των **permissions** καθορίζοντας **seLinuxOptions** και **seccompProfile** +- ΜΗΝ δίνεις πρόσβαση σε **privilege** **group** μέσω **runAsGroup.** -Σημείωσε ότι στα attributes που ορίζονται και στα **SecurityContext και PodSecurityContext**, η τιμή που καθορίζεται στο **SecurityContext** έχει **προτεραιότητα**. +Σημείωσε ότι στα attributes που ορίζονται και στα **SecurityContext και PodSecurityContext**, υπερισχύει η τιμή που ορίζεται στο **SecurityContext**. -|

allowPrivilegeEscalation
boolean

| Το **AllowPrivilegeEscalation** ελέγχει αν μια process μπορεί να **αποκτήσει περισσότερα privileges** από τη parent process της. Αυτό το bool ελέγχει άμεσα αν το no_new_privs flag θα οριστεί στο container process. Το AllowPrivilegeEscalation είναι πάντα true όταν το container εκτελείται ως **Privileged** ή έχει **CAP_SYS_ADMIN** | +|

allowPrivilegeEscalation
boolean

| Το **AllowPrivilegeEscalation** ελέγχει αν ένα process μπορεί να **αποκτήσει περισσότερα privileges** από το parent process του. Αυτό το bool ελέγχει άμεσα αν το no_new_privs flag θα οριστεί στο container process. Το AllowPrivilegeEscalation είναι πάντα true όταν το container εκτελείται ως **Privileged** ή έχει **CAP_SYS_ADMIN** | | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -|

capabilities
Capabilities
More info about Capabilities

| Τα **capabilities που θα προστεθούν/αφαιρεθούν κατά την εκτέλεση containers**. Προεπιλογή το default set of capabilities. | -|

privileged
boolean

| Εκτέλεσε το container σε privileged mode. Οι processes σε privileged containers είναι ουσιαστικά **ισοδύναμες με root στο host**. Προεπιλογή false. | -|

procMount
string

| Το procMount δηλώνει τον **τύπο proc mount που θα χρησιμοποιηθεί για τα containers**. Η προεπιλογή είναι DefaultProcMount, που χρησιμοποιεί τα container runtime defaults για readonly paths και masked paths. | -|

readOnlyRootFilesystem
boolean

| Αν αυτό το **container έχει root filesystem μόνο για ανάγνωση**. Η προεπιλογή είναι false. | -|

runAsGroup
integer

| Το **GID για να εκτελεστεί το entrypoint** της container process. Χρησιμοποιεί το runtime default αν δεν οριστεί. | -|

runAsNonRoot
boolean

| Δείχνει ότι το container πρέπει να **εκτελείται ως non-root user**. Αν είναι true, το Kubelet θα επαληθεύσει το image κατά το runtime ώστε να διασφαλίσει ότι δεν εκτελείται ως UID 0 (root) και θα αποτύχει να ξεκινήσει το container αν το κάνει. | -|

runAsUser
integer

| Το **UID για να εκτελεστεί το entrypoint** της container process. Προεπιλογή ο χρήστης που έχει οριστεί στα image metadata αν δεν καθοριστεί. | -|

seLinuxOptions
SELinuxOptions
More info about seLinux

| Το **SELinux context που θα εφαρμοστεί στο container**. Αν δεν οριστεί, το container runtime θα αποδώσει ένα τυχαίο SELinux context για κάθε container. | +|

capabilities
Capabilities
More info about Capabilities

| Τα **capabilities που θα προστεθούν/αφαιρεθούν κατά την εκτέλεση containers**. Προεπιλογή είναι το default set of capabilities. | +|

privileged
boolean

| Εκτέλεση container σε privileged mode. Τα processes σε privileged containers είναι ουσιαστικά **ισοδύναμα με root στο host**. Προεπιλογή είναι false. | +|

procMount
string

| Το procMount δηλώνει τον **τύπο του proc mount που θα χρησιμοποιηθεί για τα containers**. Η προεπιλογή είναι το DefaultProcMount, το οποίο χρησιμοποιεί τα container runtime defaults για readonly paths και masked paths. | +|

readOnlyRootFilesystem
boolean

| Αν αυτό το **container έχει read-only root filesystem**. Προεπιλογή είναι false. | +|

runAsGroup
integer

| Το **GID για να εκτελεστεί το entrypoint** του container process. Χρησιμοποιεί runtime default αν δεν οριστεί. | +|

runAsNonRoot
boolean

| Δείχνει ότι το container πρέπει να **εκτελείται ως non-root user**. Αν είναι true, το Kubelet θα επαληθεύσει το image κατά το runtime ώστε να βεβαιωθεί ότι δεν εκτελείται ως UID 0 (root) και θα αποτύχει να ξεκινήσει το container αν το κάνει. | +|

runAsUser
integer

| Το **UID για να εκτελεστεί το entrypoint** του container process. Προεπιλογή είναι ο user που ορίζεται στα image metadata αν δεν καθοριστεί. | +|

seLinuxOptions
SELinuxOptions
More info about seLinux

| Το **SELinux context που θα εφαρμοστεί στο container**. Αν δεν καθοριστεί, το container runtime θα εκχωρήσει ένα τυχαίο SELinux context για κάθε container. | |

seccompProfile
SeccompProfile

| Οι **seccomp options** που θα χρησιμοποιηθούν από αυτό το container. | -|

windowsOptions
WindowsSecurityContextOptions

| Οι **Windows-specific ρυθμίσεις** που εφαρμόζονται σε όλα τα containers. | +|

windowsOptions
WindowsSecurityContextOptions

| Οι **ρυθμίσεις ειδικές για Windows** που εφαρμόζονται σε όλα τα containers. | ## Practical workload review checklist -Όταν κάνεις review ένα Pod ή ένα workload template, εξέτασε τόσο το `spec.securityContext` όσο και κάθε container-level `securityContext` κάτω από `containers`, `initContainers` και `ephemeralContainers`. Τα container-level fields μπορούν να κάνουν override τα pod-level defaults, οπότε ένα safe-looking pod default δεν εγγυάται ότι κάθε container είναι ασφαλές. +Όταν ελέγχεις ένα Pod ή workload template, εξέτασε και το `spec.securityContext` και το `securityContext` σε επίπεδο container κάτω από τα `containers`, `initContainers`, και `ephemeralContainers`. Τα fields σε επίπεδο container μπορούν να υπερισχύσουν των pod-level defaults, οπότε ένα pod default που φαίνεται ασφαλές δεν εγγυάται ότι κάθε container είναι ασφαλές. -High-risk combinations που πρέπει να προτεραιοποιήσεις: +Συνδυασμοί υψηλού κινδύνου που πρέπει να προτεραιοποιήσεις: -- `privileged: true`, ειδικά με `hostPID`, `hostIPC`, `hostNetwork`, `hostPath`, host ports ή runtime socket mounts. -- Προσθήκη capabilities όπως `SYS_ADMIN`, `NET_ADMIN`, `SYS_PTRACE`, `SYS_MODULE`, `DAC_READ_SEARCH` ή `DAC_OVERRIDE`. +- `privileged: true`, ειδικά με `hostPID`, `hostIPC`, `hostNetwork`, `hostPath`, host ports, ή runtime socket mounts. +- Προσθήκη capabilities όπως `SYS_ADMIN`, `NET_ADMIN`, `SYS_PTRACE`, `SYS_MODULE`, `DAC_READ_SEARCH`, ή `DAC_OVERRIDE`. - `allowPrivilegeEscalation: true` ή unset σε containers που μπορούν να εκτελέσουν attacker-controlled code. -- `seccompProfile: Unconfined`, `procMount: Unmasked`, ή έλλειψη runtime profiles σε sensitive workloads. -- Writable root filesystems ή ευρείς writable volume mounts σε workloads που επεξεργάζονται untrusted input. -- Έλλειψη CPU, memory ή ephemeral-storage requests και limits σε multi-tenant namespaces. +- `seccompProfile: Unconfined`, `procMount: Unmasked`, ή missing runtime profiles σε sensitive workloads. +- Writable root filesystems ή broad writable volume mounts σε workloads που επεξεργάζονται untrusted input. +- Missing CPU, memory, ή ephemeral-storage requests και limits σε multi-tenant namespaces. +- Missing ή unrealistic pod-level `spec.resources` budgets, και principals με `patch` ή `update` στο Pod `resize` subresource, επειδή τα supported clusters μπορούν να αλλάξουν το running CPU και memory desired state χωρίς να ξαναδημιουργήσουν το Pod. -Για τα περισσότερα application workloads, ένα καλό baseline είναι να εκτελούνται ως non-root UID, να ορίζεις `runAsNonRoot: true`, να βάζεις `allowPrivilegeEscalation: false`, να αφαιρείς όλα τα capabilities και να προσθέτεις μόνο τα ελάχιστα απαιτούμενα, να χρησιμοποιείς `seccompProfile: RuntimeDefault`, να προτιμάς read-only root filesystem και να αποφεύγεις host namespaces, hostPath mounts και privileged mode. +Οι resource controls δεν είναι μέρος του `securityContext`, αλλά εξέτασέ τα στο ίδιο πέρασμα του workload γιατί ορίζουν το όριο διαθεσιμότητας. Το σύγχρονο Kubernetes μπορεί να ορίσει CPU, memory, και hugepage budgets σε επίπεδο Pod κάτω από το `spec.resources` επιπλέον των container-level `resources`. Ένα Pod με sidecars μπορεί να περιορίζεται από ένα aggregate Pod envelope ακόμη κι όταν ένα container δεν έχει ατομικά limits, ενώ το local ephemeral storage εξακολουθεί να χρειάζεται ξεχωριστά `ephemeral-storage` limits, `emptyDir.sizeLimit`, LimitRanges, και ResourceQuotas. Επίσης, σύγκρινε τα desired resources στο Pod spec με το `status.containerStatuses[].resources` μετά από ένα in-place resize request· ένα failed ή pending resize μπορεί να αφήσει την τιμή που ζητήθηκε στο `spec` ενώ το kubelet κρατά την προηγούμενη runtime allocation και αναφέρει μια `PodResizePending` condition. -Σε cluster level, χρησιμοποίησε labels namespace του [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) για να επιβάλλεις τα Kubernetes [Pod Security Standards](https://kubernetes.io/docs/concepts/security/pod-security-standards/) όπου είναι δυνατόν. Χρησιμοποίησε `restricted` για namespaces που μπορούν να το υποστηρίξουν, τουλάχιστον `baseline` για συνηθισμένα application namespaces, και κράτα τις privileged εξαιρέσεις στενές, τεκμηριωμένες και απομονωμένες σε trusted platform namespaces ή node pools. +Για τα περισσότερα application workloads, ένα καλό baseline είναι να εκτελούνται με non-root UID, να ορίζεται `runAsNonRoot: true`, να ορίζεται `allowPrivilegeEscalation: false`, να αφαιρούνται όλα τα capabilities και να προστίθενται πίσω μόνο τα ελάχιστα απαιτούμενα, να χρησιμοποιείται `seccompProfile: RuntimeDefault`, να προτιμάται ένα read-only root filesystem, και να αποφεύγονται host namespaces, hostPath mounts, και privileged mode. + +Σε cluster level, χρησιμοποίησε namespace labels του [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) για να επιβάλλεις τα Kubernetes [Pod Security Standards](https://kubernetes.io/docs/concepts/security/pod-security-standards/) όπου είναι δυνατόν. Χρησιμοποίησε `restricted` για namespaces που το υποστηρίζουν, τουλάχιστον `baseline` για συνηθισμένα application namespaces, και κράτα τις privileged εξαιρέσεις στενές, τεκμηριωμένες, και απομονωμένες σε trusted platform namespaces ή node pools. ## References - [https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core) - [https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core) - [https://kubernetes.io/docs/tasks/configure-pod-container/security-context/](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) +- [https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) - [https://kubernetes.io/docs/concepts/security/linux-kernel-security-constraints/](https://kubernetes.io/docs/concepts/security/linux-kernel-security-constraints/) - [https://kubernetes.io/docs/concepts/security/pod-security-standards/](https://kubernetes.io/docs/concepts/security/pod-security-standards/) - [https://kubernetes.io/docs/concepts/security/pod-security-admission/](https://kubernetes.io/docs/concepts/security/pod-security-admission/) +- [https://kubernetes.io/docs/tasks/configure-pod-container/assign-pod-level-resources/](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pod-level-resources/) +- [https://kubernetes.io/docs/tasks/configure-pod-container/resize-container-resources/](https://kubernetes.io/docs/tasks/configure-pod-container/resize-container-resources/) {{#include ../../../banners/hacktricks-training.md}}