mmul.kubelab
Diese Rolle kann verwendet werden, um ein Kubernetes-Cluster mit einer vollständig automatisierten und idempotenten Implementation mehrerer Komponenten bereitzustellen.
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)
This role automates the creation of a Kubernetes cluster complete of additional dashboard, users and operators.
ansible-galaxy install mmul.kubelab