Introducere în Docker și Kubernetes

Sistemele distribuite pe scară largă, realizate din mai multe servicii cooperante, devin din ce în ce mai importante. Aceste sisteme rulează pe grupuri de sute, mii sau mai multe servere. Dezvoltarea, implementarea și menținerea acestor sisteme în mod eficient și economic este o ordine înaltă.

Virtualizarea și, mai recent, containerizarea permit o partajare flexibilă și gestionarea resurselor. Docker a făcut containerizarea populară. Verificați acest articol Envato Tuts + pentru o introducere extraordinară: Ghidul autostopistului pentru Docker și Modulus.

Google a executat imensele sale software-uri și centre de date pe containerizare de ani de zile și a acumulat o mult de experiență și de cunoștințe. Kubernetes este un proiect open-source de la Google care aduce toate aceste cunoștințe masei.

În acest articol, voi explora Docker pe scurt și apoi se va arunca cu capul în Kubernetes. Voi folosi un exemplu de rulare a unui Python 3 quote REST API. Hai să intrăm.

Serviciul de citare

Serviciul de cotație este un API REST care vă permite să adăugați citate și să obțineți o listă a tuturor citatelor. Este implementat ca un serviciu web Python 3 folosind biblioteca excelentă de îmbrățișare. Expune un singur punct final numit / citate. Puteți obține toate citatele sau să postați un nou citat. Să adăugăm câteva citate:

cuvintele "http: // localhost: 8000 / quotes -d" quote = TV este guma de mestecat pentru ochi. ~ Frank Lloyd Wright "curl http: // localhost: 8000 / quotes -d" quote = "Emiliano Zapata" curl http: // localhost: 8000 / quotes -d "quote = Trebuie să fim foarte atenți atunci când acordăm sfaturi tinerilor: uneori îl urmăresc! ~ Edsger W. Dijkstra"

Dacă răsfoiți http: // localhost: 8000 / citate vei primi: ["Televiziunea este o gumă de mestecat pentru ochi - Frank Lloyd Wright", "este mai bine să mori pe picioare decât să trăiești pe genunchi." "Trebuie să fim foarte atenți când acordăm sfaturi tinerilor: uneori îl urmăresc! ~ Edsger W. Dijkstra "] Dacă doriți doar să vedeți documentația generată automat de HUG, răsfoiți: http: // localhost: 8000

"404": "Apelul API pe care ați încercat să-l faceți nu a fost definit. Iată o definiție a API pentru a vă ajuta să mergeți :)", "documentation": "/ quotes": "GET" ":" ["http: // localhost: 8000 / citate"], "outputs": content_type ": application / json, format: JSON : "output": "content_type": "aplicație / json", "format": "JSON (Javascript Serialized Notation Object)", "inputs" valoarea șirului "

Documente de bază ale Docker

Nu voi explica prea mult despre Docker și o aplic doar la serviciul de citare.

Dockerarea unei aplicații Python

Mai întâi avem nevoie de un Dockerfile. Efectuează următorii pași:

  1. Bazat pe cea mai recentă imagine ubuntu
  2. Instalează Python 3 și alte câteva dependențe
  3. Copiați directorul serviciului de citare
  4. Instalează dependențele de tip quote-service din fișierul requirment.txt
  5. Expune portul 8000
  6. Lansați serviciul de cotație prin îmbrățișare

De la ubuntu: ultimul MAINTAINER Gigi Sayfan "[email protected]" RUN apt-get update -y RUN apt-get install -y python3 python3-pip python3-dev build-esențiale COPY. / quote-service WORKDIR / quote-service RUN PIP3 Instalarea -r requirements.txt EXPOSE 8000 ENTRYPOINT hug -f app.py

Construirea unei imagini

Următorul pas este să construiți o imagine Docker. Acest lucru este la fel de simplu ca:

docker build .

Îmi place, de asemenea, să etichetez imagini:

docker tag-ul 715624b7e22a g1g1 / quote-service

g1g1 este numele meu de utilizator pe Docker Hub.

Pentru a verifica dacă imaginea a fost construită cu succes, tastați:

docker ps - tot 

Ar trebui să vedeți noua imagine:

CONTAINER ID IMAGE COMMAND CREAT STATUS PORTS NAMES 715624b7e22a g1g1 / quote-service "/ bin / sh -c 'hug -f a" Acum 4 ore Sus 35 minute 0.0.0.0:8000->8000/tcp agitated_northcutt

Împingerea unei imagini către centrul de andocare

Când creați o imagine, puteți să-l împingeți și în Docker Hub, astfel încât să poată fi folosită de alte persoane (sau de dvs. pe o altă mașină).

docker push g1g1 / quote-service

Rețineți că trebuie să creați un cont pe Docker Hub și să vă conectați la nivel local utilizând:

docker login

Rularea unei aplicații dockerizate

O.K. Să rulați imaginea serviciului de cotație și expuneți portul 8000 la gazdă.

docker rulează -i -t -p 8000 g1g1 / quote-service

Ar trebui sa vezi: / ################################################# ##################### \ '.---- "... ------- ...". : / ::::: -: ---------: - ::::: // ... + :::: ---- ## / - / oo +: - ## - --- :::: // // :: ------- / oosoo ------- ::: //. ## ## ## ## ##### .-: ------./++ o / o -.------ :: - ' ## ## ## ## ## ----.-./ + O +: ... ----. .: ///. ######## ## ## ## '------ :::::: ------' .- :::: //. ## ## ## ## ## ####: // ::--. -:... ----- ... ": - :::::: -. ## ## ## ## ## ##: / ::::::::: -:- “. :::::-. ## ## #### ###### .--::::::: ... ::::."... :: ... :: EMBRACE API-ULUI VIITORULUI :: -. :: - :: :: :: - VERSIUNEA 1.9.6 :: - - :: -::- -:: - ####################################### ######################### Drepturi de autor (C) 2015 Timothy Edmund Crosley Sub licența MIT

Servind pe portul 8000 ... "Aceasta este destul de cool. Înainte de a încerca să vă accesați serviciul de cotație minunat pe portul 8000, este posibil să aveți nevoie de unele activități suplimentare în funcție de mediul dvs..

Dacă rulați pe Mac OS X folosind VirtualBox și docker-machine, este posibil să aveți nevoie să publicați portul 8000 pe VirtualBox pentru al face accesibil pe gazdă.

Presupunând că ai încercat să navighezi http: // localhost: 8000 / citate. Oh nu. Eroare interna a serverului! Ce s-a întâmplat?

Să ne uităm la cod:

redis_host = os.environ.get ('QUOTE_STORE_SERVICE_HOST', 'localhost') redis_server = redis.StrictRedis (host = redis_host, port = 6379, db = 0)

Serviciul de citare încearcă să se conecteze la un server redis. Adresa gazdă poate fi configurată ca variabilă de mediu și, dacă nu este setată, aceasta va fi implicită la localhost. Din păcate, Redis nu este instalat în mod implicit și nu rulează în interiorul containerului. Să o rezolvăm temporar. Pentru a obține accesul shell în container, tastați următoarea comandă:

docker exec -it 715624b7e22a / bin / bash

Apoi veți obține accesul shell-ului la container și puteți instala redis:

root @ 715624b7e22a: / quote-service # apt-get a instala redis-server

În cele din urmă, rulați redis: root # 715624b7e22a: / quote-service # redis-server [25] 29 Nov 00: 14: 24.546 # Avertisment: nici un fișier de configurare nu a fost specificat, utilizând configurația implicită. Pentru a specifica un fișier de configurare, utilizați redis-server /path/to/redis.conf _._ _.- "__" -._ _.- "." _ "" -._ Redis 2.8.4 (00000000 / 0) 64 de biți .- ".-.„\ / .,"-._ (' , .- | , ) Rularea în mod autonom-._-... - __ ... -.-._ |“ .-„| Port: 6379 | -._ . / .-'| PID: 25 -._ -. -./-.-._ -..-'' - '' | -._-._ _.-'_.- ' http://redis.io -._ -._-.__.-'_.- '_.-'-._-._ -..-"_.-".-„| | -._-._ .-'.-'| -._ -.-.__.-'_.- '_.-' -. -.__.- '_.-' -."-

[25] 29 Nov 00: 14: 24.547 # Serverul a început, Redis versiunea 2.8.4 [25] 29 Nov 00: 14: 24.547 # AVERTISMENT supracommit_memory este setat la 0! Salvarea fundalului poate eșua în condiții de memorie scăzută. Pentru a remedia această problemă, adăugați 'vm.overcommit_memory = 1' la /etc/sysctl.conf și apoi reporniți sau executați comanda 'sysctl vm.overcommit_memory = 1' pentru ca aceasta să aibă efect. [25] 29 Nov 00: 14: 24.547 * DB este încărcat din disc: 0.000 secunde [25] 29 Nov 00: 14: 24.547 * Serverul este acum gata să accepte conexiuni pe portul 6379 citate prin http: // localhost: 8000 / citate punct final.

Plasarea aplicației (serviciul de cotație) și a bazei de date (redis) funcționează într-un punct de siguranță pentru un singur server. Dar, evident, acest lucru nu scade. Introduceți Kubernetes.

Bazele Kubernetes

Kubernetes, a.k.a. k8s, este un cadru consacrat pentru gestionarea și orchestrarea containerelor multiple. Are propriul mod de a face lucruri, care de obicei este foarte bun. Se află încă în curs de dezvoltare, așa că mai sunt câteva margini aspre aici și acolo. Kubernetes are o mulțime de concepte și este foarte flexibil. Voi explica și demonstra acele concepte prin aplicarea lor la serviciul de citare.

Configurarea unui cluster

Există multe modalități de a crea un cluster Kubernetes. Kubernetes poate rula pe metale goale, pe motorul Google Container, pe AWS, pe metale goale (cu Linux) și pe orice sistem de operare folosind mașini virtuale. În scopul acestui articol, am creat un cluster de un master și doi minioni folosind clusterul k8s CoreOS OSX GUI. Pe Mac OS X oferă un mic meniu frumos în care puteți accesa multe instrumente de gestionare a clusterului.

Urmați instrucțiunile și veți fi bine să mergeți în cel mai scurt timp.

Dacă nu utilizați Mac OSX sau pur și simplu nu vă pasă mult pentru GUI, puteți utiliza acest proiect pentru a configura un cluster de testare într-un VM Vagrant.

Voi folosi linia de comandă de acum încolo.

Instrumentul pentru linia de comandă kubectl

kubectl este cuțitul elvețian al Kubernetes. Puteți să vă controlați complet și să gestionați clusterul din confortul consolei dvs. folosind doar kubectl.

Iată lista de comenzi: get Afișează una sau mai multe resurse descrie Afișați detalii despre o anumită resursă creați Creați o resursă după numele fișierului sau actualizarea stdin Actualizați o resursă după numele fișierului sau stdin. șterge Șterge o resursă după nume de fișier, stdin, resursă și ID, sau prin resurse și selector de etichete. namespace SUPERCEDED: Setați și vizualizați jurnalul curent al spațiului de nume Kubernetes Imprimați jurnalele pentru un container într-un pod. update roll-up Efectuați o actualizare în timp real a replicatoruluiController dat. resize Setați o nouă dimensiune pentru un controler de replicare. exec Executați o comandă într-un container. port-forward Redirecționați unul sau mai multe porturi locale către un pod. proxy Rulați un proxy serverului Kubernetes API run-container Rulați o anumită imagine pe cluster. Opriți oprirea grațios a unei resurse prin id sau nume de fișier. expune Faceți o aplicație replicată și expuneți-o ca etichetă Service Kubernetes Actualizați etichetele într-o config config modifică fișierele kubeconfig cluster-info Afișare informații cluster api-versiuni Imprimați versiunile API disponibile. versiune Imprimați informațiile despre versiunea clientului și a serverului. ajutați-vă cu ajutorul oricărei comenzi

Simțiți-vă liber să utilizați comanda de ajutor sau documentația pentru a investiga ceea ce face fiecare. Multe dintre ele sunt utilizate pentru a efectua operații manuale care sunt mai bine realizate folosind fișiere de configurare într-un sistem scalabil, distribuit, dar este indispensabil pentru explorarea rapidă și depanare. Cele mai comune comenzi pe care le voi folosi foarte mult sunt: ​​obțineți, creați, ștergeți și începeți.

pods

Un pod este unitatea de bază a implementării și gestionării în Kubernetes. Un pod este un grup de unul sau mai multe containere. Puteți specifica un pod folosind un fișier dedicat YAML sau ca parte a unui serviciu Kubernetes (a se vedea mai jos). Un pod este întotdeauna implementat pe o singură gazdă, iar toate containerele dintr-un pod pot avea acces reciproc prin localhost. Toate containerele podului sunt întotdeauna pornite, oprite și scalate împreună.

Pentru a verifica toate păstăile din cluster, tastați:

kubectl obține păstăi

Rezultatul va fi ceva de genul: NUMAI READY STATUS RESTARTS AGE quote-frontend-4kyns 1/1 Rularea 0 1h quote-frontend-v4xk1 1/1 Rularea 0 1h quote-store-controller-y4ya1 1/1 Rularea 0 23h ### Volumele

Containerele nu trebuie să mențină starea persistentă. Atunci când un container se blochează sau se repornește, sistemul de fișiere local este șters. Dacă doriți să păstrați stări persistente, ar trebui să utilizați volume persistente. Din moment ce totul în Kubernetes se bazează pe păstăi, trebuie să definiți volumele într-un pod. Aici este un fișier de definiție pod cu un volum persistent: apiVersion: v1 fel: Pod metadate: nume: quote-store etichete: app: quote-api rol: persistent-storage spec: recipiente: - nume: redis image: redis volumeMounts: / volume redis: - nume: quote-store-volume emptyDir: Rețineți că volumele persistente sunt limitate la nod și vor supraviețui blocărilor de containere și vor reporni, dar nu noduri / gazde. Încă mai trebuie să faci munca de replicare și de copiere a datelor importante.

Replicatoare Controlere

Una dintre cele mai importante caracteristici ale Kubernetes este abilitatea sa de a gestiona si de a mari cu ușurință în sus și în jos numărul de păstăi. În mod obișnuit, veți avea diferite tipuri de păstăi în sistemul dvs. și veți dori să puteți specifica numărul de păstăi de fiecare tip care ar trebui să fie difuzate.

Salutați controlerele de replicare. Un controler de replicare are un șablon care definește un grup de containere, un set de etichete pentru a identifica aceste păstăi și numărul de păstăi dorite. Controlorul de replicare asigură faptul că numărul de păstăi care rulează identificat de etichetele sale se potrivește întotdeauna cu numărul dorit. Dacă un pod întrerupe, controlerul de replicare va crea imediat unul nou.

Există mai multe cazuri interesante de utilizare susținute de controlorii de replicare, cum ar fi disponibilitatea înaltă, scalarea elastică și actualizările de rulare. De exemplu, puteți să adăugați și să eliminați păstăile din stăpânirea unui controlor de replicare prin schimbarea etichetei.

Replicatoarele sunt specificate într-un fișier YAML, desigur. Iată un exemplu: "apiVersion: v1 kind: ReplicationController

metadate: nume: quote-frontend spec: replici: 2 # selector identifică setul de Pods că acest controler de replicare este responsabil pentru gestionarea selectorului: app: quote-api rol: frontend # podTemplate definește " noi șabloane atunci când șablonul este necesar: metadate: etichete: # Important: aceste etichete trebuie să se potrivească cu selectorul de mai sus # Serverul api aplică această constrângere. aplicație: quote-api rol: spec. frontend: containere: - nume: quote-service imagine: g1g1 / quote-service env: - nume: GET_HOSTS_FROM # value: dns value: porturi env: quote-service container utilizează imaginea g1g1 / quote-service pe care am împins-o mai devreme în Docker Hub env secțiune în care schimbul de informații între păstăi poate apărea fie prin intermediul variabilelor DNS sau de mediu.

Pentru a crea un controler de replicare, tastați:

kubectl crea -f

Pentru a vizualiza controlerele de replicare curente din cluster, tastați:

kubectl get rc

Ar trebui să vedeți ceva de genul: CONTROLLER CONTAINER IMAGINE SELECTOR REPLICAS AGE quote-frontend quote-service g1g1 / quote-service app = quote-api, rol = frontend 2 1h quote-store-controler master redis app = quote-api, role = persistent - stocare 1 1d ### Servicii

Un serviciu expune pod-ul său la restul clusterului și posibil extern prin intermediul fie a variabilelor de mediu, fie a DNS. De exemplu, serviciul de cotație este alcătuit din două tipuri de păstăi: un magazin de magazin redis și un pod frontal. Containerul frontal ar trebui să găsească containerul de magazin, iar clienții ar trebui să poată atinge un singur punct final public pentru a accesa serviciul.

Serviciul Kubernetes este implementat într-un alt fișier YAML. Fiecare componentă a sistemului dvs. care trebuie să fie accesată de alte componente ar trebui să aibă propriul fișier de serviciu. Iată cele două fișiere de serviciu pentru componentele serviciului de cotație:

SRV-citat-frontend.yaml

apiVersion: v1 kind: Metadata de serviciu: nume: quote-frontend spec: tip: Porturi NodePort: - port: 8000 # portul pe care acest serviciu ar trebui să servească pe # containerul din fiecare pod pentru conectare; "www") sau un număr (de ex. 80) targetPort: 80 protocol: TCP # la fel ca și selectorul din controlerul de replicare, # dar de data aceasta identifică setul de păstăi pentru a încărca traficul # de echilibru. selector: app: quote-api rol: frontend #### srv-quote-store.yaml apiVersion: v1 kind: Metadata de serviciu: nume: quote-store spec: porturi: - port: 6379 # portul pe care acest serviciu ar trebui să îl servească pe targetPort: 6379 # exact ca selectorul din controlerul de replicare, set de păstăi pentru a încărca balanța # trafic la. selector: app: quote-api rol: persistent-storage Gazda și portul fiecărui serviciu sunt puse la dispoziția fiecărui container din cluster. De exemplu, dacă rulați o coajă interactivă pe unul dintre containerele frontend:

kubectl quote-frontend-4kins exec -i-t bash

Apoi, puteți verifica dacă mediul conține informațiile gazdă și port necesare pentru a vă conecta la magazinul de cotații. rădăcină @ quote-frontend-4kyns: / quote-service # env | grep STORE QUOTE_STORE_PORT_6379_TCP_ADDR = 10.100.234.192 QUOTE_STORE_PORT_6379_TCP_PROTO = tcp QUOTE_STORE_SERVICE_PORT = 6379 QUOTE_STORE_PORT_6379_TCP_PORT = 6379 QUOTE_STORE_PORT = tcp: //10.100.234.192: 6379 QUOTE_STORE_PORT_6379_TCP = tcp: //10.100.234.192: 6379 QUOTE_STORE_SERVICE_HOST = 10.100.234.192 Doar, pentru a vă reîmprospăta memoria, acesta este exact ceea ce face frontendul: redis_host = os.environ.get ('QUOTE_STORE_SERVICE_HOST', 'localhost') redis_server = redis.StrictRedis (host = redis_host, port = 6379, db = 0) Concluzie

Docker și Kubernetes sunt tehnologii interesante. Acest articol abia a zgâriat suprafața a ceea ce este posibil. Beneficiile sunt enorme, însă infrastructura, instrumentele și cele mai bune practici continuă să evolueze. Dacă sunteți chiar conectat la distanță de sistemele distribuite la scară largă, vă încurajez să rămâneți cel puțin pe lângă aceste tehnologii și în mod ideal să vă scufundați degetele de la picioare și, de fapt, să încercați să le folosiți. Există mai multe modalități de a experimenta și de a învăța fără a migra pe întregul dvs. infrastructură de producție.

În ceea ce privește Kubernetes, există și alte câteva alternative pentru gestionarea și orchestrarea cu mai multe containere, cum ar fi propriul compozit al lui Mesos și Docker. Cred că Kubernetes este mai solid din punct de vedere arhitectural, are o mulțime de impulsuri și este mai bun decât alternativele.

Cod