Difference between revisions of "Kubernetes"
(Created page with " :File:ClipCapIt-190313-214212.PNG") |
|||
Line 5: | Line 5: | ||
:[[File:ClipCapIt-190313-214212.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=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) ... | ||
+ | </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> | ||
+ | |||
+ | <pre> | ||
+ | # kubectl config view | ||
+ | apiVersion: v1 | ||
+ | clusters: | ||
+ | - cluster: | ||
+ | certificate-authority: /root/.minikube/ca.crt | ||
+ | server: https://192.168.42.224:8443 | ||
+ | name: minikube | ||
+ | </pre> | ||
+ | |||
+ | |||
+ | |||
+ | <pre> | ||
+ | # kubectl get nodes | ||
+ | NAME STATUS ROLES AGE VERSION | ||
+ | minikube Ready master 11m v1.13.4 | ||
+ | </pre> | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ==Nodes== | ||
+ | |||
+ | <pre> | ||
+ | # kubectl get nodes | ||
+ | NAME STATUS ROLES AGE VERSION | ||
+ | minikube Ready master 11m v1.13.4 | ||
+ | </pre> | ||
+ | |||
+ | |||
+ | |||
+ | <pre> | ||
+ | # kubectl get nodes | ||
+ | NAME STATUS ROLES AGE VERSION | ||
+ | minikube Ready master 3d4h v1.13.4 | ||
+ | </pre> | ||
+ | |||
+ | |||
+ | |||
+ | POD: | ||
+ | =========== | ||
+ | =========== | ||
+ | |||
+ | //Docker típusú futtatás. Ugyan úgy létre fog hozni egy pod-ot és benne el fogja indítani az image-et. | ||
+ | $ kubectl run db --image mongo | ||
+ | |||
+ | 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 [*] | ||
+ | # kubectl get -f pod-db.yaml -o jsonpath="{.spec.containers[*].name}" | ||
+ | db api | ||
+ | |||
+ | |||
+ | //Címke alapján rendeljünk node-hoz. | ||
+ | # kubectl label nodes <your-node-name> disktype=ssd | ||
+ | |||
+ | nodeSelector: | ||
+ | labelName: labelvalue | ||
+ | |||
+ | |||
+ | első pod a listáról: | ||
+ | # 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]} | ||
+ | |||
+ | |||
+ | |||
+ | # 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: | ||
+ | # 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. | ||
+ | |||
+ | |||
+ | # 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. | ||
+ | # 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: | ||
+ | |||
+ | # 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. |
Revision as of 21:41, 29 March 2019
Contents
[hide]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 -
# kubectl config view apiVersion: v1 clusters: - cluster: certificate-authority: /root/.minikube/ca.crt server: https://192.168.42.224:8443 name: minikube
# kubectl get nodes NAME STATUS ROLES AGE VERSION minikube Ready master 11m v1.13.4
Nodes
# kubectl get nodes NAME STATUS ROLES AGE VERSION minikube Ready master 11m v1.13.4
# kubectl get nodes NAME STATUS ROLES AGE VERSION minikube Ready master 3d4h v1.13.4
POD:
=
=
//Docker típusú futtatás. Ugyan úgy létre fog hozni egy pod-ot és benne el fogja indítani az image-et. $ kubectl run db --image mongo
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 [*]
- kubectl get -f pod-db.yaml -o jsonpath="{.spec.containers[*].name}"
db api
//Címke alapján rendeljünk node-hoz.
- kubectl label nodes <your-node-name> disktype=ssd
nodeSelector:
labelName: labelvalue
első pod a listáról:
- 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]}
- 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:
- 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.
- 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.
- 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:
- 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.