Docker 101: Βασικές αρχές και πρακτική

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

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

Λιμενεργάτης

Εδώ είναι ο ορισμός του Docker, σύμφωνα με τη Wikipedia:

Το Docker είναι ένα πρόγραμμα υπολογιστή που εκτελεί εικονικοποίηση σε επίπεδο λειτουργικού συστήματος.

Πολύ απλό, σωστά; Λοιπόν, όχι ακριβώς. Εντάξει, εδώ είναι ο ορισμός μου για το τι είναι ο λιμενεργάτης:

Το Docker είναι μια πλατφόρμα για τη δημιουργία και λειτουργία κοντέινερ από εικόνες .

Ακόμα χάνεται; Μην ανησυχείτε, αυτό συμβαίνει επειδή πιθανώς δεν ξέρετε τι είναι τα δοχεία ή οι εικόνες .

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

Σημαντική σημείωση: Πριν συνεχίσετε, βεβαιωθείτε ότι έχετε εγκαταστήσει το docker χρησιμοποιώντας τα προτεινόμενα βήματα για το λειτουργικό σας σύστημα.

Μέρος 1. "Γεια, Κόσμος!" από μια εικόνα Python

Ας υποθέσουμε ότι δεν έχετε εγκαταστήσει το Python στο μηχάνημά σας - ή τουλάχιστον όχι την τελευταία έκδοση - και χρειάζεστε το python για να εκτυπώσετε "Γεια, Κόσμος!" στο τερματικό σας. Τι κάνεις? Χρησιμοποιείτε το docker!

Προχωρήστε και εκτελέστε την ακόλουθη εντολή:

docker run --rm -it python:3 python

Μην ανησυχείτε, θα εξηγήσω αυτήν την εντολή σε ένα δευτερόλεπτο, αλλά τώρα πιθανότατα βλέπετε κάτι τέτοιο:

Αυτό σημαίνει ότι βρισκόμαστε επί του παρόντος σε ένα κοντέινερ docker που δημιουργήθηκε από μια εικόνα πύργου python 3 , εκτελώντας την pythonεντολή. Για να ολοκληρώσετε το παράδειγμα, πληκτρολογήστε print("Hello, World!")και παρακολουθήστε καθώς συμβαίνει η μαγεία.

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

Σπάζοντας το

Ας ξεκινήσουμε από την αρχή. Η docker runεντολή είναι το βασικό εργαλείο του docker για να σας βοηθήσει να ξεκινήσετε και να εκτελέσετε τα κοντέινερ.

Η --rmσημαία είναι εκεί για να πει στο Docker Daemon να καθαρίσει το κοντέινερ και να αφαιρέσει το σύστημα αρχείων μετά την έξοδο του κοντέινερ. Αυτό σας βοηθά να εξοικονομήσετε χώρο στο δίσκο αφού εκτελέσετε κοντέινερ μικρής διάρκειας όπως αυτό, που ξεκινήσαμε να εκτυπώνουμε μόνο "Γεια, Κόσμος!"

Η -t (or --tty)σημαία λέει στο Docker να εκχωρήσει μια εικονική συνεδρία τερματικού μέσα στο κοντέινερ. Αυτό χρησιμοποιείται συνήθως με την -i (or --interactive)επιλογή, η οποία διατηρεί το STDIN ανοιχτό ακόμη και αν εκτελείται σε ανεξάρτητη λειτουργία (περισσότερα για αυτό αργότερα).

Σημείωση: Μην ανησυχείτε πάρα πολύ για αυτούς τους ορισμούς αυτή τη στιγμή. Απλώς ξέρετε ότι θα χρησιμοποιήσετε τη -itσημαία όποτε θέλετε να πληκτρολογήσετε ορισμένες εντολές στο κοντέινερ σας.

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

Τελευταίο αλλά όχι λιγότερο σημαντικό, pythonήταν η εντολή που είπαμε στον Docker να εκτελέσει μέσα στην python:3εικόνα μας , η οποία ξεκίνησε ένα κέλυφος python και επέτρεψε την print("Hello, World!")κλήση μας να λειτουργήσει.

Ακόμη ένα πράγμα

Για έξοδο από το python και τερματισμό του κοντέινερ μας, μπορείτε να χρησιμοποιήσετε CTRL / CMD + D ή exit(). Προχωρήστε και κάντε το τώρα. Μετά από αυτό, προσπαθήστε να εκτελέσετε docker runξανά την εντολή μας και θα δείτε κάτι λίγο διαφορετικό και πολύ πιο γρήγορα.

Αυτό συμβαίνει επειδή έχουμε ήδη κατεβάσει την python:3εικόνα, οπότε το κοντέινερ μας ξεκινά πολύ πιο γρήγορα τώρα.

Μέρος 2. Αυτοματοποιημένο "Hello World!" από μια εικόνα Python

Τι καλύτερο από το γράψιμο "Γεια, Κόσμος!" στο τερματικό σας μία φορά; Το καταλάβατε, γράφοντάς το δύο φορές!

Δεδομένου ότι δεν μπορούμε να περιμένουμε να δούμε "Γεια, Κόσμος!" εκτυπώνονται ξανά στο τερματικό μας και δεν θέλουμε να περάσουμε από το θόρυβο του ανοίγματος του πύθωνα και της πληκτρολόγησης printξανά, ας προχωρήσουμε και αυτοματοποιήσουμε λίγο αυτήν τη διαδικασία. Ξεκινήστε δημιουργώντας ένα hello.pyαρχείο οπουδήποτε θέλετε.

# hello.py
print("Hello, World!")

Στη συνέχεια, προχωρήστε και εκτελέστε την ακόλουθη εντολή από τον ίδιο φάκελο.

docker run --rm -it -v $(pwd):/src python:3 python /src/hello.py

Αυτό είναι το αποτέλεσμα που αναζητούμε:

Σημείωση: Χρησιμοποίησα lsπριν από την εντολή για να σας δείξω ότι ήμουν στον ίδιο φάκελο στον οποίο δημιούργησα το hello.pyαρχείο.

Όπως κάναμε νωρίτερα, ας κάνουμε ένα βήμα πίσω και να καταλάβουμε πώς λειτούργησε.

Σπάζοντας το

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

Η -v $(pwd):/srcεπιλογή λέει στο Docker Daemon να ξεκινήσει έναν τόμο στο κοντέινερ μας . Οι τόμοι είναι ο καλύτερος τρόπος για να διατηρήσετε δεδομένα στο Docker. Σε αυτό το παράδειγμα, λέμε στο Docker ότι θέλουμε τον τρέχοντα κατάλογο - από τον οποίο ανακτήθηκε $(pwd)- να προστεθεί στο κοντέινερ μας στο φάκελο /src.

Σημείωση: Μπορείτε να χρησιμοποιήσετε οποιοδήποτε άλλο όνομα ή φάκελο που θέλετε, όχι μόνο /src

Εάν θέλετε να ελέγξετε ότι /src/hello.pyυπάρχει πραγματικά μέσα στο κοντέινερ μας, μπορείτε να αλλάξετε το τέλος της εντολής μας από python hello.pyσε bash. Αυτό θα ανοίξει ένα διαδραστικό κέλυφος μέσα στο κοντέινερ μας και μπορείτε να το χρησιμοποιήσετε όπως θα περιμένατε.

Σημείωση: Μπορούμε να το χρησιμοποιήσουμε μόνο bashεδώ επειδή είναι προεγκατεστημένο στην python:3εικόνα. Ορισμένες εικόνες είναι τόσο απλές που δεν έχουν καν bash. Αυτό δεν σημαίνει ότι δεν μπορείτε να το χρησιμοποιήσετε, αλλά θα πρέπει να το εγκαταστήσετε μόνοι σας εάν το θέλετε.

Το τελευταίο κομμάτι της εντολής μας είναι η python /src/hello.pyεντολή. Εκτελώντας το, λέμε στο κοντέινερ μας να κοιτάξει μέσα στο /srcφάκελό του και να εκτελέσει το hello.pyαρχείο χρησιμοποιώντας python.

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

Μέρος 3. Ευκολότερο "Γεια, Κόσμος!" δυνατή από μια εικόνα Python χρησιμοποιώντας το Dockerfile

Έχετε κουραστεί να πείτε γεια στον όμορφο πλανήτη μας; Είναι κρίμα, γιατί θα το ξανακάνουμε!

Η τελευταία εντολή που μάθαμε ήταν λίγο λεκτική και μπορώ ήδη να δω τον εαυτό μου να κουράζεται να πληκτρολογώ όλο αυτόν τον κώδικα κάθε φορά που θέλω να πω "Γεια, Κόσμος!" Ας αυτοματοποιήσουμε τα πράγματα λίγο περισσότερο τώρα. Δημιουργήστε ένα αρχείο με όνομα Dockerfileκαι προσθέστε το ακόλουθο περιεχόμενο σε αυτό:

# Dockerfile
FROM python:3
WORKDIR /src/app
COPY . .
CMD [ "python", "./hello.py" ]

Τώρα εκτελέστε αυτήν την εντολή στον ίδιο φάκελο με τον οποίο δημιουργήσατε Dockerfile:

docker build -t hello .

Το μόνο που μένει να κάνουμε τώρα είναι να τρελαθείτε χρησιμοποιώντας αυτόν τον κωδικό:

docker run hello

Ξέρετε ήδη πώς είναι. Ας πάρουμε λίγο χρόνο για να καταλάβουμε πώς λειτουργεί το Dockerfile τώρα.

Σπάζοντας το

Ξεκινώντας με το Dockerfile, η πρώτη γραμμή FROM python:3λέει στο Docker να ξεκινήσει τα πάντα με τη βασική εικόνα που ήδη γνωρίζουμε python:3.

Η δεύτερη γραμμή, WORKDIR /src/appορίζει τον κατάλογο εργασίας μέσα στο κοντέινερ μας. Αυτό είναι για ορισμένες οδηγίες που θα εκτελέσουμε αργότερα, όπως CMDή COPY. Μπορείτε να δείτε τις υπόλοιπες υποστηριζόμενες οδηγίες WORKDIRεδώ.

Η τρίτη γραμμή, COPY . .βασικά λέει στο Docker να αντιγράψει τα πάντα από τον τρέχοντα φάκελο μας (πρώτο .) και να το επικολλήσει /src/app(δεύτερο .). Η τοποθεσία επικόλλησης ορίστηκε με την WORKDIRεντολή ακριβώς πάνω από αυτήν.

Σημείωση: Θα μπορούσαμε να επιτύχουμε τα ίδια αποτελέσματα αφαιρώντας την WORKDIRεντολή και αντικαθιστώντας την COPY . .εντολή με COPY . /src/app. Σε αυτήν την περίπτωση, θα πρέπει επίσης να αλλάξουμε την τελευταία οδηγία CMD ["python", "./hello.py"]σε CMD ["python", "/src/app/hello.py"].

Τέλος, η τελευταία γραμμή CMD ["python", "./hello.py"]παρέχει την προεπιλεγμένη εντολή για το κοντέινερ μας. Βασικά λέει ότι κάθε φορά που κάνουμε runένα κοντέινερ από αυτήν τη διαμόρφωση, θα πρέπει να εκτελείται python ./hello.py. Λάβετε υπόψη ότι τρέχουμε σιωπηρά και /src/app/hello.pyόχι μόνο hello.py, γιατί εκεί είναι που μας επεσήμανε WORKDIR.

Σημείωση: Η CMDεντολή μπορεί να αντικατασταθεί κατά το χρόνο εκτέλεσης. Για παράδειγμα, εάν θέλετε να εκτελέσετε bashαντ 'αυτού, θα το κάνατε docker run hello bashμετά την κατασκευή του κοντέινερ.

Με το Dockerfile τελείωσε, προχωράμε και ξεκινάμε τη buildδιαδικασία μας . Η docker build -t hello .εντολή διαβάζει όλη τη διαμόρφωση που προσθέσαμε στο Dockerfile και δημιουργεί μια εικόνα από αυτό. Αυτό είναι σωστό, όπως και η python:3εικόνα που χρησιμοποιούμε για ολόκληρο το άρθρο. Το .τέλος λέει στο Docker ότι θέλουμε να τρέξουμε ένα Dockerfile στην τρέχουσα τοποθεσία μας και η -t helloεπιλογή δίνει σε αυτήν την εικόνα το όνομα hello, ώστε να μπορούμε εύκολα να το αναφέρουμε στο χρόνο εκτέλεσης.

Μετά από όλα αυτά, το μόνο που χρειάζεται να κάνουμε είναι να εκτελέσουμε τις συνήθεις docker runοδηγίες, αλλά αυτή τη φορά με το helloόνομα της εικόνας στο τέλος της γραμμής. Αυτό θα ξεκινήσει ένα κοντέινερ από την εικόνα που δημιουργήσαμε πρόσφατα και τελικά θα εκτυπώσουμε το καλό ol '"Γεια, Κόσμος! στο τερματικό μας.

Επέκταση της βασικής μας εικόνας

Τι κάνουμε εάν χρειαζόμαστε κάποια εξάρτηση για να εκτελέσουμε τον κώδικα που δεν είναι προεγκατεστημένος με τη βασική μας εικόνα; Για να λυθεί αυτό το πρόβλημα, ο docker έχει την RUNεντολή.

Ακολουθώντας το παράδειγμα του python, εάν χρειαζόμασταν τη numpyβιβλιοθήκη για να εκτελέσουμε τον κώδικα, θα μπορούσαμε να προσθέσουμε την RUNεντολή αμέσως μετά την FROMεντολή μας .

# Dockerfile
FROM python:3
# NEW LINERUN pip3 install numpy
WORKDIR /src/app
COPY . .
CMD [ "python", "./hello.py" ]

Η RUNοδηγία δίνει βασικά μια εντολή για εκτέλεση από το τερματικό του κοντέινερ. Με αυτόν τον τρόπο, δεδομένου ότι η βασική μας εικόνα έρχεται ήδη με pip3εγκατεστημένη, μπορούμε να χρησιμοποιήσουμε pip3 install numpy.

Σημείωση: Για μια πραγματική εφαρμογή python, πιθανότατα θα προσθέσατε όλες τις εξαρτήσεις που χρειάζεστε σε ένα requirements.txtαρχείο, να το αντιγράψετε στο κοντέινερ και, στη συνέχεια, να ενημερώσετε τις RUNοδηγίες σε RUN pip3 install -r requirements.txt.

Μέρος 4. "Γεια, Κόσμος!" από μια εικόνα Nginx χρησιμοποιώντας ένα μακρόχρονο ανεξάρτητο δοχείο

Ξέρω ότι πιθανότατα έχετε κουραστεί να με ακούτε να το λέω, αλλά έχω ένα ακόμη «Γεια» να πω πριν φύγω. Ας προχωρήσουμε και χρησιμοποιήστε την πρόσφατα αποκτηθείσα δύναμη λιμενεργάτη για να δημιουργήσουμε ένα απλό μακρόβιο κοντέινερ, αντί αυτών των βραχύβιων που χρησιμοποιούμε μέχρι τώρα.

Δημιουργήστε ένα index.htmlαρχείο σε νέο φάκελο με το ακόλουθο περιεχόμενο.

# index.html

Hello, World!

Τώρα, ας δημιουργήσουμε ένα νέο Dockerfile στον ίδιο φάκελο.

# Dockerfile
FROM nginx:alpine
WORKDIR /usr/share/nginx/html
COPY . .

Δημιουργήστε την εικόνα και δώστε της το όνομα simple_nginx, όπως κάναμε προηγουμένως.

docker build -t simple_nginx .

Τέλος, ας τρέξουμε τη νέα μας εικόνα με την ακόλουθη εντολή:

docker run --rm -d -p 8080:80 simple_nginx

Ίσως σκέφτεστε ότι δεν συνέβη τίποτα επειδή επιστρέφετε στο τερματικό σας, αλλά ας ρίξουμε μια πιο προσεκτική ματιά με την docker psεντολή.

Η docker psεντολή εμφανίζει όλα τα δοχεία που λειτουργούν στο μηχάνημά σας. Όπως μπορείτε να δείτε στην παραπάνω εικόνα, έχω ένα δοχείο με το όνομα που simple_nginxτρέχει στο μηχάνημά μου αυτήν τη στιγμή. Ας ανοίξουμε ένα πρόγραμμα περιήγησης ιστού και να δούμε αν nginxκάνει τη δουλειά του με πρόσβαση localhost:8080.

Όλα φαίνονται να λειτουργούν όπως αναμενόταν και εξυπηρετούμε μια στατική σελίδα μέσω της nginxεκτέλεσης μέσα στο κοντέινερ μας. Ας πάρουμε λίγο χρόνο για να καταλάβουμε πώς το καταφέραμε αυτό.

Σπάζοντας το

Θα παραλείψω την εξήγηση του Dockerfile επειδή έχουμε ήδη μάθει αυτές τις εντολές στην τελευταία ενότητα. Το μόνο "νέο" πράγμα σε αυτήν τη διαμόρφωση είναι η nginx:alpineεικόνα, την οποία μπορείτε να διαβάσετε περισσότερα γι 'αυτήν εδώ.

Εκτός από αυτό που είναι καινούργιο, αυτή η διαμόρφωση λειτουργεί επειδή nginxχρησιμοποιεί το usr/share/nginx/htmlφάκελο για να αναζητήσει ένα index.htmlαρχείο και να αρχίσει να το εξυπηρετεί, οπότε αφού ονομάσαμε το αρχείο μας index.htmlκαι διαμορφώσαμε το WORKDIRνα είναι usr/share/nginx/html, αυτή η ρύθμιση θα λειτουργεί αμέσως.

Η buildεντολή είναι ακριβώς όπως αυτή που χρησιμοποιήσαμε και στην τελευταία ενότητα. Χρησιμοποιούμε μόνο τη διαμόρφωση Dockerfile για να δημιουργήσουμε μια εικόνα με ένα συγκεκριμένο όνομα.

Τώρα για το διασκεδαστικό μέρος, η docker run --rm -d -p 8080:80 simple_nginxοδηγία. Εδώ έχουμε δύο νέες σημαίες. Η πρώτη είναι η αποσπασμένη ( -d) σημαία, που σημαίνει ότι θέλουμε να εκτελέσουμε αυτό το κοντέινερ στο παρασκήνιο και γι 'αυτό επιστρέφουμε στο τερματικό μας αμέσως μετά τη χρήση της docker runεντολής, παρόλο που το κοντέινερ εξακολουθεί να λειτουργεί.

Η δεύτερη νέα σημαία είναι η -p 8080:80επιλογή. Όπως ίσως μαντέψατε, αυτή είναι η portσημαία και βασικά χαρτογραφεί τη θύρα 8080από το τοπικό μηχάνημά μας στο λιμάνι 80μέσα στο δοχείο μας. Θα μπορούσατε να χρησιμοποιήσετε οποιαδήποτε άλλη θύρα αντί 8080, αλλά δεν μπορείτε να αλλάξετε τη θύρα 80χωρίς να προσθέσετε μια επιπλέον ρύθμιση στην nginxεικόνα, καθώς 80είναι η τυπική θύρα στην οποία nginxεκτίθεται η εικόνα.

Σημείωση: Εάν θέλετε να σταματήσετε ένα αποσυνδεδεμένο κοντέινερ όπως αυτό, μπορείτε να χρησιμοποιήσετε την docker psεντολή για να λάβετε το όνομα του κοντέινερ (όχι την εικόνα) και, στη συνέχεια, να χρησιμοποιήσετε την docker stopεντολή με το επιθυμητό όνομα κοντέινερ στο τέλος της γραμμής.

Μέρος 5. Το τέλος

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

Επιτρέψτε μου να μάθω τη γνώμη σας για αυτό το άρθρο στα σχόλια και θα φροντίσω να γράψω ένα επόμενο άρθρο που θα καλύπτει πιο προηγμένα θέματα όπως docker-composeκάπου στο εγγύς μέλλον.

Εάν έχετε απορίες, ενημερώστε με.

Στην υγειά σας!