Kubernetes Cluster in Proxmox VE (AlmaLinux/CentOS)


Anleitung um ein Kubernetes Cluster innerhalb von Proxmox VE einzurichten.


Getestet auf AlmaLinux 8

Vorbereitungen

Controller und Worker

Hostname festlegen

vi /etc/hostname

Für den Controller .z.B.:

k8s-ctrlr

Für die Worker-Nodes z.B.:

k8s-node-1

# Containerd installieren

dnf install -y yum-utils
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
dnf install containerd

# Die ggf. automatisch installierte config.toml löschen und neu generieren:

rm /etc/containerd/config.toml
containerd config default | tee /etc/containerd/config.toml

# Die neu erzeugte config.toml bearbeiten

vi /etc/containerd/config.toml

Folgenden Absatz suchen und SystemdCgroup auf true setzen (Suchen in vi mit /<Suchbegriff>):

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
            BinaryName = ""
            CriuImagePath = ""
            CriuPath = ""
            CriuWorkPath = ""
            IoGid = 0
            IoUid = 0
            NoNewKeyring = false
            NoPivotRoot = false
            Root = ""
            ShimCgroup = ""
            SystemdCgroup = false

#

vi /etc/sysctl.conf

Folgende Zeile am Ende einfügen, bzw. auskommentieren, falls schon vorhanden:

net.ipv4.ip_forward=1

# Module config / Enable bridge netfilter

vi /etc/modules-load.d/k8s.conf

Einfügen:

br_netfilter

# Anschließend noch ein Neustart um alle Änderungen zu übernehmen

reboot

# Add kubernetes repository

cat <<EOF | tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-\$basearch
enabled=1
gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
exclude=kubelet kubeadm kubectl
EOF

# Da kubelet noch nicht SELinux optimimert ist muss dieses dauerhaft deaktiviert werden

Nur so können die Container auf das Dateisystem des Hosts zugreifen.

Disable SELinux /

setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

Controller

Feste IP einrichten


Grafische Oberfläche:

nmtui

Oder per Konsole (Name des Interfaces kann abweichen):

vi /etc/sysconfig/network-scripts/ifcfg-ens18

Beispiel:

BOOTPROTO=none
IPADDR=192.168.2.65
PREFIX=24
GATEWAY=192.16.2.1
DNS1=192.168.2.1
DNS2=1.1.1.1

Hosts-Datei anpassen:

vi /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4

192.168.2.65   k8s-ctrlr.my.domain k8s-ctrlr


Kubernetes installieren

dnf update
dnf install kubeadm kubectl kubelet --disableexcludes=kubernetes

Den kubelet Service automatisch starten:

systemctl enable kubelet

##

- kubeadm / initialize new cluster & joining nodes & updating cluster

- kubectl / cmd line util to manage cluster

- kubelet / communication between nodes and API

##

Firewall konfigurieren

Controller

firewall-cmd --permanent --add-port={6443,10250,10256,2379-2380,30000-32767}/tcp
firewall-cmd --permanent --add-port=8472/udp
firewall-cmd --permanent --add-masquerade
firewall-cmd --reload

Worker

firewall-cmd --permanent --add-port={10250,10256,30000-32767}/tcp
firewall-cmd --permanent --add-port=8472/udp
firewall-cmd --permanent --add-masquerade
firewall-cmd --reload


Jetzt ist der perfekte Zeitpunkt ein Template aus dem Worker zu erstellen, welches dann für jeden weiteren Node verwendet werden kann.


Auf jedem Worker-Node muss jetzt noch eine feste IP vergeben werden

Feste IP einrichten

Grafische Oberfläche:

nmtui

Oder per Konsole (Name des Interfaces kann abweichen):

vi /etc/sysconfig/network-scripts/ifcfg-ens18

Beispiel:

BOOTPROTO=none
IPADDR=192.168.2.65
PREFIX=24
GATEWAY=192.16.2.1
DNS1=192.168.2.1
DNS2=1.1.1.1

Hosts-Datei anpassen:

vi /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4

192.168.2.65   k8s-ctrlr.my.domain k8s-ctrlr

Wenn alle VMs aus dem selben Template erstellt wurden, muss die 'machine-id' neu generiert werden damit sie auf jedem Node einzigartig ist:

rm /etc/machine-id
systemd-machine-id-setup

Als Rückmeldung sollte folgendes kommen:

Initializing machine ID from KVM UUID

Das bedeutet, dass die machine-id aus der UUID der Proxmox VM generiert wurde.

 
VM UUID in Proxmox

Controller

## Cluster initialisieren

kubeadm init --control-plane-endpoint=<Controller-IP> --node-name k8s-ctrlr --pod-network-cidr=10.244.0.0/16

## Join Kommandos brauch man sich nicht zu speichern da der Token jederzeit mit kubeadm token create --print-join-command neu generiert werden kann.

Damit ein Linux User auf dem Controller Administrativen Zugriff auf den Cluster hat m

# Benutzer die Berechtigung für kubernetes geben

mkdir -p $HOME/.kube
cp /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config

# Als root muss nur folgender Befehl ausgeführt werden

export KUBECONFIG=/etc/kubernetes/admin.conf

Damit das nicht bei jeder neuen Sitzung wiederholt werden muss die Zeile am Ende von .bash_profile einfügen:

vi ~/.bash_profile

# Network overlay konfigurieren

kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml

## Auf dem Controller das join command anzeigen lassen

kubeadm token create --print-join-command

######################

##  Nur auf worker   ##

####################

#Den Join Befehl auf jedem Worker-Node ausführen

 kubeadm join 192.168.2.65:6443 --token b1j6iu.s91gq99vytd2x096 --discovery-token-ca-cert-hash sha256:244dcacceb61419bc00d6dff2bea8ec694732be1d03b289308a58436da5e17d0

# Auf dem controller überprüfen ob der node registreiert wurde

kubectl get nodes

Ausgabe:

k8s-ctrlr   Ready   control-plane   19m     v1.26.0
k8s-node-1  Ready   <none>          3m1s    v1.26.0

Dashboard

# Dashboard installieren

kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.6.1/aio/deploy/recommended.yaml

# Zugriff von LAN / https://www.thegeekdiary.com/how-to-access-kubernetes-dashboard-externally/ Den Dashboard Service editieren:

kubectl -n kubernetes-dashboard edit service kubernetes-dashboard

Den Parameter type: ClusterIP in NodePort ändern:

apiVersion: v1
kind: Service
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"k8s-app":"kubernetes-dashboard"},"name":"kubernetes-dashboard","namespace":"kubernetes-dashboard"},"spec":{"ports":[{"port":443,"targetPort":8443}],"selector":{"k8s-app":"kubernetes-dashboard"}}}
  creationTimestamp: "2022-12-14T23:09:44Z"
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
  resourceVersion: "23315"
  uid: 5011d061-dce0-4e4e-a245-3de3eac0a77c
spec:
  clusterIP: 10.109.124.10
  clusterIPs:
  - 10.109.124.10
  externalTrafficPolicy: Cluster
  internalTrafficPolicy: Cluster
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - nodePort: 31293
    port: 443
    protocol: TCP
    targetPort: 8443
  selector:
    k8s-app: kubernetes-dashboard
  sessionAffinity: None
  type: ClusterIP # Ändern in NodePort
status:
  loadBalancer: {}

# Create admin-user

https://github.com/kubernetes/dashboard/blob/master/docs/user/access-control/creating-sample-user.md

# Metrics Server installieren / https://www.scmgalaxy.com/tutorials/kubernetes-metrics-server-error-readiness-probe-failed-http-probe-failed-with-statuscode/

Download metrics-server

wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

- Modify and add "- --kubelet-insecure-tls" in deployment.spec.template.spec.containers.args

kubectl apply -f components.yaml

###############################

###Speziell gitlab

###############################

# DNS zur gitlab-runner config

[runners.kubernetes.dns_config]

nameservers = [

  "10.16.0.3",

  "10.16.0.4"

]

Weiterführende Link

Quellen

https://www.youtube.com/watch?v=U1VzcjCB_sY

https://docs.docker.com/engine/install/centos/

https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/