|
|
(136 intermediate revisions by the same user not shown) |
Line 1: |
Line 1: |
| + | [[Kubernetes alapok]] |
| | | |
| + | [[Google Kubernetes Engine]] |
| | | |
− | =Kubernetes felépítése=
| + | [[Openshift basics]] |
| | | |
| + | [[Helm]] |
| | | |
− | ==Logikai építőkockák==
| + | [[Kubernetes parancsok]] |
− | | |
− | * 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=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>
| |
− | | |
− | 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 view
| |
− | apiVersion: v1
| |
− | clusters:
| |
− | - 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 nodes
| |
− | NAME STATUS ROLES AGE VERSION
| |
− | minikube 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:'''<br>
| |
− | 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:'''<br>
| |
− | | |
− | | |
− | <source lang="C++">
| |
− | apiVersion: v1
| |
− | kind: ReplicaSet
| |
− | metadata:
| |
− | name: go-demo-2
| |
− | spec:
| |
− | replicas: 3
| |
− | selector:
| |
− | matchLabels:
| |
− | type: backend
| |
− | service: db-service
| |
− | template:
| |
− | metadata:
| |
− | name:
| |
− | labels:
| |
− | type: backend
| |
− | service: db-service
| |
− | db: mongo
| |
− | language: go
| |
− | spec:
| |
− | containers:
| |
− | - name: db
| |
− | image: mongo:3.3
| |
− | livenesProbe:
| |
− | httpGet:
| |
− | path:
| |
− | port:
| |
− | initialDelySecond: 5
| |
− | </source>
| |
− | | |
− | | |
− | ===Pod-ok kezelése===
| |
− | | |
− | | |
− | Pod-ok listázása
| |
− | <pre>
| |
− | # kubectl get pods
| |
− | NAME READY STATUS RESTARTS AGE
| |
− | db-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 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
| |
− | </pre>
| |
− | | |
− | | |
− | Részletes pod lista. A lényeg itt az IP cím.
| |
− | <pre>
| |
− | # 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>
| |
− | </pre>
| |
− | | |
− | | |
− | Egy pod összes adatának listázása. Itt külön listában láthatjuk a POD-ban futó összes konténert.
| |
− | <pre>
| |
− | [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
| |
− | </pre>
| |
− | | |
− | | |
− | <pre>
| |
− | # 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
| |
− | </pre>
| |
− | | |
− | | |
− | <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>
| |
− | | |
− | | |
− | //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 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
| |
− | | |
− | | |
− | | |
− | <pre>
| |
− | # 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
| |
− | </pre>
| |
− | | |
− | | |
− | <pre>
| |
− | # 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
| |
− | </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 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
| |
− | </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: 32730
| |
− | Ez a port az összes node publikus IP -én elérhető.
| |
− | | |
− | | |
− | <pre>
| |
− | # 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
| |
− | </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 yaml
| |
− | apiVersion: v1
| |
− | kind: Service
| |
− | metadata:
| |
− | name: http
| |
− | spec:
| |
− | 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 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.
| |
− | | |
− | <pre>
| |
− | # 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
| |
− | </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-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
| |
− | </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-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.
| |