Von 0 auf Kubernetes - Aufbau einer Kubernetes-CI/CD-Infrastruktur per GitLab-Pipeline - Teil 3 - Starten der Services

titelbild-rancher-services

Ansible, Terraform, GitLab und etwas Magie: Wie ich eine ganze Infrastruktur auf Knopfdruck erstelle.

In dieser Serie möchte ich euch zeigen, wie ihr automatisiert ein Kubernetes-Cluster aufbaut, ein GitLab mit GitLab-Runner installiert und eine eigene Docker-Registry zur Verfügung stellt. Das Ziel wird sein, dass ihr eure Anwendungen direkt aus dem GitLab heraus in eurem Cluster bauen und starten könnt.

Im dritten Teil dieser Serie zeige ich euch, wie wir die im zweiten Teil definierten Services auf unserem Zielsystem starten lassen können.

Rückblick

Im zweiten Teil haben wir uns eine docker-compose.yml erstellt, in der wir vier Services definiert haben: GitLab mit seiner Datenbank, eine Docker-Registry und Traefik. Sie alle liegen in demselben Docker-Netzwerk und werden mit Traefik automatisch über die zugehörigen Hostnames freigegeben.

Unser Ziel für diesen Teil

In diesem Teil wollen wir eine zweite Ansible-Rolle erstellen, die zuerst Docker-Compose installieren, dann unsere docker-compose.yml auf das Zielsystem kopieren und anschließend unsere Services starten kann. Zusätzlich müssen wir uns für GitLab ein API-Token generieren, welches wir zur Authentifizierung innerhalb der Konfiguration in einem späteren Teil benötigen.

Unsere zweite Ansible-Rolle

Für unsere zweite Ansible-Rolle, der ich den Namen gitlab gegeben habe, benötigen wir eine ähnliche Ordnerstruktur wie die der ersten Rolle. Der Pfad unserer neuen main.yml sollte also wie folgt lauten:

ansible-setup/roles/gitlab/tasks/main.yml

Vorbereitungen zum Start der Services

- name: Install docker-compose 
  get_url: 
    url: "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-Linux-x86_64" 
    dest: /usr/local/bin/docker-compose 
    mode: '0777' 

- name: Stop services with docker-compose if running 
  command: docker-compose down 
  async: 600 
  poll: 5 
  ignore_errors: true 

- name: Delete all container data 
  file: 
    path: /home/ubuntu/{{ item }} 
    state: absent 
  with_items: 
    - database 
    - gitlab 
    - registry 

- name: Copy docker-compose.yml 
  copy: 
    src: ./roles/gitlab/docker-compose.yml 
    dest: /docker-compose.yml 
    mode: '0666' 

- name: Create conf dir 
  file: 
    path: /conf 
    state: directory 
    mode: '0755' 

- name: Copy traefik.yml 
  copy: 
    src: ./roles/gitlab/traefik.yml 
    dest: /conf/traefik.yml 
    mode: '0666'  

Mithilfe dieser Tasks installieren wir Docker-Compose, kopieren die docker-compose.yml auf das Zielsystem und legen eine Konfigurationsdatei für Traefik an. Zuerst laden wir per Modul get_url Docker-Compose in der Version 1.27.4 herunter und erlauben per mode die Ausführung.

Als Nächstes müssen wir uns Folgendes überlegen: Wie wollen wir reagieren, wenn wir unsere spätere Pipeline mehrmals ausführen? Oder anders ausgedrückt: Wie soll unsere Ansible-Rolle agieren, wenn die Infrastruktur bereits läuft? Ich habe mich dazu entschieden, dass die Pipeline bei jedem Durchlauf bereits existierende Daten löschen und somit die gesamte Infrastruktur komplett neu aufbauen soll. Daher führe ich zuerst über das Modul command ein docker-compose down aus. Dies beendet unsere Services, falls sie bereits laufen sollten und falls überhaupt eine docker-compose.yml existiert. Da dies bei der ersten Ausführung der Pipeline selbstverständlich nicht der Fall sein wird, würde dieser Aufruf zu einem Fehler führen und Ansible würde die Ausführung abbrechen. Damit dies im Fehlerfall nicht passiert, markieren wir diesen Task mit ignore_errors: true. Da das Beenden einiger Services teilweise einige Zeit in Anspruch nimmt, könnte Ansible an dieser Stelle ein Timeout erreichen. Um dies zu vermeiden, arbeiten wir hier mit async und poll. Daraufhin löschen wir alle Verzeichnisse, die wir in der docker-compose.yml als Volumes verwendet haben. Auf diese Weise haben wir alle Spuren unserer bisher laufenden Services beseitigt.

Nun können wir mit dem copy-Modul die docker-compose.yml auf das Zielsystem kopieren (eine bereits existierende Datei würde hier überschrieben werden). Zusätzlich erstellen wir noch das Verzeichnis /conf, welches wir als Volume für Traefik verwenden. In dieses Verzeichnis kopieren wir analog zur docker-compose.yml eine traefik.yml, die ich erst in einem späteren Teil dieser Anleitung besprechen werde. In dieser Datei werden wir Traefik im Zusammenhang mit unserem Kubernetes-Cluster konfigurieren.

Start der Services

- name: Run services with docker-compose 
  command: docker-compose up -d 
  async: 600 
  poll: 5 
 
- name: Create gitlab api token 
  command: > 
    docker exec -it gitlab gitlab-rails runner "token = 
    User.find_by_username('root').personal_access_tokens.create(scopes: 
    [:api, :read_user, :read_api, :read_repository, :write_repository, :sudo], 
    name: 'automation_token'); token.set_token('super_save_api_token'); token.save!"  

Nun starten wir unsere Services über das command-Modul per docker-compose up -d. Wie wir in Teil 2 sichergestellt haben, wird dieser Befehl so lange benötigen, bis alle Services erfolgreich gestartet wurden und bereit sind. Um ein Timeout seitens Ansible zu vermeiden, kommen hier ebenfalls async und poll zum Einsatz. Um auch die spätere Konfiguration GitLabs automatisieren zu können, benötigen wir noch ein API-Token mit vollen Admin-Rechten. Dieses können wir mit GitLabs gitlab-rails Konsole erstellen. Wir führen also ebenfalls über das command-Modul einen Befehl im GitLab-Container aus und erstellen somit ein Token für den Root-User.

Zusammenfassung

In diesem Teil haben wir uns eine weitere Ansible-Rolle erstellt, die unsere Docker-Services startet, nachdem sie die docker-compose.yml auf das Zielsystem kopiert hat. Vor dem Start räumen wir noch alle Spuren eventuell laufender Services auf und nach dem Start erstellen wir ein API-Token, welches uns später die Konfiguration GitLabs ermöglicht.

Im vierten Teil dieser Anleitung werden wir unser Inventory und unser erstes Ansible-Playbook erstellen. Im Playbook werden wir die bisher geschriebenen Ansible-Rollen verwenden und damit unsere erste ausführbare Einheit fertiggestellt haben.

By accepting you will be accessing a service provided by a third-party external to https://blog.ordix.de/