Openshift basics
Contents
Telepítés
Telepítsük fel a függőségeket, ha ezek hiányoznának
A minisfhit KVM virtuális gépet hoz létre, amit docker-machine driver-el vezérel.
# sudo dnf install libvirt qemu-kvm
Telepítsük föl a docker-machine driver-t:
# curl -L https://github.com/dhiltgen/docker-machine-kvm/releases/download/v0.10.0/docker-machine-driver-kvm-centos7 -o /usr/local/bin/docker-machine-driver-kvm # chmod +x /usr/local/bin/docker-machine-driver-kvm
Külön fel kell telepítsük az oc scriptet, ami az OpenShfit parancssori eszköze: https://github.com/CCI-MOC/moc-public/wiki/Installing-the-oc-CLI-tool-of-OpenShift
ln -s /path to download/oc /usr/bin/oc
Harmadik lépésként le kell tölteni a minishift binárist. Ezzel indíthatjuk el majd a lokális, egy node-os clusterünket. Ez csak az indító script, induláskor le fogja tölteni az oc programot és a centOs-mini-t, majd libvirt-el létrehoz egy qemu virtuális gépet.
https://github.com/minishift/minishift/releases
# ln -s /path to download /minishift-1.34.0-linux-amd64/minishift /usr/bin/minishift
Indítsuk el a minishift-et.
# minishfit start -- Starting profile 'minishift' -- Check if deprecated options are used ... OK ... ... The server is accessible via web console at: https://192.168.42.185:8443/console You are logged in as: User: developer Password: developer To login as administrator: oc login -u system:admin
Ha letöltötte a CentOS-t és feltelepítette rá az OpenShfit-et, ki fogja írni, hogy az OpenShift konzol milyen címen érhető el. Ez a KVM VM IP címe. Ezen felül láthatjuk, hogy két user-t is létrehozott, egy admin-t és egy developer-t.
Virsh-val nézzük meg hogy fut e a VM:
# virsh list --all Id Name State ---------------------------- 1 minishift running
Login
Az oc login paranccsal kell belépni a klaszerbe. A sikeres oc login inicializálja a kubernetes config-ot is.
# oc login -u system:admin Logged into "https://192.168.42.185:8443" as "system:admin" using existing credentials. You have access to the following projects and can switch between them with 'oc project <projectname>': default kube-dns kube-proxy kube-public kube-system * myproject ...
OpenShift-ben a projekt egyenlő a Kubernetes névtérrel. Láthatjuk, hogy a myproject névtérbe vagyunk belépve.
Listázzuk a Kubernetes konfigurációt:
# kubectl config view .... - context: cluster: 192-168-42-185:8443 namespace: myproject user: system:admin/192-168-42-185:8443 name: myproject/192-168-42-185:8443/system:admin
Láthatjuk, hogy létrehozott az oc login egy külön kontextust. Innentől kezdve a kubectl parancsokat tudjuk használni.
Listázzuk ki a felhasználókat. Látni fogjuk hogy a fenti is látott system és developer felhasználók vannak a klaszterben:
# kubectl get users NAME UID FULL NAME IDENTITIES developer f59113f2-9f30-11e9-ba85-525400efb4ec anypassword:developer system df29da3c-9f35-11e9-ba85-525400efb4ec anypassword:system
A webes konzolon is be tudunk lépni: https://192.168.42.64:8443/console/catalog
Note
Ha később újra el akarjuk indítani a minishfit-et, akkor fontos, hogy indulás előtt a kubectl kontextust átállítsuk a minishfit-es kontextusra ha több kontextusunk is van, különben nem fog elindulni a minishfit.
# kubectl config use-context myproject/192-168-42-185:8443/system:admin
Deployment és service létrehozása
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
revisionHistoryLimit: 5
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: bitnami/nginx
ports:
- containerPort: 80
Warning
Az OpenShift-el nem kompatibilis a standard ngingx image, mert root felhasználóval kéne futtatni, ahhoz hogy létre tudja hozni a szükséges mappákat a konténerben. Ez ki van küszöbölve a bitnami/nginx image-ben.
# kubectl apply -f deployment-demo.yaml
# kubectl get deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE nginx-deployment 3 3 3 3 2d
apiVersion: v1
kind: Service
metadata:
name: nginx-service
namespace: my-namespace
spec:
ports:
- nodePort: 32730
port: 8080
protocol: TCP
targetPort: 8080
selector:
app: nginx
type: NodePort
# kubectl apply -f service-demo.yaml service/http created
# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx-service NodePort 172.30.198.61 <none> 8080:32730/TCP 31s
Openshfit console:
# minishfit ip 192.168.42.185
# kubectl get pods NAME READY STATUS RESTARTS AGE nginx-deployment-58b5fbbff4-6cztz 1/1 Running 0 7m nginx-deployment-58b5fbbff4-bsq6x 1/1 Running 0 7m nginx-deployment-58b5fbbff4-gzr8g 1/1 Running 0 7m # kubectl exec -it nginx-deployment-58b5fbbff4-6cztz /bin/bash $ curl nginx-service:8080 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title>
Openshift sepcific commands
Openshift specific object
DeploymentConfig
Route
https://docs.openshift.com/container-platform/3.11/architecture/networking/routes.html#route-types
Default: HAProxy
Ez az Ingress megfelelője az OpenShfit-ben. Az alapértelmezett implementációja a HAProxy. A load-balancing-ot OpenShift-ben a szabványos Kubernetes-el szemben a router végzi, nem a service. Alapértelmezetten a router-ek a node-on a 80-as ill a 443-as portokra fognak kapcsolódni.
apiVersion: v1
kind: Route
metadata:
name: nginx-route
namespace: my-namespace
spec:
path: /
to:
kind: Service
name: nginx-service
weight: 100
port:
targetPort: 8080
wildcardPolicy: None
tls:
insecureEdgeTerminationPolicy: Allow
termination: edge
- Edge Termination: a TLS terminálva lesz még a load-balancing előtt. A TLS beállításokat ebben az esetben a router-ben kell megadni. Ha nem adjuk meg, akkor az alapértelmezett tanúsítványt fogja használni.
- Passthrough Termination: ebben az esetben a router nem választja le a TLS-t, a kérést egy az egyben továbbküldi a service-nek, aki meg a POD-oknak. A POD-ok felelőssége, hogy a megfelelő tanúsítványt kezeljék.
- Re-encryption Termination: A router végez TLS terminálást, de a router és a service közötti kapcsolat megint csak titkosítva történik.
Ingress definíciót is meg lehet adni, ezt konvertálni fogja az OpenShift Route objektumra.
Telepítés:
A kubectl parancsot nem használhatjuk a router telepítésére, nem nem ismeri ezt a típust, kizárólag az oc paranccsal tudjuk telepíteni:
# oc apply -f route-nginx.yaml route.route.openshift.io/nginx-route created
Lekérdezni már kubectl -el is lehet :
# kubectl get route -o wide NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD nginx-route nginx-route-dsp.192.168.42.185.nip.io / nginx-service 8080 edge/Allow None
Mivel nem adtunk meg host nevet az OpenShift generált egyet a route-hoz. Az openShift alapértelmezetten a nip.io szolgáltatást használja host név generáláshoz. Ez egy ingyenes DNS szolgáltatás, ahol a <anything>[.-]<IP Address>.nip.io szerkezetű host neveket mindig a megadott IP címre oldja fel a nip.io DNS szervere.
# nslookup nginx-route-dsp.192.168.42.185.nip.io Server: 192.168.0.1 Address: 192.168.0.1#53 Non-authoritative answer: Name: nginx-route-dsp.192.168.42.185.nip.io Address: 192.168.42.185
Nézzük meg az OpenShift konzolon a szolgáltatásunkat:
Láthatjuk, hogy létrejött hozzá egy route az nginx-route-dsp.192.168.42.185.nip.io URL-el.
Íjuk be a böngészőbe: https://nginx-route-dsp.192.168.42.185.nip.io
# kubectl get dc -n default NAME REVISION DESIRED CURRENT TRIGGERED BY router 1 1 1 config
# kubectl get dc router -n default -o yaml apiVersion: apps.openshift.io/v1 kind: DeploymentConfig spec: containers: image: openshift/origin-haproxy-router:v3.11.0 name: router
Metrikák gyűjtése
https://docs.openshift.com/container-platform/3.10/install_config/router/default_haproxy_router.html
A HAProxy szolgáltat magáról metrikákat a router-hez tartozó Kubernetes service-en keresztül. Az alapértelmezett metrika URL az alábbi:
http://<user>:<password>@<router_IP>:<STATS_PORT>/metrics
Listázzuk ki a router-hez tartozó service-t:
# kubectl get svc -n default NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE router ClusterIP 172.30.130.191 <none> 80/TCP,443/TCP,1936/TCP 4d
Láthatjuk, hogy az 1936-os porton is hallgatózik, ez a metrika végpontjának a portja.
A metrika user és jelszó pedig a service definíciójában van benne:
# kubectl get svc router -n default -o yaml apiVersion: v1 kind: Service metadata: annotations: prometheus.openshift.io/password: 4v9a7ucfMi prometheus.openshift.io/username: admin service.alpha.openshift.io/serving-cert-secret-name: router-metrics-tls service.alpha.openshift.io/serving-cert-signed-by: openshift-service-serving-signer@1562703761 creationTimestamp: "2019-07-09T20:26:25Z" labels: router: router
Ennek függvényében, a node IP címét felhasználva, (minishfit IP) a metrika URL az alábbi: http://admin:4v9a7ucfMi@192.168.42.64:1936/metrics
# curl admin:4v9a7ucfMi@192.168.42.64:1936/metrics # HELP apiserver_audit_event_total Counter of audit events generated and sent to the audit backend. # TYPE apiserver_audit_event_total counter apiserver_audit_event_total 0 # HELP apiserver_client_certificate_expiration_seconds Distribution of the remaining lifetime on the certificate used to authenticate a request. # TYPE apiserver_client_certificate_expiration_seconds histogram apiserver_client_certificate_expiration_seconds_bucket{le="0"} 0 apiserver_client_certificate_expiration_seconds_bucket{le="21600"} 0 apiserver_client_certificate_expiration_seconds_bucket{le="43200"} 0 apiserver_client_certificate_expiration_seconds_bucket{le="86400"} 0 apiserver_client_certificate_expiration_seconds_bucket{le="172800"} 0 apiserver_client_certificate_expiration_seconds_bucket{le="345600"} 0 apiserver_client_certificate_expiration_seconds_bucket{le="604800"} 0
Minishfit docker registry
https://torstenwalter.de/minishift/openshift/docker/registry/2017/07/25/build-docker-image-and-upload-to-openshift-registry.html
https://github.com/minishift/minishift/issues/817
Áttekintés
Ahhoz hogy egy általunk készült docker image-et futtatni tudjunk a minishift klaszteren, elsőként fel kell tölteni azt a minshift image repository-ba, ami nem is annyira egyszerű. A minishift docker registry-t csak a minishfit-et futtató VM-ről lehet elérni, az anyagépről nem.
Az openshfit saját docker registry-je egy deploymentConfig-al definiált pod-ban fut:
# kubectl get dc -n default NAME REVISION DESIRED CURRENT TRIGGERED BY docker-registry 1 1 1 config ...
A registry ebből az image-ből készül: openshift/origin-docker-registry:v3.11.0
Lépésel:
- A minishit-et futó VM-en a docker klienssel be kell lépni a minisfht-ben futó docker registry-be az első pontban szerzett token-el.
- Docker-el build-elni kell az image-t a minishfit VM-en.
- A minisfhit-et futtató VM-ről push-olni kell az image-t a minisfhit image registry-be.
- kubectl run-al el lehet indítani az általunk létrehozott image-et.
Az egyik lehetőségünk az, hogy ssh-val belépünk a minisfhit VM-re (minisfhit ssh) és ott lépünk be a registry-be (docker login) és ott build-eljük és push-oljuk az image-et. A másik sokkal kényelmesebb lehetőség, hogy a minishift VM docker démon-ját átirányítjuk a lokális docker kliensünkre a minishift docker-env paranccsal. Ezt azért tudjuk megtenni, mert a minisfhit is docker-machine-t használ. Ugyan ezt a parancsot használjuk docker swarm esetén is, hogy a swarm master-en adjuk ki a swarm parancsokat. Ennek az a nagy előnye, hogy a docker build-hez szükséges fájlokat vehetjük a lokáli gépről, de a build-elt docker image már a minishfit VM docker lokális repository-ban fog landolni, ahonnan már push-olni tudjuk a minishfit repositroy-ba.
Kísérlet képen írtunk egy olyan Java webalkalmazást, ami a GET paraméterben kapott milliszekundum után adja vissza a 200 : 'OK' választ. Az alkalmazás embedded jetty-vel készült, a Docker fájlja az alábbi:
FROM openjdk:11-jdk
RUN mkdir /home/lib
ADD ./*.jar /home
ADD ./lib/* /home/lib/
EXPOSE 8080
CMD ["java", "-cp", "/home/lib/*:/home/testapp.jar", "com.adam.testapp.App"]
Az openjdk-11 base image-ből indulunk ki, majd belemásoljuk az összes függőséget, rárakjuk classPath-ra az összes bemásolt jar-t, amjd elindítjuk az alkalmazást a com.adam.testapp.App main osztállyal. A cél, hogy az ebből készült image-et másoljuk fel az opensfhit repository-ba, majd készítsünk belőle egy Kubernetes deploymentet-et service-el együtt. A Dokcerfile és az abban hivatkozott összes további fájl a host gépen lesz, de mivel a docker-kliens a minishift-en lévő démonhoz csatlakozik, mikor kiadjuk majd a build parancsot, az image a minishfit VM ottani lokális docker repository-ába fog bekerülni.
Belépés az openshfit registriy-be
Ahogy azt már korábban írtuk, át fogjuk irányítani a host gépen futó docker klienst, hogy a minisfhit VM-en futó docker démonhoz kapcsolódjon, így a lokálisan kiadott docker parancsok mind a minishift VM-en futó docker-en fognak végrehajtódni. Ez megegyezik azzal, ahogy a docker swarm esetében is csatlakozunk a swarm master node-on futó démonhoz:
# minishift docker-env export DOCKER_TLS_VERIFY="1" export DOCKER_HOST="tcp://192.168.42.185:2376" export DOCKER_CERT_PATH="/root/.minishift/certs" # eval $(minishift docker-env)
Innentől kezdve minden lokálisan kiadott docker parancs a minishfit vm-en fog futni.
Ezt le tudjuk ellenőrizni, ha listázzuk vagy a futó konténereket vagy az elérhető image-eket a docker démonon, ahova a docker kliens csatlakozik:
# docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE bitnami/nginx latest ab5cdb60157c 11 hours ago 78.3MB 172.30.1.1:5000/mynamespace/test-app 1.1.0 f984e2105039 23 hours ago 620MB ... openshift/origin-control-plane v3.11.0 2905f7137f05 4 days ago 829MB openshift/origin-hyperkube v3.11.0 7f2cb107435c 4 days ago 509MB openshift/origin-hypershift v3.11.0 7507661b73ff 4 days ago 549MB ...
Láthatjuk, hogy csupa openshift-es image van a repóban, tehát már nem az anyagép lokális repository-ját nézzük.
A célunk, hogy a minisfhit VM-en futó docker démon belépjen a minshift saját docker registry-ébe, és oda push-olja a saját lokális repository-ban lévő image-et. Ehhez szereznünk kell egy openShift login toke-ent és meg kell szerezzük a repository címét.
Lépjünk be az oc login-al az OpenShift-be. Fontos hogy ne a system hanem a developer felhasználóval lépjünk be, mert csak neki lesz push joga.
Note
Ha így lépünk be nem jó: 'oc login -u system:admin, mert nem keletkezik token.
# oc login Authentication required for https://192.168.42.185:8443 (openshift) Username: developer Password: Login successful. You have access to the following projects and can switch between them with 'oc project <projectname>': * mynamespace myproject
Ellenőrizzük, hogy kaptunk e tokent. Ezt az oc whoami parancs -t (token) kapcsolójával lehet megtenni. Ha itt nem látjuk a toke-nt akkor dolgozni kell még a belépésen.
# oc whoami -t JbdYzUHpsyJCBt3JQ7XBahLq6UAp0hiYsOTYTiD1arE
A minishift -nek a openshift registry parancsával kérhetjük le a docker registry címét.
# minishift openshift registry 172.30.1.1:5000
Ez a cím a minishift-et futtató VM-en értelmezett IP cím, ezért csak a minishift VM-en futó docker démon-al tudunk rácsatlakozni a repository-ra.
A docker login paranccsal léphetünk be a minishift registriy-be. Ha ezt lokálisan kiadjuk, akkor már a minishit VM-en fog lefutni így el fogjuk érni a 172.30.1.1:5000 címen a registry-t (A docker kliens átirányítása nélkül nem érnénk el a lokális gépről ezt a címet). Ezzel a minisfhit VM-en futó docker démon csatlakozik a minisfhit registry-hez, tehát nem az anyagépen futó docker démon.
# docker login -u developer -p $(oc whoami -t) $(minishift openshift registry) WARNING! Using --password via the CLI is insecure. Use --password-stdin. WARNING! Your password will be stored unencrypted in /root/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded
Fontos, hogy csak token-el engedi a belépést az openshfit registry, jelszóval nem.
docker build és push
Az openshfit registry-be szánt image-nek a neve az alábbi szintaxist kell kövesse:
<registry-host>:<port>/<névtér>/<image-név>:<tag>
Ahhoz hogy push-olni tudjuk az OpenShift registry-be az image-et a "172.30.1.1:5000/" prefixel kell kezdődjön a neve. Innen fogja tudni a docker, hogy melyik registry-be akarjuk push-olni. A második elem a névtér neve, amihez az image tartozni fog. Az image-ek ugyan úgy névterekbe kerülnek mint minden kubernetes objektum.
A docker build paranccsal építsük meg az image-t. Ezt az image-et is tegyük a mynamespace névtérebe.
# docker build -t 172.30.1.1:5000/mynamespace/test-app:1.1.0 . Sending build context to Docker daemon 14.99MB Step 1/6 : FROM openjdk:11-jdk ---> f06fdc42d01a ... Successfully built ecc484546662 Successfully tagged 172.30.1.1:5000/mynamespace/test-app:1.1.0
Ellenőrizzük le, hogy bekerült e a test-app a minisfhit VM lokális docker repository-jába: (mivel az anyagépen futó docker kliens át van irányítva, ezért az anyagépen kiadott docker parancsokkal elvégezhető az ellenőrzés)
# docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE ... 172.30.1.1:5000/mynamespace/test-app 1.1.0 f984e2105039 23 hours ago 620MB
Nem maradt más dolgunk, mint hogy a docker push paranccsal felküldjük az image-t az opensfhit registry-be. A nevéből fogja tudni a docker push hogy melyik repository-ba kell küldeni és ott melyik névtérbe.
# docker push 172.30.1.1:5000/mynamespace/test-app:1.1.0
A minishift registry-ben úgynevezett imageScream-ek vannak. A frissen push-olt test-api image-hez is létrejött egy imageScream. Az oc paranccsal listázhatjuk a imageScream-eket:
# oc get is -n mynamespace NAME DOCKER REPO TAGS UPDATED test-app 172.30.1.1:5000/mynamespace/test-app 1.1.0 8 minutes ago
Teszt alkalmazás futtatása
Az egyszerűség kedvéért a kubectl run paranccsal fogjuk futtatni az alkalmazást. Ha nem adjuk meg a -it kapcsolót, akkor létre fog hozzá hozni egy deployment-et és egy replicaSet-et is, nem csak a pod-ot fogja elindítani.
# kubectl run test-app --image=172.30.1.1:5000/mynamespace/test-app:1.1.0 --replicas=1 --port=8080 -n mynamespace
Ellenőrizzük, hogy létrejött e a test-app nevű deployment.
# kubectl get deployment -n mynamespace NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE .. test-app 1 1 1 1 2m
Nézzük meg a deployment definícióját (csak a releváns részeket tüntetem fel):
# kubectl get deployment test-app -n mynamespace -o yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
run: test-app
name: test-app
namespace: mynamespace
spec:
replicas: 1
selector:
matchLabels:
run: test-app
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
run: test-app
spec:
containers:
- image: 172.30.1.1:5000/mynamespace/test-app:1.1.0
imagePullPolicy: IfNotPresent
name: test-app
ports:
- containerPort: 8080
protocol: TCP
restartPolicy: Always
A kubectl run parancshoz hasonlóan a kubectl expose paranccsal instant módon készíthetünk service-t a deployment-hez. A deployment-ben megadott portot (8080) fogja kinyitni a pod-ok felé:
# kubectl expose deployment test-app --type=LoadBalancer --name=test-app-service -n mynamespace service/test-app-service exposed
Ellenőrizzük, hogy létrejött e a service. Láthatjuk, hogy a 30534 porton érhető el kívülről a service.
# kubectl get svc -n mynamespace NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ... test-app-service LoadBalancer 172.30.254.3 172.29.192.241,172.29.192.241 8080:30534/TCP 2m
Ha a minishift VM publikus címét beírjuk a fenti port számmal, akkor meg kell tudjuk szólítani az alkalmazásunkat:
http://192.168.42.185:30534/test/slowresponse/2000
Hozzunk létre egy opensfhit route-ot is az imént létrehozott service-hez ugyan úgy instant módon az oc create route paranccsal.
# oc create route -n mynamespace edge --service test-app-service --insecure-policy Allow route.route.openshift.io/test-app-service created
Listázzuk ki az imént létrehozott route-ot wide módban, hogy megtudjuk mi lett a host neve. A minisfhit alapértelmezetten készít egy nip.io-s host nevet minden route-hoz, ahol nem adjuk meg mi legyen a host név:
# kubectl get route test-app-service -n mynamespace NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD test-app-service test-app-service-mynamespace.192.168.42.185.nip.io test-app-service <all> edge/Allow None
http://test-app-service-mynamespace.192.168.42.185.nip.io/test/slowresponse/2000