Changes

Kubernetes

19,100 bytes removed, 19:15, 18 January 2020
no edit summary
[[Kubernetes alapok]]
[[Google Kubernetes Engine]]
=Kubernetes felépítése=[[Openshift basics]]
[[Helm]]
==Logikai építőkockák== * Container:* Pod:* ReplicaSet:* Deployment:* Service:* Endpoint: :[[File:ClipCapIt-190330-184913.PNG]] ==Infrastruktúra elemek==  :[[File:ClipCapIt-190330-193336.PNG]]    :[[File:ClipCapIt-190313-214212.PNG]] =Telepítés=  '''kubectl''' <pre>$ 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</pre> <pre>$ kubectl version --output=yaml</pre>  '''Minikube'''<pre>$ 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</pre> '''kvm2 driver install'''<pre>$ curl -LO https://storage.googleapis.com/minikube/releases/latest/docker-machine-driver-kvm2 \ && sudo install docker-machine-driver-kvm2 /usr/local/bin/ $ minikube version</pre>  '''Minikube indítása'''<pre>$ minikube start --vm-driver=kvm2Creating 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) ...</pre> Letölti a minikube.iso image-et a /home/adam/.minikube/cache/iso/ mappába, és innen létrehoz egy kvm vm-et: <pre># virsh list Id Name State---------------------------------------------------- 1 minikube running</pre>    ==Minikube parancsok==<pre>$ minikube dashboard </pre>   A minikube itt mutatja meg, hogy egy adott service hol érhető el: <pre># minikube service <service-name> --url</pre>  Be lehet ssh-zni a vm-be mint a docker-machine ssh nál. <pre># minikube ssh -</pre> 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. <pre># kubectl config viewapiVersion: v1clusters:- cluster: certificate-authority: /root/.minikube/ca.crt server: https://192.168.42.224:8443 name: minikube</pre>   ==Nodes== Az összes node listázása. <pre># kubectl get nodesNAME STATUS ROLES AGE VERSIONminikube Ready master 11m v1.13.4</pre>Megfelel a swarm-ban: docker node ls parancsnak. =Pod= :[[File: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.<pre>$ kubectl run db --image mongo</pre>  ===Deklaratív megközelítés===  <source lang="C++">apiVersion: v1kind: Podmetadata: name: go-demo-2 labels: app: myappspec: containers: - name: db image: mongo:3.3 </source>  <pre># kubectl create -f pod-db.yamlpod/go-demo-2 created # kubectl get podNAME READY STATUS RESTARTS AGEgo-demo-2 1/1 Running 0 50s</pre>   ==Pod-ok kezelése==  Pod-ok listázása<pre># kubectl get podsNAME READY STATUS RESTARTS AGEdb-7fdd878ff9-7v66g 0/1 ContainerCreating 0 66s</pre> Belépés a pod-ban futó konténerekbe: <pre># kubectl exec -it <pod név> /bin/bash</pre> Ha több konténer is van a pod-ban, akkor a -c vel meg kell adni a konténer nevét: <pre># kubectl exec -it -c db dbstack /bin/bash</pre> Ha több konténer is van a pod-ban, akkor a pod neve után meg kell adni a konténer nevét. <pre># kubectl logs dbstack -c db</pre>  Minden kubernetes elem listázása: <pre># kubectl get allNAME READY STATUS RESTARTS AGEpod/db-6b5c96c65f-9lxnb 1/1 Running 0 2m46s NAME READY UP-TO-DATE AVAILABLE AGEdeployment.apps/db 1/1 1 1 2m46s NAME DESIRED CURRENT READY AGEreplicaset.apps/db-6b5c96c65f 1 1 1 2m46s</pre>   Egy pod összes adatának listázása. Itt külön listában láthatjuk a POD-ban futó összes konténert. <source lang="java" line highlight="4-6">[root@adamDell2 ~]# kubectl describe pod dbstackName: dbstackNamespace: defaultPriority: 0PriorityClassName: <none>Node: minikube/192.168.122.228Start Time: Wed, 13 Mar 2019 21:51:19 +0100Labels: type=stackAnnotations: <none>Status: RunningIP: 172.17.0.5Containers: db: Container ID: docker://c371653e62b4bb1f8a7fb7de4d88452b6de623cf02caa41df9728df15d080481 Image: mongo:3.3 ... api: Container ID: docker://6b64c392a77347ce5e7b36ddfd80f2ef320a0e31d25985f813294d08cacf76b3 Image: vfarcic/go-demo-2</source>  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. <pre># kubectl describe -f pod-db.yaml Name: dbNamespace: defaultPriority: 0PriorityClassName: <none>Node: minikube/192.168.122.228Start Time: Wed, 13 Mar 2019 20:49:30 +0100Labels: 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</pre>  ===-o kapcsoló használata==={| class="wikitable"! scope="col"| Név! scope="col"| 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. <pre># kubectl get -f pod-db.yaml -o json{ "apiVersion": "v1", "kind": "Pod", "metadata": { "creationTimestamp": "2019-03-13T19:49:30Z", "labels": { "type": "db", "vendor": "MongoLabs" },...</pre>  Részletes pod lista. A lényeg itt az IP cím. <pre># kubectl get pods -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESdb 1/1 Running 0 2m39s 172.17.0.2 minikube <none> <none></pre>  első pod a listáról: <pre># kubectl get pods -o name | tail -1</pre>   ===Szűrés===Listázzuk ki JSON-ban a pod részleteket. <source lang="json"> "status": { ... "hostIP": "192.168.122.228",...</source> Szűrni a '''-o jsonpath''' -al lehet. <br>Mindig úgy kell szűrni, hogy a legfelsőbb szintű elem elé teszünk egy .-ot. Majd megadjuk a path-t. <pre># kubectl get -f pod-db.yaml -o jsonpath="{.status.hostIP}"192.168.122.228</pre>  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]<br>Pl. az összes konténer nevét így listázhatjuk: <pre># kubectl get -f pod-db.yaml -o jsonpath="{.spec.containers[*].name}"db api</pre>  ===Címkék===A selector-ok címék alapján működnek.  Címke hozzáadása egy node-hoz: <pre># kubectl get nodeNAME STATUS ROLES AGE VERSIONminikube Ready master 22d v1.13.4 # kubectl label node minikube disktype=ssdnode/minikube labeled</pre><source lang="java" highlight="6"># kubectl describe node minikubeName: minikubeRoles: masterLabels: beta.kubernetes.io/arch=amd64 beta.kubernetes.io/os=linux disktype=ssd ...</source><source># kubectl get node --show-labelsNAME STATUS ROLES AGE VERSION LABELSminikube Ready master 22d v1.13.4 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disktype=ssd,..</source> Szintaxis: <pre># kubectl label <resource type: node, pod, ...> <resource név> <címke neve>=<címke értéke></pre>  nodeSelector: labelName: labelvalue  Címke felrakása pod-ra: <pre># kubectl label pod go-demo-2 type=examplepod/go-demo-2 labeled</pre><pre># kubectl get pod --show-labelsNAME READY STATUS RESTARTS AGE LABELSgo-demo-2 1/1 Running 1 23h app=myapp,type=example</pre>  Címke törlése<pre># kubectl label pod go-demo-2 type-pod/go-demo-2 labeled # kubectl get pod --show-labelsNAME READY STATUS RESTARTS AGE LABELSgo-demo-2 1/1 Running 1 23h app=myapp</pre> ===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ástperiodSeconds: 5 --> ilyen sürün timeoutSeconds: 10failureTreshold: 20 =ReplicaSets=:[[File: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]}   # kubectl get rs -o wideNAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTORgo-demo-2 2 2 2 23s db,api mongo:3.3,vfarcic/go-demo-2 service=go-demo-2,type=backend   <pre># kubectl describe rs go-demo-2Name: go-demo-2Namespace: defaultSelector: service=go-demo-2,type=backendLabels: <none>Annotations: <none>Replicas: 2 current / 2 desiredPods Status: 2 Running / 0 Waiting / 0 Succeeded / 0 FailedPod 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</pre>  <pre># kubectl get pods --show-labelsNAME READY STATUS RESTARTS AGE LABELSgo-demo-2-5c2sk 2/2 Running 0 5m41s db=mongo,language=go,service=go-demo-2,type=backendgo-demo-2-6nq9h 2/2 Running 0 5m41s db=mongo,language=go,service=go-demo-2,type=backend</pre>  //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: # 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.  # 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.  <pre># kubectl get svc http -o wideNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTORhttp NodePort 10.98.187.168 <none> 80:32730/TCP 8m3s run=my-nginx</pre>  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: 32730Ez a port az összes node publikus IP -én elérhető.   <pre># kubectl get node -o wideNAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIMEminikube Ready master 7d1h v1.13.4 192.168.122.228 <none> Buildroot 2018.05 4.15.0 docker://18.6.2</pre> ^^^^^^  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: <pre># kubectl get svc http -o yamlapiVersion: v1kind: Servicemetadata: name: httpspec: ports: - nodePort: 32730 port: 80 protocol: TCP targetPort: 80 selector: run: my-nginx type: NodePort</pre>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. # kubectl get ep NAME ENDPOINTS AGEhttp 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.  <pre># kubectl get ep http -o yamlapiVersion: v1kind: Endpointsmetadata: creationTimestamp: "2019-03-17T19:49:12Z" name: http namespace: default resourceVersion: "84822" selfLink: /api/v1/namespaces/default/endpoints/http uid: bd23a709-48ed-11e9-8d39-5254008eeeecsubsets:- 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</pre> ------------------------------ 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.  <pre># kubectl describe svc db-svcName: db-svcNamespace: defaultLabels: <none>Annotations: <none>Selector: service=mongo-db,type=dbType: ClusterIPIP: 10.111.222.165Port: <unset> 27017/TCPTargetPort: 27017/TCPEndpoints: 172.17.0.2:27017</pre> 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:  # kubectl exec -it rs-db-api-m6hkf /bin/sh / # nslookup db-svcName: db-svcAddress 1: 10.111.222.165 db-svc.default.svc.cluster.local / # nc -vz db-svc 27017db-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.