Docker i Kubernetes – Deo II
U prethodnom tekstu je opisan koncept kontejnera i definisan je Docker kao aplikacija otvorenog koda koja automatizuje razvijanje aplikacija u kontejneru. Opisane su osnovne komponente Docker-a: klijent i server, slike, registri i kontejneri. Pored arhitekture Dockera-a dato je uputstvo za listanje i preuzimanje Docker slika i opisan je način kreiranja nove Docker slike.
U nastavku ovog teksta biće reči o Kubernetes-ima, njihovoj arhitekturi na visokom i niskom nivou. Takođe, dat je i primer korišćenja Docker-a i Kubernetes-a.
Sadržaj
Kubernetes
Kubernetes je platforma otvorenog koda razvijena od strane Google-a koja služi za automatizaciju operacija nad kontejnerima, kao što su razvoj, raspoređivanje i skalabilnost u klasteru.
Komponente Kubernetes-a su:
- Podovi
- Lebele i selektori
- Replikacioni kontroleri
- Servisi
Kubernetes Arhitektura
Na visokom nivou Kubernetes prati sledeću arhitekturu:
Na najvišem nivou Kubernetes se sastoji od:
- Podova – najmanja jedinica u Kubernetes-u.
- Mastera – centralna jedinica u klasteru.
- Minioni – radnici (slave) koji rade zadatke nametnute od strane Master-a.
Na niskom nivou Kubernetes prati sledeću arhitekturu:
- API server je server bez stanja (stateless) koji dozvoljava ostalim komponentama da koriste prikazane servise. API-ju se pristupa pomoću kubectl komande iz komandne linije, ili preko web interfejsa baziranom na AJAX tehnologiji.
- Kubelet je proces koji se pokreće na svakoj fizičkoj mašini i on upravlja Pod-ovima.
- Scheduler ili raspoređivač nalazi se samo na glavnoj mašini I on služi za raspoređivanje podova na ostale mašine koje se nazivaju radnici (slaves).
- Controller Manager je glavni servis koji pokreće Kubernetes. On održava jednu beskonačnu petlju koja nadgleda stanje celog sistema.
Više o arhitekturi Kubernetes-a može se naći na http://kubernetes.io/docs/.
Podovi su najmanje razvojne jedinice u Kubernetes-u. Svaki Pod može da sadrži jedan ili više kontejnera. Svi kontejneri koji se nalaze u istom Pod-u dele host, što znači da dele IP adresu, portove i međusobno mogu da komuniciraju putem localhost-a.
Labele su parovi ključ/vrednost koji mogu da se postave na bilo koji objekat u Kubernetes-u(Pod, mašina u klasteru). Labele bi trebale da sadrže informacije bitne za korisnike. Mogu da se kreiraju pri pokretanju ili da se dodaju kasnije. Labele ne moraju da budu jedinstvene, čak se i očekuje da veliki broj objekata ima iste labele.
Preko selektora, korisnik može da izabere grupu objekata. Trenutno postoje dva tipa selektora, selektor baziran na jednakosti (Equality-based) i selektor zasnovan na grupama (set-based).
Selektori bazirani na jednakosti služe za filtriranje po ključevima ili vrednostima. Podržavaju samo dva operatora, == i !=.
Selektori bazirani na grupama podržavaju tri operatora:
- in – filtrira labele tako da se ključ ili vrednost nalati u zadatoj grupi vrednosti
- notin – filtrira labele tako da se ključ ili vrednost ne nalati u zadatoj grupi vrednosti
- exists – samo jedna vrednos po kojoj se pretražuje.
Replikacioni kontroler je zadužen za to da određeni, zadati broj Pod-ova uvek bude pokrenut. Ako postoji više Pod-ova od zadatog broja Kubernetes će ubiti neke Podove, u suprotnom će ih kreirati. Za razliku od Pod-ova koji su manuelno pokrenuti, Pod-ovi pokrenuti od strane kontrolera će automatski biti zamenjeni ukoliko u nekom od njih dođe do greške, ili neki od njih bude obrisan.
Problem sa pod-ovima je to što kad se napravi nova replika, ne možemo da znamo koju će IP adresu dobiti i kako da joj pristupimo. Ovaj problem rešavaju Servisi. Servisi određuju način na koji pristupamo pod-ovima. Servis može da opisuje jedan ili više podova i vezuje se na njih na osnovu selektora.
Primer korišćenja
Za pokretanje Kubernetes-a koristićemo:
- VirtualBox
- Vagrant
VirtualBox je softver otvorenog koda koji služi za virtuelizaciju operativnih sistema. Vagrant je softver koji kreira i konfiguriše virtuelnu mašinu. Predstavlja omotač oko VirtualBox-a i omogućava bržu i lakšu konfiguraciju virtuelne mašine.
Pokretanje Kubernetes-a vrši se na sledeći način:
- Kloniramo repozitorijum koji sadrži Kubernetes. To možemo da uradimo komandom:
git clone https://github.com/coreos/coreos-kubernetes.git
- Za pokretanje Kubernetes-a koristimo komandu
vagrant up
koja povlači sliku koja sadrži operativni sistem CentOS, pokreće je i pokreće Kubernetes u njoj.
Nakon uspešnog izvršavanja prethodnih komandi Kubernetes je startovan i spreman za upotrebu.
Kubernetes zadajemo kao argumente skripti kubectl.sh
koja se nalazi u cluster
folderu. Ovo možemo olakšati instalacijom kubectl-a. Kubectl binarni fajl treba da povučemo sa interneta i smestima u direktorijum /usr/local/bin. To možemo da uradimo komandom:
wget https://storage.googleapis.com/kubernetes-release/release/v0.17.0/bin /darwin/amd64/kubectl -O /usr/local/bin/kubectl
Nakon uspešnog izvršavanja ove komande, binarni fajl koji sadrži kubectl nalazi se na zadatoj lokaciji i sve što treba da uradimo je da damo prava izvršavanja za njega. To možemo da uradimo komandom:
chmod +x /usr/local/bin/kubectl
Nakon ove komande možemo da upravljamo Kubernetes-om preko kubectl-a.
Pripremanje Docker slike
Za osvaj primer napravićemo Docker sliku koja sadrži jednostavan node.js server.
Primer Dockerfile-a:
FROM node:4-onbuild EXPOSE 8888
Za pravljenje slike na osnovu datog Dockerfile-a koristimo komandu:
docker build -t simple-server
Pre nego sto pokrenemo ovu komandu u direktorijumu u kom se nalazi Dockerfile mora da postoji package.json, koji sadrži start skriptu.
Primer jednostavnog package.json
fajla:
{ "name": "test-server", "scripts": { "start": "node server.js" } }
U ovom fajlu kazemo da na start pokrene server.js. U server.js treba da se nalazi kod servera. Primer jednostavnog server.js
fajla:
var http = require('http'); const PORT = 8888; function handleRequest(request, response){ response.end('It works!'); } var server = http.createServer(handleRequest); server.listen(PORT, function(){ console.log("Server listening on: http://localhost:%s", PORT); });
Dokumenova komande korišćene za pravljenje ovog jednostavnog servera mogu se naći na https://nodejs.org/api/.
Kad imamo sve potrebne fajlove i izvršimo komandu:
docker build -t dusanz/simple-server
Nakon toga sliku postavljamo na javni registar komandom:
docker push dusanz/simple-server
Docker će da napravi sliku sa zadatim serverom i nju možemo da pokrenemo komandom:
docker run -it --rm dusanz/simple-server
Nakon usprešnog izvršenja ove komande, možemo pristupiti serveru na adresi: IP_KONTEJNERA:8888
.
Pripremanje fajlova za Kubernetes
Replikacioni kontroleri imaju yaml format. Primer node-server-replica.yaml
fajla, koji definiše jednu repliku:
apiVersion: v1 kind: ReplicationController metadata: labels: name: simple-server name: simple-server spec: replicas: 1 template: metadata: labels: name: simple-server spec: containers: - image: dusanz/simple-server name: simple-server ports: - name: simple-server containerPort: 8888 hostPort: 8888
Ovaj replikacioni kontroler možemo da primenimo komandom:
kubectl create -f node-server-replica.yaml
Nakon ove komande Kubernetes će obezbediti da u svakom trenutku u klasteru postoji tačno jedna instanca pokrenutog servera.
Servisi takođe imaju yaml format. Definisaćemo servis koji za pod-ove sa labelom simple-server
preusmerava saobraćaj koji dolazi na port 80 na port 8888.
apiVersion: v1 kind: Service metadata: name: sipmple-server labels: name: simple-server spec: type: NodePort ports: - port: 80 targetPort: 8888 nodePort: 31400 protocol: TCP selector: name: simple-server
Servis kreiramo komandom:
kubectl create -f node-server-service.yaml
Zaključak
Docker i Kubernetes našli su veliku primenu kod serverskih aplikacija od kojih se zahteva da imaju dobar odziv i rade na velikom broju mašina. Kubernetes, koji je razvijen od strane Google-a, je u početku imao velike probleme sa produkcijom, najviše zbog toga što je najveći broj mašina kojima je mogao da upravlja bio 500. Nakon verzije 1.2 ovo ograničenje je ukinuto i Kubernetes počinje sve češće da se koristi u produkciji.