- Kubernetes – orchestrátor kontejnerů (1) – schedulery vs. PaaS
- Kubernetes – orchestrátor kontejnerů (2) – instalace a první běžící kontejner
- Kubernetes – orchestrátor kontejnerů (3) – deployment aplikací, škálování a rollback
- Kubernetes – orchestrátor kontejnerů (4) – interní balancing a discovery služeb
- Kubernetes – orchestrátor kontejnerů (5) – přístup zvenku
V minulém díle jsme jsme si Kubernetes nainstalovali a rozjeli svůj první workload. Dnes si s konceptem “deployment” pohrajeme trochu víc.
Koncept deployment
Přestože je Kubernetes dost mladý projekt, koncept deployment můžete považovat za řešení “nové generace”. V klasickém Kubernetes se používalo replikačních kontrolerů, ale deployment vše výrazně zjednodušuje a přináší mnoho příjemných vlastností.
Kontejnery (pody, deploymenty apod.) nebudeme startovat z příkazové řádky, raději si je popíšeme v YAML souboru. Vytvořte soubor mujweb.yaml s tímto obsahem. Všimněte si pár zajímavostí. Replicas říká v kolika kopiích má pod běžet. Labels je velmi důležitý koncept. Jde o značku, kterou pak můžete používat pro vyhledání podů (například pro identifikaci co zařadit do externí služby a tak podobně). Dále si všimněte, že jsou tam popsány kontejner image.
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: mujweb-deployment spec: replicas: 3 template: metadata: labels: app: mujweb spec: containers: - name: mujweb image: cloudsvet/k8s-web:v1 ports: - containerPort: 3000
Použijme teď tento soubor k vytvoření deploymentu.
$ kubectl create -f mujweb.yaml deployment "mujweb-deployment" created
Pohlédněte si ho.
$ kubectl get deployments NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE mujweb-deployment 3 0 0 0 21s $ kubectl describe deployment mujweb-deployment Name: mujweb-deployment Namespace: default CreationTimestamp: Sat, 23 Apr 2016 12:02:26 -0700 Labels: app=mujweb Selector: app=mujweb Replicas: 3 updated | 3 total | 0 available | 3 unavailable StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 1 max unavailable, 1 max surge OldReplicaSets: <none> NewReplicaSet: mujweb-deployment-3445720265 (3/3 replicas created) Events: FirstSeen LastSeen Count From SubobjectPath Type Reason Message --------- -------- ----- ---- ------------- -------- ------ ------- 1m 1m 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set mujweb-deployment-3445720265 to 3
Zatím pody ještě nejsou nahoře – požadovaný počet neodpovídá aktuálnímu skutečnému. Všimněte si ale v popisu především toho, že Kubernetes vytvořil nový ReplicaSet (ten bude mít na starost udržování požadovaného počtu živých kontejnerů).
Po chvilce to zkuste znova.
$ kubectl describe deployment mujweb-deployment Name: mujweb-deployment Namespace: default CreationTimestamp: Sat, 23 Apr 2016 12:02:26 -0700 Labels: app=mujweb Selector: app=mujweb Replicas: 3 updated | 3 total | 3 available | 0 unavailable StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 1 max unavailable, 1 max surge OldReplicaSets: <none> NewReplicaSet: mujweb-deployment-3445720265 (3/3 replicas created) Events: FirstSeen LastSeen Count From SubobjectPath Type Reason Message --------- -------- ----- ---- ------------- -------- ------ ------- 2m 2m 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set mujweb-deployment-3445720265 to 3
Můžeme kouknout specificky na ReplicaSet.
$ kubectl get rs NAME DESIRED CURRENT AGE mujweb-deployment-3445720265 3 3 1m
Podívejme se na běžící pody a jejich rozmístění v clusteru.
$ kubectl get pods -o wide NAME READY STATUS RESTARTS AGE NODE mujweb-deployment-3445720265-0em54 1/1 Running 0 2m 172.17.4.202 mujweb-deployment-3445720265-de5gd 1/1 Running 0 2m 172.17.4.201 mujweb-deployment-3445720265-yg90y 1/1 Running 0 2m 172.17.4.203
Upravte teď soubor mujweb.yaml a zvyšte počet replik.
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: mujweb-deployment spec: replicas: 5 template: metadata: labels: app: mujweb spec: containers: - name: mujweb image: cloudsvet/k8s-web:v1 ports: - containerPort: 3000
Aplikujte ho.
$ kubectl apply -f mujweb.yaml deployment "mujweb-deployment" configured
Jak teď vypadají deploymenty?
$ kubectl get deployments NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE mujweb-deployment 5 3 3 3 21h
DESIRED je nově 5, ale pokud jste byli dostatečně rychlí, CURRENT je zatím jen 3.
Podívejme se na běžící pody.
$ kubectl get pods NAME READY STATUS RESTARTS AGE mujweb-deployment-3445720265-0em54 1/1 Running 0 21h mujweb-deployment-3445720265-67d7h 0/1 ContainerCreating 0 15s mujweb-deployment-3445720265-de5gd 1/1 Running 0 21h mujweb-deployment-3445720265-vg9rn 0/1 Pending 0 15s mujweb-deployment-3445720265-yg90y 1/1 Running 0 21h
3 jsou nahoře, dva se zatím vytváří.
Pochvilce to zkusme znovu.
$ kubectl get pods NAME READY STATUS RESTARTS AGE mujweb-deployment-3445720265-0em54 1/1 Running 0 21h mujweb-deployment-3445720265-67d7h 1/1 Running 0 1m mujweb-deployment-3445720265-de5gd 1/1 Running 0 21h mujweb-deployment-3445720265-vg9rn 1/1 Running 0 1m mujweb-deployment-3445720265-yg90y 1/1 Running 0 21h
Rolling updaty
Kubernetes vám umožní inteligentně updatovat image kontejnerů ve vašem deploymentu. Představme si, že máme připraven nový image (s tage v2) a chceme dostat svoje prostředí z v1 do v2 rolling způsobem (tedy pozvolna a bez odstávky).
Upravte mujweb.yaml takto:
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: mujweb-deployment spec: replicas: 5 template: metadata: labels: app: mujweb spec: containers: - name: mujweb image: cloudsvet/k8s-web:v2 ports: - containerPort: 3000
Aplikujte.
$ kubectl apply -f mujweb.yaml deployment "mujweb-deployment" configured
Podívejme se na podrobnosti deploymentu. Jak to Kubernetes dělá? Pro novou verzi vytvoří nový ReplicaSet. Následně v novém ReplicaSetu přidává a současně ze starého ubírá. Takhle to dělá až je postupně infrastruktura přemigrována na novou verzi.
$ kubectl describe deployment mujweb Name: mujweb-deployment Namespace: default CreationTimestamp: Sat, 23 Apr 2016 12:02:26 -0700 Labels: app=mujweb Selector: app=mujweb Replicas: 5 updated | 5 total | 5 available | 0 unavailable StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 1 max unavailable, 1 max surge OldReplicaSets: mujweb-deployment-3445720265 (5/4 replicas created) NewReplicaSet: mujweb-deployment-3524429002 (1/1 replicas created) Events: FirstSeen LastSeen Count From SubobjectPath Type Reason Message --------- -------- ----- ---- ------------- -------- ------ ------- 26s 26s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set mujweb-deployment-3524429002 to 1 11s 11s 1 {deployment-controller } Normal ScalingReplicaSet Scaled down replica set mujweb-deployment-3445720265 to 4
Podívejte se na ReplicaSety.
$ kubectl get rs NAME DESIRED CURRENT AGE mujweb-deployment-3445720265 4 4 21h mujweb-deployment-3524429002 2 1 43s
První uvedený je starý a Kubernetes od něj chce 4 kopie (tedy od jednu méně). Druhý je nový a od něj Kubernetes chce aktuálně 2 kopie. Takto pozvolna bude Kubernetes přelévat verze.
Mrkněte na pody. V mém případě jsem je chytil při tom, jak se dva nové vytvářejí a jeden je právě sestřelován.
$ kubectl get pods NAME READY STATUS RESTARTS AGE mujweb-deployment-3445720265-0em54 1/1 Running 0 21h mujweb-deployment-3445720265-67d7h 1/1 Running 0 3m mujweb-deployment-3445720265-de5gd 1/1 Running 0 21h mujweb-deployment-3445720265-vg9rn 1/1 Terminating 0 3m mujweb-deployment-3445720265-yg90y 1/1 Running 0 21h mujweb-deployment-3524429002-a8n5w 0/1 ContainerCreating 0 30s mujweb-deployment-3524429002-rrlx9 0/1 ContainerCreating 0 54s
Pojďme to teď vypisovat co nejrychleji a zkoumat celý proces.
$ kubectl get rs NAME DESIRED CURRENT AGE mujweb-deployment-3445720265 4 4 21h mujweb-deployment-3524429002 2 2 1m $ kubectl get pods NAME READY STATUS RESTARTS AGE mujweb-deployment-3445720265-0em54 1/1 Running 0 21h mujweb-deployment-3445720265-67d7h 1/1 Terminating 0 4m mujweb-deployment-3445720265-de5gd 1/1 Running 0 21h mujweb-deployment-3445720265-vg9rn 0/1 Terminating 0 4m mujweb-deployment-3445720265-yg90y 1/1 Running 0 21h mujweb-deployment-3524429002-a8n5w 0/1 ContainerCreating 0 1m mujweb-deployment-3524429002-rrlx9 1/1 Running 0 1m $ kubectl get rs NAME DESIRED CURRENT AGE mujweb-deployment-3445720265 2 2 21h mujweb-deployment-3524429002 4 4 3m $ kubectl get pods NAME READY STATUS RESTARTS AGE mujweb-deployment-3445720265-0em54 1/1 Running 0 21h mujweb-deployment-3445720265-de5gd 1/1 Terminating 0 21h mujweb-deployment-3445720265-yg90y 1/1 Running 0 21h mujweb-deployment-3524429002-a8n5w 1/1 Running 0 2m mujweb-deployment-3524429002-qzhsh 0/1 ContainerCreating 0 48s mujweb-deployment-3524429002-rrlx9 1/1 Running 0 3m mujweb-deployment-3524429002-ssao6 0/1 ContainerCreating 0 1m $ kubectl get rs NAME DESIRED CURRENT AGE mujweb-deployment-3445720265 0 0 21h mujweb-deployment-3524429002 5 5 4m $ kubectl get pods NAME READY STATUS RESTARTS AGE mujweb-deployment-3524429002-a8n5w 1/1 Running 0 14m mujweb-deployment-3524429002-hc8mw 1/1 Running 0 10m mujweb-deployment-3524429002-qzhsh 1/1 Running 0 12m mujweb-deployment-3524429002-rrlx9 1/1 Running 0 14m mujweb-deployment-3524429002-ssao6 1/1 Running 0 12m
Máme hotovo. Podívejme se teď na historii deploymentů.
$ kubectl rollout history deployment/mujweb-deployment deployments "mujweb-deployment": REVISION CHANGE-CAUSE 1 <none> 2 <none>
Pohlédněme si detaily.
$ kubectl rollout history deployment/mujweb-deployment --revision=1 deployments "mujweb-deployment" revision 1 Labels: app=mujweb,pod-template-hash=3445720265 Annotations: kubernetes.io/change-cause= Image(s): cloudsvet/k8s-web:v1 No volumes. $ kubectl rollout history deployment/mujweb-deployment --revision=2 deployments "mujweb-deployment" revision 2 Labels: app=mujweb,pod-template-hash=3524429002 Annotations: kubernetes.io/change-cause= Image(s): cloudsvet/k8s-web:v2 No volumes.
Nepovedla se vám nová verze? Jednoduše můžete udělat rollback na původní.
$ kubectl rollout undo deployment/mujweb-deployment --to-revision=1 deployment "mujweb-deployment" rolled back $ kubectl get rs NAME DESIRED CURRENT AGE mujweb-deployment-3445720265 5 5 23h mujweb-deployment-3524429002 0 0 1h