Cloud Computing Grundbegriffe

  • Container: Ein Container ist ein Paket mit dem auszuführenden Programm und allen seinen Abhängigkeiten, wie z.B. die Laufzeitumgebung, System-Bibliotheken…​, alles zusammengepackt in einer "Schachtel" → Ergebnis von docker build.

  • Kubernetes: Kubernetes (von griechisch κυβερνήτης, "Steuermann") ist ein Open-Source-System zur Automatisierung der Bereitstellung, Skalierung und Verwaltung von Container-Anwendungen.

  • Node: ein Computer

  • Cluster: Ein Kubernetes Cluster ist eine gewisse Anzahl von Nodes um Container - Anwendungen auszuführen.

  • Pod: Ein Pod ist eine logische Verpackungseinheit für einen Container, um diesen auf einem Cluster auszuführen.

Kubernetes Cluster
Figure 1. Ein Kubernetes Cluster
  • Controller: Etwas, das den Ist- Zustand mit dem Soll-Zustand vergleicht und den Ist-Zustand ändert, bis er dem Soll-Zustand entspricht.

  • ReplicaSet: versucht immer eine stabile Menge von Pods am Laufen zu halten.

  • Deployment: stellt deklarative Updates für Pods und Replicasets zur Verfügung. Der Controller ändert den Status der Deployments, so dass dieser dem vorgegebenen Zustand des Deployments entspricht.

  • Service: Ein abstrakter Weg um eine Applikation, die auf einer Menge von Pods läuft, nach außen verfügbar zu machen.

  • Ingress: ein Controller, der ständig nachsieht, ob es aktuell neue Services gibt, die - falls ja - auf einem öffentlichen Port in das Internet freigegeben werden.

Ingress
Figure 2. Ingress

Workshop

Die LeoCloud zum Anfassen und Mitarbeiten.

die kanonische Anwendung

Die Anwendung caberger/leocloud ist ein Beispiel dafür, wie wir aus unserem Source Code automatisch alle benötigten Container erzeugen und diese anschliessend in die Cloud installieren.

benötigte Software

Um mit diesem Beispiel zu arbeiten, benötigen wir für unser Betriebssystem folgende kostenlose Anwendungen:

Windows Benutzer benötigen noch folgende zusätzlichen Installationen:

Kubernetes

Wenn Sie Ihre email als Github Secret angegeben haben (siehe readme.md im k8s Verzeichnis), dann wird ein Deployment File erzeugt (siehe Anhang). Speichern Sie diesen unter dem Dateinamen deployment.yaml. Dann können sie Ihre Anwendung mit folgender Anweisung in die Cloud einspielen:

 kubectl apply -f deployment.yaml
Kubernetes
Figure 3. Kubernetes (von griechisch κυβερνήτης, "Steuermann")

kubectl

Beim Debugging von Kubernetes hilft das Kubectl Cheat Sheet. Beispiel: die Logs des init-scripts eines Pods ansehen mit:

kubectl log command
 kubectl logs <podname> -c <init-container-name>

Appendix A: Kubernetes Deyployment File

deployment.yaml
# MySql Database server
#
#https://unix.stackexchange.com/questions/116520/mysql-server-wont-install-to-a-new-os-debian-ubuntu/116523#116523          
apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql-setup
data:
  create.sql: |
    select "hello from database init script!" from dual;
  wait.sh: |
    until echo '\q' | mysql -hmysql -P"$PORT" -u"$USER" -p"$PASSWORD" $DATABASE; do
        echo "waiting for godot ..."
        sleep 2
    done
  leocloud.cnf: |
    [mysqld]
    innodb_use_native_aio = 0
---
apiVersion: v1
kind: Secret
metadata:
  name: mysql-admin
type: kubernetes.io/basic-auth
stringData:
  username: user
  password: password
  database: db
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: database
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: standard
  resources:
    requests:
      storage: 5Mi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
spec:
  replicas: 1
  selector:
    matchLabels:
      component: mysql
  template:
    metadata:
      labels:
        component: mysql
    spec:
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
      volumes:
        - name: mysql-storage
          persistentVolumeClaim:
            claimName: database
        - name: init-script
          configMap:
            name: mysql-setup
            items:
              - key: create.sql
                path: create.sql
        - name: mysql-cnf
          configMap:
            name: mysql-setup
            items:
              - key: leocloud.cnf
                path: leocloud.cnf                  
      containers:
        - name: mysql
          image: mysql:8
#          command: ["tail", "-f", "/dev/null"]
          resources:
            limits:
              memory: "1Gi"
              cpu: "1000m"
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 3306
          volumeMounts:
            - name: mysql-storage
              mountPath: /var/lib/mysql
            - name: init-script
              mountPath: /docker-entrypoint-initdb.d
              readOnly: true
            - name: mysql-cnf
              mountPath: /etc/mysql/conf.d/leocloud.cnf
              subPath: leocloud.cnf
              readOnly: true      
          env:
            - name: MYSQL_USER
              valueFrom:
                secretKeyRef:
                  name: mysql-admin
                  key: username
            - name: MYSQL_DATABASE
              valueFrom:
                secretKeyRef:
                  name: mysql-admin
                  key: database
            - name: MYSQL_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-admin
                  key: password
            - name: MYSQL_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-admin
                  key: password
            - name: MYSQL_ROOT_HOST
              value: '%'
---
apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  ports:
    - port: 3306
      targetPort: 3306
      protocol: TCP
      name: mysql
  selector:
    component: mysql
---
# Quarkus Application Server
apiVersion: apps/v1
kind: Deployment
metadata:
  name: appsrv
spec:
  replicas: 1
  selector:
    matchLabels:
      app: appsrv
  template:
    metadata:
      labels:
        app: appsrv
    spec:
      containers:
        - name: appsrv
          image: ghcr.io/qrzbrz/leocloud-appsrv:latest
          ports:
            - containerPort: 8080
          resources:
            limits:
              memory: 1024Mi
              cpu: 1024m
      initContainers:
        - name: wait
          image: mysql:8
          command: ["sh", "-c", "/usr/local/bin/wait.sh"]
          volumeMounts:
            - name: init-script
              mountPath: /usr/local/bin
              readOnly: true
          env:
            - name: USER
              valueFrom:
                secretKeyRef:
                  name: mysql-admin
                  key: username
            - name: DATABASE
              valueFrom:
                secretKeyRef:
                  name: mysql-admin
                  key: database
            - name: PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-admin
                  key: password
      volumes:
        - name: init-script
          configMap:
            name: mysql-setup
            items:
              - key: wait.sh
                path: wait.sh
            defaultMode: 0744
---
apiVersion: v1
kind: Service
metadata:
  name: appsrv
spec:
  ports:
    - port: 8080
      targetPort: 8080
      protocol: TCP
      name: appsrv
  selector:
    app: appsrv
---
# nginx Web Server
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: ghcr.io/qrzbrz/leocloud-nginx:latest
          ports:
            - containerPort: 80
          env:
            - name: BASE_HREF
              value: "c.aberger"
          resources:
            requests:
              memory: "64Mi"
              cpu: "250m"
            limits:
              memory: "128Mi"
              cpu: "500m"
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
      name: http
  selector:
    app: nginx
---
# Allow access from the internet
#
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  rules:
    - host: student.cloud.htl-leonding.ac.at
      http:
        paths:
          - path: /c.aberger(/|$)(.*)$
            pathType: Prefix
            backend:
              service:
                name: nginx
                port:
                  number: 80

## backend ingress is unused, forwarded by nginx in default.conf
#---
#apiVersion: networking.k8s.io/v1
#kind: Ingress
#metadata:
#  name: appsrv-ingress
#  annotations:
#    nginx.ingress.kubernetes.io/rewrite-target: /api/$1
#spec:
#  rules:
#    - host: student.cloud.htl-leonding.ac.at
#      http:
#        paths:
#          - path: /${{ c.aberger }}/api/(.*)$
#            pathType: Prefix
#            backend:
#              service:
#                name: appsrv
#                port:
#                  number: 8080