Kubernetes Cluster mit Rancher RKE - Containerized

In unserem ersten Blogpost zu dem Thema Rancher Kubernetes Engine hatten wir bereits - wie immer :) - zahlreiche Verbesserungsideen.

Einige von diesen Ideen haben wir umgesetzt und wollen Euch hier zeigen, welche Ergebnisse wir erzielt haben.

Die erste Version

Zur Erinnerung: Es geht um die automatische Provisionierung eines Kubernetes-Clusters mit der Rancher Kubernetes Engine (RKE), Terraform und (natürlich!) Docker CE.

In der ersten Version haben wir die benötigten Ressourcen per Terraform in der Digital Ocean Cloud angelegt, mit einem Script die Config-Datei für RKE erstellt, und danach die Installation von RKE gestartet.

Dazu waren aber immer noch einige Vorbereitungen oder Zwischenschritte nötig, die wir aber mit Tool-Container eleganter abbilden wollten. Z.B waren das

  • Installation von Terraform auf dem lokalen Rechner
  • Installation von RKE zum Erzeugen des Kubernetes-Clusters
  • Installation von kubectl, um sich den entstandenen Kubernetes-Cluster anzuschauen
  • Manuelles erstellen und übertragen des SSH-Keys zum Zugriff auf die Digital Ocean Droplets
  • Erzeuge der Cluster-Konfiguration per Python-Script

Der neue Ansatz

Die verschiedenen Werkzeuge wollten wir lieber in Tool-Docker-Container bereitstellen. So bleibt das lokale System von einer umfangreichen Tool-Installation verschont, die zahlreichen anderen Vorteile von Container möchte ich diesmal nicht wieder aufzählen :)

Dazu brauchen wir einfach je Tool einen Container:

  • Terraform
  • RKE
  • kubectl

Die ersten beiden bauen wir selbst, für kubectl hatten wir der Einfachheit halber auf einen fertigen Container zurückgegriffen.

Terraform kann ja ein bisschen mehr als nur ein paar Droplets erzeugen. Für uns sollte Terraform daher auch

  • den generierten SSH-Key für Digital Ocean bereitstellen
  • mit Hilfe von Templates direkt die fertige Konfigurationsdatei (cluster.yml) für RKE erstellen, denn dort müssen ja primär die IP-Adressen der Droplets sowie der Pfad zum SSH-Key eingetragen werden.

Die Umsetzung

Container bauen

Zur Vereinfachung haben wir ein Makefile hinterlegt, so dass die Images einfach gebaut werden können:

make build baut also das Terraform-Image aus dem zugehörigen Dockerfile, make build-rke macht das gleiche für RKE.

Hier exemplarisch mal die Version für RKE:

FROM alpine:3.7
# Maintainer
LABEL maintainer="maintainers@bee42.com"

# Environment variables
ARG RKE_VERSION="v0.1.2"

# RKE-Installation
RUN apk --no-cache add wget ca-certificates  git bash openssh-client && \
    wget -O /usr/local/bin/rke https://github.com/rancher/rke/releases/download/${RKE_VERSION}/rke_linux-amd64 && \
    chmod +x /usr/local/bin/rke && \
    apk del --purge wget  && \
    rm -rf /var/cache/apk/*

ENV RKE_USER=rke \
    RKE_UID=1000 \
    RKE_GID=1000 \
    RKE_HOME=/rke

RUN addgroup -S $RKE_USER -g ${RKE_GID} \
    && adduser -S  \
    -g $RKE_USER \
    -h $RKE_HOME \
    -u ${RKE_UID} \
    $RKE_USER

USER $RKE_USER

WORKDIR $RKE_HOME

Wir Ihr seht, braucht Ihr für eine andere RKE-Version nur die Versionsnummer anzupassen und neu zu bauen. Getestet haben wir das ganze mit der zur Zeit aktuellen Version v0.1.2.

Das allmächtige Terraform…

Was vielleicht nicht alle wissen: Terraform besitzt einen spannenden Templating-Provider. Mit dessen Hilfe gelingt auch die Erzeugung der cluster.yml-Datei.

Als Besonderheit haben wir noch eingebaut, dass die Anzahl der ControlePlanes und Worker konfigurierbar ist.

variables.tf:


variable "worker_count" {
   description="Describes the amount of worker for the clusters"
   default=2
}

Für die Worker gibt es zunächst ein eigenes Template, in das die IP-Adressen eingebaut werden

template/worker.tpl


- address: ${worker_address}
  internal_address: ""
  role:
  - worker 
  hostname_override: ""
  user: root
  docker_socket: /var/run/docker.sock
  ssh_key: ""
  ssh_key_path: ""

So werden jetzt die IP-Adressen injiziert:

template.tf

data "template_file" "worker" {
 template = "${file("${path.module}/template/worker.tpl")}"
 count= "${var.worker_count}"
 vars {
   worker_address = "${element(digitalocean_droplet.worker.*.ipv4_address,count.index)}"
 }
}

Damit ist der Teil für die Worker fertig, diesen könnte man jetzt einfach ausgeben. Oder - und das machen wir im Folgenden - als Eingabe für ein weiteres Template verwenden:

template/cluster.tpl

nodes:
${controlplane}
${worker}
services:
  etcd:
    image: quay.io/coreos/etcd:latest
    extra_args: {}
#…

template.tf

data "template_file" "cluster" {
 template = "${file("${path.module}/template/cluster.tpl")}"
 vars {
   controlplane = "${join("\n",data.template_file.controlplane.*.rendered)}"
   worker = "${join("\n",data.template_file.worker.*.rendered)}"
   ssh_key_path ="${var.ssh_cluster_private_key}"
 }
}

So kann also in einem Arbeitsgang nicht nur die eigentliche Infrastruktur durch Terraform erstellt werden, sondern auch gleich die fertige cluster.yml mit beliebig vielen ControlPlanes und Workern generiert werden!

SSH-Key und die Datei cluster.yml werden danach extrahiert und dem RKE-Container übergeben.

Das Ergebnis

Mit wenigen Befehlen und viel Technologie lässt sich so ein Kubernetes-Cluster einfach provisionieren.

Nachdem die Images gebaut sind, müssen sie nur noch gestartet werden, und schon ist der K8s-Cluster verfügbar.

Hier unser kleines Script dazu, dass den Digital Ocean-Token als Parameter benötigt:

start.sh

docker run -it --rm -v tf:/tf --env DO_TOKEN=$1 bee42/terraform apply
docker run -it --rm -v tf:/tf --env DO_TOKEN=$1 bee42/terraform output cluster_template > cluster.yml
docker run -it --rm -v tf:/tf --env DO_TOKEN=$1 bee42/terraform output ssh_private_key > private_key
docker run -it --rm -v $(pwd):/rke -v $(pwd) /private_key:/tf/.ssh/cluster_ed25519 bee42/rke rke up --config cluster.yml
docker run -v $(pwd)/.kube_config_cluster.yml:/root/.kube/config ceroic/kubectl kubectl get nodes

Fazit

Im Unterschied zur ersten Lösung haben wir jetzt wieder einige weitere Ziele erreicht: Die Containerisierung, das Entfallen einiger Zwischenschritte und nebenbei auch ein etwas tieferer Einstieg in die Terraform-Templating-Engine!

Wenn Ihr Euch das genauer ansehen wollt: Auf Github steht alles bereit!

"Um unsere Webseite für Sie optimal zu gestalten und fortlaufend verbessern zu können, verwenden wir Cookies. Durch die weitere Nutzung der Webseite stimmen Sie der Verwendung von Cookies zu. Weitere Informationen zu Cookies erhalten Sie in unserer Datenschutzerklärung."