Gitea Helm Chart

Seit kurzem gibt es ein Gitea Helm Chart das von Gitea betreut wird. In diesem Artikel zeige ich wie man einfach eine neue Instanz von Gitea mit K3D ausetzen kann.

Install on K3D/K3S Cluster

Die Installation mittels Helm ist einfach. Zunächst muss das Repository von Gitea hinzugefügt werden. Ein obligatorisches helm repo update aktualisiert alle Repositorys, so dass nun eine Installation erfogen kann.

Für die Installation sind minimale Parameter anzupassen:

Parameter Beschreibung Wert
persistence.size PVC Größe Gitea 100Mi
postgresql.persistence.size PVC Größe Postgres 100Mi
ngress.enabled Ingress erlauben true
ingress.hosts[0] Host FQDN gitea.XXX.org
persistence.storageClass StorageClass local-path

Achtung: K3D/K3S erzeugt automatisch eine Storage Class local-path. Der Name der Storage Class muss daher hier in dem Gitea Helm Chart angepasst werden.

helm repo add gitea-charts https://dl.gitea.io/charts/
helm repo update

helm install gitea gitea-charts/gitea \
    -n gitea --create-namespace \
    --set persistence.size=100Mi \
    --set postgresql.persistence.size=100Mi \
    --set ingress.enabled=true \
    --set ingress.hosts[0]=gitea.XXX.org \
    --set persistence.storageClass=local-path

KeyCloak mit WebAuthn

Ziel dieser Reihe soll es werden Anwendungen über WebAuthn zu schützen. Dazu wird ein K3S Cluster mit K3D aufgesetzt. Diese soll über .cluster.local erreichbar sein.

  • Im Ersten Teil beschäftige ich mich mit der Installation einer KeyCloak Instanz in einem K3S Cluster.

  • Im zweiten Teil wird die Demoanwendung (Gitea) deployt

  • Im dritte Teil geht es um die Konfiguration von KeyCloak, sodass die Anwendung von WebAuthn gescchützt wird

K3D Setup

Um den Cluster aufzusetzen werde ich K3D verwenden.

K3D installieren

Die Installation habe ich für Manjaro/Arch Linux bereits in dem Artikel K3D Cluster ausfsetzen beschrieben. Anmerkung: Die aktuelle Version kann nun mit yay bereits aus AUR gezogen werden.

K3D Cluster erstellen

Für diese Reihe erstelle ich einen kleinen Demo Cluster mit 2 Knoten und öffne den Port 8080 für den LoadBalancer. D.h. der NginX Reverse Proxy muss später auf den Host und Port 8080 verweisen, so dass die Anfragen vom KeyCloak dann beantwortet werden können.

k3d cluster create demo -a2 -p 8080:80@loadbalancer -p 8443:443@loadbalancer

Achtung: Die Syntax von K3D hat sich seit Version 3.0.0 geändert und folgt nun den anderen K8S Anwendungen, in dem es Nomen und Verb als Parameter verlangt. Bsp: aus k3d create cluster wurde nun k3d cluster create.

Namespace

Wie immer sollte mna einen eigenen Namespace für die Trennung der Anwendung verwenden. Diesen legen wir zuerst mit:

k create namespace keycloak

an.

Hinweis: K ist bei mir immer ein Alias für kubectl.

Self Signed Certificate ausstellen

Installation Cert-Manager

Die Installation von Cert-Manager wird hier beschrieben.

Selbst Signiertes Zertifikat ausstellen

Zunächst müssen wir ein Manifest erstellen, das einen Issuer und ein Certificate beschreibt. Die Domain wird hier auf *.clouster.local festgelegt.

apiVersion: cert-manager.io/v1alpha2 
kind: Issuer
metadata:
   name: selfsigned-issuer
spec:
   selfSigned: {}

---

apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
   name: first-tls
spec:
   secretName: first-tls
   dnsNames:
   - "*.cluster.local"
   issuerRef:
     name: selfsigned-issuer

Jetzt muss das Manifest angewendet werden und der Cert-Manager erstellt für uns das selbst signierte Zertifikat, welches wir in dem Ingress später referenzieren werden.

k apply -n keycloak -f keycloak-cert.yaml

Überprüfung der Ausstellung

Ein paar Schnelltests geben auskunft über die erfolgreiche Erstellung der Zertifikate:

# Zertifikat überprüfen
k -n keycloak get certificate
# Secret überprüfen
k -n keycloak get secret first-tls

Nun zum Abschluss noch mit OpenSSL überprüfen…

openssl x509 -in <(kubectl -n keycloak get secret first-tls -o jsonpath='{.data.tls\.crt}' | base64 -d) -text -noout

…in der Ausgabe erhält man dann die Informationen…

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            2e:df:ae:86:5c:27:f9:25:bf:77:ca:d1:7a:3a:48:c6
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: 
        Validity
            Not Before: Sep  2 08:14:52 2020 GMT
            Not After : Dec  1 08:14:52 2020 GMT
        Subject: 
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:c5:e0:f9:be:a6:b9:41:cb:38:e9:11:57:0a:1b:
                    b5:2b:c2:7e:78:87:5f:43:dc:22:c3:7d:8b:a7:f3:
                    c0:d4:f9:bc:75:4e:96:93:66:17:67:f7:e2:02:96:
                    37:19:90:64:6f:fa:c3:1f:c5:21:80:de:e0:aa:76:
                    12:d6:24:a0:f2:7b:37:14:34:a8:eb:9c:1a:17:b0:
                    4f:d8:a4:9b:3a:51:fe:18:30:3e:81:f5:20:01:85:
                    c1:af:61:cf:2e:30:fd:42:3c:00:c0:28:f9:60:37:
                    84:80:84:85:54:33:6c:0f:cb:c2:7e:5f:50:ee:82:
                    a1:4a:35:c3:5b:fe:8a:47:21:75:c5:0e:03:08:f2:
                    2d:fa:98:e8:d6:16:d6:fb:af:97:d8:86:3a:c6:84:
                    63:5d:bd:f1:1b:72:0f:73:f5:09:33:26:aa:bc:8f:
                    8c:9b:fa:a6:11:53:19:69:33:bc:68:47:c3:74:6a:
                    70:86:c5:19:93:83:cc:9e:07:11:0d:6e:9f:f8:5b:
                    67:d7:d8:ef:ca:37:4e:7c:1b:a2:f5:ee:70:eb:55:
                    2f:86:45:02:b4:4d:6d:9a:1b:20:3b:c4:d5:db:f3:
                    66:8c:22:e1:da:94:c4:e6:20:9f:c4:ff:79:b9:26:
                    b6:ae:d0:8f:f2:45:d5:7d:eb:88:7f:39:36:7d:ef:
                    f6:85
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Subject Alternative Name: critical
                DNS:*.cluster.local
    Signature Algorithm: sha256WithRSAEncryption
         39:b5:cf:d7:08:b1:9d:07:44:ef:79:f3:13:46:11:f9:07:96:
         f3:db:cb:8d:5e:df:14:5f:2f:74:ff:4a:c8:58:af:57:fa:35:
         fb:19:1e:73:af:f5:d2:eb:ec:b9:d1:60:f5:28:c1:39:ba:a1:
         0c:4e:0d:3c:10:83:ba:0f:ef:4f:7a:1c:68:25:3a:3c:bf:de:
         04:24:f0:ca:15:34:6d:66:8f:3b:69:96:fe:b8:03:54:98:a6:
         fe:b8:0f:d4:6f:1b:7a:87:6a:5a:c6:57:ff:62:ee:0f:24:ff:
         e9:e8:e9:b5:4d:ca:ec:27:7c:03:7b:63:2e:ff:4d:3a:c8:5e:
         d8:b4:f5:8a:e8:0c:2c:62:f1:00:c6:4d:fe:cf:45:e2:5b:74:
         55:0a:fe:f7:5a:b4:c0:5a:2c:04:4c:ae:b2:5a:d3:d7:26:ca:
         63:2c:69:2b:81:cd:6e:39:c4:66:5f:67:47:2d:f4:ea:eb:9b:
         31:17:5d:4c:5b:77:26:d4:a4:4c:f1:52:ae:92:84:e9:f4:01:
         7e:f1:f5:cf:1d:54:a5:8c:6b:58:b2:35:b3:44:0d:81:b6:da:
         4e:0b:02:fe:21:21:75:59:53:15:17:67:7e:37:00:59:00:11:
         67:47:4e:5f:0b:1d:c4:1e:4b:5c:d2:80:57:7f:2b:58:01:ba:
         83:fc:c9:ce   

Download Kubernetes Manifest

Wir laden das Manifest keycloak.yaml mit wget runter und modifizieren die Defaultwerte für den Namespace und setzen ein neues Passwort. Der Namespace wird auf den zuvor erstellten Namespace keycloak gesetzt. Das Passwort wird auf 123 gesetzt.

wget -q -O - https://raw.githubusercontent.com/keycloak/keycloak-quickstarts/latest/kubernetes-examples/keycloak.yaml | sed "s/namespace: default/namespace: keycloak/" > keycloak.yaml

Achtung: Username und Passwort sind hier admin. Wer es sicherer mag, der sollte das YAML bearbeiten und die Werte ersetzen.

k apply -n keycloak -f keycloak.yaml   

Das hochfahre der Pods kan mit

watch kubectl -n keycloak get pods

überwacht werden.

Ingress

Da K3S in der Defaulteinstellung Traefik als Ingress Controller verwendet, nutze ich hier nicht die von KeyCloak Team bereitgestelltes Kubernetes Manifest für Ingress.

HTTPS Anfragen für die FQDN keycloak.cluster.local an den Cluster werden werden so an den Service keycloak an Port 8443 weitergeleitet.

apiVersion: cert-manager.io/v1alpha2
kind: Issuer
metadata:
  name: selfsigned-issuer
spec:
  selfSigned: {}

---

apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
  name: first-tls
spec:
  secretName: first-tls
  dnsNames:
  - "*.cluster.local"
#  - "*.keyclaok"
  issuerRef:
    name: selfsigned-issuer

Hosts Datei Vorbereiten

Damit das Ganze funtkioniert, muss der FQDN keycloak.cluster.local in die /etc/hosts Datei eingetragen werden:

192.168.2.XXX keycloak.cluster.local

Erster Test mit CURL

curl -k https://keycloak.cluster.local:8443
<!--
  ~ Copyright 2016 Red Hat, Inc. and/or its affiliates
  ~ and other contributors as indicated by the @author tags.
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~ http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
<head>
    <meta http-equiv="refresh" content="0; url=/auth/" />
    <meta name="robots" content="noindex, nofollow">
    <script type="text/javascript">
        window.location.href = "/auth/"
    </script>
</head>
<body>
    If you are not redirected automatically, follow this <a href='/auth'>link</a>.
</body>
</html>

Aufruf mit dem Browser

Nun kann nach dem ersten erfolgreichen Test der KeyCloak über https://keycloak.cluster.local:8443/auth/ bzw. die Admin-Console über https://keycloak.cluster.local:8443/auth/admin/master/console/ aufgerufen werden. Die Credentials für die Admin-Console sind im Kubernetes Manifest (siehe oben) festgelegt worden.

Standard ist hier Username admin und Passwort admin.

Kubernetes mit Manjaro

Diese Liste wird ständig von mir erweitert und unterliegt daher der Änderung.

Lokale Kubernetes Cluster

Name Beschreibung Homepage
minikube Der Standard um Kubernetes lokal zu testen https://minikube.sigs.k8s.io/docs/
k3s Minimale Kubernetes Cluster basierend auf einem einzigen Executable https://k3s.io/
k3d Mit K3D kann man lokal ein Kubernetes Cluster aus mehreren Nodes innerhalb von Sekunden erzeugen. Intern werden Docker Container mit K3S, um die Nodes zu erzeugen. Es ist zu empfehlen hier auf das Beta der Version 3 zu wechseln. https://github.com/rancher/k3d
k3sup K3sup ist ein Tool um K3S lokal oder per SSH auf einem entfernten Rechner zu installieren. Da k3sup in GO geschrieben ist, besteht es auch nur aus einem Binary und besitzt keien weiteren Abhängigkeiten https://github.com/alexellis/k3sup
k3c https://github.com/rancher/k3c
yay --noconfirm -S minikube k3s-bin rancher-k3d-beta-bin

Kubernetes Tools

Introspektion

Name Beschreibung Homepage
k9s Kommandoszeilentool mit dem man sehr einfach und schnell einen bestehenden Cluster untersuchen kann. Universelles Tool das man mit dem Kubernetes Dashboard für die Konsole vergleichen kann. https://github.com/derailed/k9s
kubespy
kubectx
kubefwd Findet alle Services in einem Namespace und erstellt ein Portforwarding für den Dienst ein und erstellt einen Eintrag in der /etc/hosts Datei, sodass sehr einfach auf die laufenden Dienste zugegriffen werden kann https://github.com/txn2/kubefwd
yay --noconfirm -S kubespy kubectx kubefwd-bin

Logging

Name Beschreibung Homepage
stern Mit Stern kann man die Logausgaben meherer Container in mehreren Pods ausgeben lassen. Für eine gute Unterscheidbarkeit werden die Ausgaben der verschiedenen Container in unterschiedlichen Farben eingefärbt. Dieses erlaubt ein schnelleres Debugging in komplexen Setups https://github.com/wercker/stern
yay --noconfirm -S stern-bin

Development

Name Beschreibung Homepage
tilt Mit Hilfe von einem Autodeployment in ein Kubernetes Cluster, werden Codeänderungen sofort wirksam und es werden Fehler überrsichtlich in einer Web UI dargestellt. https://tilt.dev/
yay -S --noconfirm  tilt-bin

K3D

Ist ein Hilfsmittel um einen K3S Cluster mit Docker innerhalb weniger Sekunden aufzusetzen. Hierbei wird eine Installation von K3S auf dem Host nicht benötigt, da K3S in Docker Containern gestartet wird. Wenn einmal die Docker Images geladen sind und lokal vorliegen, dann lässt sich sogar auf einem älteren Laptop ein Cluster mit mehreren Nodes innerhalb weniger Sekunden starten.

Installation

Die Installation erfolg über ein PKGBUILD, da

pkgname="rancher-k3d-bin"
pkgver=3.0.0b2
_pkgver=3.0.0-beta.2
pkgrel=1
pkgdesc='Little helper to run Rancher Labs k3s in Docker'
arch=('x86_64')
url='https://github.com/rancher/k3d'
license=('MIT')
provides=("k3d")
source=("${pkgname}-${_pkgver}::https://github.com/rancher/k3d/releases/download/v$_pkgver/k3d-linux-amd64")
md5sums=('563d008cf92dbe42afe280b0930a0d79')

package() {
  install -Dm 0755 ${pkgname}-${_pkgver} "$pkgdir/usr/bin/k3d"
}

Die Version 3.0.0 befindet sich aktuell noch in der Entwicklung, aber da sie einige wichtige Änderungen beinhaltet, werde ich hier auf die Beta setzen. Diese scheint aber bereits ausgereift, so dass sie getestet werden kann. Bislang gab es keine Probleme.

Einen Cluster erstellen

Wie bereits beschrieben, lässt sich ein Cluster sehr einfach und schnell starten. K3D benötigt hierzu nur wenige Parameter. Der Cluster soll den Namen Demo erhalten und insgesamt 3 Worker (Nodes) bereitstellen. Zusätzlich wird ein Portmapping eingerichtet, sodass auf die Anwendung von außen zugegriffen werden kann.

k3d create cluster Demo -w 3 -p 8081:80@loadbalancer

Das Portmapping -p auf dem Host Port 8081 wird auf den Container gematched der auf den Nodefilter loadbalancer hört.

Liste der Cluster ausgeben

k3d get cluster

Cluster löschen

k3d delete cluster Demo

Cluster starten und stoppen

$k3d stop cluster Demo
INFO[0000] Stopping cluster 'demo'  

$k3d start cluster Demo
INFO[0000] Starting cluster 'demo'                      
INFO[0000] Starting Node 'k3d-demo-worker-3'            
INFO[0000] Starting Node 'k3d-demo-worker-2'            
INFO[0001] Starting Node 'k3d-demo-worker-1'            
INFO[0001] Starting Node 'k3d-demo-worker-0'            
INFO[0002] Starting Node 'k3d-demo-master-0'            
INFO[0002] Starting Node 'k3d-demo-masterlb'

Die Nodes anzeigen

Eine Liste der Nodes auf dem Cluster kann man sich mit get node anzeigen lassen.

k3d get node