Kubernetes Basics
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
The original author of this page is Jorge (read his original post here)
Επιτρέπει την εκτέλεση κοντέινερ σε μια μηχανή κοντέινερ.
Ο προγραμματισμός επιτρέπει την αποστολή κοντέινερ με αποδοτικό τρόπο.
Διατηρεί τα κοντέινερ ενεργά.
Επιτρέπει τις επικοινωνίες μεταξύ κοντέινερ.
Επιτρέπει τεχνικές ανάπτυξης.
Διαχειρίζεται όγκους πληροφοριών.
Node: λειτουργικό σύστημα με pod ή pods.
Pod: Περιτύλιγμα γύρω από ένα κοντέινερ ή πολλαπλά κοντέινερ. Ένα pod θα πρέπει να περιέχει μόνο μία εφαρμογή (έτσι συνήθως, ένα pod εκτελεί μόνο 1 κοντέινερ). Το pod είναι ο τρόπος που το kubernetes αφαιρεί την τεχνολογία κοντέινερ που εκτελείται.
Service: Κάθε pod έχει 1 εσωτερική διεύθυνση IP από την εσωτερική περιοχή του κόμβου. Ωστόσο, μπορεί επίσης να εκτεθεί μέσω μιας υπηρεσίας. Η υπηρεσία έχει επίσης μια διεύθυνση IP και ο στόχος της είναι να διατηρεί την επικοινωνία μεταξύ των pods, έτσι ώστε αν ένα πεθάνει, η νέα αντικατάσταση (με διαφορετική εσωτερική IP) θα είναι προσβάσιμη εκτεθειμένη στην ίδια IP της υπηρεσίας. Μπορεί να ρυθμιστεί ως εσωτερική ή εξωτερική. Η υπηρεσία λειτουργεί επίσης ως ισοκατανομητής φόρτου όταν 2 pods είναι συνδεδεμένα στην ίδια υπηρεσία.
Όταν μια υπηρεσία είναι δημιουργημένη, μπορείτε να βρείτε τα endpoints κάθε υπηρεσίας εκτελώντας kubectl get endpoints
Kubelet: Κύριος πράκτορας κόμβου. Το στοιχείο που καθορίζει την επικοινωνία μεταξύ του κόμβου και του kubectl, και μπορεί μόνο να εκτελεί pods (μέσω του API server). Ο kubelet δεν διαχειρίζεται κοντέινερ που δεν δημιουργήθηκαν από το Kubernetes.
Kube-proxy: είναι η υπηρεσία που είναι υπεύθυνη για τις επικοινωνίες (υπηρεσίες) μεταξύ του apiserver και του κόμβου. Η βάση είναι ένα IPtables για τους κόμβους. Οι πιο έμπειροι χρήστες θα μπορούσαν να εγκαταστήσουν άλλους kube-proxies από άλλους προμηθευτές.
Sidecar container: Τα sidecar κοντέινερ είναι τα κοντέινερ που θα πρέπει να εκτελούνται μαζί με το κύριο κοντέινερ στο pod. Αυτό το μοτίβο sidecar επεκτείνει και ενισχύει τη λειτουργικότητα των τρεχόντων κοντέινερ χωρίς να τα αλλάξει. Σήμερα, γνωρίζουμε ότι χρησιμοποιούμε την τεχνολογία κοντέινερ για να περιτυλίξουμε όλες τις εξαρτήσεις για την εφαρμογή να εκτελείται οπουδήποτε. Ένα κοντέινερ κάνει μόνο ένα πράγμα και το κάνει πολύ καλά.
Master process:
Api Server: Είναι ο τρόπος που οι χρήστες και τα pods χρησιμοποιούν για να επικοινωνούν με τη διαδικασία master. Μόνο οι αυθεντικοποιημένες αιτήσεις θα πρέπει να επιτρέπονται.
Scheduler: Ο προγραμματισμός αναφέρεται στη διασφάλιση ότι τα Pods αντιστοιχίζονται σε Nodes έτσι ώστε ο Kubelet να μπορεί να τα εκτελέσει. Έχει αρκετή νοημοσύνη για να αποφασίσει ποιος κόμβος έχει περισσότερους διαθέσιμους πόρους και να αναθέσει το νέο pod σε αυτόν. Σημειώστε ότι ο προγραμματιστής δεν ξεκινά νέα pods, απλώς επικοινωνεί με τη διαδικασία Kubelet που εκτελείται μέσα στον κόμβο, η οποία θα εκκινήσει το νέο pod.
Kube Controller manager: Ελέγχει πόρους όπως σύνολα αναπαραγωγής ή αναπτύξεις για να ελέγξει αν, για παράδειγμα, ο σωστός αριθμός pods ή κόμβων εκτελούνται. Σε περίπτωση που ένα pod λείπει, θα επικοινωνήσει με τον προγραμματιστή για να ξεκινήσει ένα νέο. Ελέγχει την αναπαραγωγή, τα tokens και τις υπηρεσίες λογαριασμού στο API.
etcd: Αποθήκευση δεδομένων, μόνιμη, συνεπής και κατανεμημένη. Είναι η βάση δεδομένων του Kubernetes και η αποθήκευση κλειδιού-τιμής όπου διατηρεί την πλήρη κατάσταση των κλάσεων (κάθε αλλαγή καταγράφεται εδώ). Στοιχεία όπως ο Scheduler ή ο Controller manager εξαρτώνται από αυτά τα δεδομένα για να γνωρίζουν ποιες αλλαγές έχουν συμβεί (διαθέσιμοι πόροι των κόμβων, αριθμός τρεχόντων pods...)
Cloud controller manager: Είναι ο συγκεκριμένος ελεγκτής για ροές ελέγχου και εφαρμογές, δηλαδή: αν έχετε κλάσεις σε AWS ή OpenStack.
Σημειώστε ότι καθώς μπορεί να υπάρχουν αρκετοί κόμβοι (που εκτελούν αρκετά pods), μπορεί επίσης να υπάρχουν αρκετές διαδικασίες master των οποίων η πρόσβαση στον Api server είναι ισοκατανεμημένη και το etcd συγχρονισμένο.
Volumes:
Όταν ένα pod δημιουργεί δεδομένα που δεν θα πρέπει να χαθούν όταν το pod εξαφανιστεί, θα πρέπει να αποθηκευτούν σε έναν φυσικό όγκο. Το Kubernetes επιτρέπει την προσθήκη ενός όγκου σε ένα pod για να διατηρηθούν τα δεδομένα. Ο όγκος μπορεί να είναι στη τοπική μηχανή ή σε μια απομακρυσμένη αποθήκευση. Εάν εκτελείτε pods σε διαφορετικούς φυσικούς κόμβους, θα πρέπει να χρησιμοποιήσετε μια απομακρυσμένη αποθήκευση ώστε όλα τα pods να μπορούν να έχουν πρόσβαση σε αυτήν.
Other configurations:
ConfigMap: Μπορείτε να ρυθμίσετε URLs για να αποκτήσετε πρόσβαση σε υπηρεσίες. Το pod θα αποκτήσει δεδομένα από εδώ για να γνωρίζει πώς να επικοινωνεί με τις υπόλοιπες υπηρεσίες (pods). Σημειώστε ότι αυτό δεν είναι το προτεινόμενο μέρος για να αποθηκεύσετε διαπιστευτήρια!
Secret: Αυτός είναι ο χώρος για να αποθηκεύσετε μυστικά δεδομένα όπως κωδικούς πρόσβασης, API keys... κωδικοποιημένα σε B64. Το pod θα μπορεί να έχει πρόσβαση σε αυτά τα δεδομένα για να χρησιμοποιήσει τα απαιτούμενα διαπιστευτήρια.
Deployments: Αυτό είναι το σημείο όπου υποδεικνύονται τα στοιχεία που θα εκτελούνται από το kubernetes. Ένας χρήστης συνήθως δεν θα εργάζεται απευθείας με pods, τα pods είναι αφαιρεμένα σε ReplicaSets (αριθμός ίδιων pods που αναπαράγονται), τα οποία εκτελούνται μέσω αναπτύξεων. Σημειώστε ότι οι αναπτύξεις είναι για stateless εφαρμογές. Η ελάχιστη ρύθμιση για μια ανάπτυξη είναι το όνομα και η εικόνα που θα εκτελείται.
StatefulSet: Αυτό το στοιχείο προορίζεται ειδικά για εφαρμογές όπως βάσεις δεδομένων που χρειάζονται πρόσβαση στην ίδια αποθήκευση.
Ingress: Αυτή είναι η ρύθμιση που χρησιμοποιείται για να εκθέσει την εφαρμογή δημόσια με μια URL. Σημειώστε ότι αυτό μπορεί επίσης να γίνει χρησιμοποιώντας εξωτερικές υπηρεσίες, αλλά αυτός είναι ο σωστός τρόπος για να εκθέσετε την εφαρμογή.
Εάν εφαρμόσετε ένα Ingress, θα χρειαστεί να δημιουργήσετε Ingress Controllers. Ο Ingress Controller είναι ένα pod που θα είναι το endpoint που θα δέχεται τις αιτήσεις και θα τις ελέγχει και θα τις ισοκατανέμει στις υπηρεσίες. Ο ingress controller θα στείλει την αίτηση με βάση τους κανόνες ingress που έχουν ρυθμιστεί. Σημειώστε ότι οι κανόνες ingress μπορούν να δείχνουν σε διαφορετικές διαδρομές ή ακόμη και υποτομείς σε διαφορετικές εσωτερικές υπηρεσίες kubernetes.
Μια καλύτερη πρακτική ασφάλειας θα ήταν να χρησιμοποιήσετε έναν ισοκατανομητή φόρτου cloud ή έναν διακομιστή proxy ως σημείο εισόδου για να μην εκτεθεί καμία μέρος του κλάσματος Kubernetes.
Όταν ληφθεί μια αίτηση που δεν ταιριάζει με κανέναν κανόνα ingress, ο ingress controller θα την κατευθύνει στο "Default backend". Μπορείτε να describe
τον ingress controller για να αποκτήσετε τη διεύθυνση αυτού του παραμέτρου.
minikube addons enable ingress
CA είναι η αξιόπιστη ρίζα για όλα τα πιστοποιητικά μέσα στην κλάση.
Επιτρέπει στα στοιχεία να επικυρώνουν το ένα το άλλο.
Όλα τα πιστοποιητικά κλάσης υπογράφονται από την CA.
Το ETCd έχει το δικό του πιστοποιητικό.
τύποι:
πιστοποιητικό apiserver.
πιστοποιητικό kubelet.
πιστοποιητικό scheduler.
Minikube μπορεί να χρησιμοποιηθεί για να εκτελέσει μερικές γρήγορες δοκιμές στο kubernetes χωρίς να χρειάζεται να αναπτύξετε ένα ολόκληρο περιβάλλον kubernetes. Θα εκτελεί τις διαδικασίες master και node σε μία μηχανή. Το Minikube θα χρησιμοποιήσει το virtualbox για να εκτελέσει τον κόμβο. Δείτε εδώ πώς να το εγκαταστήσετε.
Kubectl
είναι το εργαλείο γραμμής εντολών για τα clusters kubernetes. Επικοινωνεί με τον διακομιστή Api της κύριας διαδικασίας για να εκτελεί ενέργειες στο kubernetes ή για να ζητά δεδομένα.
Ο πίνακας ελέγχου σας επιτρέπει να βλέπετε πιο εύκολα τι εκτελεί το minikube, μπορείτε να βρείτε το URL για να το αποκτήσετε εδώ:
Κάθε αρχείο ρύθμισης έχει 3 μέρη: metadata, specification (τι χρειάζεται να εκκινήσει), status (επιθυμητή κατάσταση). Μέσα στη ρύθμιση του αρχείου ρύθμισης ανάπτυξης μπορείτε να βρείτε το πρότυπο που ορίζεται με μια νέα δομή ρύθμισης που ορίζει την εικόνα που θα εκτελείται:
Example of Deployment + Service declared in the same configuration file (from here)
Καθώς μια υπηρεσία συνήθως σχετίζεται με μια ανάπτυξη, είναι δυνατόν να δηλωθούν και οι δύο στο ίδιο αρχείο ρύθμισης (η υπηρεσία που δηλώνεται σε αυτή τη ρύθμιση είναι προσβάσιμη μόνο εσωτερικά):
Παράδειγμα ρύθμισης εξωτερικής υπηρεσίας
Αυτή η υπηρεσία θα είναι προσβάσιμη εξωτερικά (ελέγξτε τα χαρακτηριστικά nodePort
και type: LoadBlancer
):
Αυτό είναι χρήσιμο για δοκιμές, αλλά για παραγωγή θα πρέπει να έχετε μόνο εσωτερικές υπηρεσίες και ένα Ingress για να εκθέσετε την εφαρμογή.
Παράδειγμα αρχείου ρύθμισης Ingress
Αυτό θα εκθέσει την εφαρμογή στο http://dashboard.com
.
Παράδειγμα αρχείου ρύθμισης παραμέτρων μυστικών
Σημειώστε πώς οι κωδικοί πρόσβασης είναι κωδικοποιημένοι σε B64 (το οποίο δεν είναι ασφαλές!)
Παράδειγμα ConfigMap
Ένα ConfigMap είναι η ρύθμιση που παρέχεται στα pods ώστε να γνωρίζουν πώς να εντοπίζουν και να έχουν πρόσβαση σε άλλες υπηρεσίες. Σε αυτή την περίπτωση, κάθε pod θα γνωρίζει ότι το όνομα mongodb-service
είναι η διεύθυνση ενός pod με το οποίο μπορούν να επικοινωνούν (αυτό το pod θα εκτελεί ένα mongodb):
Τότε, μέσα σε μια deployment config αυτή η διεύθυνση μπορεί να καθοριστεί με τον εξής τρόπο ώστε να φορτωθεί μέσα στο env του pod:
Παράδειγμα ρύθμισης όγκου
Μπορείτε να βρείτε διάφορα παραδείγματα αρχείων ρύθμισης αποθήκευσης yaml στο https://gitlab.com/nanuchi/youtube-tutorial-series/-/tree/master/kubernetes-volumes. Σημειώστε ότι οι όγκοι δεν βρίσκονται μέσα σε namespaces
Το Kubernetes υποστηρίζει πολλαπλούς εικονικούς κλάδους που υποστηρίζονται από τον ίδιο φυσικό κλάδο. Αυτοί οι εικονικοί κλάδοι ονομάζονται namespaces. Αυτοί προορίζονται για χρήση σε περιβάλλοντα με πολλούς χρήστες που είναι διασκορπισμένοι σε πολλές ομάδες ή έργα. Για κλάδους με λίγους έως δεκάδες χρήστες, δεν θα πρέπει να χρειάζεται να δημιουργήσετε ή να σκεφτείτε καθόλου namespaces. Πρέπει να αρχίσετε να χρησιμοποιείτε namespaces για να έχετε καλύτερο έλεγχο και οργάνωση κάθε μέρους της εφαρμογής που έχει αναπτυχθεί στο kubernetes.
Τα namespaces παρέχουν ένα πεδίο για ονόματα. Τα ονόματα των πόρων πρέπει να είναι μοναδικά εντός ενός namespace, αλλά όχι σε όλη την έκταση των namespaces. Τα namespaces δεν μπορούν να είναι φωλιασμένα το ένα μέσα στο άλλο και κάθε πόρος του Kubernetes μπορεί να είναι σε ένα namespace.
Υπάρχουν 4 namespaces από προεπιλογή αν χρησιμοποιείτε minikube:
kube-system: Δεν προορίζεται για χρήση από τους χρήστες και δεν θα πρέπει να το αγγίζετε. Είναι για τις διαδικασίες master και kubectl.
kube-public: Δημόσια προσβάσιμα δεδομένα. Περιέχει ένα configmap που περιέχει πληροφορίες του cluster.
kube-node-lease: Καθορίζει τη διαθεσιμότητα ενός κόμβου.
default: Ο χώρος ονομάτων που θα χρησιμοποιήσει ο χρήστης για να δημιουργήσει πόρους.
Σημειώστε ότι οι περισσότερες πόροι Kubernetes (π.χ. pods, services, replication controllers και άλλοι) βρίσκονται σε κάποια namespaces. Ωστόσο, άλλοι πόροι όπως οι πόροι namespace και οι χαμηλού επιπέδου πόροι, όπως οι κόμβοι και τα persistenVolumes δεν βρίσκονται σε namespace. Για να δείτε ποιες πόροι Kubernetes είναι και δεν είναι σε namespace:
Μπορείτε να αποθηκεύσετε το namespace για όλες τις επόμενες εντολές kubectl σε αυτό το πλαίσιο.
Helm είναι ο διαχειριστής πακέτων για το Kubernetes. Επιτρέπει τη συσκευασία αρχείων YAML και τη διανομή τους σε δημόσιες και ιδιωτικές αποθήκες. Αυτά τα πακέτα ονομάζονται Helm Charts.
Helm είναι επίσης μια μηχανή προτύπων που επιτρέπει τη δημιουργία αρχείων ρυθμίσεων με μεταβλητές:
Ένα Secret είναι ένα αντικείμενο που περιέχει ευαίσθητα δεδομένα όπως ένας κωδικός πρόσβασης, ένα token ή ένα κλειδί. Τέτοιες πληροφορίες μπορεί να τοποθετηθούν σε μια προδιαγραφή Pod ή σε μια εικόνα. Οι χρήστες μπορούν να δημιουργήσουν Secrets και το σύστημα δημιουργεί επίσης Secrets. Το όνομα ενός αντικειμένου Secret πρέπει να είναι έγκυρο DNS subdomain name. Διαβάστε εδώ την επίσημη τεκμηρίωση.
Τα μυστικά μπορεί να είναι πράγματα όπως:
API, SSH Keys.
OAuth tokens.
Credentials, Passwords (plain text ή b64 + κρυπτογράφηση).
Πληροφορίες ή σχόλια.
Κωδικός σύνδεσης βάσης δεδομένων, συμβολοσειρές… .
Υπάρχουν διαφορετικοί τύποι μυστικών στο Kubernetes
Opaque
τυχαία δεδομένα που ορίζονται από τον χρήστη (Προεπιλογή)
kubernetes.io/service-account-token
token λογαριασμού υπηρεσίας
kubernetes.io/dockercfg
σειριοποιημένο αρχείο ~/.dockercfg
kubernetes.io/dockerconfigjson
σειριοποιημένο αρχείο ~/.docker/config.json
kubernetes.io/basic-auth
διαπιστευτήρια για βασική αυθεντικοποίηση
kubernetes.io/ssh-auth
διαπιστευτήρια για αυθεντικοποίηση SSH
kubernetes.io/tls
δεδομένα για πελάτη ή διακομιστή TLS
bootstrap.kubernetes.io/token
δεδομένα bootstrap token
Ο τύπος Opaque είναι ο προεπιλεγμένος, το τυπικό ζεύγος κλειδιού-τιμής που ορίζεται από τους χρήστες.
Πώς λειτουργούν τα μυστικά:
Το παρακάτω αρχείο ρυθμίσεων ορίζει ένα secret που ονομάζεται mysecret
με 2 ζεύγη κλειδιού-τιμής username: YWRtaW4=
και password: MWYyZDFlMmU2N2Rm
. Ορίζει επίσης ένα pod που ονομάζεται secretpod
που θα έχει το username
και το password
που ορίζονται στο mysecret
εκτεθειμένα στις μεταβλητές περιβάλλοντος SECRET_USERNAME
__ και __ SECRET_PASSWOR
. Θα τοποθετήσει επίσης το μυστικό username
μέσα στο mysecret
στη διαδρομή /etc/foo/my-group/my-username
με δικαιώματα 0640
.
etcd είναι μια συνεπής και εξαιρετικά διαθέσιμη αποθήκη κλειδιών-τιμών που χρησιμοποιείται ως αποθήκη υποστήριξης του Kubernetes για όλα τα δεδομένα του κλάστερ. Ας αποκτήσουμε πρόσβαση στα μυστικά που αποθηκεύονται στο etcd:
Θα δείτε πιστοποιητικά, κλειδιά και διευθύνσεις URL που βρίσκονται στο FS. Μόλις τα αποκτήσετε, θα μπορείτε να συνδεθείτε στο etcd.
Μόλις επιτύχετε να εδραιώσετε την επικοινωνία, θα είστε σε θέση να αποκτήσετε τα μυστικά:
Προσθήκη κρυπτογράφησης στο ETCD
Από προεπιλογή, όλα τα μυστικά είναι αποθηκευμένα σε απλό κείμενο μέσα στο etcd, εκτός αν εφαρμόσετε μια στρώση κρυπτογράφησης. Το παρακάτω παράδειγμα βασίζεται στο https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/
Μετά από αυτό, πρέπει να ρυθμίσετε την επιλογή --encryption-provider-config
στον kube-apiserver
για να δείξετε την τοποθεσία του δημιουργηθέντος αρχείου ρυθμίσεων. Μπορείτε να τροποποιήσετε το /etc/kubernetes/manifest/kube-apiserver.yaml
και να προσθέσετε τις παρακάτω γραμμές:
Κάντε κύλιση προς τα κάτω στα volumeMounts:
Κάντε κύλιση προς τα κάτω στα volumeMounts για hostPath:
Επαλήθευση ότι τα δεδομένα είναι κρυπτογραφημένα
Τα δεδομένα κρυπτογραφούνται όταν γράφονται στο etcd. Μετά την επανεκκίνηση του kube-apiserver
, οποιοδήποτε νέο ή ενημερωμένο μυστικό θα πρέπει να είναι κρυπτογραφημένο κατά την αποθήκευση. Για να ελέγξετε, μπορείτε να χρησιμοποιήσετε το πρόγραμμα γραμμής εντολών etcdctl
για να ανακτήσετε το περιεχόμενο του μυστικού σας.
Δημιουργήστε ένα νέο μυστικό με το όνομα secret1
στο namespace default
:
Χρησιμοποιώντας την εντολή etcdctl, διαβάστε αυτό το μυστικό από το etcd:
ETCDCTL_API=3 etcdctl get /registry/secrets/default/secret1 [...] | hexdump -C
όπου [...]
πρέπει να είναι τα επιπλέον επιχειρήματα για τη σύνδεση με τον διακομιστή etcd. 3. Επαληθεύστε ότι το αποθηκευμένο μυστικό έχει πρόθεμα k8s:enc:aescbc:v1:
που υποδηλώνει ότι ο πάροχος aescbc
έχει κρυπτογραφήσει τα αποτελέσματα δεδομένα. 4. Επαληθεύστε ότι το μυστικό αποκρυπτογραφείται σωστά όταν ανακτάται μέσω του API:
θα πρέπει να ταιριάζει με mykey: bXlkYXRh
, τα mydata είναι κωδικοποιημένα, ελέγξτε αποκωδικοποίηση ενός μυστικού για να αποκωδικοποιήσετε πλήρως το μυστικό.
Δεδομένου ότι τα μυστικά είναι κρυπτογραφημένα κατά την εγγραφή, η εκτέλεση μιας ενημέρωσης σε ένα μυστικό θα κρυπτογραφήσει αυτό το περιεχόμενο:
Τελικές συμβουλές:
Προσπαθήστε να μην κρατάτε μυστικά στο FS, αποκτήστε τα από άλλες πηγές.
Δείτε το https://www.vaultproject.io/ για να προσθέσετε περισσότερη προστασία στα μυστικά σας.
Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)