Τι είναι το Docker: μια σύντομη εκδρομή στην ιστορία και βασικές αφαιρέσεις

Ξεκίνησε στις 10 Αυγούστου στο Slurm Μάθημα βίντεο Docker, στο οποίο το αναλύουμε πλήρως - από βασικές αφαιρέσεις έως παραμέτρους δικτύου.

Σε αυτό το άρθρο θα μιλήσουμε για την ιστορία του Docker και τις κύριες αφαιρέσεις του: Image, Cli, Dockerfile. Η διάλεξη προορίζεται για αρχάριους, επομένως είναι απίθανο να ενδιαφέρει έμπειρους χρήστες. Δεν θα υπάρχει αίμα, σκωληκοειδής απόφυση ή βαθιά βύθιση. Τα πολύ βασικά.

Τι είναι το Docker: μια σύντομη εκδρομή στην ιστορία και βασικές αφαιρέσεις

Τι είναι το Docker

Ας δούμε τον ορισμό του Docker από τη Wikipedia.

Το Docker είναι λογισμικό για την αυτοματοποίηση της ανάπτυξης και διαχείρισης εφαρμογών σε περιβάλλοντα κοντέινερ.

Τίποτα δεν είναι ξεκάθαρο από αυτόν τον ορισμό. Δεν είναι ιδιαίτερα σαφές τι σημαίνει «σε περιβάλλοντα που υποστηρίζουν τη μεταφορά εμπορευματοκιβωτίων». Για να το μάθουμε, ας γυρίσουμε τον χρόνο πίσω. Ας ξεκινήσουμε με την εποχή που ονομάζω συμβατικά «Μονολιθική Εποχή».

Μονολιθική εποχή

Η μονολιθική εποχή είναι οι αρχές της δεκαετίας του 2000, όταν όλες οι εφαρμογές ήταν μονολιθικές, με ένα σωρό εξαρτήσεις. Η ανάπτυξη πήρε πολύ χρόνο. Ταυτόχρονα, δεν υπήρχαν πολλοί διακομιστές· όλοι τους γνωρίζαμε ονομαστικά και τους παρακολουθούσαμε. Υπάρχει μια τέτοια αστεία σύγκριση:

Τα κατοικίδια είναι κατοικίδια ζώα. Στη μονολιθική εποχή, συμπεριφερόμασταν στους διακομιστές μας σαν κατοικίδια, περιποιημένους και αγαπητούς, απομακρύνοντας τα στίγματα σκόνης. Και για καλύτερη διαχείριση των πόρων, χρησιμοποιήσαμε εικονικοποίηση: πήραμε έναν διακομιστή και τον κόψαμε σε πολλές εικονικές μηχανές, διασφαλίζοντας έτσι την απομόνωση του περιβάλλοντος.

Συστήματα εικονικοποίησης που βασίζονται σε Hypervisor

Όλοι πιθανότατα έχουν ακούσει για συστήματα εικονικοποίησης: VMware, VirtualBox, Hyper-V, Qemu KVM κ.λπ. Παρέχουν απομόνωση εφαρμογών και διαχείριση πόρων, αλλά έχουν και μειονεκτήματα. Για να κάνετε εικονικοποίηση, χρειάζεστε έναν hypervisor. Και ο hypervisor είναι ένας γενικός πόρος. Και η ίδια η εικονική μηχανή είναι συνήθως ένας ολόκληρος κολοσσός - μια βαριά εικόνα που περιέχει ένα λειτουργικό σύστημα, Nginx, Apache και πιθανώς MySQL. Η εικόνα είναι μεγάλη και η εικονική μηχανή είναι άβολη στη λειτουργία. Ως αποτέλεσμα, η εργασία με εικονικές μηχανές μπορεί να είναι αργή. Για την επίλυση αυτού του προβλήματος, δημιουργήθηκαν συστήματα εικονικοποίησης σε επίπεδο πυρήνα.

Συστήματα εικονικοποίησης σε επίπεδο πυρήνα

Η εικονικοποίηση σε επίπεδο πυρήνα υποστηρίζεται από συστήματα OpenVZ, Systemd-nspawn, LXC. Ένα εντυπωσιακό παράδειγμα τέτοιας εικονικοποίησης είναι το LXC (Linux Containers).

Το LXC είναι ένα σύστημα εικονικοποίησης σε επίπεδο λειτουργικού συστήματος για την εκτέλεση πολλαπλών μεμονωμένων παρουσιών του λειτουργικού συστήματος Linux σε έναν μόνο κόμβο. Η LXC δεν χρησιμοποιεί εικονικές μηχανές, αλλά δημιουργεί ένα εικονικό περιβάλλον με δικό της χώρο διεργασιών και στοίβα δικτύου.

Ουσιαστικά η LXC δημιουργεί κοντέινερ. Ποια είναι η διαφορά μεταξύ εικονικών μηχανών και κοντέινερ;

Τι είναι το Docker: μια σύντομη εκδρομή στην ιστορία και βασικές αφαιρέσεις

Το κοντέινερ δεν είναι κατάλληλο για απομόνωση διεργασιών: υπάρχουν ευπάθειες σε συστήματα εικονικοποίησης σε επίπεδο πυρήνα που τους επιτρέπουν να διαφύγουν από το κοντέινερ στον κεντρικό υπολογιστή. Επομένως, εάν χρειάζεται να απομονώσετε κάτι, είναι καλύτερο να χρησιμοποιήσετε μια εικονική μηχανή.

Οι διαφορές μεταξύ εικονικοποίησης και κοντέινερ φαίνονται στο διάγραμμα.
Υπάρχουν hypervisors υλικού, hypervisors πάνω από το λειτουργικό σύστημα και κοντέινερ.

Τι είναι το Docker: μια σύντομη εκδρομή στην ιστορία και βασικές αφαιρέσεις

Οι hypervisors υλικού είναι καλοί αν θέλετε πραγματικά να απομονώσετε κάτι. Επειδή είναι δυνατή η απομόνωση σε επίπεδο μνήμης σελίδων και επεξεργαστών.

Υπάρχουν hypervisors ως πρόγραμμα, και υπάρχουν κοντέινερ, και θα μιλήσουμε για αυτούς περαιτέρω. Τα συστήματα Containerization δεν διαθέτουν hypervisor, αλλά υπάρχει ένας Container Engine που δημιουργεί και διαχειρίζεται κοντέινερ. Αυτό το πράγμα είναι πιο ελαφρύ, επομένως λόγω της εργασίας με τον πυρήνα υπάρχει λιγότερη επιβάρυνση ή καθόλου.

Τι χρησιμοποιείται για τη μεταφορά εμπορευματοκιβωτίων σε επίπεδο πυρήνα

Οι κύριες τεχνολογίες που σας επιτρέπουν να δημιουργήσετε ένα κοντέινερ απομονωμένο από άλλες διεργασίες είναι οι Χώροι ονομάτων και οι Ομάδες Ελέγχου.

Χώροι ονομάτων: PID, Networking, Mount και User. Υπάρχουν περισσότερα, αλλά για ευκολία κατανόησης θα επικεντρωθούμε σε αυτά.

Ο χώρος ονομάτων PID περιορίζει τις διαδικασίες. Όταν, για παράδειγμα, δημιουργούμε έναν χώρο ονομάτων PID και τοποθετούμε μια διεργασία εκεί, γίνεται με PID 1. Συνήθως στα συστήματα το PID 1 είναι systemd ή init. Αντίστοιχα, όταν τοποθετούμε μια διεργασία σε ένα νέο χώρο ονομάτων, λαμβάνει επίσης PID 1.

Το Networking Namespace σάς επιτρέπει να περιορίσετε/απομονώσετε το δίκτυο και να τοποθετήσετε τις δικές σας διεπαφές μέσα. Το Mount είναι ένας περιορισμός συστήματος αρχείων. Χρήστης—περιορισμός στους χρήστες.

Ομάδες ελέγχου: Μνήμη, CPU, IOPS, Δίκτυο - περίπου 12 ρυθμίσεις συνολικά. Διαφορετικά ονομάζονται και Cgroups ("C-groups").

Οι ομάδες ελέγχου διαχειρίζονται πόρους για ένα κοντέινερ. Μέσω των Ομάδων Ελέγχου μπορούμε να πούμε ότι το δοχείο δεν πρέπει να καταναλώνει περισσότερο από ένα συγκεκριμένο ποσό πόρων.

Για να λειτουργήσει πλήρως το κοντέινερ, χρησιμοποιούνται πρόσθετες τεχνολογίες: Δυνατότητες, Αντιγραφή σε εγγραφή και άλλες.

Οι δυνατότητες είναι όταν λέμε σε μια διαδικασία τι μπορεί και τι δεν μπορεί να κάνει. Σε επίπεδο πυρήνα, αυτά είναι απλά bitmaps με πολλές παραμέτρους. Για παράδειγμα, ο χρήστης root έχει πλήρη δικαιώματα και μπορεί να κάνει τα πάντα. Ο διακομιστής ώρας μπορεί να αλλάξει την ώρα του συστήματος: έχει δυνατότητες στο Time Capsule, και αυτό είναι. Χρησιμοποιώντας προνόμια, μπορείτε να διαμορφώσετε με ευελιξία τους περιορισμούς για τις διεργασίες και έτσι να προστατεύσετε τον εαυτό σας.

Το σύστημα Copy-on-write μας επιτρέπει να εργαζόμαστε με εικόνες Docker και να τις χρησιμοποιούμε πιο αποτελεσματικά.

Το Docker έχει επί του παρόντος προβλήματα συμβατότητας με το Cgroups v2, επομένως αυτό το άρθρο εστιάζει ειδικά στο Cgroups v1.

Ας επιστρέψουμε όμως στην ιστορία.

Όταν τα συστήματα εικονικοποίησης εμφανίστηκαν σε επίπεδο πυρήνα, άρχισαν να χρησιμοποιούνται ενεργά. Η γενική επιβάρυνση του hypervisor εξαφανίστηκε, αλλά παρέμειναν ορισμένα προβλήματα:

  • μεγάλες εικόνες: σπρώχνουν ένα λειτουργικό σύστημα, βιβλιοθήκες, ένα σωρό διαφορετικό λογισμικό στο ίδιο OpenVZ και στο τέλος η εικόνα εξακολουθεί να είναι αρκετά μεγάλη.
  • Δεν υπάρχει κανονικό πρότυπο για τη συσκευασία και την παράδοση, επομένως το πρόβλημα των εξαρτήσεων παραμένει. Υπάρχουν περιπτώσεις όπου δύο κομμάτια κώδικα χρησιμοποιούν την ίδια βιβλιοθήκη, αλλά με διαφορετικές εκδόσεις. Μπορεί να υπάρξει σύγκρουση μεταξύ τους.

Για να λυθούν όλα αυτά τα προβλήματα, ήρθε η επόμενη εποχή.

Εποχή κοντέινερ

Όταν έφτασε η εποχή των κοντέινερ, η φιλοσοφία της συνεργασίας μαζί τους άλλαξε:

  • Μία διαδικασία - ένα δοχείο.
  • Παραδίδουμε όλες τις εξαρτήσεις που χρειάζεται η διαδικασία στο κοντέινερ της. Αυτό απαιτεί κοπή μονόλιθων σε μικροϋπηρεσίες.
  • Όσο μικρότερη είναι η εικόνα, τόσο το καλύτερο - υπάρχουν λιγότερες πιθανές ευπάθειες, εμφανίζεται πιο γρήγορα και ούτω καθεξής.
  • Οι περιπτώσεις γίνονται εφήμερες.

Θυμάστε τι είπα για κατοικίδια εναντίον βοοειδών; Παλαιότερα, οι περιπτώσεις ήταν σαν κατοικίδια ζώα, αλλά τώρα έχουν γίνει σαν τα βοοειδή. Προηγουμένως, υπήρχε ένα μονόλιθο - μία εφαρμογή. Τώρα είναι 100 μικροϋπηρεσίες, 100 κοντέινερ. Ορισμένα δοχεία μπορεί να έχουν 2-3 αντίγραφα. Γίνεται λιγότερο σημαντικό για εμάς να ελέγχουμε κάθε δοχείο. Αυτό που είναι πιο σημαντικό για εμάς είναι η διαθεσιμότητα της ίδιας της υπηρεσίας: τι κάνει αυτό το σετ κοντέινερ. Αυτό αλλάζει τις προσεγγίσεις στην παρακολούθηση.

Το 2014-2015, το Docker άνθισε - η τεχνολογία για την οποία θα μιλήσουμε τώρα.

Ο Docker άλλαξε τη φιλοσοφία και τυποποίησε τη συσκευασία εφαρμογών. Χρησιμοποιώντας το Docker, μπορούμε να συσκευάσουμε μια εφαρμογή, να την στείλουμε σε ένα αποθετήριο, να την κατεβάσουμε από εκεί και να την αναπτύξουμε.

Τοποθετούμε όλα όσα χρειαζόμαστε στο κοντέινερ Docker, έτσι το πρόβλημα εξάρτησης λύνεται. Το Docker εγγυάται την αναπαραγωγιμότητα. Νομίζω ότι πολλοί άνθρωποι αντιμετώπισαν μη αναπαραγωγιμότητα: όλα λειτουργούν για σένα, τα σπρώχνεις στην παραγωγή και εκεί σταματά να λειτουργεί. Με το Docker αυτό το πρόβλημα εξαφανίζεται. Εάν το κοντέινερ Docker σας ξεκινήσει και κάνει αυτό που χρειάζεται, τότε με μεγάλη πιθανότητα θα ξεκινήσει την παραγωγή και θα κάνει το ίδιο και εκεί.

Παρέκβαση σχετικά με τα γενικά έξοδα

Υπάρχουν πάντα διαφωνίες για τα γενικά έξοδα. Μερικοί άνθρωποι πιστεύουν ότι το Docker δεν φέρει επιπλέον φορτίο, καθώς χρησιμοποιεί τον πυρήνα του Linux και όλες τις διαδικασίες του που είναι απαραίτητες για τη μεταφορά κοντέινερ. Όπως, "αν λέτε ότι το Docker είναι γενικά, τότε ο πυρήνας του Linux είναι επιβάρυνση".

Από την άλλη πλευρά, αν πάτε πιο βαθιά, υπάρχουν πράγματι αρκετά πράγματα στο Docker που, με ένα τέντωμα, μπορούμε να πούμε ότι είναι γενικά.

Το πρώτο είναι ο χώρος ονομάτων PID. Όταν τοποθετούμε μια διεργασία σε έναν χώρο ονομάτων, της εκχωρείται PID 1. Ταυτόχρονα, αυτή η διαδικασία έχει ένα άλλο PID, το οποίο βρίσκεται στον χώρο ονομάτων του κεντρικού υπολογιστή, έξω από το κοντέινερ. Για παράδειγμα, ξεκινήσαμε το Nginx σε ένα κοντέινερ, έγινε PID 1 (κύρια διαδικασία). Και στον κεντρικό υπολογιστή έχει PID 12623. Και είναι δύσκολο να πούμε πόσο μεγάλο κόστος είναι.

Το δεύτερο πράγμα είναι το Cgroups. Ας πάρουμε τα Cgroups ανά μνήμη, δηλαδή τη δυνατότητα περιορισμού της μνήμης ενός κοντέινερ. Όταν είναι ενεργοποιημένη, ενεργοποιούνται οι μετρητές και η λογιστική μνήμης: ο πυρήνας πρέπει να κατανοήσει πόσες σελίδες έχουν εκχωρηθεί και πόσες είναι ακόμα δωρεάν για αυτό το κοντέινερ. Αυτό είναι πιθανώς επιβάρυνση, αλλά δεν έχω δει ακριβείς μελέτες για το πώς επηρεάζει την απόδοση. Και εγώ ο ίδιος δεν παρατήρησα ότι η εφαρμογή που εκτελείται στο Docker γνώρισε ξαφνικά μια απότομη απώλεια απόδοσης.

Και μια ακόμη σημείωση για την απόδοση. Ορισμένες παράμετροι πυρήνα μεταβιβάζονται από τον κεντρικό υπολογιστή στο κοντέινερ. Ειδικότερα, ορισμένες παράμετροι δικτύου. Επομένως, εάν θέλετε να εκτελέσετε κάτι υψηλής απόδοσης στο Docker, για παράδειγμα, κάτι που θα χρησιμοποιεί ενεργά το δίκτυο, τότε τουλάχιστον πρέπει να προσαρμόσετε αυτές τις παραμέτρους. Κάποια nf_conntrack, για παράδειγμα.

Σχετικά με την έννοια του Docker

Το Docker αποτελείται από διάφορα στοιχεία:

  1. Το Docker Daemon είναι το ίδιο Container Engine. εκτοξεύει κοντέινερ.
  2. Το Docker CII είναι ένα βοηθητικό πρόγραμμα διαχείρισης Docker.
  3. Dockerfile - οδηγίες για το πώς να δημιουργήσετε μια εικόνα.
  4. Εικόνα — η εικόνα από την οποία βγαίνει το κοντέινερ.
  5. Δοχείο.
  6. Το μητρώο Docker είναι ένα αποθετήριο εικόνων.

Σχηματικά μοιάζει κάπως έτσι:

Τι είναι το Docker: μια σύντομη εκδρομή στην ιστορία και βασικές αφαιρέσεις

Ο δαίμονας Docker εκτελείται στο Docker_host και εκκινεί κοντέινερ. Υπάρχει ένας πελάτης που στέλνει εντολές: δημιουργία της εικόνας, λήψη της εικόνας, εκκίνηση του κοντέινερ. Ο δαίμονας Docker πηγαίνει στο μητρώο και τους εκτελεί. Ο πελάτης Docker μπορεί να έχει πρόσβαση τόσο τοπικά (σε μια υποδοχή Unix) όσο και μέσω TCP από έναν απομακρυσμένο κεντρικό υπολογιστή.

Ας εξετάσουμε κάθε στοιχείο.

Docker daemon - αυτό είναι το τμήμα διακομιστή, λειτουργεί στον κεντρικό υπολογιστή: κατεβάζει εικόνες και εκκινεί κοντέινερ από αυτά, δημιουργεί ένα δίκτυο μεταξύ κοντέινερ, συλλέγει αρχεία καταγραφής. Όταν λέμε «δημιουργήστε μια εικόνα», ο δαίμονας το κάνει επίσης.

Docker CLI — Εξάρτημα πελάτη Docker, βοηθητικό πρόγραμμα κονσόλας για εργασία με τον δαίμονα. Επαναλαμβάνω, μπορεί να λειτουργήσει όχι μόνο τοπικά, αλλά και μέσω δικτύου.

Βασικές εντολές:

docker ps - εμφάνιση κοντέινερ που εκτελούνται αυτήν τη στιγμή στον κεντρικό υπολογιστή Docker.
εικόνες docker - εμφάνιση εικόνων που έχουν ληφθεί τοπικά.
αναζήτηση docker <> - αναζήτηση για μια εικόνα στο μητρώο.
docker pull <> - κατεβάστε μια εικόνα από το μητρώο στο μηχάνημα.
docker build < > - συλλέξτε την εικόνα.
docker run <> - εκκίνηση του κοντέινερ.
docker rm <> - αφαιρέστε το δοχείο.
Docker logs <> - αρχεία καταγραφής κοντέινερ
docker start/stop/restart <> - εργασία με το κοντέινερ

Εάν κατέχετε αυτές τις εντολές και είστε σίγουροι για τη χρήση τους, θεωρήστε τον εαυτό σας 70% ικανό στο Docker σε επίπεδο χρήστη.

Dockerfile - οδηγίες για τη δημιουργία μιας εικόνας. Σχεδόν κάθε εντολή εντολής είναι ένα νέο επίπεδο. Ας δούμε ένα παράδειγμα.

Τι είναι το Docker: μια σύντομη εκδρομή στην ιστορία και βασικές αφαιρέσεις

Έτσι φαίνεται το Dockerfile: εντολές στα αριστερά, ορίσματα στα δεξιά. Κάθε εντολή που είναι εδώ (και γενικά γραμμένη στο Dockerfile) δημιουργεί ένα νέο επίπεδο στο Image.

Ακόμη και κοιτάζοντας την αριστερή πλευρά, μπορείτε να καταλάβετε κατά προσέγγιση τι συμβαίνει. Λέμε: "δημιουργήστε έναν φάκελο για εμάς" - αυτό είναι ένα στρώμα. Το "Make the folder working" είναι ένα άλλο επίπεδο και ούτω καθεξής. Το κέικ με στρώματα κάνει τη ζωή πιο εύκολη. Εάν δημιουργήσω ένα άλλο Dockerfile και αλλάξω κάτι στην τελευταία γραμμή - εκτελώ κάτι διαφορετικό από το "python" "main.py" ή εγκαταστήσω εξαρτήσεις από άλλο αρχείο - τότε τα προηγούμενα επίπεδα θα χρησιμοποιηθούν ξανά ως προσωρινή μνήμη.

Εικόνα - πρόκειται για συσκευασία δοχείων· τα δοχεία εκτοξεύονται από την εικόνα. Αν δούμε το Docker από τη σκοπιά ενός διαχειριστή πακέτων (σαν να δουλεύαμε με πακέτα deb ή rpm), τότε η εικόνα είναι ουσιαστικά ένα πακέτο rpm. Μέσω του yum install μπορούμε να εγκαταστήσουμε την εφαρμογή, να τη διαγράψουμε, να τη βρούμε στο αποθετήριο και να την κατεβάσουμε. Είναι περίπου το ίδιο εδώ: τα κοντέινερ εκκινούνται από την εικόνα, αποθηκεύονται στο μητρώο του Docker (παρόμοιο με το yum, σε ένα αποθετήριο) και κάθε εικόνα έχει έναν κατακερματισμό SHA-256, ένα όνομα και μια ετικέτα.

Η εικόνα δημιουργείται σύμφωνα με τις οδηγίες από το αρχείο Docker. Κάθε εντολή από το Dockerfile δημιουργεί ένα νέο επίπεδο. Τα επίπεδα μπορούν να επαναχρησιμοποιηθούν.

Μητρώο Docker είναι ένα αποθετήριο εικόνων Docker. Παρόμοιο με το λειτουργικό σύστημα, το Docker διαθέτει ένα δημόσιο τυπικό μητρώο - το dockerhub. Αλλά μπορείτε να δημιουργήσετε το δικό σας αποθετήριο, το δικό σας μητρώο Docker.

Δοχείο - τι εκτοξεύεται από την εικόνα. Δημιουργήσαμε μια εικόνα σύμφωνα με τις οδηγίες από το Dockerfile και μετά την εκκινούμε από αυτήν την εικόνα. Αυτό το δοχείο είναι απομονωμένο από άλλα δοχεία και πρέπει να περιέχει όλα τα απαραίτητα για τη λειτουργία της εφαρμογής. Σε αυτή την περίπτωση, ένα δοχείο - μία διαδικασία. Συμβαίνει ότι πρέπει να κάνετε δύο διαδικασίες, αλλά αυτό είναι κάπως αντίθετο με την ιδεολογία του Docker.

Η απαίτηση "ένα κοντέινερ, μία διεργασία" σχετίζεται με τον χώρο ονομάτων PID. Όταν μια διεργασία με PID 1 ξεκινά στον Χώρο ονομάτων, αν πεθάνει ξαφνικά, τότε πεθαίνει και ολόκληρο το κοντέινερ. Εάν δύο διεργασίες εκτελούνται εκεί: η μία είναι ζωντανή και η άλλη είναι νεκρή, τότε το δοχείο θα συνεχίσει να ζει. Αλλά αυτό είναι θέμα Βέλτιστων Πρακτικών, θα μιλήσουμε για αυτές σε άλλα υλικά.

Για να μελετήσετε αναλυτικότερα τα χαρακτηριστικά και το πλήρες πρόγραμμα του μαθήματος, ακολουθήστε τον σύνδεσμο:Μάθημα βίντεο Docker».

Συγγραφέας: Marcel Ibraev, πιστοποιημένος διαχειριστής Kubernetes, ασκούμενος μηχανικός στο Southbridge, ομιλητής και προγραμματιστής μαθημάτων Slurm.

Πηγή: www.habr.com

Προσθέστε ένα σχόλιο