Teckids-Wiki

Kubernetes-Cluster

Auf unserem Kubernetes-Cluster laufen die meisten unserer Anwendungen. Das Produkt beschreibt den Cluster an sich mit allen Komponenten, die für den Betrieb notwendig sind. Nicht im Scope sind deployte Anwendungen, die hier nicht explizit aufgelistet sind.

Infos

Nutzerdokumentation

Nutzung von kubectl

Mit kubectl können CRUD-Operationen auf Kubernetes-API-Ressourcen durchgeführt werden.

Wo und wie?

Lokal auf Deinem Gerät 😉!

Installation von kubectl: https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/
Installation von kubelogin: Aktuellstes Build von https://github.com/int128/kubelogin/releases nach /usr/local/bin/kubectl-oidc_login packen

Folgende Config in ~/.kube/config packen:

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMvakNDQWVhZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJeE1Ea3lNVEUxTXpVMU5sb1hEVE14TURreE9URTFNelUxTmxvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTXVICnkxWVkzaU5jdlRLbG16NTJRZWU1bFBjOXBmSHVkMUExdnIraGNCelUzdlZtRWFjd2txMEdVYTYvUXc0N3B2NDUKKy9HVHBKWmNNOU5aVG96Q1B2ZDJhVVVySGFSZS9JaURwK0NxNHhmUFVjZi9Za0I4WkxWdzZPMWNwcW1OZ2xWQQp5VDlkSzVURkYxZDBJM0N5Vms2Vzlic29BeTJFSWg2ai9iMDlMSmNxTjBmSVZvb2JEdndGYzBNZEdibGNrRzVmCnZpOTJicnNvRnB1TTVTQVBMUkc1ZitqdjZjdjlQb3JqU3ZQVVVQWjVGUHV4Z2dSRnZVeDZLSE5OeVFueVhoR3YKK2FUT2hTM0oxcmRyQzVBY21MbGdNOGlsZmgwVnlCZTk3bjg4bG1FNnA2VnZZUXI2eFJEVmc4aitPOHNmMWk4LwpwOFRLV0c4dlJwS0c4c3NkanA4Q0F3RUFBYU5aTUZjd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZIMG5CbFF2MFVSblBwTHhZdTRScmhyS2l0M3dNQlVHQTFVZEVRUU8KTUF5Q0NtdDFZbVZ5Ym1WMFpYTXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBQUp2SmFPTUJKMVJBYTFHQW1ibQp1dk5wcWd5Z2NxNGJlTnlaTzZabk1RcG15UkVzUEwxK09Nd2NpVFE4VHZtWlVibUUzZ2lUb24reWYzSGV2NXdNCk1TQnV3VkVmZ3RNcTFvTzd3Mk9MdXMrTkdOY1dmQVRVS0dWNS9SQlY0bDJmS1B5TDZYN0w5QlNxMzlVaUhsL0UKaDNHTWRJQWRkSWNuZERaS1FBSks0V05iNzc2RzhmYlhZQTBxM1dEZkNoQ1ZaWXNZeGNHNFc5L3ZSbHlxWEU2awplYncrL1htcFNjOXlBYUVSMVl0bytjRGdnMXJtWVM0R2J0cGVpQkZ4bXJKMUQ1UHJZL09QaFRtU2NJbGViVVBGCmhzRTlDWFZPQlZPZ0FiWTFpV09RL01NLzVzNEIzeHdKWTRVdlAwakU1ZGZ5a2J1SmRXdjlpNWlmUERiL282aloKR1lBPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
    server: https://master.kube.teckids.org
  name: Teckids_PROD
contexts:
- context:
    cluster: Teckids_PROD
    user: Teckids_PROD
  name: Teckids_PROD
current-context: Teckids_PROD
kind: Config
preferences: {}
users:
- name: Teckids_PROD
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1beta1
      args:
      - oidc-login
      - get-token
      - --oidc-issuer-url=https://ticdesk.teckids.org
      - --oidc-client-id=RcO3weOpSnlenZcBaBbXKFoNpElQzxjU0O20T273
      - --oidc-extra-scope=openid,profile,http://aleksis.org/_/oidc/groups
      command: kubectl
      env: null
      interactiveMode: IfAvailable
      provideClusterInfo: false

Nutzung

Achtung: Du musst Verbindungen zu master.kube.teckids.org über den Jump-Host shuttlen!
z.B. sshuttle -r jump.teckids.org master.kube.teckids.org

Struktur

Die meisten Kubectl-Befehle arbeiten mit den gleichen Ressourcen:

$ kubectl get
You must specify the type of resource to get. Valid resource types include: 

  * all  
  * certificatesigningrequests (aka 'csr')  
  * clusterrolebindings  
  * clusterroles  
  * componentstatuses (aka 'cs')  
  * configmaps (aka 'cm')  
  * controllerrevisions  
  * cronjobs  
  * customresourcedefinition (aka 'crd')  
  * daemonsets (aka 'ds')  
  * deployments (aka 'deploy')  
  * endpoints (aka 'ep')  
  * events (aka 'ev')  
  * horizontalpodautoscalers (aka 'hpa')  
  * ingresses (aka 'ing')  
  * jobs  
  * limitranges (aka 'limits')  
  * namespaces (aka 'ns')  
  * networkpolicies (aka 'netpol')  
  * nodes (aka 'no')  
  * persistentvolumeclaims (aka 'pvc')  
  * persistentvolumes (aka 'pv')  
  * poddisruptionbudgets (aka 'pdb')  
  * podpreset  
  * pods (aka 'po')  
  * podsecuritypolicies (aka 'psp')  
  * podtemplates  
  * replicasets (aka 'rs')  
  * replicationcontrollers (aka 'rc')  
  * resourcequotas (aka 'quota')  
  * rolebindings  
  * roles  
  * secrets  
  * serviceaccounts (aka 'sa')  
  * services (aka 'svc')  
  * statefulsets (aka 'sts')  
  * storageclasses (aka 'sc')error: Required resource not specified.
Use "kubectl explain <resource>" for a detailed description of that resource (e.g. kubectl explain pods).
See 'kubectl get -h' for help and examples.

Diese Ressourcen lassen sich dann:

Mit -n wird der Namespace angegeben: 
kubectl get -n ticdesk pod

Nodes

Port-Forwarding

kubectl port-forward -n prometheus alertmanager-prometheus-0 :9093

Logs

kubectl logs -n kube-system mein-pod -c mein-container

kubectl logs -n ticdesk -l app=aleksis | grep MON

stern -n ticdesk -l app=aleksis --tail=1

stern ist ebenfalls auf dem Jumphost vorinstalliert

CronJobs

CRONJOB=mein-cronjob
kubectl -n default create job ${CRONJOB}-manually --from=cronjob/${CRONJOB}

Pods

Known Issues

Unauthorized

Das kann verschiedene Gründe haben:

SealedSecrets

Damit wir Secrets einfach in git-Repositories speichern können, nutzen wir "SealedSecrets".

Die Verschlüsselung ist asymmetrisch: Auf dem Client kann ein Secret verschlüsselt und dann auch in einem Git-Repository gespeichert werden. Das verschlüsselte SealedSecret wird in den Cluster deployt, und dort vom Sealed-Secrets-Controllers entschlüsselt.

Installation

https://github.com/bitnami-labs/sealed-secrets?tab=readme-ov-file#kubeseal

Plaintext verschlüsseln

NAMESPACE=<Namespace>
CONTEXT=Teckids_PROD
(read -p 'Password: ' -r -s password && echo -n "${password}" | kubeseal --controller-namespace=flux-system --controller-name=sealed-secrets  --context=$CONTEXT --raw --scope=namespace-wide --namespace=$NAMESPACE);echo

Dann das Passwort eingeben, und mit Enter bestätigen. Man erhält dann das verschlüsselte Secret.

Datei verschlüsseln

Es ist auch möglich, eine ganze Datei zu verschlüsseln:

NAMESPACE=<Namespace>
CONTEXT=Teckids_PROD
kubeseal --controller-namespace=flux-system --controller-name=sealed-secrets  --context=$CONTEXT --raw --scope=namespace-wide --namespace=$NAMESPACE < $DATEI

Cluster und Namespace müssen hier mit dem Ziel übereinstimmen, sonst kann das Secret dort nicht entschlüsselt werden. Wenn es mehrere Ziel-Cluster/-Namespaces gibt, muss man das Secret mehrmals (einmal pro Cluster/Namespace) verschlüsseln.

Resource anlegen

Die Ausgabe von kubeseal fügt man dann in ein SealedSecrets-Objekt ein. Das wird dann innerhalb des Clusters verschlüsselt:

apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
  annotations:
    sealedsecrets.bitnami.com/namespace-wide: "true"
  name: NAME
  namespace: NAMESPACE
spec:
  encryptedData:
    A: [… verschlüsselter Wert]

Secret aus bestehender Resource editieren

NAMESPACE=<Namespace>
CONTEXT=Teckids_PROD
SECRET=<Secret-Name>
KEY=<Key aus encryptedData>
TEMPSEC=$(mktemp)
kubectl -n $NAMESPACE get secret -o json $SECRET | jq -r '.data."'"$KEY"'"' | base64 -d >"$TEMPSEC"
edit "$(TEMPSEC)"
kubeseal --controller-namespace=flux-system --controller-name=sealed-secrets  --context=$CONTEXT --raw --scope=namespace-wide --namespace=$NAMESPACE < "$TEMPSEC"
shred -u "$TEMPSEC"

Services

Alle Services des Typs LoadBalancer bekommen automatisch eine private IP aus dem Netz 10.98.2.0/24. Eine öffentlich routbare IP bekommt man mit den passenden Annotations am Service:

"projectcalico.org/ipv4pools": '["loadbalancer-ip-pool-public-v4"]'
"projectcalico.org/ipv6pools": '["loadbalancer-ip-pool-public-v6"]'

Bei öffentlichen Services darauf achten, spec.ipFamilyPolicy auf RequireDualStack zu setzen, damit IPv6 funktioniert.

Gateway / HTTP(S)-Services

Config/Deployment: https://code.teckids.org/teckids/sysadmin-flux/src/branch/main/infrastructure/kgateway/gateways

Verschiedene Gateways

Wir haben aktuell 3 Gateways für verschiedene Anwendungsfälle:

OIDC-Gateway

Beim teckids-gateway haben wir die Möglichkeit, HTTPRoutes entsprechend abzusichern, sodass man nur nach erfolgreichem TIC-Desk-Login zugreifen darf. Wir können auch eine bestimmte Gruppenmitgliedschaft voraussetzen.

Beispiel einer solchen TrafficPolicy: https://code.teckids.org/teckids/sysadmin-flux/src/branch/main/apps/rspamd/rspamd/gateway/ticdesk-oauth2-trafficpolicy.yaml

Das Webinterface von rspamd dürfen nur Mitglieder der Gruppe ag-sysadmin aufrufen.

Betriebsdokumentation

Controlplane

Worker-Nodes

Netzwerk

Storage

Updates

Backups und Restore