This is an old revision of the document!


Laboratorul 04 - Docker Swarm NFS. Kong API Gateway

Introducere Laborator

In acest laborator vom discuta despre utilizarea volumelor NFS (network file system) la nivel de Docker Swarm si despre folosirea uneltei declarative Kong pentru crearea de API Gateway-uri mult mai eficient.

Laboratorul se va desfasura, din nou, pe Play With Docker si va avea suport de cod repo-ul din laboratorul precedent, peste care am mai adaugat 2 fisiere .yml in plus (stack-nfs.yml si stack-kong.yml).

Docker NFS

Din pacate, infrastructura de la Play with Docker nu permite realizarea unui demo practic care sa ilustreze folosirea volumelor NFS, avand limitari la nivel de comunicatie inter-masini

In contextul Docker Swarm, nu mai exista un singur host, ci multiple noduri conectate in retea. Acest lucru face ca folosirea volumelor locale sa fie o practica rea, deoarce orchestrarea unui task pe un nod care nu are volumul cerut de containerul taskului va rezulta in rejectarea acelui task.

Exista 2 posibiltati de reparare a acestei probleme:

  • Constrangerea unor servicii sa ruleze doar pe noduri manager
services:
  example:
    deploy:
      placement:
        constraints: [node.role == manager]

Aceasta practica este utila atunci cand exista doar un nod manager (si astfel sunteti siguri ca taskurile ale caror containere au nevoie de volumele definite in configuratie vor rula doar pe managerul unde exista volumele)

In cazul in care exista mai multe noduri manager si vreti, de exemplu, sa rulati o baza de date, daca aceasta va fi orchestrata sa ruleze pe alt nod fata de care a fost prima oara orchestrata, baza de date nu va mai avea acces la volumul unde a stocat date initial si va crea unul nou, ajungandu-se, deci, la neconsistenta

  • Utilizarea volumelor NFS

Server NFS

Un server NFS poate fi rulat, fie nativ, fie folosind Docker. Exista multiple solutii de rulare a unui server NFS folosind Docker, insa noi va recomandam aceasta solutie populara bazata pe Alpine Linux.

Solutia de mai sus reprezinta un container care ruleaza in mod privilegiat, avand acces la resursele gazdei. Inainte sa rulati containerul, trebuie sa va creati un folder ce va fi partajat in retea.

Folderul nu trebuie sa fie de tipul OverlayFS

Pentru a vedea sistemul de fisiere, executati comanda df -Th (pe linux)

Dupa ce ati creat folderul ce va retine datele partajate in retea, executati comanda

docker run -d --name nfs --privileged -v /cale/catre/folderul/creat:/nfsshare -e SHARED_DIRECTORY=/nfsshare itsthenetwork/nfs-server-alpine:latest

Utilizarea Volumelor NFS

Pentru a utiliza volumele partajate, este nevoie sa faceti modificari in configuratia volumelor din cadrul fisierelor .yml. Ca si exemplu, vom folosi o baza de date care are nevoie de volum pentru scriptul de configuratie si pentru persistenta datelor.

services:
  db:
    image: postgres:12
    volumes:
      - db-data-nfs:/var/lib/postgresql/data
      - db-config-nfs:/docker-entrypoint-initdb.d

volumes:
  db-data-nfs:
    driver: local
    driver_opts:
      type: nfs4
      o: "addr=IP_NFS,rw"
      device: ":/database/data"
  db-config-nfs:
    driver: local
    driver_opts:
      type: nfs4
      o: "addr=IP_NFS,rw"
      device: ":/database/config"

IP_NFS este ip-ul masinii pe care ruleaza containerul NFS

Directoarele /database/data si /database/config trebuie sa existe in interiorul directorului partajat de gazda containerului de server NFS (adica /cale/catre/folderul/creat din exemplul precedent)

Kong Api Gateway

In cadrul laboratorului precedent, ati vazut beneficiile unui API Gateway:

  • expune rute din aplicatie
  • functioneaza ca un punct central de acces in sistem

Cu toate astea, implementarea programatica a unui API Gateway necesita timp si, de multe ori, munca depusa implica scriere repetitiva de cod.

Kong este unul dintre liderii din domeniul Cloud in materie de solutii de API Gateway declarative. Kong este nativ Docker, si nu necesita scriere de cod, ci doar furnizarea unei configuratii (sau configurarea on-the-fly prin cereri HTTP).

Kong functioneaza ca un serviciu de Docker si intercepteaza traficul venit, in functie de regulile mentionate, si apoi il redirecteaza catre alte servicii.

Arhitectura Implementata

Arhitectura este identica cu cea a exercitiului din laboratorul precedent, insa, in loc de API Gateway programatic, vom folosi Kong. In plus, vom expune si serviciul Adminer tot prin intermediul Kong.

Comportamentul dorit va fi ca, in urma apelului IP_PUBLIC/api/books sa interactionam cu serviciul books (POST/GET) si in urma apelului IP_PUBLIC/adminer sa interactionam cu serviciul adminer.

Implementare Kong

Kong poate fi rulat atat in modul DB-on cat si in modul DB-less. Noi vom folosi abordarea DB-less, furnizand o configuratie bazata pe un fisier .yml. In modul DB-on, Kong mai foloseste o baza de date si configuratia se face pe baza de cereri POST catre api-ul intern de configurare.

Fisierul de Configuratie
_format_version: "2.1"

services:
  - name: books-service
    url: http://lab4-cluster_books-service/api
    plugins:
      - name: key-auth
    routes:
      - name: books-service-route
        paths: 
          - /api/books
          
  - name: db-adminer
    url: http://lab4-cluster_adminer:8080
    routes:
      - name: adminer-service
        paths:
          - /adminer

consumers:
  - username: lab-student
    keyauth_credentials:
      - key: mobylab
  • Services - reprezinta ce servicii se vor conecta la Kong pentru interceptare si forwardare de trafic
  • Consumers - reprezinta ce optiuni se pot seta fiecarui serviciu, in functie de plugin (este optional, si se foloseste doar in contextul pluginurilor)

Fiecare serviciu trebuie sa aiba obligatoriu definite urmatoarele: name, url, routes

  • services → name - numele serviciului din punct de vedere al configurarii rezultate. Trebuie sa fie unic.
  • services → url - calea de comunicare cu serviciul de docker. In cazul nostru, reprezinta ruta din interioriul serviciilor de docker, unde se vor forwarda cererile HTTP.

Observati ca in URL se precizeaza NUME-STIVA_NUME_SERVICIU_DOCKER, in loc de ip.

  • services → routes - rutele pe care se va mapa traficul din exterior
  • services → routes → name - numele rutei din punct de vedere al configurarii rezultate. Trebuie sa fie unic.
  • services → routes → path - calea de comunicare din exterior, care se va mapa pe ruta furnizata in url

Plugins sunt optionale, insa am vrut sa va demonstram utilizarea unui plugin de autorizare pe baza de apikey trimis in header. Deoarece pluginul este activat doar pe serviciul books-service, numai calea /api/books este securizata

Includerea in Stiva de Servicii Docker

Ca si oricare alt serviciu de Docker, Kong se adauga in fisierul de configuratie al stivei .yml.

services:
  kong:
    image: kong:latest
    volumes:
      - ./kong:/usr/local/kong/declarative #injectarea fisierului de configurare la calea specificata
    environment:
      KONG_DATABASE: 'off' #obligatoriu, daca se vrea modul DB-less
      KONG_DECLARATIVE_CONFIG: /usr/local/kong/declarative/kong.yml #trebuie specificat unde anume se va gasi fisierul de configurare
      KONG_PROXY_ACCESS_LOG: /dev/stdout
      KONG_ADMIN_ACCESS_LOG: /dev/stdout
      KONG_PROXY_ERROR_LOG: /dev/stderr
      KONG_ADMIN_ERROR_LOG: /dev/stderr
      KONG_ADMIN_LISTEN: 0.0.0.0:8001, 0.0.0.0:8444 ssl
    ports:
      - 80:8000 #expunerea porturilor
      - 443:8443
    deploy:
      placement:
        constraints: [node.role == manager] #constrangerea de rulare doar pe master, pentru a nu exista conflict la nivel de volume
    networks:
      - internal

Aveti grija sa conectati toate serviciile pe care le vreti expuse in Kong, in aceeasi retea cu el. Observati ca, in cadrul configuratiei de mai sus, am folosit reteaua internal. Atat serviciul Books cat si Adminer vor trebui, si ele, sa fie in reteaua internal

Kong asculta pe porturile 8000 si 8443. Pentru a expune, in public, 80 si 443, este nevoie sa faceti mapare explicita

Comportament Asteptat

Daca totul a decurs bine, apelarea rutei IP_PUBLIC_PLAY_WITH_DOCKER/adminer va trebui sa rezulte in panoul de administrare al bazei de date, iar cererile din Postman pe ruta IP_PUBLIC_PLAY_WITH_DOCKER/api/books vor trebui sa esueze, in cazul in care nu exista apikey in header, sau sa functioneze, daca se pune cheia mobylab in header.

Extindere Kong

Bineinteles, exemplul aratat in cadrul acestui laborator este unul trivial. Kong se poate folosi pentru mult mai multe lucruri utile in lucrul cu servicii distribuite si microservicii, precum rate limiting, distributed logging, ip restriction, 3rd party authorization, cors, samd…

Esential, Kong se foloseste ca un punct central de acces in sistemul vostru, care se introduce nativ in ecosistemul Docker.

idp/laboratoare/04.1616765488.txt.gz · Last modified: 2021/03/26 15:31 by radu.ciobanu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0