Netdata

Netdata beitet ähnlich zu dem Gespann Prometheus/Grafana eine umfassende Monitoring Lösunng an.

Installation

Die Installation von Netdata ist unter dem Kubernetes Cluster mit K3D mit Fallstricken versehen.

Nach erfolgreicher Basisinstallation stellt sich Netdata wie folgt vor:

Worauf muss man nun genau bei der Installation achten? Wer keine weiteren Anpassungen bei dem Kreieren des K3D Cluster vornimmt, der installiert automatisch Traefik v1.7 in den Cluster. Dieses verursacht mit dem bereitgestellten Helm Chart Probleme, da es auf NginX als Ingress-Controller ausgerichtet ist.

Traefik als Ingress-Controller verwenden

Unter Kubernetes lässt sich der zu verwendende Ingress-Controller bestimmen. Dazu muss die kubernetes.io/ingress.class auf traefik gesetzt werden.

Mit Helm 3 hat sich die Syntax geändert, sodass viele Informationen die man im Internet zu dem Thema findet schlicht veraltet sind und somit zu einer Fehlermeldung für. Wie kann man nun die ingress.class mit Helm setzen?

--set ingress.annotations."kubernetes\.io/ingress\.class"=traefik

Es muss die Annotation in Anführungsstrichen gesetzt werden und Punkte müssen mit dem “\” Escaped werden. Also wird somit aus kubernetes.io/ingress.class=traefik folgendes “kubernetes.io/ingress.class”=traefik

DockerHub Registry verwenden

Da es beim 1. Test Probleme mit der Registry gab, habe ich kurzerhand die offizielle Docker Hub Registry verwendet. Diese wird über registry.hub.docker.com angesprochen. Die Registry lässt sich über image.registry steuern.

--set image.registry=registry.hub.docker.com

Danach konnte das image sofort heruntergeladen werden.

Das Repo zu Helm hinzufügen

Die Helm Charts sind auf GitHub unter https://netdata.github.io/helmchart/ gehostet.

helm repo add netdata https://netdata.github.io/helmchart/
helm repo update

Zusammenfassung

Faskst man alles zusammen ergibt sich folgende Befehlsreihenfolge:

helm repo add netdata https://netdata.github.io/helmchart/
helm repo update

helm install netdata netdata/netdata \
  -n netdata \
  --create-namespace \
  --set ingress.hosts[0]=netdata.k3d.duckdns.org \
  --set image.registry=registry.hub.docker.com \
  --set ingress.annotations."kubernetes\.io/ingress\.class"=traefik

Nach dem Deployment kann man Netdata unter https://netdata.k3d.duckddns.org aufrufen,

K3D Kubernetes Cluster

Ein Kubernetes Cluster ist nach außen hin für die laufenden Services abgeschottet. Das heißt man kann nicht von außen auf die laufenden Dieste zugreifen.

Um Dienste zugänglich zu machen, kann man Ports exposen oder ein Ingress verwenden. Mit Ingress (auf einem LoadBalancer) kann über den Host im Header der Service identifiziert werden. Erfolgt nun eine Namensauflösung z.B. https://demo.k3d.duckdns.org auf ihre öffentliche IP Adressen, dann kann ein Reverse Proxy die Anfragen entgegennehmen und an den Cluster intern weiterleiten.

Der Ingress-Controller wertet nun die Information in dem Header aus und entscheidet das Routing innerhalb des Clusters.

In diesem Artikel möchte ich zeigen, wie man mit NginX, Duckdns und K3D eine flexible Lösung erstellt, in der automatisch alle Endpoints über TLS gesichert sind.

NGinX

Damit das Ganze funktioniert sind ein paar Voraussetzungen zu erfüllen:

  • Es muss ein gültiges Zertifikat für die Domain vorliegen (siehe Wildcard Zertifikat mit Lets Encrypt)
  • Eine DynDNS oder entsprechend konfigurierter DNS Server oder Host Einträge müssen vorliegen
  • Der Server Block in NginX muss die Anfrage matchen
  • Ein paar nötige Header müssen gesetzt werden

HTTP auf HTTPS umlenken

Mit einer 301 Antwort kann den Traffic auf HTTPS umlenken.

    # Redirect http -> https
    server {
        listen 80;
        server_name "~^.+\.k3d\.duckdns\.org$";
        return 301 https://$host$request_uri;
    }

Wichtig: Es darf hier nicht $server_name verwendet werden! Es muss $host genommen werden, da es sonst zu Fehlern im Browser kommt. Dann enthält der Header location die RegEx und der Browser spuckt eine Fehlermeldung aus.

Server_Name matching

Da ich nicht für jede neue Anwendung eine eigenständige Konfiguration für NginX schreiben möchte, habe ich NginX so konfiguriert, dass es Pattern Matching in dem Server_Name betreibt.

Ich habe für den lokalen Kubernetes Cluster das Schema https://keycloak.k3d.duckdns.org verwendet.

server {
    listen 443 ssl http2;

    server_name "~^+\.k3d\.duckdns\.org$";
...
}

Die RegEx nimmt alle Anfragen für https://XXXXXX.k3d.duckdns.org entgegen.

Header setzen

Im NGINX Server Block müssen folgende Header gesetzt sein, damit der Ingress-Controller das Routing vornehmen kann.

proxy_set_header X-Forwarded-For $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection ‘upgrade’;
proxy_set_header Host $host;

Die PROXY_PASS Anweisung leitet nun Anfragen an den Cluster weiter.

proxy_pass http://10.10.10.10:4000;

Der Cluster läuft in diesem Fall auf dem Server mit der IP Adresse 10.10.10.10 und lauscht auf dem Port 4000.

TLS konfigurieren

Für die Absicherung der Verbindung mit TLS, kommt folgender Block in der Konfiguration zum Einsatz. Per Default werden die von dem Cert-Bot aktualiesierten SSL Zertifikate unter halb den Verzeichnisses /etc/letsencryp/live/DOMAIN/ abgelegt. Die Fullchain und der private key werden eingebunden und somit der Endpoint mit TLS abgesichert.

# SSL
ssl_certificate /etc/letsencrypt/live/k3d.duckdns.org/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/k3d.duckdns.org/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

Zusammenfassung der Konfiguration von NginX

Hier nun die gesamte Konfiguration von NginX.

###################################
#                                 #
# Kubernetes Cluster              #
#                                 #
#                                 #
###################################

# Redirect http -> https
server {
    listen 80;
    server_name "~^.+\.k3d\.duckdns\.org$";
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;

    server_name "~^-.+\.k3d\.duckdns\.org$";

    # logging
    error_log /var/log/nginx/kubernetes_error.log debug;
    access_log /var/log/nginx/kubernetes_access.log;

    location / {
        proxy_pass http://10.10.10.10:4000;
        proxy_set_header Connection ""; # to keep alive

        proxy_set_header X-Forwarded-For $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection ‘upgrade’;
        proxy_set_header Host $host;
    }

    # SSL
    include ssl/*.k3d.duckdns.org;
}

In einem K3D Cluster das Kubernetes Dashboard deployen

Hat man einen K3D Cluster aufgesetzt, dann liegt es gerade in den Anfängen nahe das Dashboard zu installieren. Für das Kubernetes Dashboard gibt es sogar ein Helm Chart.

Die Installation mit Helm ist ja an und für sich nicht schwierig, nur wird man nach der Installation eine Überraschung erleben. Folgt man der Anleitung:

# Add kubernetes-dashboard repository
helm repo add kubernetes-dashboard https://kubernetes.github.io/dashboard/
# Deploy a Helm Release named "my-release" using the kubernetes-dashboard chart
helm install kubernetes-dashboard/kubernetes-dashboard --name my-release

Nach der Installation wird man anders als gedacht, von einem freundlichen internal server error empfangen.

Ingress

Der Ingress-Controler steuert das Routing anhand der vorhandenen Host Informationen im Header. Bei K3S/K3D wird implitziet Traefik v1.7 installiert.

Diese sorg für das genannte Problem und daher müssen wir ein paar Änderungen vornehmen, damit wir das Dashboard mit dem K3D Cluster zum laufen bringen.

Variante 1

Man übergibt direkt in den ingress.annotations die ingress.class=traefik und setzt den Host direkt.

--set ingress.annotations."kubernetes\.io/ingress\.class"=traefik \
--set ingress.enabled=true \
--set ingress.hosts[0]=dashboard.k3d.duckdns.org

Variante 2

Bei der Variante 2 wird das Ingress in dem Helm Chart nicht genutzt und das Ingress klassisch als Kubernetes Manifest gesetzt.

Ingress in dem Helm Chart deaktivieren

Wie bereits angesprochen, müssen wir zunächst das Ingress in dem Helm Chart deaktivieren. Das geschied über den Parameter **–set ingress.enabled=false **

 --set ingress.enabled=false

Traefik Ingress per Kubernetes Manifest

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  labels:
    name: kubernetes-dashboard 
  name: kubernetes-dashboard-secure
  namespace: default
  annotations:
   kubernetes.io/ingress.class: traefik
spec:
  rules:
  - host: dashboard.k3d.duckdns.org
    http:
      paths:
      - backend:
          serviceName: dashboard-kubernetes-dashboard
          servicePort: 8080

Das Skript create_cluster_admin.sh

Das Skript create_cluster_admin.sh verwende ich, um einen Service Account mit der Rolle cluster-admin.

create_cluster_admin dashboard

Installation

Insgesamt ergeben sich nun daraus folgende Installationsschritte.

# add repo
helm repo add kubernetes-dashboard https://kubernetes.github.io/dashboard/

# add SA for Dashboard
create_cluster_admin.sh dashboard

# install chart
helm install dashboard kubernetes-dashboard/kubernetes-dashboard --set protocolHttp=true --set metricsScraper.enabled=true --set service.externalPort=8080 --set serviceAccount.name=dashboard --set serviceAccount.create=false

# set traefik ingress
kubectl apply -f ./ingress.yaml

Sonarqube im Kubernetes Cluster

Sonarqube ist ein Open Source Tool, um die Verbesserung der Qualität der Software zu erhöhen. Sonarqube bedindt sich der statischen Codeanalyse und kann verhindern, dass übliche Fehler sich in den Quelltext einschleichen.

Für die Installation sollte zunächst ein K3D aufgesetz werden.

Da es im moment kein offizielles Helm Chart für die Installation gibt, es aber im Stable Repository auf oteemocharts verwiesen wird, nutze ich das Repository.

Repository hinzufügen

Zunächst muss man das Repository von oteemocharts hinzufügen.

helm repo add oteemocharts https://oteemo.github.io/charts

Installation

Die Installation ist recht einfach. Es sind für den Basisbetrieb zunächst nur wenige Parameter nötig. Wie üblich sollte man die Anwendung in einem eigenen Namespace laufen lassen. Ich verwende hier den Namespace sonarqube.

kubectl create namespace sonarqube
helm install sonarqube --namespace sonarqube oteemocharts/sonarqube --set ingress.enabled=true --set ingress.hosts[0].name=sonarqube.xxx.org

Nach dem Download dauer es jedoch einen kleinen Augenblick bis Sonarqube gestartet ist. Es muss zunächst die Datenbank initialisiert werden und der Startup nimmt einige Zeit in Anspruch.

Anmeldung

Ist die Anwendung gestartet, dann kann man sich mit den Standard admin und admin Credentials anmelden.

Krew

Krew ist ein Tool für die Verwaltung von Plugins für kubectl. Es gibt bereits mehr als 100 Plugins für Krew. Mit Krew lassen sich die Plugins stöbern, installieren und aktuell halten.

Installation von Krew

Die Installation ist relativ einfach. Es muss nur das Paket kubectl-krew installiert werden.

yay -S --noconfirm kubectl-krew

Pfade konfigurieren

Um die Installation abzuschließen, müssen die Pfade noch angepasst werden. Mit einem Texteditor die ~./bashrc bearbeiten. Es muss der Pfad ~/.krew/bin mit aufgenommen werden.

export PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH"

Plugin Index aktualisieren

Bevor man die Lister der Plugins anschauen kann, muss zuvor der Index lokal aktualisiert werden. Hierfür muss man krew update ausführen.

 k krew update

Tipp: Ich habe immer ein Alias k für kubectl auf meinen Maschinen, sodass die Verwendung einfacher ist.

Krew Search – Die Liste der Plugins anzeigen

Mit krew search kan man die Liste der verfügbaren Plugins für kubectl ausgeben lassen.

Installation eines Plugins

Als Beispiel verwende ich hier das Plugin rolesum. Rolesum gibt auf der Konsole eine Übersicht der Rollen zu einem Serviceaccount aus.

k krew install rolesum

Nach der Installation kann man rolesum verwenden.

k rolesum kubeapps-admin

Upgrade – Die installierten Plugins aktuell halten

Mit krew upgrade kann eine Aktualisierung der installierten Plugin durchgeführt werden.

KubeApps

Mit Kubeapps lassen sich Anwendungen per Operator oder Helm Chart sehr schnell und einfach deployen. Es können beliebige Repository hinzugefügt werden, sodass sich schnell eine Vielzahl von Anwendungen deployen lassen.

Vorteile von Kubeapps

Einer ger großen Vorteile von Kubeapps ist, dass man eine Basiskonfiguration von Helm Charts per UI vornehmen kann. Die Values werden dann im Chart entsprechend gesetzt. Das macht es gerade auch für Anfänger einfacher einen Überblick über die unzähligen Parameter zu gewinnen.

Installation

Die Installation von Kubeapps geschiet seinerseits wiederum der Helm Chart. Besondere Voraussetzungen sind nicht zu erfüllen.

helm install kubeapps --namespace kubeapps bitnami/kubeapps --set ingress.enabled=true --set ingress.hostname=kubeapps.xxx.org

Für eine Installation empfehle ich immer mit Ingress zu arbeiten. Dazu muss ein Reverse Proxy vorhanden sein, der die Anfragen weiterleitet und ein entsprechend konfigurierter DNS. Auch ein Zertifikat z.B. mit DuckDNS beseitigt durch TLS viele Probleme.

Kubernetes mit K3D

Mit K3D lässt sich schnell ein Cluster aufsetzen. Wer also noch keinen hat, der sollte hier nicht zurückschrecken. Es lässt sich mit K3D schnell auch auf älterer Hardware ein Cluster aufsetzen. Es lohnt sich.

Serviceaccout für den Cluster-Admin erstellen

Damit man nun mit Kubeapps Anwendungen deployen kann, benötigt man ein Token. Diese sollte zu einem Serviceaccout mit cluster-admin Rechten gehören. In dem Artikel Cluster-Admin Serviceaccount beschreibe ich wie das geht.

Mit dem nun erzeugten Token könnt ihr euch nun in Kubeapps anmelden und das Erste Deployment vornehmen.

Einen Cluster Admin Account erstellen

Hat man K3d aufgesetzt, so braucht man oftmals noch ein Token um zum Beispiel den Cluster über dritte Anwendungen zu administrieren.

Einen Kubernetes Serviceaccount erstellen

Zunächst benötigen wir einen Serviceaccout. Diesen kann man kubectl create serviceaccout einfach erstellen. Es werden keine weiteren Parameter benötigt.

kubectl create serviceaccount admin

RBAC – Clusterrolebinding

In Kubernetes werden die Berechtigung über RBAC gesteuert. Es gibt hier 2 Arten der Bindung. Eine Bindung die eine Rolle innerhalb eines Namespaces zuweist oder halt eben das Clusterrolebinding welches die Rolle Clusterweit zuweist.

Das Clusterrolebinding wird mit kubectl create clusterrolebinding kreiert. Als Parameter sind ein Name, die Rolle (hier also cluster-admin) und der zuvor erstellte Serviceaccountname nötig.

kubectl create clusterrolebinding admin --clusterrole=cluster-admin --serviceaccount=default:admin

Das Token extrahieren

Jetzt wird es etwas komplizierter, da wir zunächst den Namen des Serviceaccount benötigen. Dann können wir das Token mit kubectl get secret aus dem Serviceaccount auslesen.

Namen des Serviceaccount ermitteln

 kubectl get serviceaccount admin -o jsonpath='{range .secrets[*]}{.name}{"\n"}{end}' | grep kubeapps-operator-token
 admin-token-bfj2q

Das Base64 kodierte Token auslesen

Den Names des Serviceaccounts verwenden wir nun, um das Base64 kodierte Token mit der Hilfe von go-template zu dekodieren.

kubectl get secret admin-token-bfj2q -o go-template='{{.data.token | base64decode}}'

Bash Skript

Hier habe ich das Ganze als kurze Bash Skript zusammengefasst. Es benötigt nur einen Parameter. Es muss der Name für den Cluster Administrator angegeben werden.

#!/bin/bash

if [ $# -eq 0 ]; then
  echo "give $0 a parameter name" 
  exit
fi

NAME=$1

kubectl create serviceaccount $NAME
kubectl create clusterrolebinding $NAME --clusterrole=cluster-admin --serviceaccount=default:$NAME
kubectl get secret $(kubectl get serviceaccount $NAME -o jsonpath='{range .secrets[*]}{.name}{"\n"}{end}' | grep $NAME-token) -o go-template='{{.data.token | base64decode}}' && echo

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

Kubectl Autovervollständigung für die Bash

Das zentrale Administrationsprogramm kubectl bietet die Möglichkeit Bash Completion zu erstellen, so dass die Autovervollständigung funktioniert.

Installation der Bash-Completion

Falls die bash-completion nicht nicht installiert sein sollte, so kann dieses mit:

yay -S --noconfirm install bash-completion

schnell installiert werden.

Hinweis: Damit die Completion wirksam wird, muss man sich einmal an der Shell abmelden.

Bash Completion einbauen

Zunächst muss die aktuelle Beschreibung der Autovervollständigung erzeugt und unter /etc/bash_completion.d gespeichert werden.

sudo kubectl completion bash > /etc/bash_completion.d/kubectl

Sofortige Wirkung

Die neue Autovervollständigung würde erst ziehen, wenn man sich an einer neuen Sitzung der Bash anmeldet. Es gibt aber auch die Möglichkeit mit source dieses zu umgehen.

 source /etc/bash_completion.d/kubectl

Jetzt sollte die Autovervollständigung in der Bash für kubectl funktionieren.

k als Alias für kubectl

Wer k als Alias für kubectl gesetzt hat wird enttäuscht sein, da es nämlich nicht wie erwartet funktioniert. Für das Komando k sind die Autovervollständigungen schlicht nicht definiert.

Fügen sie complete -F __start_kubectl k mit in ihre .bashrc ein. Dann wird auch das Alias k die Autovervollständigung anzeigen.

echo 'complete -F __start_kubectl k' >>~/.bashrc

Lens

Lens plattformunabhängiges Dashboard für Kubernetes Cluster. Es integriert sogar die Installation von Helm Charts aus einem Helm Repository von der UI. Hier lassen sich vor der Installation Parameter anpassen. Installierte Charts können auch wieder entfernt werden. Getestet habe ich das mit einem lokalen K3D Cluster.

Insgesamt macht das Programm von seinem Umfang und der Optik einen guten Eindruck.

Installation

Die Installation geht unter Manjaro oder Arch Linux schell mit yay:

yay -S --noconfirm lens-bin