In questo tutorial, daremo un'occhiata alla storia della containerizzazione, Docker, i suoi componenti e come iniziare a usarlo nel nostro lavoro quotidiano. Ma prima di immergerci troppo nel tutorial, diamo un'occhiata a cosa sia Docker in modo da capire cosa è con cui lavoreremo.
Docker è una piattaforma aperta per la creazione, la spedizione e l'esecuzione di applicazioni distribuite. Fornisce ai programmatori, ai team di sviluppo e agli ingegneri operativi gli strumenti comuni di cui hanno bisogno per sfruttare la natura distribuita e in rete delle applicazioni moderne.
Come affermato nella definizione formale di Docker di cui sopra, aiuta gli sviluppatori o gli ingegneri operativi nell'automazione dell'ambiente infrastrutturale di cui hanno bisogno le applicazioni.
Supponiamo che tu abbia un'applicazione scritta in Node.js che usa Express per il servizio RESTful e MongoDB per la persistenza dei dati. Rendiamolo più complesso e aggiungere più istanze di Node.js e Nginx Load Balancer di fronte alle istanze Node.js.
Non sarebbe meglio se annotassi i passaggi dell'installazione in un file di testo e permettessi a qualcuno di installare l'intero ambiente per me? Docker ti aiuta a containerizzare tutti i componenti dell'architettura (istanza Node.js, Nginx Web Server, database MongoDB, ecc.) Molto facilmente.
Tuttavia, che cos'è la containerizzazione? Diamo un'occhiata alla storia della tecnologia di containerizzazione.
Il primo progetto di containerizzazione che posso ricordare è OpenVZ, che è una virtualizzazione basata su container per Linux rilasciata nel 2005. OpenVZ consente di creare più contenitori Linux isolati e sicuri per eseguirli sullo stesso server fisico senza alcun conflitto tra le applicazioni.
Allo stesso tempo, un altro progetto di FreeBSD si avvicinò, chiamato Jails. Questo ti consente di mettere app e servizi in un solo Jail (possiamo chiamarlo container) usando chroot.
Ci sono stati altri progetti come Solaris Containers, ma perché Docker è diventato popolare anche se tutti i progetti di containerizzazione sopra riportati hanno otto anni in più rispetto a Docker? Continua a leggere per migliorare la conoscenza del Docker.
Prima di spiegare come funziona Docker, lascia che ti spieghi come funzionano i contenitori. Un contenitore è qualcosa legato alla virtualizzazione a livello di sistema operativo che ci consente di creare più spazi utente isolati invece di uno solo. Questo isolamento è fatto usando il chroot
.
La principale differenza tra contenitori e macchine virtuali è la seguente. Quando si creano più macchine virtuali tramite VM, i sistemi operativi e i componenti hardware virtualizzati vengono duplicati per ciascun guest. Tuttavia, se si creano più contenitori, solo le cartelle relative alla distribuzione del sistema operativo vengono create da zero, mentre le parti relative al kernel Linux vengono condivise tra i contenitori. Puoi dare un'occhiata all'immagine qui sotto per vedere la differenza in modo visivo.
Come puoi vedere nello schema, se crei guest Ubuntu e Mint usando la VM, il loro sistema operativo guest verrà duplicato anche se usano lo stesso kernel Linux. In realtà, la distribuzione significa differenziazione del bidoni e libs cartelle e il kernel Linux è lo stesso.
Se osservi la seconda immagine sopra, vedrai che tutta l'architettura a livello di sistema operativo è condivisa tra i contenitori e solo la bidoni e libs sono creati da zero per diversi contenitori. Docker Engine ha Namespace, cgroups
, e SELinux, e ti aiuta con l'orchestrazione dei contenitori. Se hai bisogno di ulteriori informazioni su Docker Engine, puoi dare un'occhiata al sito web di Docker.
Prima di procedere con la spiegazione dei componenti, è possibile installare Docker sul computer. Ha passaggi abbastanza semplici da installare.
Docker ha principalmente due componenti: Docker Engine e Docker Hub. Docker Engine serve per orchestrare i container, come detto sopra e Docker Hub è un servizio SaaS per la gestione e la condivisione di stack di applicazioni. Ad esempio, se si desidera utilizzare Redis con Docker, è possibile caricarlo sul computer locale eseguendo il seguente comando:
docker pull redis
Questo recupererà tutti i livelli dell'immagine del contenitore e sarà pronto per essere eseguito sul tuo ambiente. Puoi dare un'occhiata a Docker Hub per un sacco di repository.
Docker ha anche un file system speciale chiamato AUFS (UNdvanced Multi Layered Unification File System). Con questo sistema, ogni singola modifica del commit viene mantenuta a livelli, come il controllo della versione. Se apporti una modifica all'immagine Docker, verrà mantenuta come un commit diverso e non verrà completamente ricostruita durante l'operazione di compilazione. Tutti gli altri livelli sono costruiti prima.
Inoltre, quando si estrae un repository sul computer locale, si noterà che l'operazione di recupero viene effettuata strato per strato. Diciamo che hai apportato una modifica e testi il tuo nuovo contenitore, ma fallisce. Nessun problema, puoi ripristinare le modifiche e ricostruire come fai sempre in Git.
Supponendo che Docker sia già installato sul tuo computer, possiamo iniziare con alcuni bellissimi comandi Docker.
docker pull ubuntu docker run -it ubuntu bash
Come puoi immaginare, il comando sopra recupererà l'immagine ubuntu da Docker Hub e la eseguirà, seguita dal comando bash.
Vedrai che sei all'interno del contenitore dopo aver eseguito il comando precedente. Ora sei nella shell di Ubuntu e sei libero di eseguire comandi * nix. Puoi creare qualcosa, cancellare qualcosa, vedere processi, ecc.
Tuttavia, fai attenzione perché quando esci dal container, i tuoi dati andranno persi. Perché? Perché è necessario progettare i contenitori come immutabili.
Per prima cosa progettate quali pacchetti saranno inclusi, quali applicazioni saranno clonate nel contenitore, ecc., Quindi eseguite il contenitore. Ogni volta che si fallisce qualcosa, è necessario essere in grado di cambiare la configurazione ed eseguire di nuovo. Non mantenere mai lo stato nei contenitori.
Per eseguire il contenitore, è possibile utilizzare il seguente formato.
finestra mobile [OPZIONI] IMAGE [: TAG | @DIGEST] [COMMAND] [ARG ...]
Ci sono molti parametri disponibili in Docker per l'operazione di esecuzione. Puoi fare riferimento alla documentazione per tutte le opzioni, ma ti fornirò un paio di esempi per l'utilizzo nella vita reale.
finestra mobile run -d redis
Questo comando eseguirà un'immagine Redis in modalità indipendente. Ciò significa che tutto l'I / O verrà eseguito tramite connessioni di rete o condivise. Si può presumere che sia in esecuzione in modalità daemon. Abbiamo detto Redis
qui, ma puoi specificare l'autore e il tag dell'immagine anche usando un comando come quello qui sotto.
finestra mobile run -d huseyinbabal / mongodb: 1.0
Stiamo eseguendo a MongoDB
immagine a cui appartiene huseyinbabal
con una versione specifica 1.0
.
Puoi anche eseguire l'immagine in modo interattivo in questo modo:
finestra mobile run -it huseyinbabal / ubuntu: 1.2 bash
Quando si esegue il comando sopra, verrà eseguito ubuntu 1.2
e quindi eseguire a bash
comando per inserire il prompt nel terminale all'interno del contenitore.
Abbiamo eseguito immagini che sono state estratte da Docker Hub Repository. Che ne dici di costruire la nostra immagine? Possiamo farlo usando il comando di costruzione Docker, ma dobbiamo specificare a Dockerfile
per fare in modo che Docker esegua ogni istruzione definita all'interno di Dockerfile.
DA ubuntu MAINTAINER Huseyin BABAL RUN apt-key adv --keyserver keyserver.ubuntu.com --recv 7F0CEB10 RUN echo "deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen" | tee -a /etc/apt/sources.list.d/10gen.list RUN apt-get update RUN apt-get -y install apt-utils RUN apt-get -y install mongodb-10gen RUN echo "alcune configurazioni" >> /etc/mongodb.conf CMD ["/ usr / bin / mongod", "--config", "/etc/mongodb.conf"]
Questa è una definizione Dockerfile molto semplice che ci aiuterà a costruire la nostra immagine. In questa definizione di Dockerfile, prima di tutto stiamo dicendo che erediteremo tutte le proprietà dall'immagine ubuntu. Questa immagine verrà recuperata prima dal tuo server locale. Se non può essere trovato, verrà recuperato da Docker Hub.
Sulla seconda riga, stiamo definendo l'autore o il manutentore dell'immagine. Nei seguenti file, stiamo semplicemente eseguendo alcuni comandi * nix con il comando RUN per installare pacchetti essenziali e pacchetti relativi a MongoDB. Per iniziare MongoDB, stiamo scrivendo mongodb.conf
, e nel passaggio finale eseguiamo il comando usando CMD
.
Per eseguire la nostra immagine, dovremmo costruire l'immagine usando questo Dockerfile. È possibile utilizzare il seguente per costruire l'immagine.
docker build -t huseyinbabal / mongodb: 1.0 .
Semplicemente, questo costruirà un'immagine con un tag huseyinbabal / mongodb: 1.0
e utilizzerà Dockerfile nella cartella corrente (vedere il punto alla fine del comando). Per verificare se è stato creato o meno, è possibile utilizzare il seguente comando.
immagini docker
Questo elencherà tutte le immagini che esistono sul tuo computer come di seguito.
Se vuoi eseguire un'immagine costruita, puoi semplicemente eseguire:
finestra mobile run -d huseyinbabal / mongodb: 1.0
Ma aspetta! Questo è un nodo daemon. Quindi, come posso inserire questo contenitore? È molto semplice Innanzitutto, ottenere il nome del nome dei contenitori mongodb utilizzando il seguente comando.
docker ps
Vedrai un output come sotto.
Puoi vedere il nome nella colonna NAMES. Ora è il momento di andare nel contenitore con il seguente comando.
finestra mobile exec -i -tbash
Puoi vedere i processi in esecuzione all'interno di questo contenitore.
Come ho detto prima, se si chiude il contenitore in esecuzione, tutti i dati relativi a quel contenitore andranno persi. Questo è normale nel mondo Docker.
Ad esempio, nel nostro contenitore, MongoDB scrive tutti i dati in un percorso specificato in mongodb.conf. Questa cartella esiste nel contenitore e se si chiude il contenitore, tutti i dati andranno persi. Se si persistono i dati in una cartella condivisa su un computer host su cui è in esecuzione Docker, è possibile utilizzare -v
opzione all'interno del correre
comando. Per esempio:
finestra mobile run -d -v / host / mongo_data_path: / container / mongo_data_path huseyinbabal / mongodb: 1.0
Questo mapperà /host / mongo_db_path
che è nella tua macchina host per /contenitore / mongo_data_path
che è nel contenitore. Ogni volta che mongo scrive i dati nel percorso all'interno del contenitore, sarà automaticamente accessibile all'interno della macchina host. Anche se si chiude il contenitore, i dati rimarranno nel percorso all'interno della macchina host.
Diciamo che MongoDB è in esecuzione all'interno del contenitore. È possibile esporre la porta MongoDB all'esterno del contenitore sulla porta 27017 ed è possibile utilizzare il seguente comando per accedere dall'esterno del contenitore con la porta 5000.
finestra mobile run -d -P 5000: 27017 -v / host / mongo_data_path: / container / mongo_data_path huseyinbabal / mongodb: 1.0
Quindi puoi connetterti a MongoDB all'interno del container dall'esterno usando la porta 5000.
Diciamo che hai bisogno delle informazioni di rete del contenitore specificato. Puoi afferrare quel dettaglio usando il docker ispezionare
comando. Questo comando stamperà molti metadati sul contenitore.
è la parte che esiste in ID CONTENITORE
nel docker ps
produzione. L'output dell'ispezione sarà in formato JSON. Per ottenere l'indirizzo IP del contenitore, puoi utilizzare:
docker inspect --format '.NetworkSettings.IPAddress'
I comandi precedenti sono quelli di base mentre stai facendo cose Docker. Se hai bisogno di imparare molto sui comandi Docker, consulta la documentazione.
È consigliabile assegnare una sola responsabilità a ciascun contenitore. Quello che intendo è che non dovresti installare le applicazioni MongoDB e Spring Boot in un contenitore per servire i livelli DB e Application in un contenitore. Invece, puoi mettere un'app in un contenitore. Ogni istanza dell'applicazione, membro del database, coda messaggi, ecc. Dovrebbe indicare un solo contenitore.
Supponiamo che tu inserisca i livelli dell'applicazione e del database in un unico contenitore. Sarà molto difficile misurare le prestazioni o la diagnostica per l'applicazione o il database. Allo stesso modo, se si desidera ridimensionare l'applicazione, non sarà possibile ridimensionare tale contenitore, poiché in tale contenitore è installata anche un'applicazione di database.
Quando si esegue il contenitore, non inserire mai ssh in quel contenitore per aggiornare o eliminare qualcosa. Il motivo principale per l'utilizzo di Docker è quello di mantenere storicamente le modifiche in Dockerfile. Se si desidera modificare qualcosa, modificare Dockerfile, creare l'immagine ed eseguire il contenitore. Anche se si modifica qualcosa all'interno del contenitore manualmente, verrà eliminato se il contenitore viene rieseguito.
Normalmente, potresti voler scrivere ogni comando su linee separate come di seguito.
DA ubuntu MAINTAINER Huseyin BABAL RUN apt-get update RUN apt-get install -y build-essential RUN apt-get install -y php5 RUN apt-get install -y nginx CMD ["nginx", "g", "demone off; "] ESPOSTA 80
Questo significa un livello per ogni linea. Non è un modo suggerito per costruire Dockerfile. Puoi separare i tuoi comandi con una barra rovesciata (\) per ogni gruppo di lavori, come di seguito:
DA ubuntu: 15.04 MAINTAINER Huseyin BABAL RUN apt-get update \ -y build-essential -y php5 \ -y nginx = 1.7.9 \ apt-get clean CMD ["nginx", "g", "daemon off;"] ESPORTA 80
Nel Dockerfile precedente, abbiamo pianificato di installare i pacchetti richiesti su una riga ed eseguito a pulito
operazione per rendere l'ambiente pulito. Facendo ciò, non abbiamo creato livelli separati per ogni comando.
Costruire e gestire un container è molto facile. Dopo due mesi potresti finire con 50 contenitori per l'architettura dell'applicazione! Sarà molto difficile trovare la causa principale di un problema se si verifica un errore nei contenitori.
Il modo più semplice per gestirlo è registrare le attività del contenitore in un sistema di log centrale. Ad esempio, reindirizzare i log di stdout in un file di registro all'interno di ciascun contenitore. E un agente può trasmettere questi contenuti del registro a un sistema di gestione dei registri centralizzato come ELK o Splunk. Se si inviano dati specifici del contenitore all'interno dei registri, ad esempio id contenitore, sarà molto facile filtrare gli errori sul dashboard di gestione dei registri.
Si consiglia di monitorare il contenitore stesso. Questa volta, puoi dare un'occhiata a Google consulente. Ciò consente di monitorare il contenitore tramite un servizio REST. Ad esempio, per visualizzare le informazioni sul contenitore, è possibile effettuare una richiesta GET http: // nome_host
/api/v1.0/containers/
.
Se si applicano procedure standard al ciclo di vita del contenitore, sarà molto semplice controllare l'architettura generale. Ad esempio, è possibile creare un contenitore di base per ereditare alcune operazioni all'interno di altri contenitori. D'altra parte, è possibile utilizzare posizioni standard per i file di configurazione, i file di registro e i file di origine. Fai attenzione all'utilizzo di un Dockerfile separato per ogni contenitore. Infine, applica il controllo delle versioni a tutti i tuoi contenitori per separare le funzionalità e utilizzare versioni diverse in base alle tue esigenze.
La sicurezza è un argomento molto importante nel caso di container. Esegui sempre i contenitori in modalità non privilegiata. Ti suggerisco di usare Apparmor per proteggere il tuo contenitore da thread esterni, anche attacchi zero-day. Suggerisco inoltre a SELinux che i contenitori applichino le politiche di sicurezza del controllo accessi in base alle proprie esigenze. Inoltre, tieni aggiornato con gli aggiornamenti delle immagini che utilizzi all'interno dei contenitori per applicare le ultime patch al contenitore. Durante questa operazione, non dimenticare di aggiungere l'immagine a una versione stabile.
Modulus è una piattaforma di distribuzione e orchestrazione aziendale completamente supportata. Inizialmente hanno iniziato con un PaaS focalizzato su Node.js su LXC, e poi hanno deciso di passare a Docker, e questo ha permesso loro di supportare più lingue diverse da Node.js, vale a dire PHP, Java, Python e progetti statici.
Ciò che intendo per supporto linguistico qui è che sei in grado di distribuire la tua applicazione scritta nelle lingue di cui sopra a Modulus con un singolo comando con proprietà predefinite. Diciamo che implementerai un'applicazione Node.js su Modulus e l'unica cosa che devi fare è eseguire modulo distribuire
all'interno della cartella principale del progetto. Il modulo consiste dei seguenti componenti.
Modulo CLI è per l'operazione di distribuzione per l'applicazione dalla riga di comando e può essere semplicemente installato con npm install -g modulo
. È possibile creare progetti, distribuire progetti, registri di flusso ed eseguire alcune operazioni legate al database con Modulus CLI. In alternativa, puoi implementare il tuo progetto caricando attraverso il pannello di amministrazione.
È possibile creare e distribuire l'applicazione con un paio di semplici passaggi. È possibile selezionare la lingua, la dimensione del servo e la posizione. Quindi preparati a distribuire il tuo progetto.
In alternativa, puoi creare un progetto sulla riga di comando con modulo di progettazione crea
e poi modulo distribuire
.
Si consiglia di memorizzare alcuni dati all'interno dell'applicazione. Modulus consente inoltre di aggiungere un database alla propria applicazione. MongoDB è usato dietro le quinte. Puoi andare e creare un database all'interno della dashboard, e inoltre sei in grado di creare un database sulla riga di comando. Puoi vedere la schermata del database qui sotto.
Puoi prendere l'URL del database nella schermata dei dettagli e usarlo nelle tue applicazioni.
È possibile aggiungere i registri delle applicazioni dalla riga di comando con modulo log coda
, oppure puoi eseguire lo streaming dei registri sul dashboard come di seguito.
Quando fai clic sul STREAM pulsante, puoi vedere i log in tempo reale.
Quelli sono i componenti principali di Modulus. Puoi dare un'occhiata ad altri componenti come Metrica, Auto-Scaling, Addons, notifiche, e Amministrazione sul Modulus Dashboard.
Abbiamo discusso dei contenitori e abbiamo dato una breve storia. Rispetto alle macchine virtuali, Docker offre molte alternative per gestire l'infrastruttura delle applicazioni.
Se si utilizza Docker per la propria architettura, è necessario prestare attenzione ad alcuni concetti, come Single Responsibility, Immutable Server, Security, Application e Container Monitoring.
Quando il tuo sistema diventa più grande, sarà molto facile da controllare. Modulus è una delle aziende che utilizza Docker per il suo sistema PaaS. Utilizzando la potenza di Docker, Modulus ha progettato un ottimo sistema per aiutare le persone a distribuire le loro applicazioni scritte in Node.js, PHP, Java e Python molto facilmente.