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.

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:

Arhitektura Kubernetes-a na visokom nivou

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:

Arhitekture Kubernetes-a na niskom nivou

  • 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.