Komplettes Docker Feature Deployment – Digital Ocean, Rancher und Gitlab | Part 3

Im dritten Teil schauen wir uns aufsetzen von Rancher + Nodes mit Digital Ocean an um unsere Feature Branches Container einfach zu deployen. Ihr könnt dafür auch einen anderen Service nutzen, ich habe mich aber für Digital Ocean entschieden, da es am zuverlässigsten funktioniert.

Rancher

Rancher 2.x is a multi-cloud Kubernetes management platform. It is built on top of Kubernetes, and includes an upstream Kubernetes hyperkube distribution. Rancher 2 uses Docker as the underlying container runtime and utilizes Kubernetes to coordinate running containers between multiple discrete physical nodes. (Quelle: WIkipedia)

Wir kontrollieren/provisionieren also mit Rancher unsere Kühe, äh Container und verteilen diese falls nötig auf verschiedene Nodes.

Digital Ocean

Info: Falls Ihr schon mit AWS arbeitet, könnt Ihr auch das nutzen, müsst euch aber selbst durch die Doku kämpfen 🙂

Als erstes erstellen wir uns einen API KEY

Digital Ocean API Key

Diesen brauchen wir später für die Konfiguration oder die CLI. Außerdem solltet Ihr gleich euren SSH Key hinterlegen, falls noch nicht geschehen:

SSH Key in Digital Ocean anlegen

Und schon seid Ihr ready – simpel oder? Wenn du jetzt starten willst nutze einfach diesen Link – damit bekommst du 50$ Startguthaben. Das reicht für einige Tage an Tests mit +5 Nodes und Rancher. Oder 1-2 VMs für einen ganzen Monat.

Jetzt müssen wir nur noch die Nodes, VMs oder Droplets wie sie Digital Ocean nennt starten. Das machen wir aber nicht alles per Hand, sondern mit Terrform. Ganz einfach über die API und in nur wenigen Sekunden.

Rancher Cluster mit Terraform (Advanced)

Ja ich weiß – schon wieder ein neues Tool/Software. Aber hier könnt Ihr mit einer einfachen config ganz einfach Rancher und die entsprechenden Nodes konfigurieren. Das Repo dazu findet Ihr hier -> https://github.com/rancher/quickstart.git

Installiert euch erstmal terrform mit einer passenden binary:

https://www.terraform.io/downloads.html

Die schiebt Ihr dann z.B. in /usr/bin/ oder /usr/local/bin/

terraform --version

Wichtig: Die Version sollte mind. 0.12.0 sein – sonst funktioniert die terraform.tfvars Konfigurationdatei nicht.

Danach clonen wir uns das Repository von rancher in welchem wir schon alle nötigen Konfigurationsdateien finden und nur noch anpassen müssen.

git clone https://github.com/rancher/quickstart.git 
cd do
nano terraform.tfvars
# DigitalOcean API token
do_token = "DEIN DIGITAL OCEAN API KEY"
# Admin password to access Rancher
admin_password = "DEINPASSWORT"
# Name of custom cluster that will be created
cluster_name = "shopware"
# Resources will be prefixed with this to avoid clashing names
prefix = "micha"
# rancher/rancher image tag to use
rancher_version = "latest"
# Region where resources should be created
region = "fra1"
# Count of agent nodes with role all
count_agent_all_nodes = "1"
# Count of agent nodes with role etcd
count_agent_etcd_nodes = "0"
# Count of agent nodes with role controlplane
count_agent_controlplane_nodes = "0"
# Count of agent nodes with role worker
count_agent_worker_nodes = "0"
# Docker version of host running `rancher/rancher`
docker_version_server = "18.09"
# Docker version of host being added to a cluster (running `rancher/rancher-agent`)
docker_version_agent = "18.09"
# Droplet size
size = "s-2vcpu-4gb"
# DigitalOcean ssh-keyid: retrieve using `curl -s -X GET -H "Content-Type: application/json" -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/account/keys?per_page=200"  | jq -r '.ssh_keys[] | select(.name=="YOUR_KEY_NAME") | .id'`
# ssh_keys = [ "your_key_id" ]
# If this is not specified, you will get an email with the root password
ssh_keys = [ "2328941041" ]

Wichtig sind hier folgende Daten:

  • admin_password
  • do_token
  • region
  • size
  • ssh_keys

Die oder den SSH Key Ids holt Ihr euch mit:

 curl -s -X GET -H "Content-Type: application/json" -H "Authorization: Bearer $DEINAPITOKEN" "https://api.digitalocean.com/v2/account/keys?per_page=200"  | jq -r '.ssh_keys[] | select(.name=="$DEINKEYNAME") | .id'

Eventuell müsst Ihr noch jq installieren – das ist ein JSON processor, weil der Response ein JSON ist.

Nachdem Ihr alle Daten angepasst habt könnt Ihr einfach

terraform init
terraform apply

ausführen und es sollte folgendes erscheinen:

  Enter a value: yes

digitalocean_droplet.rancherserver[0]: Creating...
digitalocean_droplet.rancherserver[0]: Still creating... [10s elapsed]
digitalocean_droplet.rancherserver[0]: Still creating... [20s elapsed]
digitalocean_droplet.rancherserver[0]: Still creating... [30s elapsed]
digitalocean_droplet.rancherserver[0]: Still creating... [40s elapsed]
digitalocean_droplet.rancherserver[0]: Creation complete after 45s [id=163113385]
data.template_file.userdata_agent: Refreshing state...
digitalocean_droplet.rancheragent-all[0]: Creating...
digitalocean_droplet.rancheragent-all[0]: Still creating... [10s elapsed]
digitalocean_droplet.rancheragent-all[0]: Still creating... [20s elapsed]
digitalocean_droplet.rancheragent-all[0]: Still creating... [30s elapsed]
digitalocean_droplet.rancheragent-all[0]: Creation complete after 33s [id=163113462]

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

Outputs:

rancher-url = [
  "https://46.101.185.XXX",
]

Damit wurde der Rancher Server und ein Agent/Node gestartet und auch sofort in Digital Ocean sichtbar:

Digital Ocean Droplets (Rancher Server und Agent)

Über die Server URL können wir direkt zugreifen. Benutzername ist admin und das Passwort habt Ihr in der terraform.tfvars gesetzt.

Rancher 2.x Backend

Danach haben wir eine Übersicht über den Cluster (shopware) und über alle Nodes/Agents (hier erstmal nur einer)

Cluster
Nodes

Wenn Ihr die Droplets löschen wollt führt einfach terraform destroy –force aus und alles wird automatisch runtergefahren und dann gelöscht.

Rancher Cluster direkt in Digital Ocean (Beginner)

Die einfache Variante eignet sich gut zum testen, wenn man nicht unbedingt 10 Nodes und Endpunkte konfigurieren muss.

Docker Droplet erstellen

Am besten deployed Ihr das ganze mit einer passenden Domain, da Ihr sonst selbst mit dem SSL Cert dealen müsst. Mit der Option –acme-domain macht das Certbot für euch.

# Login über SSH auf die IP (vergesst euren SSH Key nicht in DO einzutragen)
ssh root@11.11.11.11

# Rancher Container bauen und die passende URL mitgeben
docker run -d --restart=unless-stopped -p 80:80 -p 443:443 -v /host/rancher:/var/lib/rancher rancher/rancher:latest --acme-domain rancher.DEINEDOMAIN.de

Danach tragt Ihr bei eurem Hoster die IP des Servers als A Record ein (am besten vorher, da die TTL ja meist 5-15 min ist). Ruft die URL auf und tragt euer Passwort ein und fügt einen Cluster hinzu:

Danach wählen wir noch Endpunkt, Größe und Image aus:

Danach sollten wir das folgende in Digital Ocean sehen und unser Setup ist ready für Gitlab 🙂

Digital Ocean Übersicht

Gitlab CI

So nun haben wir unsere Framework Infrastruktur fertig gebaut (Dockerfiles + docker-compose.yml), unser Reverse Proxy ist ready und Rancher ist bereit um die Container zu deployen. Alles was jetzt noch fehlt ist die Gitlab CI in einem passenden Repository.

Solltet Ihr noch keins haben könnt Ihr euch das kostenlos auf https://gitlab.com/users/sign_in#register-pane anlegen. Sobald das fertig ist, richten wir unseren Kubernetes Cluster von Rancher auf – richtig – Rancher setzt seit der Version 2.0 ebenfalls auf Kubernetes auf.

Kubernetes/Rancher Cluster einrichten

Erstmal holen wir uns die Konfiguration vom Cluster:

Advanced

Hier brauchen wir die Agent URL, das Zertifikat. Wichtig – nehmt hier auf jeden Fall die AGENT URL + Zertifikat – sonst bekommt Ihr einen Fehler beim installieren von HELM.

Beginner

Wenn Ihr den einfachen Weg mit Rancher gegangen seid müsst Ihr die Daten direkt vom Cluster setzen:

Und wir brauchen noch einen Secret Key den wir uns auch in Rancher generieren:

Das ganze tragen wir dann in Gitlab unter Operations -> Kubernetes ein.

Kubernetes Cluster in Gitlab
Konfiguration eines Kubernetes Clusters in Gitlab

Wichtig: Entfernt den Haken bei Gitlab Managed cluster, sonst könnt Ihr kein HELM installieren.

Installiert danach HELM und darauf den Gitlab Runner:

Danach solltet Ihr nun in Rancher unter Projects einen neuen Namespace sehen:

und ein docker ps auf dem agent Server zeigt die Container für den Gitlab Runner und HELM Tiller. Sweet!

Gitlab Runner

Um Pipelines auszuführen braucht Ihr Runners – diesen haben wir eben hinzugefügt. Ich empfehle euch die öffentlichen Runner zu deaktivieren und euren eigenen Runner zu nutzen. Passwörter solltet Ihr sowieso in Variablen übergeben, aber es kann dabei immer was durchsickern..

Und wenn wir gerade hier sind, fügen wir auch gleich unsere Rancher Url, Secret und Key ein:

Rancher Variablen setzen
RANCHER_URL=http://RANCHER_HOST_IP:8080/
RANCHER_ACCESS_KEY=...
RANCHER_SECRET_KEY=...

.gitlab-ci.yml

Jetzt beginnt der eigentliche Spaß! Ich war hier nun auch wieder sicher 30min am debuggen und googeln bis ich eine Lösung gefunden habe. Gitlab und andere Services wie Rancher arbeiten immer „on the edge“. Sprich nicht immer sind sie mit den neusten Docker Images kompatibel:

variables:
    # URL for later
    DOMAIN: $CI_COMMIT_REF_SLUG.$CI_PROJECT_NAME.michahobert.de
    # Image Name + Tag
    IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
    # Future Rancher Stack Name
    STACK: $CI_PROJECT_NAME-$CI_COMMIT_REF_SLUG

stages:
    - build
    - deploy


build:
    image: docker:latest
    stage: build
    variables:
        DOCKER_DRIVER: overlay
        DOCKER_HOST: tcp://localhost:2375
    services:
        - docker:18.09.7-dind
    only:
        - branches
    before_script:
        - docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN $CI_REGISTRY
        - docker pull $IMAGE || true
    script:
        - docker build --pull -t $IMAGE -f docker/php/Dockerfile .
        - docker push $IMAGE

Da der Gitlab Runner noch nicht auf die neuste Version vom Docker-in-Docker (dind) Container angepasst war, kam es hier zu einem Fehler mit dem Socket:

Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

Also wurde docker:dind mit docker:18.09.7-dind ausgetauscht, aber weiter im Text…

Unsere Pipeline läuft nun wie gewünscht durch und das ganze sieht dann wie folgt aus:

Gitlab Pipeline

Schreibe einen Kommentar

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