Openshift basics

Revision as of 17:37, 27 July 2019 by Adam (talk | contribs) (Áttekintés)

Revision as of 17:37, 27 July 2019 by Adam (talk | contribs) (Áttekintés)


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

ClipCapIt-190710-211718.PNG


ImportantIcon.png

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
WarningIcon.png

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:

ClipCapIt-190705-175555.PNG




# minishfit ip
192.168.42.185

http://192.168.42.185:32730/

ClipCapIt-190705-174259.PNG


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

ClipCapIt-190707-225959.PNG

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

ClipCapIt-190707-225815.PNG


# 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 pod ebből az image-ből készül: openshift/origin-docker-registry:v3.11.0

Lépésel:

  1. 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.
  2. Docker-el build-elni kell az image-t a minishfit VM-en.
  3. A minisfhit-et futtató VM-ről push-olni kell az image-t a minisfhit image registry-be.
  4. 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.


ClipCapIt-190727-002450.PNG


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.

ImportantIcon.png

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

ClipCapIt-190725-235129.PNG



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