Kubernetes

From berki WIKI
Revision as of 23:04, 30 March 2019 by Adam (talk | contribs) (POD)

Jump to: navigation, search


Kubernetes felépítése

Logikai építőkockák

  • Container:
  • Pod:
  • ReplicaSet:
  • Deployment:
  • Service:
  • Endpoint:
ClipCapIt-190330-184913.PNG

Infrastruktúra elemek

ClipCapIt-190330-193336.PNG



ClipCapIt-190313-214212.PNG

Telepítés

kubectl

$ curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
$ chmod +x ./kubectl
$ ln -s /home/adam/Programs/Kubernetes/kubectl /usr/local/bin/kubectl
$ kubectl version --output=yaml


Minikube

$ curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-"linux-amd64 && 
$ chmod +x minikube 
$ ln -s /home/adam/Programs/Kubernetes/minikube /usr/local/bin/minikube

kvm2 driver install

$ curl -LO https://storage.googleapis.com/minikube/releases/latest/docker-machine-driver-kvm2 \
  && sudo install docker-machine-driver-kvm2 /usr/local/bin/

$ minikube version


Minikube indítása

$ minikube start --vm-driver=kvm2
Creating kvm VM (CPUs=2, Memory=2048MB, Disk=20000MB)
...
- docker
- kubernetes master
- kubernetes node: kublet
😄  minikube v0.35.0 on linux (amd64)
🔥 Creating virtualbox VM (CPUs=2, Memory=2048MB, Disk=20000MB) ...

Letölti a minikube.iso image-et a /home/adam/.minikube/cache/iso/ mappába, és innen létrehoz egy kvm vm-et:

# virsh list
 Id    Name                           State
----------------------------------------------------
 1     minikube                       running



Minikube parancsok

$ minikube dashboard		


A minikube itt mutatja meg, hogy egy adott service hol érhető el:

# minikube service <service-name> --url


Be lehet ssh-zni a vm-be mint a docker-machine ssh nál.

# minikube ssh  -

A minikube telepítő beállította a kubectl-t is, hogy a minikube-ban futó cluster-re csatlakozzon. Ha listázzuk a kubectl beállításait, láthatjuk a minikube VPN IP címét.

# kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority: /root/.minikube/ca.crt
    server: https://192.168.42.224:8443
  name: minikube


Nodes

Az összes node listázása.

# kubectl get nodes
NAME       STATUS   ROLES    AGE   VERSION
minikube   Ready    master   11m   v1.13.4

Megfelel a swarm-ban: docker node ls parancsnak.

Pod

Konténert a legegyszerűbben a kubectl run paranccsal futtathatunk. Létre fog hozni egy pod-ot és benne el fogja indítani az image-et.

$ kubectl run db --image mongo
ClipCapIt-190331-000406.PNG



Ez ekvivalens ezzel: kubectl create deployment db --image mongo

# kubectl get pods
NAME                  READY   STATUS              RESTARTS   AGE
db-7fdd878ff9-7v66g   0/1     ContainerCreating   0          66s
# kubectl exec -it <pod név> /bin/bash

//Ha több konténer is van a pod-ban, akkor a -c vel meg kell adni a konténer nevét:

# kubectl exec -it -c db dbstack /bin/bash

//Ha több konténer is van a pod-ban, akkor a pod neve után meg kell adni a konténer nevét.

# kubectl logs dbstack -c db


//A törléshez meg kell mondani azt is, hogy ez egy deployment. MÉg akkor is, ha ez csak egy pod.

# kubectl delete deployment db
deployment.extensions "db" deleted
# kubectl create deplyoment db --image mongo 

//Csinált hozzá egy doploymentet-et, egy ReplicaSet-et és egy Pod-ot.

# kubectl get all
NAME                      READY   STATUS    RESTARTS   AGE
pod/db-6b5c96c65f-9lxnb   1/1     Running   0          2m46s

NAME                 READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/db   1/1     1            1           2m46s

NAME                            DESIRED   CURRENT   READY   AGE
replicaset.apps/db-6b5c96c65f   1         1         1       2m46s


# kubectl get pods -o wide
NAME   READY   STATUS    RESTARTS   AGE     IP           NODE       NOMINATED NODE   READINESS GATES
db     1/1     Running   0          2m39s   172.17.0.2   minikube   <none>           <none>


[root@adamDell2 ~]# kubectl describe pod dbstack
Name:               dbstack
Namespace:          default
Priority:           0
PriorityClassName:  <none>
Node:               minikube/192.168.122.228
Start Time:         Wed, 13 Mar 2019 21:51:19 +0100
Labels:             type=stack
Annotations:        <none>
Status:             Running
IP:                 172.17.0.5
Containers:
  db:
    Container ID:   docker://c371653e62b4bb1f8a7fb7de4d88452b6de623cf02caa41df9728df15d080481
    Image:          mongo:3.3
   ...
  api:
    Container ID:   docker://6b64c392a77347ce5e7b36ddfd80f2ef320a0e31d25985f813294d08cacf76b3
    Image:          vfarcic/go-demo-2


# kubectl describe -f pod-db.yaml 
Name:               db
Namespace:          default
Priority:           0
PriorityClassName:  <none>
Node:               minikube/192.168.122.228
Start Time:         Wed, 13 Mar 2019 20:49:30 +0100
Labels:             type=db


# kubectl get -f pod-db.yaml -o json
{
    "apiVersion": "v1",
    "kind": "Pod",
    "metadata": {
        "creationTimestamp": "2019-03-13T19:49:30Z",
        "labels": {
            "type": "db",
            "vendor": "MongoLabs"
        },


//Mindig úgy kell szűrni, hogy a legfelsőbb szintű elem elé teszünk egy .-ot. Majd megadjuk a path-t.

# kubectl get -f pod-db.yaml -o jsonpath="{.status.hostIP}"
192.168.122.228


//Ha az összes lista elem kell, akkor [*]

  1. kubectl get -f pod-db.yaml -o jsonpath="{.spec.containers[*].name}"

db api


//Címke alapján rendeljünk node-hoz.

  1. kubectl label nodes <your-node-name> disktype=ssd

nodeSelector:

 labelName: labelvalue


első pod a listáról:

  1. kubectl get pods -o name | tail -1

//címke felrakása kubectl label $POD_NAME service=go-demo-2

//címke levétele kubectl label $POD_NAME service-


címkék listázás kubectl get pods --show-labels


Health check

readinessProbe: --> ezt addig fogja futtatni amíg nem lesz egyszer sikeres, ez után fogja ready-re állítani a konténert. livenessProbe:

 exec:
   command:
   - cat
   - /tmp/healthy


livenessProbe:

  httpGet:
    path:
    port: 
    httpHeaders:
    - name: 
      value: 

livenessProbe:

 tcpSocket:
   port: 8080
 


initialDelaySeconds: 5 --> ennyi után fogja elkezdeni a próbálozást periodSeconds: 5 --> ilyen sürün timeoutSeconds: 10 failureTreshold: 20

ReplicaSets

Arra szolgál, hogy a benne definiált pod lehetőleg mindig annyi példányban fusson, amit defináltunk.

A ReplicaSet és a ReplicaController között a selector-ban van a különbség. A Controller-ben csak a = b-vel selector-okat lehet megadni, míg a Set-ben meg lehet adni összetett kifejezéseket is:

  selector:
    matchExpressions:
     - {key: app, operator: In, values: [soaktestrs, soaktestrs, soaktest]}
     - {key: teir, operator: NotIn, values: [production]}


  1. kubectl get rs -o wide

NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR go-demo-2 2 2 2 23s db,api mongo:3.3,vfarcic/go-demo-2 service=go-demo-2,type=backend


# kubectl describe rs go-demo-2
Name:         go-demo-2
Namespace:    default
Selector:     service=go-demo-2,type=backend
Labels:       <none>
Annotations:  <none>
Replicas:     2 current / 2 desired
Pods Status:  2 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  db=mongo
           language=go
           service=go-demo-2
           type=backend
  Containers:
   db:
    Image:        mongo:3.3
    Port:         <none>
    Host Port:    <none>
    Environment:  <none>
    Mounts:       <none>
   api:
    Image:      vfarcic/go-demo-2
...
Events:
  Type    Reason            Age   From                   Message
  ----    ------            ----  ----                   -------
  Normal  SuccessfulCreate  112s  replicaset-controller  Created pod: go-demo-2-6nq9h
  Normal  SuccessfulCreate  112s  replicaset-controller  Created pod: go-demo-2-5c2sk


# kubectl get pods --show-labels
NAME              READY   STATUS    RESTARTS   AGE     LABELS
go-demo-2-5c2sk   2/2     Running   0          5m41s   db=mongo,language=go,service=go-demo-2,type=backend
go-demo-2-6nq9h   2/2     Running   0          5m41s   db=mongo,language=go,service=go-demo-2,type=backend


//A pod-ok és az RS között csak lazán csatolt kapcsolat van. Ha --cascade=false kapcoslóval töröljük az RS-t akkor a //podokat meg fogja hagyni. És ha újra létrehozzuk az RS-t ezeket a pod-okat fogja felhasználni. kubectl delete -f rs/go-demo-2.yml --cascade=false


kubectl apply --> frissíti a konfigurációt. Rárak egy annotációt, és később az alapjén dönti el, hogy mi válozott. Csak akkor lehet használni, ha eleve apply-al hoztuk létre, vagy create --save-confg kapcsolóval. kubectl create --save-config

kubectl edit: egyenlő azzal, mint ha describe -o yaml -el elmentenénk a konfigot, átírnánk, majd nyomnánk rá egy applay-t.

A -o yaml-el meg tudjuk szeretni az eredeti konfigurációs fájlt:

  1. kubectl get rs go-demo-2 -o yaml



Service

https://sookocheff.com/post/kubernetes/understanding-kubernetes-networking-model/


//A containerPort csak informatív jellegű a konténer definícióban. Ettől függetlenül bármilyen porotot expose-álni lehet később, olyat is ami itt nincs magadva. Ezt nem lehet később felülírni. Ha az expose parancsban nem adunk meg --target-port-ot akkor a -containerPort-al megadott portot fogja megosztani.

     containers:
     - name: my-nginx
       image: nginx
       ports:
       - containerPort: 80


//Az expose paranccsal lehet egy Pod vagy ReplicSet vagy Deployment-hez service-t készíteni implicit (tehát nem dekleratív módon). Meg kell mondnai, hogy miből indulunk ki. Mi most egy replicaSet-ből, ezért az rs után megadtuk a ReplicaSet nevét. Utána meg kell adni a service nevét, a portot, amit ki akarunk nyitni, valamint a típust.

  1. kubectl expose rs nginx-rs --name=http --port=80 --type=NodePort --target-port=80


Típusok:

  • NodePort: a külvilágból is elérhető lesz, minden egyes node-on --> clientIP típust is létrehoz, így a többi node is eléri ezt automatikusan
  • ClusterIP: csak a cluster-en belülről
  • ExternalName: ehhez cloud szolgáltató kell, pl aws
  • LoadBalancer

Három féle port érdekes egy NodePort típusú service estetén, amiből az expose paranccsal csak kettőt lehet megadni:

  • port: ezen a porton érhető el a service a cluster-en belül. Ennek nincs köze ahhoz hogy a cluster-n kivül hol érhető el a szolgáltatás. Ha nem adjuk meg, akkor ugyan az lesz mint a target-port
  • target-port: ez azt mondja meg, hogy a pod-on/container-en belül hol hallgatózik a service. Ha nem adjuk meg külön, akkor a -containerPort -ból szedni.
  • nodePort: na ezt nem lehet itt megadni. Azt mondja meg, hogy a cluster-en kívül hol lesz elérhető a szolgálatás. Ha nem adjuk meg akkor random választ.
# kubectl get svc http -o wide
NAME   TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE    SELECTOR
http   NodePort   10.98.187.168   <none>        80:32730/TCP   8m3s   run=my-nginx


Az itt mutatott IP cím a belső virtuális cím ami csak a Kubernetes cluster-en belül érvényes. A konténernek sincs ilyen 10.X.X.X-es tartományú IP címe, ez egy Kubernetes belső dolog.

Láthatjuk, hogy a service belső IP címe 80 (ezt adtuk meg a --port -nál, bármi lehetett volna, szabadon választható) és ehhez rendelte hozzá a külső portot: 32730 Ez a port az összes node publikus IP -én elérhető.


# kubectl get node -o wide
NAME       STATUS   ROLES    AGE    VERSION   INTERNAL-IP       EXTERNAL-IP   OS-IMAGE            KERNEL-VERSION   CONTAINER-RUNTIME
minikube   Ready    master   7d1h   v1.13.4   192.168.122.228   <none>        Buildroot 2018.05   4.15.0           docker://18.6.2
^^^^^^


Az expose autómatikusan legyártja a service definíciót a ReplicaSet-ből, amiből kiindultunk. A végerdmény az alábbi:

# kubectl get svc http -o yaml
apiVersion: v1
kind: Service
metadata:
  name: http
spec:
  ports:
  - nodePort: 32730
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    run: my-nginx
  type: NodePort

A service és a ReplicaSet semmilyen kapcsolatban nincsenek egymással. Mind a kettő a selector-okkal találják meg a POD-okat.


A pod-ok úgynevezett Endpoint-okon keresztül ajálják ki a portokat a service-ek számára. Rövidítése ep. Tehát itt a 80-as port megegyezik a target-port-nál megadott értékkel.

  1. kubectl get ep

NAME ENDPOINTS AGE http 172.17.0.7:80 23m


Ha megnézzük az ep definícoját, akkor ott fel van sorolva az összes pod aki részt vesz a service-ben. Látható, hogy két pod van jelenleg . Az is ki van listázva, hogy mi a belső IP címük és hogy melyik node-on vannak.

# kubectl get ep http -o yaml
apiVersion: v1
kind: Endpoints
metadata:
  creationTimestamp: "2019-03-17T19:49:12Z"
  name: http
  namespace: default
  resourceVersion: "84822"
  selfLink: /api/v1/namespaces/default/endpoints/http
  uid: bd23a709-48ed-11e9-8d39-5254008eeeec
subsets:
- addresses:
  - ip: 172.17.0.7
    nodeName: minikube
    targetRef:
      kind: Pod
      name: nginx-rs-wtzmm
      namespace: default
      resourceVersion: "73593"
      uid: 1820549d-48d9-11e9-8d39-5254008eeeec
  notReadyAddresses:
  - ip: 172.17.0.8
    nodeName: minikube
    targetRef:
      kind: Pod
      name: nginx-rs-jkvx7
      namespace: default
      resourceVersion: "84820"
      uid: 1c547797-48ee-11e9-8d39-5254008eeeec
  ports:
  - port: 80

A service-ek neve bekerül a DNS-be, és feloldja a Kubernetes a konténerek számára a belső virtuális IP címmel. Ha van egy ClusterIP típusú service-ünk a db-svc névvel, akkor a cluster-ben minden egyes konténerben ezt fel fogja oldani a service IP címére: 10.111.222.165. A service meg a felsorolt Enpoints-okon éri el a konténert.

# kubectl describe svc db-svc
Name:              db-svc
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          service=mongo-db,type=db
Type:              ClusterIP
IP:                10.111.222.165
Port:              <unset>  27017/TCP
TargetPort:        27017/TCP
Endpoints:         172.17.0.2:27017

A service round-rubin módon választ a végpontok között. De csak azoknak küld csomagot, amiben a livenessProbe. sikeresen futott le. Korábban userpase-el ment a kommunikácó, most már iptabels szabályokkal, ami sokkal gyorsabb, viszont nem tudja deketálni ha egy pod kiesett. Erre kell a livenessProbe

Lépjünk be egy harmadik konténerbe, amire nincs rákötve a service:

  1. kubectl exec -it rs-db-api-m6hkf /bin/sh

/ # nslookup db-svc Name: db-svc Address 1: 10.111.222.165 db-svc.default.svc.cluster.local

/ # nc -vz db-svc 27017 db-svc (10.111.222.165:27017) open


Publikus port lekrédezése: PORT=$(kubectl get svc svc-api -o jsonpath="{.spec.ports[0].nodePort}"

Tehát nem kell a -o json ahhoz hogy tudjunk szűrni.