Modius - Techblog

  • Ansible
  • Docker
  • DevOps
  • Gastautor werden
  • Newsletter abonnieren
  • Über Mich
  • Kontakt

Installation eines Kubernetes Cluster unter CentOS 7

Veröffentlicht am 29. Juli 2020 von Christian Piazzi 1 Kommentar , Aktualisiert am 28. Juli 2020
Geschätzte Lesezeit: 5 Minuten

Titlebild Kubernetes Cluster - Containerschiff mit Beleuchtung

In einem der Letzten Artikel habe ich bereits gezeigt, wie man sich ein kleines Setup mit Minikube realisiert. Heute will ich euch zeigen, wie ein Kubernetes Cluster bestehend aus drei CentOS Maschinen erstellt wird.

Inhaltsverzeichnis

Für die Installation des Cluster habe ich die drei Maschinen mit einem aktuellen CentOS 7 installiert und statische IPs sowie Hostnamen auf den Systemen konfiguriert.

  • k8s-master: 192.168.10.200
  • k8s-node1: 192.168.10.201
  • k8s-node2: 192.168.10.202

Installation von Kubernetes

Die folgenden Schritte müssen auf allen drei Maschinen durchgeführt werden.

/etc/hosts anpassen

Als erstes müssen wir sichergehen, dass die drei Systeme sich gegenseitig unter ihrem DNS Namen erreichen können. Dies kann man zum Beispiel dadurch lösen, dass man einen eigenen DNS Server mit Bind in seinem Netzwerk betreibt.

Will man das nicht oder will sich nur ein einfaches Testsetup aufbauen, können wir die drei Adresse auch einfach direkt auf den Systemen hinterlegen. Dazu öffnen wir mit einen Editor die Datei /etc/hosts und fügen die folgenden Zeilen ein:

1
2
3
192.168.10.200      k8s-master
192.168.10.201      k8s-node1
192.168.10.202      k8s-node2

Um das ganze zu testen, können wir von jedem System die jeweils anderen beiden versuchen mit einem Ping zu erreichen. Die Befehle für den k8s-master sehen dabei zum Beispiel wie folgt aus:

1
2
ping k8s-node1
ping k8s-node2

SELinux konfigurieren

Da ich mich hier nicht weiter mit SELinux in diesem Tutorial auseinandersetzen will, schränke ich die Funktion von SELinux ein. Ich persönlich mache das, indem ich SELinux in den permissive Mode setzte. Falls man später dann doch mal SELinux aktivieren will macht das weniger Probleme. In einem Testsetup kann man es aber auch einfach auf disabled setzen.

Um die Einstellung entsprechend anzupassen, öffnen wir die Datei /etc/selinux/config mit einem Editor und ändern die Zeile SELINUX=enforcing auf die gewünschte Einstellung. Die Datei sieht bei mir dann wie folgt aus:

1
2
3
4
5
6
7
8
9
10
11
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=permissive
# SELINUXTYPE= can take one of three two values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected.
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted

Anschließend muss das System einmal neugestartet werden.

br_netfilter Kernel Module aktivieren

Dieses Kernel-Modul muss aktiviert werden, damit die Pakete, welche die Network-Bridge durchlaufen, von iptables verarbeitet werden können und die Kubernetes Pods im gesamten Cluster ohne Probleme miteinander kommunizieren können.

Zum Aktivieren des Kernel Modules kann der folgende Befehl verwendet werden:

1
2
modprobe br_netfilter
echo '1' > /proc/sys/net/bridge/bridge-nf-call-iptables

SWAP deaktivieren

Damit Kubernetes zur Laufzeit keine Probleme bekommt, müssen wir auf allen System den SWAP Speicher deaktivieren. Dazu kann der aktuelle Befehl verwendet werden:

1
swapoff -a

Damit der SWAP Speicher auch nach dem Neustart deaktiviert ist, sollte dieser in der fstab Datei auskommentiert werden. Dazu öffnet man die Datei /etc/fstab mit einem Editor und und kommentiert die Zeile mit SWAP aus. Der Eintrag sollte ungefähr so aussehen:

1
#/dev/mapper/cl-swap     swap                    swap    defaults        0 0

Installation Docker CE

Bevor die Installation von Docker CE durchgeführt werden kann, müssen ein paar Pakete installiert werden. Dazu verwenden wir den folgenden Befehl:

1
yum install -y yum-utils device-mapper-persistent-data lvm2

Anschließend fügt man das Docker Repository auf dem Systemen hinzu und installiert das Docker Paket

1
2
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install -y docker-ce

Nach der Installation wird Docker gestartet und dem Autostart hinzugefügt.

1
systemctl start docker && systemctl enable docker

Installation Kubernetes

Um nun die Komponenten für Kubernetes zu installieren, müssen wir als erstes das passende Repository auf den Systemen hinterlegen. Dafür können wir den folgenden Befehl in unser Terminal kopieren.

1
2
3
4
5
6
7
8
9
10
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg
        https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF

Jetzt können die drei Pakete kubelet, kubeadm und kubectl installiert werden.

1
yum install -y kubelet kubeadm kubectl

Nun müssen wir noch kubelete starten und dem Autostart hinzufügen.

1
systemctl start kubelet && systemctl enable kubelet

Zum Testen ob Docker und kubelet starten, sollten die Systeme jetzt alle neugestartet werden.

cgroup Konfiguration

Für einen reibungslosen Betrieb des Cluster müssen wir sichergehen, dass Docker und kubelet dieselbe cgroup verwenden. Dafür müssen wir als erstes herausfinden, welche cgroup Docker verwendet. Dazu können wir den folgenden Befehl verwenden:

1
2
3
docker info | grep -i cgroup
 
Cgroup Driver: cgroupfs

In der Ausgabe können wir sehen, das cgroupfs verwendet wird. Diese Einstellung setzen wir nun mit sed auch für Kubernetes.

1
sed -i 's/cgroup-driver=systemd/cgroup-driver=cgroupfs/g' /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf

Anschließend muss systemd und kubelet neugestartet werden.

1
2
systemctl daemon-reload
systemctl restart kubelet

Kubernetes Cluster Konfiguration

Wir wollen nun das Cluster auf dem Master initialisieren (alle Befehle werden nun nur noch auf dem k8s-master ausgeführt). Dafür verwenden wir den Befehl kubeadm init. Dazu kommen noch zwei Parameter die ich vorher kurz erläutern will.

–apiserver-advertise-addres: Mit dieser Einstellung legen wir fest, unter welcher IP Adresse die Kubernetes API zur Verfügung gestellt werden soll. Normalerweise verwendet man dafür die IP Adresse des Masters.

–pod-network-cidr: Dieser Parameter dient zur Konfiguration des Pod Netzwerkes. Man gibt hier eine IP Adresse Range mit Subnetzmaske an.

Bei mir sieht der fertige Befehl wie folgt aus:

1
kubeadm init --apiserver-advertise-address=192.168.10.200 --pod-network-cidr=10.13.0.0/16

Bei der Ausgabe sollte man sich die letzten Zeilen in eine Texteditor speichern, da man diese noch gebrauchen kann.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
kubeadm init --apiserver-advertise-address=192.168.10.200 --pod-network-cidr=10.13.0.0/16
W0728 10:12:10.030243    1493 configset.go:202] WARNING: kubeadm cannot validate component configs for API groups [kubelet.config.k8s.io kubeproxy.config.k8s.io]
[init] Using Kubernetes version: v1.18.6
 
....
 
Your Kubernetes control-plane has initialized successfully!
 
To start using your cluster, you need to run the following as a regular user:
 
  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config
 
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/
 
Then you can join any number of worker nodes by running the following on each as root:
 
kubeadm join 192.168.10.200:6443 --token hb7xqv.neqox2ozk3qbtzxj \
    --discovery-token-ca-cert-hash sha256:3b46bbd3da96870b7fc64d9b29500adc6b7e1a1b1fb5cfd0afa8f305cc7201f8

Wie am Ende beschrieben, legen wir uns jetzt eine .kube Konfiguration an. Dies sollte man als nicht root User machen.

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

Nun wird noch das flannel network auf dem Cluster deployed:

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

Jetzt müssen wir einige Minuten warten, da im Cluster u.A. Pods gestartet werden. Ist also genug Zeit für einen neuen Kaffee oder Tee.

Mit einem neuen Getränk auf dem Tisch prüfen wir als erstes mit dem Befehl kubectl get nodes ob der Master in der Node Übersicht angezeigt wird.

1
2
3
kubectl get nodes
NAME         STATUS   ROLES    AGE   VERSION
k8s-master   Ready    master   16m   v1.18.6

Wenn bis jetzt alles geklappt hat, sollte der Status der k8s-master Node Ready sein.

Auch die ersten Pods sollten bereits laufen. Dies kann mit dem Befehl kubectl get pods –all-namespaces geprüft werden und sollte ungefähr so aussehen:

1
2
3
4
5
6
7
8
9
10
kubectl get pods --all-namespaces
NAMESPACE     NAME                                 READY   STATUS    RESTARTS   AGE
kube-system   coredns-66bff467f8-rnpj7             1/1     Running   0          21m
kube-system   coredns-66bff467f8-tmmkz             1/1     Running   0          21m
kube-system   etcd-k8s-master                      1/1     Running   1          21m
kube-system   kube-apiserver-k8s-master            1/1     Running   1          21m
kube-system   kube-controller-manager-k8s-master   1/1     Running   3          21m
kube-system   kube-flannel-ds-amd64-lkdwl          1/1     Running   1          14m
kube-system   kube-proxy-s698h                     1/1     Running   1          21m
kube-system   kube-scheduler-k8s-master            1/1     Running   2          21m

Damit ist das Kubernetes Cluster initialisiert. Als nächstes können die beiden Nodes in das Cluster aufgenommen werden.

Hinzufügen der Cluster Nodes

Das einbinden der anderen beiden Nodes ist relative einfach. Dazu verbinden wir uns auf k8s-node1 und k8s-node2 und führen den Befehl aus, den wir bei der Initialisierung des Clusters in der Textdatei gesichert haben.

Für k8s-node2 sieht das ganze bei mir zum Beispiel so aus:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
kubeadm join 192.168.10.200:6443 --token hb7xqv.neqox2ozk3qbtzxj \
>     --discovery-token-ca-cert-hash sha256:3b46bbd3da96870b7fc64d9b29500adc6b7e1a1b1fb5cfd0afa8f305cc7201f8
W0728 10:46:42.221942    4436 join.go:346] [preflight] WARNING: JoinControlPane.controlPlane settings will be ignored when control-plane flag is not set.
[preflight] Running pre-flight checks
[WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". Please follow the guide at https://kubernetes.io/docs/setup/cri/
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'
[kubelet-start] Downloading configuration for the kubelet from the "kubelet-config-1.18" ConfigMap in the kube-system namespace
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...
 
This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.
 
Run 'kubectl get nodes' on the control-plane to see this node join the cluster.

Jetzt können wir noch mal die Cluster Nodes prüfen.

1
2
3
4
5
kubectl get nodes
NAME         STATUS   ROLES    AGE   VERSION
k8s-master   Ready    master   33m   v1.18.6
k8s-node1    Ready    <none>   80s   v1.18.6
k8s-node2    Ready    <none>   59s   v1.18.6

Wie man auf dem Terminal nun sehen kann, sind k8s-node1 und k8s-node2 erfolgreich dem Cluster hinzugefügt.

Auch die Liste mit Pods ist länger geworden, da es einige Pods gibt, wo auf jeder Node eine Instanz laufen muss:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
kubectl get pods --all-namespaces
NAMESPACE     NAME                                 READY   STATUS    RESTARTS   AGE
kube-system   coredns-66bff467f8-rnpj7             1/1     Running   0          33m
kube-system   coredns-66bff467f8-tmmkz             1/1     Running   0          33m
kube-system   etcd-k8s-master                      1/1     Running   1          33m
kube-system   kube-apiserver-k8s-master            1/1     Running   1          33m
kube-system   kube-controller-manager-k8s-master   1/1     Running   3          33m
kube-system   kube-flannel-ds-amd64-lkdwl          1/1     Running   1          26m
kube-system   kube-flannel-ds-amd64-ppzsc          1/1     Running   2          2m10s
kube-system   kube-flannel-ds-amd64-wcc8b          1/1     Running   0          109s
kube-system   kube-proxy-dhrdl                     1/1     Running   0          2m10s
kube-system   kube-proxy-k5w4z                     1/1     Running   0          109s
kube-system   kube-proxy-s698h                     1/1     Running   1          33m
kube-system   kube-scheduler-k8s-master            1/1     Running   2          33m

Nun wollen wir im letzten Abschnitt noch einen ersten eigenen Pod deployen.

Testen mit dem nginx Pod

Nachdem das Cluster nun erfolgreich eingerichtet ist, soll natürlich auf dem Cluster auch eine Applikation laufen. Zum Testen bietet sich hier nginx an, weil es recht unkompliziert funktioniert.

Als erstes verbinden wir uns mit dem k8s-master. Hier legen wir nun ein nginx Deployment an.

1
2
kubectl create deployment nginx --image=nginx
deployment.apps/nginx created

Die Details des Deployments können wir mit dem kubectl describe anzeigen lassen.

1
kubectl describe deployment nginx

Jetzt legen wir noch einen nginx Service an, damit die Applikation von außen aufgerufen werden kann.

1
kubectl create service nodeport nginx --tcp=80:80

Lassen wir uns nun einen die Pods anzeigen, sehen wir das ein nginx Pod dazugekommen ist.

1
2
3
kubectl get pods
NAME                    READY   STATUS    RESTARTS   AGE
nginx-f89759699-s6vxx   1/1     Running   0          2m48s

Ein Blick auf die Service Details zeigt uns, dass auch die Portweiterleitung erfolgreich eingerichtet wurde.

1
2
3
4
kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP        43m
nginx        NodePort    10.110.22.246   <none>        80:31553/TCP   76s

Rufen wir nun das ganze im Browser auf, bekommen wir auch die Standardseite von nginx angezeigt. Für den Aufruf verwendet man die Kubernetes API Adresse (dafür haben wir die IP Adresse des Masters verwendet) und den Port, welchen wir mit kubectl get svc angezeigt bekommen (bei mir 31553).

Testsseite ngnix - Aufruf des ersten Kubernetes Cluster Pods

Damit haben wir erfolgreich unser eigenes Kubernetes Cluster installiert.

Mich würde interessieren, welche Themen euch noch im Kontext zu Kubernetes interessieren. Hinterlasst mir doch ein kurzes Kommentar mit dem Thema. Dann kann ich mal schauen ob ich dazu auch einen Artikel hier auf dem Blog verfasse.

Ansonsten erstmal viel Spaß mit dem Cluster =)

Referenz: https://kubernetes.io/docs/home/

Kategorie: DevOps Tags: Cluster, Docker, kubeadm, kubectl, kubelete, Kubernetes, Pods

Über Christian Piazzi

Ich blogge hier über alles, was mir so in meinem ITler Altag über den Weg läuft =)
Man findet mich privat bei Google+ und Twitter

Kommentare

  1. Techs meint

    14. September 2020 um 04:21

    Vielen Dank für die umfassenden Informationen.

    Antworten

Schreibe einen Kommentar Antworten abbrechen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Kategorien

  • Linux
  • Internet, Bloggen & Co
  • Programmierung
  • Sicherheit
  • Netzwerk & Co
  • Mikrokontroller
  • Windows

Neueste Kommentare

  • Prometheus Installation unter Ubuntu - Modius - Techblog bei Prometheus Installation unter CentOS
  • Rainer bei Docker Container – anzeigen, starten, stoppen und löschen
  • Rainer Wohlfarth bei Docker Container – anzeigen, starten, stoppen und löschen
  • Rainer Wohlfarth bei Docker Container – anzeigen, starten, stoppen und löschen
  • Rainer Wohlfarth bei Docker Container – anzeigen, starten, stoppen und löschen

Werbung

Archive

Kontakt, Datenschutz und Impressum

  • Kontakt
  • Datenschutz
  • Impressum

Schlagwörter

Anleitung Ansible Apache Apple App Store Automatisierung Blogparade C++ Centos centos 7 CentOS7 Container Datenbank DevOps Docker Dr. Racket Dr. Scheme funktional Gastartikel Google HowTo httpd Icinga2 Icinga 2 Installation itsm Linux Minecraft Monitoring mooc MySQL owncloud PHP Plugin Programmierung python Raspberry Pi Schritt für Schritt Server Sicherheit Tutorial Ubuntu Update Windows Wordpress

Copyright © 2025 · Outreach Pro on Genesis Framework · WordPress · Anmelden