2021 M08 16

Commento im Kubernetes-Cluster

Commento im Kubernetes-Cluster

Aktuell ziehe ich nach und nach sämtliche Webseiten und Applikationen in mein neues Kubernetes-Cluster um (ein Blogpost zum Cluster selbst folgt bestimmt auch irgendwann 😁). Den Anfang machte ich nun mit dem Tool Commento, da es recht simpel aufgebaut ist und nur eine weitere Postgres-Datenbank braucht.

Sämtliche Konfigurationen schreibe ich dabei in eine einzige Datei mit dem Namen "commento.yaml", damit ich nicht mit zu vielen Einzeldateien durcheinander komme.

Damit auch produktiv alles geordnet zugeht, spezifiziere ich zuallererst einen Namespace:

apiVersion: v1
kind: Namespace
metadata:
  name: commento
  labels:
    name: commento

Nachdem der Namespace nun steht, folgt direkt schonmal etwas Festplattenspeicher. Dieser wird später für die Daten in der Datenbank genutzt. Bei einem Update von PostgreSQL möchte ich die darin enthaltenen Daten (eingerichtete Domains, Nutzer und die Kommentare) schließlich nicht verlieren.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: commento-storage-pvc
  namespace: commento
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi

Fürs erste sollten 5Gb völlig ausreichen, da eh noch nicht so viele Kommentare existieren und ich auch nicht glaube, dass plötzlich tausende Kommentare vom Himmel fallen werden. 😉

Nun kommt die eigentliche Applikation bzw. das Deployment, welches sowohl Commento selbst als auch die Postgres-Instanz beinhaltet:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: commento-deployment
  namespace: commento
  labels:
    app: commento
spec:
  replicas: 1
  selector:
    matchLabels:
      app: commento
  template:
    metadata:
      labels:
        app: commento
    spec:
      volumes:
      - name: commento-postgres-storage
        persistentVolumeClaim:
          claimName: commento-storage-pvc
      containers:
      - name: commento
        image: registry.gitlab.com/commento/commento:v1.8.0
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
        env:
        - name: COMMENTO_ORIGIN
          value: "https://{COMMENTO_DOMAIN}"
        - name: COMMENTO_PORT
          value: "8080"
        - name: COMMENTO_POSTGRE
          value: "postgres://postgres:PSQL_PASSWORT@localhost:5432/commento?sslmode=disable"
        - name: COMMENTO_FORBID_NEW_OWNERS
          value: "false"
        - name: COMMENTO_SMTP_HOST
          value: "{SMTP_URL}"
        - name: COMMENTO_SMTP_PORT
          value: "{SMTP_PORT}"
        - name: COMMENTO_SMTP_USERNAME
          value: "{SMTP_LOGIN}"
        - name: COMMENTO_SMTP_PASSWORD
          value: "{SMTP_PASSWORT}"
        - name: COMMENTO_SMTP_FROM_ADDRESS
          value: "{SMTP_MAIL_ADRESSE}"
        - name: COMMENTO_GZIP_STATIC
          value: "true"
        - name: COMMENTO_GOOGLE_KEY
          value: "{GOOGLE_KEY}"
        - name: COMMENTO_GOOGLE_SECRET
          value: "{GOOGLE_SECRET}"
        - name: COMMENTO_GITHUB_KEY
          value: "{GITHUB_KEY}"
        - name: COMMENTO_GITHUB_SECRET
          value: "{GITHUB_SECRET}"
      - name: postgres
        volumeMounts:
        - name : commento-postgres-storage
          mountPath: /var/lib/postgresql/data
        image: postgres:latest
        imagePullPolicy: Always
        ports:
        - containerPort: 5432
        env:
        - name: POSTGRES_PASSWORD
          value: {PSQL_PASSWORT}
        - name: POSTGRES_DB
          value: commento
        resources:
          limits:
            cpu: "0.2"
            memory: "512Mi"

Sämtliche Felder in geschweiften Klammern müssen natürlich angepasst werden. Es werden zwei getrennte Container erzeugt. Der Container "commento" beinhaltet die Applikation in der aktuellsten Version 1.8.0 und bekommt dazu noch einige Umgebungsvariablen mitgeliefert. Wofür diese sind und was sie genau machen, kann man hier ganz gut nachlesen. 🙂 Da zu Beginn noch kein User existieren wird, muss die Umgebungsvariable COMMENTO_FORBID_NEW_OWNERS vorerst auf "false" gesetzt sein, damit die Nutzerregistrierung eingeschaltet ist und man einen Administrator erstellen kann. Sobald diese auf "true" gesetzt wird, können keine weiteren Accounts mehr erstellt werden. Dies machen wir zum Schluss bzw. nach der Registrierung des Administratoraccounts, damit nicht ungebetene Gäste Zugriff auf die Weboberfläche kriegen können.

Der Container "postgres" nutzt den zuvor erzeugten Festplattenplatz und bindet diesen bei sich ein. Zudem habe ich diesem Container noch ein paar Ressourcenlimits verpasst, damit eine Node nicht bei plötzlicher Last (bspw. tausende Kommentare gleichzeitig) komplett in die Knie geht.

Um die Weboberfläche von Commento über eine Domain erreichen zu können, muss auch noch ein Service für den Container "commento" erstellt werden:

apiVersion: v1
kind: Service
metadata:
  name: commento
  namespace: commento
  labels:
    app: commento
spec:
  type: ClusterIP
  ports:
  - port: 8080
    name: http
  selector:
    app: commento

Der Service legt sich so gesehen über den Container "commento" und nutzt den oben eingestellten Port für HTTP(S). Diesem gebe ich anschließend einen Domainnamen. Dazu nutze ich in meinem Cluster den NGINX Ingress Controller und einen clusterweiten Zertifikatsaussteller, welcher TLS-Zertifikate von Let's Encrypt bezieht:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: commento
  namespace: commento
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: letsencrypt-production
spec:
  tls:
  - hosts:
    - {COMMENTO_DOMAIN}
    secretName: commento-ingress-tls-secret
  rules:
  - host: {COMMENTO_DOMAIN}
    http:
      paths:
      - path: /
        backend:
          serviceName: commento
          servicePort: 8080

Das wär's auch schon an Konfigurationen. 😃 Via kubectl apply -f commento.yaml kann das ganze dann innerhalb des Clusters angelegt werden.

Man sollte man etwas Geduld mitbringen, da sowohl die Erstellung des Speichers als auch das Holen eines TLS-Zertifikats etwas dauern kann. Hat man erst kurz vorher bei seinem DNS-Anbieter die für Commento zu nutzende Domain auf die Haupt-IP-Adresse des Kubernetes-Clusters gelegt, kann es hier beispielsweise etwas länger dauern, bis sämtliche DNS-Server auf die korrekte IP zeigen. 😉 Sollte es ziemlich lange dauern und die Domain kann noch nicht im Browser aufgerufen werden, ist mittels kubectl get [all|ingress|pvc] -n commento ggf. zu sehen, wo es hakt.

Sobald Commento im Browser aufgerufen werden kann und der Administratoraccount angelegt wurde, sollte man wie oben erklärt die Umgebungsvariable COMMENTO_FORBID_NEW_OWNERS auf "true" setzen. Das ganze kann wieder mittels kubectl apply -f commento.yaml geupdated werden.

Hierbei ist auch schön zu sehen, wie von Kubernetes ein weiteres ReplicaSet im Cluster angelegt wird. Welche ReplicaSets schon vorhanden sind, kann gezielt mittels kubectl rollout history deployment/commento-deployment -n commento angezeigt werden. Sollten bei Änderungen (beispielsweise ein Update von Commento auf die neueste Version) Probleme auftreten, kann bspw. mittels kubectl rollout undo deployment/commento-deployment --to-revision=2 auf den vorherigen Zustand zurück gegangen werden (ein weiterer Vorteil, weswegen ich in meine eigene Kubernetes-Cloud migriere 😁).

Ich hoffe, dieses Beispiel kann als kleine Hilfestellung dienen. Als nächstes werde ich wohl Matomo und meine Websites in das Cluster integrieren. In welcher Reihenfolge, werde ich noch entscheiden müssen. 😃