Difference between revisions of "Kubernetes"

From berki WIKI
Jump to: navigation, search
(Pod-ok kezelése)
(Pod-ok kezelése)
Line 207: Line 207:
  
 
Egy pod összes adatának listázása. Itt külön listában láthatjuk a POD-ban futó összes konténert.  
 
Egy pod összes adatának listázása. Itt külön listában láthatjuk a POD-ban futó összes konténert.  
<source highlight="11-12">
+
<source line start="2" highlight="4-6">
 
[root@adamDell2 ~]# kubectl describe pod dbstack
 
[root@adamDell2 ~]# kubectl describe pod dbstack
 
Name:              dbstack
 
Name:              dbstack

Revision as of 17:53, 7 April 2019


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

ClipCapIt-190331-000406.PNG

Podok készítése

Imperative megközelítés

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


Deklaratív megközelítés

apiVersion: v1
kind: Pod
metadata:
  name: go-demo-2
  labels:
    app: myapp
spec:
  containers:
  - name: db
    image: mongo:3.3


# kubectl create -f pod-db.yaml
pod/go-demo-2 created

# kubectl get pod
NAME        READY   STATUS    RESTARTS   AGE
go-demo-2   1/1     Running   0          50s


Pod-ok kezelése

Pod-ok listázása

# kubectl get pods
NAME                  READY   STATUS              RESTARTS   AGE
db-7fdd878ff9-7v66g   0/1     ContainerCreating   0          66s

Belépés a pod-ban futó konténerekbe:

# 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


Minden kubernetes elem listázása:

# 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


Egy pod összes adatának listázása. Itt külön listában láthatjuk a POD-ban futó összes konténert.

[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


A -f -el meg lehet adni a leíró fájlt a describe parancsban. Ez minden Kubernetes elemre működik. Ha nem adunk meg a formátumra paramétert, akkor egy szimpla felsorolást kapunk. A végén pedig egy esemény történet van az adott pod-ról.

# 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
...
..
Events:
  Type    Reason          Age   From               Message
  ----    ------          ----  ----               -------
  Normal  Scheduled       21h   default-scheduler  Successfully assigned default/go-demo-2 to minikube
  Normal  Pulled          21h   kubelet, minikube  Container image "mongo:3.3" already present on machine
  Normal  Created         21h   kubelet, minikube  Created container
  Normal  Started         21h   kubelet, minikube  Started container


-o kapcsoló használata

Név Leírás
-o=custom-columns=<spec> Print a table using a comma separated list of custom columns
-o=custom-columns-file=<filename> Print a table using the custom columns template in the <filename> file
-o=json Output a JSON formatted API object
-o=jsonpath=<template> Print the fields defined in a jsonpath expression
-o=jsonpath-file=<filename> Print the fields defined by the jsonpath expression in the <filename> file
-o=name Print only the resource name and nothing else
-o=wide Output in the plain-text format with any additional information, and for pods, the node name is included
-o=yaml Output a YAML formatted API object


A -o json kapcsolóval írhatjuk ki JSON -ban a pod infókat.

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


Részletes pod lista. A lényeg itt az IP cím.

# 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>


első pod a listáról:

# kubectl get pods -o name | tail -1


Szűrés

Listázzuk ki JSON-ban a pod részleteket.

    "status": {
        ...
        "hostIP": "192.168.122.228",
...

Szűrni a -o jsonpath -al lehet.
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 egy lista összes elemére akarjuk hogy illeszkedjen a keresés, akkor [*] -ot kell használni. Ha egy konkrét lista elemet akarunk, akkor azt adjuk meg így [1]
Pl. az összes konténer nevét így listázhatjuk:

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


Címkék

A selector-ok címék alapján működnek.

Címke hozzáadása egy node-hoz:

# kubectl get node
NAME       STATUS   ROLES    AGE   VERSION
minikube   Ready    master   22d   v1.13.4

# kubectl label node minikube disktype=ssd
node/minikube labeled
# kubectl describe node minikube
Name:               minikube
Roles:              master
Labels:             beta.kubernetes.io/arch=amd64
                    beta.kubernetes.io/os=linux
                    disktype=ssd   
...
# kubectl get node --show-labels
NAME       STATUS   ROLES    AGE   VERSION   LABELS
minikube   Ready    master   22d   v1.13.4   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disktype=ssd,..

Szintaxis:

# kubectl label <resource type: node, pod, ...> <resource név> <címke neve>=<címke értéke>


nodeSelector:

 labelName: labelvalue


Címke felrakása pod-ra:

# kubectl label pod go-demo-2 type=example
pod/go-demo-2 labeled
# kubectl get pod --show-labels
NAME        READY   STATUS    RESTARTS   AGE   LABELS
go-demo-2   1/1     Running   1          23h   app=myapp,type=example


Címke törlése

# kubectl label pod go-demo-2 type-
pod/go-demo-2 labeled

# kubectl get pod --show-labels
NAME        READY   STATUS    RESTARTS   AGE   LABELS
go-demo-2   1/1     Running   1          23h   app=myapp

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

ClipCapIt-190331-231800.PNG


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.