Kong & Deck. CI/CD

DECK

Deck to narzędzie, które pomaga zarządzać konfiguracją Konga w deklaratywny sposób. Konfigurację tę możemy w wygodny sposób przechowywać w repozytorium kodu. Deck odpowiada za synchronizację konfiguracji Kong umieszczonej w repozytorium kodu, z uruchomioną instancją Konga. Został stworzony głownie po to, aby w łatwy sposób można było zautomatyzować zarządzanie konfiguracją Kong w procesach CI/CD.

null

Funkcje Deck:

  • eksport bieżącej konfiguracji Kong do pliku konfiguracyjnego yaml. Funkcja przydatna do tworzenia kopi zapasowych
  • importowanie pliku konfiguracyjnego, który stworzyliśmy sami lub wcześniej wyeksportowaliśmy w celu zasilenia bazy danych z której korzysta Kong
  • analiza różnic pomiędzy konfiguracją zawartą w pliku, a bazą danych Kong
  • synchronizacja zmian pomiędzy konfiguracją w pliku konfiguracyjnym, a bazą danych Kong
  • walidacja konfiguracji. Funkcja przydatna, aby szybko zidentyfikować błędy konfiguracji
  • rozdzielenie konfiguracji na kilka plików, folderów z plikami

Podstawowe komendy Deck:

  • deck ping - sprawdzenie połączenia pomiędzy deck, a uruchomioną instancją Kong
  • deck diff - zbadanie różnić pomiędzy konfiguracją w pliku, a obecną instancją Kong
  • deck validate - walidacja konfiguracji
  • deck sync - synchronizacja konfiguracji

Więcej informacji o Deck m.in. instalacja, dostępne tutaj.

CI/CD

W tym wpisie przedstawię mechanizmy CI/CD z wykorzystaniem Deck oraz Github Actions.

Wymagania:

  • dostęp to Github
  • uruchomiona instancja Kong
  • dostęp do Kong z poziomu Github ( bardzo często nasza instancja Kong będzie działała wewnątrz organizacji, do której nie będziemy mieli dostępu z poziomu Github. W tym celu można wykorzystać Github’s self-hosted runners. W powyższym poście wykorzystałem właśnie to podejście)
  • zainstalowane narzędzie Docker
  • zainstalowane narzędzie decK (można również posłużyć się gotowym obrazem dockerowym)

PRZYGOTOWANIE PROJEKTU

Stworzenie folderów do przechowywania konfiguracji:

mkdir -p kong-deck-actions/kong
cd kong-deck-actions/kong/

Następnie eksportujemy bieżącą konfigurację Kong do pliku konfiguracyjnego - kong.yaml. Polecenie: (narzędzie decK mam zainstalowane na serwerze hosta, a deck uruchomiony lokalnie):

deck dump –kong-addr http://localhost:8001

W moim przypadku zawartość pliku konfiguracyjnego jest następująca:

_format_version: „1.1”

Kolejnym krokiem jest opublikowanie przygotowanej konfiguracji do zdalnego repozytorium Github.

KONFIGURACJA GITHUB ACTIONS

Następnie powinniśmy skonfigurować Github Actions, aby zautomatyzować proces wdrażania konfiguracji Kong. W tym celu musimy przygotować kilka plików w tym samym repozytorium Git, które stworzyliśmy w poprzednim kroku.

W pierwszej kolejności należy stworzyć plik o nazwie actions.yaml, który zawiera podstawową akcję do wykonania, bazując na obrazie dockerowym oraz zestawie parametrów do wykonania.

Zawartośc pliku action.yaml:

name: 'decK action'
description: 'Declarative Configuration management for Kong'
inputs:
  command:
    description: 'A decK ping command'
    required: true
    default: 'ping'
  kong_workspaces:
     description: 'Kong workspaces where config yaml file is located'
     required: true
     default: 'kong'
  options:
    description: 'Option parameters for a decK command'
    required: false
  runs:
    using: 'docker'
    image: 'Dockerfile'
  args:
     ${{ inputs.command }}
     ${{ inputs.kong_workspaces }}
     ${{ inputs.options }}

Przygotowujemy plik Dockerfile z którego korzysta wyżej zdefiniowany plik action.yaml. Zawartość pliku Dockerfile:

FROM kong/deck
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT [ „/entrypoint.sh” ]

Następnie tworzymy plik entrypoint.sh do którego jest odniesienie w Dockerfile. Zawartość entrypoint.sh:

#!/bin/sh -l
set -e -o pipefail
main (){
  cmd=$1
  dir=$2
  ops=$3
  if [ ! -e ${dir} ]; then
    echo${dir}: No such file or directory exists”;
    exit 1;
  fi
  echo „Executing: deck $cmd $ops -s $dir”
  deck $cmd $ops -s $dir
}

case $1 in
  „ping”) deck $1 $3;;
  „validate”|”diff”|”sync”) main $1 $2$3” ;;
  * ) echo „deck $1 is not supported.” && exit 1 ;;
esac

Uwaga! Ważne jest, aby nadać temu plikowi uprawnienie do wykonywania:

chmod +x entrypoint.sh

WORKFLOW

W kolejnym etapie powinniśmy przygotować pliki workflow, które będą odpowiedzialne za uruchomienie naszej akcji. Pliki workflow powinny być zdefiniowane pod ścieżka: „.github/workflow/”. Pierwszy plik o nazwie CI.yaml będzie odpowiedzialny za wykonanie akcji na Pull request Event, natomiast drugi – SYNC.yaml odpowiedzialny za wykonanie akcji jeśli wykonamy merge do brancha master.

Zawartość CI.yaml:

name: CI
on:
  pull_request:
    branches: [ master ]
jobs:
  build:
    runs-on: self-hosted
    steps:
     uses: actions/checkout@v2
      name: „checkout”
     name: decK ping
      id: decK_ping
      uses: ./
      with:
        command: „ping”
        options: „–kong-addr ${{ secrets.KONG_ADDR }}”
       name: decK validate
        id: decK_validate
        uses: ./
      with:
        command: „validate”
        options: „–kong-addr ${{ secrets.KONG_ADDR }}”
        kong_workspaces: „kong”
       name: decK diff
        id: decK_diff
        uses: ./
        with:
          command: „diff”
          options: „–kong-addr ${{ secrets.KONG_ADDR }}”
          kong_workspaces: „kong”

Przepływ ten odpowiada za wykonanie 4 akcji:

  • pobranie kodu źródłowego
  • wykonanie polecenia deck ping w celu potwierdzenie połączenia z Kong
  • wykonanie polecenia deck validate, aby potwierdzić poprawność konfiguracji
  • wykonanie polecenia deck diff, aby zobaczyć różnice pomiędzy konfiguracja w pliku, a zawartością bazy danych Kong

W pliku widać istnieje zmienna: secrets.KONG_ADDR, która możemy zdefiniować jako sekret w Github (Settings -> Secrets):

Komunikacja pomiędzy decK oraz Kong odbywa się między kontenerami zdefiniowanymi w domyślnej sieci bridge, dlatego w tym przypadku ustawiam adres IP kontenera Dockerowego, na którym uruchomiona jest instancja Kong.

null

Ostatnim krokiem tego etapu jest przygotowanie przepływu pracy odpowiedzialnego za synchronizację konfiguracji jeśli zmergujemy jakiekolwiek zmiany do brancha master.

Zawartość SYNC.yaml:

name: Sync
on:
  push:
    branches: [ master ]
jobs:
  build:
   runs-on: self-hosted
  steps:
    uses: actions/checkout@v2
     name: „checkout”
    name: decK ping
     id: decK_ping
     uses: ./
     with:
      command: „ping”
      options: „–kong-addr ${{ secrets.KONG_ADDR }}”
     name: decK validate
      id: decK_validate
      uses: ./
      with:
        command: „validate”
        options: „–kong-addr ${{ secrets.KONG_ADDR }}”
        kong_workspaces: „kong”
     name: decK sync
      id: decK_sync
      uses: ./
      with:
        command: „sync”
        options: „–kong-addr ${{ secrets.KONG_ADDR }}”
        kong_workspaces: „kong”

Przygotowany pliki publikujemy do zdalnego repozytorium.

TESTOWANIE

Na koniec możemy przetestować stworzone mechanizmy CI/CD. W tym celu należy stworzyć nowy branch np. git branch -b feature/addService, a następnie zmienić zawartość pliku kong.yaml:

_format_version: „1.1”
services:
 connect_timeout: 60000
  host: mockbin.org
  name: test_service
  port: 80
  protocol: http
  read_timeout: 50000
  retries: 5
  write_timeout: 50000
  routes:
   name: mocking
    paths:
   /mock
  path_handling: v0
  preserve_host: false
  protocols:
   http
   https
  regex_priority: 0
  strip_path: true
  https_redirect_status_code: 426

Następnie z poziomu Github należy otworzyć pull request do brancha maser. Powinny zostać uruchomione zadania zdefiniowane w pliku CI.yaml.

null

Jak widać deck wykonał określone kroki i w przejrzysty sposób mamy podgląd do konfiguracji, którą chcemy zmienić.

Ostatni krok to zmergowanie zmian.

null

PODSUMOWANIE

W artykule przestawiono przykładową implementację procesu CI/CD z wykorzystaniem narzędzi deck oraz GitHub. Oczywiście jest to tylko przykład, a wybór narzędzi jest dowolny. Podobny rezultat możemy również uzyskać z wykorzystaniem takich technologii jak Github, Jenskins oraz Ansible.