Wer sich mit Kubernetes beschäftigt der kommt irgendwann auch einmal an den Punkt, an dem er darüber nachdenkt wie man seine(n) Cluster einfacher verwalten kann. Kubernetes selbst sehe ich eher als Framework als als eine vollständige Lösung. Zu viele Punkte sind unbeachtet und müssen nachgearbeitet werden.
Im Unternehmensumfeld hat sich sicherlich OpenShift ziemlich gut etabliert - für mich auch eine wirklich schicke Lösung. Allerdings trifft es nicht immer den Geschmack den man haben möchte. So zum Beispiel will viele Dinge nicht haben die OpenShift mir bietet, wenn ich zum Beispiel nur einen Cluster betreibe der einfache Workloads abfangen möchte.
An dieser Stelle kommt Rancher ins Spiel. Die Firma dahinter hat ihre Produkte sauber voneinander getrennt, sodass man nutzen kann was man grade braucht - oder eben man setzt komplett auf das Pferd das einem geboten wird.
In meinem Fall tue ich das, da ich keinen Grund sehe auf die Annehmlichkeiten zu verzichten die es mir bringt.
Wer nun einen Kubernetes Cluster mit Hilfe von RKE installieren möchte und zusätzlich auch noch die Verwaltungssoftware Rancher installiert haben will: der darf jetzt weiterlesen! Ich nutze wie so oft ein CentOS Linux auf meinen Servern.
Zunächst einmal stellen wir sicher, dass wir auch die Docker CE Version installiert haben und die notwendigen Softwarepakete an Board sind.
yum remove -y docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install docker-ce docker-ce-cli containerd.io
als nächstes aktivieren wir den Docker-Dienst.
systemctl start docker
systemctl enable docker
systemctl status docker
Sobald das geschehen ist, legen wir einen neuen Benutzer an und sorgen dafür, das unser SSH-Public-Key hinterlegt wird.
useradd -m -G docker rke
mkdir /home/rke/.ssh
echo "ssh-rsa 111111111111122222222222223333333333444444444445555555566666666667777777777777778888888888 keiner@aol.com" >> /home/rke/.ssh/authorized_keys
chmod -vR 700 /home/rke/.ssh
chown -vR rke: /home/rke/.ssh
Weil wir ordentlich sind sorgen wir natürlich auch dafür, dass wir die Firewall nutzen und firewalld so konfigurieren, dass er alle unsere Ports für Kubernetes durchlässt
firewall-cmd --zone=public --add-port=6443/tcp --permanent
firewall-cmd --zone=public --add-port=2376/tcp --permanent
firewall-cmd --zone=public --add-port=2379/tcp --permanent
firewall-cmd --zone=public --add-port=2380/tcp --permanent
firewall-cmd --zone=public --add-port=9099/udp --permanent
firewall-cmd --zone=public --add-port=10250/tcp --permanent
firewall-cmd --zone=public --add-port=80/tcp --permanent
firewall-cmd --zone=public --add-port=443/tcp --permanent
firewall-cmd --zone=public --add-port=8472/tcp --permanent
firewall-cmd --zone=public --add-port=10254/tcp --permanent
firewall-cmd --zone=public --add-port=30000-32767/tcp --permanent
firewall-cmd --zone=public --add-port=30000-32767/udp --permanent
firewall-cmd --reload
Das coole an dem ganzen modernen Kram ist ja, das er darauf ausgelegt ist die Systeme reproduzierbar zu bauen. Das heisst auch, dass man alles was zur Einrichtung etc notwendig ist extern in einem Repository einchecken können muss (zum Beispiel). Daher erstellen wir uns nun einen neuen Ordner in dem wir alles sammeln was mit der Einrichtung, der Wartung und Administration des Clusters zu tun hat - samt der Binary die wir verwenden
mkdir rke-cluster
cd rke-cluster
wget https://github.com/rancher/rke/releases/download/v0.2.4/rke_linux-amd64
mv rke_linux-amd64 rke
Sobald wir das getan haben, erstellen wir auch einen weiteren SSH-PublicKey, den wir auf den Clusterteilnehmern verteilen. Das hat nochmal ein schickes Geschmäkle, weil es nicht nur allein unserer ist der zum Arbeiten genutzt wird. Dazu einfach den obigen Schritt nochmals durchführen der in die Datei /home/rke/.ssh/authorized_keys schreibt.
ssh-keygen -f rke-cluster -b 4096
Anschließend brauchen wir noch eine Konfigurationsdatei für RKE, welche unseren kompletten Cluster darstellt. Mit allen Nodes und Einstellungen und so weiter. Wer einfach starten will, der nimmt sich die minimal Konfiguration von hier oder führt den Befehl ./rke config --empty --name cluster.yml aus. In meinem Fall sieht das Ding dann ungefähr so aus:
cluster.yml
nodes:
- address: "rancher1"
port: "22"
role:
- controlplane
- etcd
user: rke
ssh_key_path: ./rke-cluster
labels:
app: ingress
- address: "rancher2"
port: "22"
role:
- controlplane
- etcd
user: rke
ssh_key_path: ./rke-cluster
labels:
app: ingress
- address: "rancher3"
port: "22"
role:
- controlplane
- etcd
user: rke
ssh_key_path: ./rke-cluster
labels:
app: ingress
services:
kube-api:
image: ""
extra_args: {}
extra_binds: []
extra_env: []
service_cluster_ip_range: 10.43.0.0/16
service_node_port_range: ""
pod_security_policy: true
always_pull_images: false
kube-controller:
image: ""
extra_args: {}
extra_binds: []
extra_env: []
cluster_cidr: 10.42.0.0/16
service_cluster_ip_range: 10.43.0.0/16
kubelet:
image: ""
extra_args: {}
extra_binds: []
extra_env: []
cluster_domain: cluster.local
infra_container_image: ""
cluster_dns_server: 10.43.0.10
fail_swap_on: false
network:
plugin: flannel
options:
flannel_iface: eth0
flannel_backend_type: vxlan
authentication:
strategy: x509
sans: []
webhook: null
addons: ""
addons_include: []
system_images:
etcd: rancher/coreos-etcd:v3.2.24-rancher1
alpine: rancher/rke-tools:v0.1.28
nginx_proxy: rancher/rke-tools:v0.1.28
cert_downloader: rancher/rke-tools:v0.1.28
kubernetes_services_sidecar: rancher/rke-tools:v0.1.28
kubedns: rancher/k8s-dns-kube-dns:1.15.0
dnsmasq: rancher/k8s-dns-dnsmasq-nanny:1.15.0
kubedns_sidecar: rancher/k8s-dns-sidecar:1.15.0
kubedns_autoscaler: rancher/cluster-proportional-autoscaler:1.0.0
coredns: rancher/coredns-coredns:1.2.6
coredns_autoscaler: rancher/cluster-proportional-autoscaler:1.0.0
kubernetes: rancher/hyperkube:v1.13.5-rancher1
flannel: rancher/coreos-flannel:v0.10.0-rancher1
flannel_cni: rancher/flannel-cni:v0.3.0-rancher1
weave_node: weaveworks/weave-kube:2.5.0
weave_cni: weaveworks/weave-npc:2.5.0
pod_infra_container: rancher/pause:3.1
ingress: rancher/nginx-ingress-controller:0.21.0-rancher3
ingress_backend: rancher/nginx-ingress-controller-defaultbackend:1.4-rancher1
metrics_server: rancher/metrics-server:v0.3.1
ssh_key_path: ~/rke-cluster
ssh_agent_auth: false
authorization:
mode: rbac
options: {}
ignore_docker_version: false
kubernetes_version: ""
private_registries: []
ingress:
provider: ""
options: {}
node_selector:
app: ingress
extra_args: {}
cluster_name: ""
monitoring:
provider: ""
options: {}
restore:
restore: false
snapshot_name: ""
dns: null
Das ist aber natürlich jedem selbst überlassen - ich mag es einfach, wenn ich so viel wie möglich von dem sehen kann, was los ist und was ich einstellen kann. Allerdings ist das auch weitaus mehr, als man minimal braucht. Wer sich mal die Beispiele anschaut wird merken, dass man hier ziemlich freue Hand hat.
Da wir jetzt so weit sind, starten wir das Setup mit einem einfachen
./rke up
Wenn das durchgelaufen ist, sollten wir einen funktionierenden Cluster haben. Während der Einrichtung wurden auch ein paar weitere Dateien erstellt. Diese sind wichtig. Testen kann man seinen Cluster nun wie folgt
export KUBECONFIG=$(pwd)/kube_config_cluster.yml
kubectl get nodes
Wer so richtig fancy mit seinem Cluster angeben will, der installiert sich auch Helm. Denn dann kann man noch einfacher die unterschiedlichsten Weichwaren installieren und damit total gut angeben. Abgesehen davon brauchen wir es um die Rancher Verwaltung zu installieren.
wget https://get.helm.sh/helm-v2.14.1-linux-amd64.tar.gz
gunzip helm-v2.14.1-linux-amd64.tar.gz
mv linux-amd64 helm
rm helm-v2.14.1-linux-amd64.tar
kubectl -n kube-system create serviceaccount tiller
kubectl create clusterrolebinding tiller --clusterrole=cluster-admin --serviceaccount=kube-system:tiller ./helm init --service-account tiller
Ist diese Aufgabe durchgelaufen, kann es auch schon losgehen mit der Installation von Rancher.
./helm repo add rancher-alpha https://releases.rancher.com/server-charts/alpha
./helm/helm repo update
./helm/helm install rancher-latest/rancher --name rancher --namespace cattle-system --set hostname=k8s.MEINETOLLEDOMAIN.de
Wenn man angeben will, dann macht man sich sofort daran LDAP einzurichten um Benutzerauthentifizierung zu haben und natürlich aktiviert man auch das Monitoring. Backup ist auch keine schlechte Sache, auch wenn einem die Cloud-Dingsis immer vermitteln, das man das nicht mehr haben will. So kann man doch arbeiten.
Quellen und Verweise
In meinem aktuellen Monitoringsetup habe ich festgestellt, dass die ausgiebige Verwendung von SNMP zu einigen False/Positives führte. Das nervt gewaltig und ist zudem auch noch ziemlich unbequem.
Daher habe ich mich an eine Ansible-Rolle gemacht, welche meine Hosts vorbereitet zukünftig NRPE zu nutzen. Um es besser nachvollziehen zu können, welche Schritte gegangen werden müssen habe ich das ganze hier einmal niedergeschrieben.
yum Install nrpe.x86_64 nrpe-selinux.x86_64 nagios-plugins-*
Anschließend muss die Datei /etc/nagios/nrpe.conf angepasst werden. Standardmässig ist nur das ausführen von Commands ohne Parameter erlaubt. Daher will ich das ändern um mehr Flexibilität bei der Anpassung der Rahmenparameter zu haben. Damit mir das nicht auf die Füße fällt muss der Wert von dont_blame geändert werden. Damit mir aber niemand dazwischen funkt, schränke ich die Hosts ein, die Checkscommands aufrufen dürfen - dazu dient allowed_hosts. Zum Schluss werden noch lokale Commands definiert. Diese sind notwendig und müssen für alle gewünschten Checks eingerichtet werden. Andernfalls kann NRPE nicht tun wofür es da ist (Nagios Remote Plugin Execution). Die Betonung liegt hier ganz klar auf Remote und Execution.
dont_blame_nrpe=1
allowed_hosts=127.0.0.1,192.168.X.X
command[check_users]=/usr/lib64/nagios/plugins/check_users -w $ARG1$ -c $ARG2$
command[check_load]=/usr/lib64/nagios/plugins/check_load -w $ARG1$ -c $ARG2$
command[check_disk]=/usr/lib64/nagios/plugins/check_disk -w $ARG1$ -c $ARG2$ -u GB -E -p $ARG3$
command[check_mailq]=/usr/lib64/nagios/plugins/check_mailq -w $ARG1$ -c $ARG2$
command[check_ntp_peer]=/usr/lib64/nagios/plugins/check_ntp_time -w $ARG1$ -c $ARG2$ -H $ARG3$
command[check_procs]=/usr/lib64/nagios/plugins/check_procs -w $ARG1$ -c $ARG2$
command[check_procs_zombie]=/usr/lib64/nagios/plugins/check_procs -w $ARG1$ -c $ARG2$ -s Z
command[check_procs_named]=/usr/lib64/nagios/plugins/check_procs -w $ARG1$ -c $ARG2$ -C named
command[check_procs_java]=/usr/lib64/nagios/plugins/check_procs -w $ARG1$ -c $ARG2$ -C java
command[check_procs_apache]=/usr/lib64/nagios/plugins/check_procs -w $ARG1$ -c $ARG2$ -C apache
command[check_procs_httpd]=/usr/lib64/nagios/plugins/check_procs -w $ARG1$ -c $ARG2$ -C httpd
command[check_procs_platform]=/usr/lib64/nagios/plugins/check_procs -w $ARG1$ -c $ARG2$ -C platform
command[check_procs_dhcpd]=/usr/lib64/nagios/plugins/check_procs -w $ARG1$ -c $ARG2$ -C dhcpd
command[check_procs_qemu]=/usr/lib64/nagios/plugins/check_procs -w $ARG1$ -c $ARG2$ -C qemu
command[check_procs_mysqld]=/usr/lib64/nagios/plugins/check_procs -w $ARG1$ -c $ARG2$ -C mysqld
command[check_sensors]=/usr/lib64/nagios/plugins/check_sensors
command[check_smtp]=/usr/lib64/nagios/plugins/check_smtp -H $ARG1$
command[check_swap]=/usr/lib64/nagios/plugins/check_swap -w $ARG1$ -c $ARG2$
command[check_security_updates]=/usr/lib64/nagios/plugins/check_updates --security-only -t 30
Nun sind wir fast fertig. Für müssen nun nur noch unserem icinga Monitoring-Server mitteilen, dass es doch bitte ein neues Checkcommand kennt und zum anderen natürlich noch einen zu monitorenden Service daraus machen. Anschließend wird der angegebene Dienst per NRPE auf dem neu installierten Host überwacht.
define command {
command_name check_nrpe
command_line /usr/lib/nagios/plugins/check_nrpe -H $ARG1$ -c $ARG2$ -a $ARG3$
}
$ARG1$ wird zum Hostnamen
$ARG2$ wird zum Command das auf dem Server definiert wurde (sehe oben)
$ARG3$ wird zu den Schwellwerten für Warning und Critical
define service {
hostgroup_name nrpe
service_description Check users on system
check_command check_nrpe!$HOSTNAME!check_users!2 5!
use generic-service
}
So zumindest erscheint es mir immer mehr und vor allem immer wieder. Das bewusstsein, dass es sich dabei nur um "somebody else computer" handelt scheint weitestgehend zu verschwinden. Umso lustiger ist es dann für mich, wenn man mit den ganzen Fehlerhaften annahmen aufräumen kann. das heißt dann auch, dass man mal bei einem Outtake schauen kann, was da so los ist.
Heute ist so ein Denkwürdiger Tag. Die Amazon S3 Cloud hat Schluckauf und die darin genutztne mehr als 143,000 Webseiten ebenso.