mmul.kubelab

Kubelab Ansible Rolle

Diese Rolle kann verwendet werden, um ein Kubernetes-Cluster mit einer vollständig automatisierten und idempotenten Implementation mehrerer Komponenten bereitzustellen.

Lint das Projekt Ansible Galaxy

Funktionen

Diese Rolle kann konfiguriert werden, um all diese Funktionen zu aktivieren:

  • Einzelne oder mehrfache Control-Plane-Cluster mit HAProxy und Keepalived für hohe Verfügbarkeit.

  • Mehrere Netzwerk-Add-ons wie Flannel und Calico.

  • Kubernetes Dashboard.

  • Benutzerverwaltung mit Zertifikatserstellung und Aktualisierung der kubeconfig-Datei.

  • Ceph-CSI StorageClass für Blockgeräte.

  • MetalLB Load Balancer für Baremetal-Umgebungen.

  • Ingress NGINX für die Exposition von Dienstleistungen.

  • Cert Manager für automatisierte Zertifikatsverwaltung.

Installieren Sie das Cluster mit dem Ansible Playbook

Der beste Weg, die Umgebung vorzubereiten, ist die Verwendung eines Python VirtualEnv, Ansible mit pip3 zu installieren:

user@lab ~ # python3 -m venv ansible
user@lab ~ # source ansible/bin/activate
(ansible) user@lab ~ # pip3 install ansible
Collecting ansible
  Using cached ansible-7.5.0-py3-none-any.whl (43.6 MB)
...
...
Installing collected packages: resolvelib, PyYAML, pycparser, packaging, MarkupSafe, jinja2, cffi, cryptography, ansible-core, ansible
Successfully installed MarkupSafe-2.1.2 PyYAML-6.0 ansible-7.5.0 ansible-core-2.14.5 cffi-1.15.1 cryptography-40.0.2 jinja2-3.1.2 packaging-23.1 pycparser-2.21 resolvelib-0.8.1

Dann benötigen Sie diese Rolle, und in diesem Fall ist es eine gute Wahl, ansible-galaxy zu verwenden, um alles automatisch zu machen:

(ansible) user@lab ~ # ansible-galaxy install mmul.kubelab -p ansible/roles/
Starte den Installationsprozess der Galaxy-Rolle
- Rolle 'kubelab', die von mmul betrieben wird, wird heruntergeladen
- Rolle wird von https://github.com/mmul-it/kubelab/archive/main.tar.gz heruntergeladen
- Extrahiere mmul.kubelab nach /home/rasca/ansible/roles/mmul.kubelab
- mmul.kubelab (main) wurde erfolgreich installiert

Mit der Rolle an ihrem Platz können Sie die Anforderungen erfüllen, erneut mit pip3:

(ansible) user@lab ~ # pip3 install -r ansible/roles/mmul.kubelab/requirements.txt
...
...
Successfully installed ansible-vault-2.1.0 cachetools-5.3.0 certifi-2023.5.7 charset-normalizer-3.1.0 google-auth-2.18.0 idna-3.4 kubernetes-26.1.0 oauthlib-3.2.2 pyasn1-0.5.0 pyasn1-modules-0.3.0 python-dateutil-2.8.2 requests-2.30.0 requests-oauthlib-1.3.1 rsa-4.9 six-1.16.0 urllib3-1.26.15 websocket-client-1.5.1

Sobald die Anforderungen verfügbar sind, verwenden Sie die Rolle in der Regel, indem Sie das tests/kubelab.yml Playbook starten, so:

(ansible) user@lab ~ # ansible-playbook -i tests/inventory/kubelab tests/kubelab.yml

HINWEIS: Datum und Uhrzeit der beteiligten Systeme sind wichtig! Wenn zwischen der Maschine, auf der Sie Ansible-Playbooks ausführen, und den Zielmaschinen eine Zeitabweichung besteht, kann die Zertifikatsüberprüfung fehlschlagen.

HINWEIS: Sie können jederzeit alles zurücksetzen, indem Sie k8s_reset auf true setzen. Dies wird Ihr gesamtes Cluster zurücksetzen, verwenden Sie es also mit Vorsicht:

(ansible) user@lab ~ # ansible-playbook -i tests/inventory/kubelab tests/kubelab.yml -e k8s_reset=true

Interaktion mit dem Cluster nach der Installation

Sobald das Playbook seine Ausführung abgeschlossen hat, ist der beste Weg, mit dem Cluster zu interagieren, den kubectl Befehl zu verwenden, der wie folgt installiert werden kann:

user@lab ~ # curl -s -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"

user@lab ~ # chmod +x kubectl

user@lab ~ # sudo mv kubectl /usr/local/bin

Die Kubernetes-Rolle erzeugt ein lokales Verzeichnis, das die Haupt kubeconfig-Datei namens admin.conf enthält. Der einfachste Weg, sie zu verwenden, besteht darin, die KUBECONFIG-Variable zu exportieren, so:

user@lab ~ # export KUBECONFIG=~/kubernetes/admin.conf

Von nun an bis zum Ende der Sitzung wird jedes Mal, wenn Sie kubectl verwenden, auf die in dieser Datei enthaltenen Anmeldeinformationen zurückgegriffen:

user@lab ~ # kubectl cluster-info
Kubernetes Control Plane läuft unter https://192.168.122.199:8443
CoreDNS läuft unter https://192.168.122.199:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

Um weitere Probleme im Cluster zu debuggen und zu diagnostizieren, verwenden Sie 'kubectl cluster-info dump'.

user@lab ~ # kubectl get nodes
NAME           STATUS   ROLES           AGE   VERSION
kubernetes-1   Ready    control-plane   26h   v1.25.3
kubernetes-2   Ready    control-plane   26h   v1.25.3
kubernetes-3   Ready    control-plane   26h   v1.25.3
kubernetes-4   Ready    <none>          26h   v1.25.3

Es ist auch möglich, verschiedene Benutzer für den Zugriff auf das Cluster zu verwenden. Weitere Informationen finden Sie im Abschnitt Benutzer.

Konfiguration

Inventory

Ein typisches Inventar hängt davon ab, was Sie bereitstellen möchten. Im Beispiel kubelab können Sie in der Hosts-Datei (siehe tests/inventory/kubelab/hosts) alle Knoten deklarieren:

# Kubernetes-Hosts
[kubelab]
kubernetes-1 k8s_role=control-plane run_non_infra_pods=true
kubernetes-2 k8s_role=control-plane run_non_infra_pods=true
kubernetes-3 k8s_role=control-plane run_non_infra_pods=true
kubernetes-4 k8s_role=worker

Sie legen fest, welche Knoten als Control Plane fungieren und ob diese nicht-Infrastruktur-Pods ausführen sollen (so dass die Control Plane auch ein Worker sein kann).

Dann können Sie in der Gruppendatei (z.B. inventory/kubelab/group_vars/kubelab.yml) alle zusätzlichen Konfigurationen definieren, je nachdem, was Sie implementieren möchten.

Der Name der Hostgruppe für die Kubernetes-Hosts ist standardmäßig kubelab, kann aber durch Deklarieren der k8s_host_group-Variablen überschrieben werden.

Kubernetes-Cluster

Wenn Sie ein Multi-Control-Plane-Cluster mit hoher Verfügbarkeit implementieren möchten, müssen Sie diese Variablen angeben:

k8s_cluster_name: kubelab

k8s_control_plane_node: kubernetes-1
k8s_control_plane_port: 6443
k8s_control_plane_cert_key: "91bded725a628a081d74888df8745172ed842fe30c7a3898b3c63ca98c7226fd"

k8s_multi_control_plane: true
k8s_balancer_VIP: 192.168.122.199
k8s_balancer_interface: eth0
k8s_balancer_port: 8443
k8s_balancer_password: "d6e284576158b1"

k8s_wait_timeout: 1200

k8s_control_plane_ports:
  - 2379-2380/tcp
  - 6443/tcp
  - 8443/tcp
  - 10250/tcp
  - 10257/tcp
  - 10259/tcp

Dies wird ein Cluster von Knoten kubernetes-1 starten, die die Multi-Control-Plane über k8s_multi_control_plane aktivieren und die VIP-Adresse sowie die Schnittstelle festlegen.

Hinweis: Sie möchten sowohl k8s_control_plane_cert_key als auch k8s_balancer_password für eine bessere Sicherheit ändern.

Hinweis: Es ist möglich, eine vor allem atomicere Art und Weise zur Konfiguration von Pods Netzwerk-CIDR, Worker-Ports, Nodeport-Bereiche und Firewall-Verwaltung zu haben; Sie können die Standard-Datei prüfen.

Netzwerk-Add-on

Die Kubernetes-Rolle unterstützt Flannel und Calico Netzwerk-Add-ons. Die Konfiguration hängt davon ab, welches Add-on Sie implementieren möchten.

Für Flannel benötigen Sie etwa Folgendes:

# Flannel Addon
k8s_network_addon: flannel
k8s_network_addon_ports:
  - 8285/udp
  - 8472/udp

Um zu prüfen, wie Calico implementiert werden kann, schauen Sie sich die Standard-Datei an.

Dashboard

Das Kubernetes-Dashboard kann implementiert werden, indem Sie dies zur Konfiguration hinzufügen:

k8s_dashboard_enable: true

Sobald die Installation abgeschlossen ist, ist der einfachste Weg, auf das Dashboard zuzugreifen, die Verwendung von kubectl proxy, um dann die entsprechende URL http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/ aufzurufen.

Es wird eine Anmeldemaske angezeigt, und Sie können sich anmelden, indem Sie einen Token angeben. Standardmäßig erstellt die Kubernetes-Rolle einen Benutzer namens dashboard-user (den Sie überschreiben können).

Um den Token abzurufen, müssen Sie kubectl verwenden, so:

user@lab ~ # kubectl -n kubernetes-dashboard create token dashboard-user
<IHR TOKEN>

Kopieren Sie die Ausgabe des obigen Befehls und fügen Sie sie in die Eingabeaufforderung ein, und Sie sind angemeldet.

Benutzer

Es ist möglich, Benutzer zu Ihrem Cluster hinzuzufügen, indem Sie etwas wie Folgendes deklarieren:

k8s_users:
  - name: pod-viewer
    namespace: default
    role_name: pod-viewer-role
    role_rules_apigroups: '""'
    role_rules_resources: '"pods","pods/exec","pods/log"'
    role_rules_verbs: '"*"'
    rolebinding_name: pod-viewer-rolebinding
    cert_expire_days: 3650
    update_kube_config: true

Dadurch wird ein lokales Verzeichnis erstellt, das diese Dateien enthält:

user@lab ~ # ls -1 kubernetes/users/
pod-viewer.crt
pod-viewer.csr
pod-viewer.key
users.conf
users-rolebindings.yaml
users-roles.yaml

Die Datei users.conf kann dann verwendet werden, um mit diesem Benutzer auf das Cluster zuzugreifen, so:

user@lab ~ # export KUBECONFIG=~/kubernetes/users/users.conf

rasca@catastrofe [~]> kubectl config get-contexts
CURRENT   NAME                       CLUSTER   AUTHINFO           NAMESPACE
*         kubernetes-admin@kubelab   kubelab   kubernetes-admin
          pod-viewer@kubelab         kubelab   pod-viewer         default

user@lab ~ # kubectl config use-context pod-viewer@kubelab
Wechsel zu Kontext "pod-viewer@kubelab".

user@lab ~ # kubectl config get-contexts
CURRENT   NAME                       CLUSTER   AUTHINFO           NAMESPACE
          kubernetes-admin@kubelab   kubelab   kubernetes-admin
*         pod-viewer@kubelab         kubelab   pod-viewer         default

user@lab ~ # kubectl get pods
Keine Ressourcen im Standard-Namensraum gefunden.

Ceph CSI

Die Kubernetes-Rolle unterstützt tatsächlich die Implementierung der Ceph CSI StorageClass. Sie kann wie folgt definiert werden:

k8s_ceph_csi_enable: true
k8s_ceph_csi_id: lab-ceph
k8s_ceph_csi_secret_userid: kubernetes
k8s_ceph_csi_secret_userkey: AQAWvU5jjBHSGhAAuAXtHFt0h05B5J/VHERGOA==
k8s_ceph_csi_clusterid: d046bbb0-4ee4-11ed-8f6f-525400f292ff
k8s_ceph_csi_pool: kubepool
k8s_ceph_csi_monitors:
  - 192.168.122.11:6789
  - 192.168.122.12:6789
  - 192.168.122.13:6789

Dann wird es möglich sein, neue PVC zu deklarieren:

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: rbd-pvc
  namespace: rasca
spec:
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    requests:
      storage: 1Gi
  storageClassName: csi-rbd-sc

Und das zugehörige Pod:

---
apiVersion: v1
kind: Pod
metadata:
  name: csi-rbd-demo-pod
  namespace: rasca
spec:
  containers:
    - name: web-server
      image: nginx
      volumeMounts:
        - name: mypvc
          mountPath: /var/lib/www/html
  volumes:
    - name: mypvc
      persistentVolumeClaim:
        claimName: rbd-pvc
        readOnly: false

HINWEIS: Derzeit wird nur die Bereitstellung von rbd unterstützt.

MetalLB

Um MetalLB zu aktivieren, eine Load-Balancer-Implementierung für Baremetal-Kubernetes-Cluster, die Standard-Routing-Protokolle verwenden, genügt es, Folgendes zu deklarieren:

k8s_metallb_enable: true
k8s_metallb_pools:
  - name: 'first-pool'
    addresses: '192.168.122.100-192.168.122.130'

Dann wird es möglich sein, diesen LoadBalancer zu verwenden, um IPs innerhalb des deklarierten Poolbereichs zu erstellen (siehe nächstes ingress-nginx Beispiel, um zu verstehen, wie).

Ingress NGINX

Um Ingress NGINX, einen Ingress-Controller für Kubernetes, der NGINX als Reverse-Proxy und Load-Balancer verwendet, zu aktivieren, genügt es, Folgendes zu deklarieren:

k8s_ingress_nginx_enable: true

Dies installiert den Ingress-NGINX-Controller, der für verschiedene Zwecke verwendet werden kann.

Ingress NGINX auf Control Planes

Zum Beispiel ist es möglich, Ingress NGINX zu verwenden, indem man die Ports 80 und 443 auf der balancierten IP freigibt, die von HAProxy verwaltet wird, indem man Folgendes deklariert:

k8s_ingress_nginx_enable: true
k8s_ingress_nginx_haproxy_conf: true
k8s_ingress_nginx_services:
  - name: ingress-nginx-externalip
    spec:
      externalIPs:
      - 192.168.122.199
      ports:
      - name: port-1
        port: 80
        protocol: TCP
      - name: port-2
        port: 443
        protocol: TCP
      selector:
        app.kubernetes.io/component: controller
        app.kubernetes.io/instance: ingress-nginx
        app.kubernetes.io/name: ingress-nginx

Dies ermöglicht das Löschen beider Ports auf der balancierten IP (in diesem Fall 192.168.122.199) und macht den Dienst ansprechbar.

Um dies zu testen, probieren Sie Folgendes aus:

$ kubectl create deployment demo --image=httpd --port=80
deployment.apps/demo erstellt

$ kubectl expose deployment demo
service/demo exponiert

$ kubectl create ingress demo --class=nginx \
    --rule="demo.192.168.122.199.nip.io/*=demo:80" \
    --annotation="nginx.ingress.kubernetes.io/service-upstream=true"
ingress.networking.k8s.io/demo erstellt

$ curl http://demo.192.168.122.199.nip.io
<html><body><h1>Es funktioniert!</h1></body></html>

Oder um TLS zu testen:

$ kubectl create deployment demo --image=httpd --port=80
deployment.apps/demo erstellt

$ kubectl expose deployment demo
service/demo exponiert

$ openssl genrsa -out cert.key 2048
(keine Ausgabe)

$ openssl req -new -key cert.key -out cert.csr -subj "/CN=demo.192.168.122.199.nip.io"
(keine Ausgabe)

$ openssl x509 -req -days 366 -in cert.csr -signkey cert.key -out cert.crt
Zertifikatsanforderung selbst-signiert ok
subject=CN = demo.192.168.122.199.nip.io

$ kubectl create secret tls tls-secret --cert=./cert.crt --key=./cert.key
secret/tls-secret erstellt

$ kubectl create ingress demo --class=nginx \
    --rule="demo.192.168.122.199.nip.io/*=demo:80,tls=tls-secret" \
    --annotation="nginx.ingress.kubernetes.io/service-upstream=true"
ingress.networking.k8s.io/demo erstellt

$ curl -k https://demo.192.168.122.199.nip.io 
<html><body><h1>Es funktioniert!</h1></body></html>

Der Grund, warum die --annotation="nginx.ingress.kubernetes.io/service-upstream=true" benötigt wird, wird in diesem Ingress-NGINX-Problem erklärt.

Ingress NGINX mit MetalLB

Eine andere Möglichkeit ist der Einsatz in Kombination mit MetalLB, indem Sie einen LoadBalancer-Dienst so deklarieren:

k8s_ingress_nginx_enable: true
k8s_ingress_nginx_services:
  - name: ingress-nginx-lb
    spec:
      type: LoadBalancer
      loadBalancerIP: 192.168.122.100
      ports:
      - name: port-1
        port: 80
        protocol: TCP
      - name: port-2
        port: 443
        protocol: TCP

Dies installiert alles, was mit dem Controller zu tun hat, und weist die loadBalancerIP zu, die Teil des von MetalLB bereitgestellten Bereichs ist, indem es beide 80 und 443 Ports freigibt.

Cert Manager

Um Cert Manager zu aktivieren, einen Controller zur Automatisierung der Zertifikatsverwaltung in Kubernetes, genügt es, Folgendes zu deklarieren:

k8s_cert_manager_enable: true
k8s_cert_manager_issuers:
  - name: letsencrypt
    cluster: true
    acme:
      server: https://acme-v02.api.letsencrypt.org/directory
      email: [email protected]
      privateKeySecretRef:
        name: letsencrypt
      solvers:
      - http01:
          ingress:
            class: nginx

Dies installiert alles, was mit dem Controller zu tun hat, und erstellt einen Cluster Issuer, der letsencrypt mit der http01-Herausforderung nutzt, über die NGINX Ingress-Klasse.

Sobald alles installiert ist und Sie eine Anwendung exponieren möchten, können Sie alles mit einer YAML wie folgt testen:

apiVersion: v1
kind: Namespace
metadata:
  name: rasca
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: index-html
  namespace: rasca
data:
  index.html: |
    Dies ist mein fabelhafter Webserver!
---
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  namespace: rasca
  labels:
    app: nginx
spec:
  containers:
    - name: web-server
      image: nginx
      volumeMounts:
      - name: docroot
        mountPath: /usr/share/nginx/html
  volumes:
    - name: docroot
      configMap:
        name: index-html
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  namespace: rasca
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt
  name: nginx-ingress
  namespace: rasca
spec:
  ingressClassName: nginx
  rules:
  - host: nginx.apps.kubelab.mmul.it
    http:
      paths:
      - backend:
          service:
            name: nginx-service
            port:
              number: 80
        path: /
        pathType: Prefix
  tls:
  - hosts:
    - nginx.apps.kubelab.mmul.it
    secretName: nginx.apps.kubelab.mmul.it

Wenn Sie sich speziell den letzten Ressourcen das Ingress namens nginx-ingress ansehen, werden Sie zwei wichtige Abschnitte sehen:

  • Unter metadata -> annotations die Annotation: cert-manager.io/cluster-issuer: letsencrypt

  • Unter spec: -> tls die Hostdeklaration.

Mit dieser Konfiguration haben Sie nach einiger Zeit Ihr Zertifikat für den exponierten Service.

Lizenz

MIT

Autoreninformation

Raoul Scarazzini (rascasoft)

Über das Projekt

This role automates the creation of a Kubernetes cluster complete of additional dashboard, users and operators.

Installieren
ansible-galaxy install mmul.kubelab
Lizenz
mit
Downloads
139
Besitzer