Differences

This shows you the differences between two versions of the page.

Link to this comparison view

idp:laboratoare:03 [2023/04/10 15:42]
radu.ciobanu
idp:laboratoare:03 [2023/04/10 20:40] (current)
radu.ciobanu
Line 1: Line 1:
 ===== Laboratorul 03 - Persistență în Docker Swarm și Kong ===== ===== Laboratorul 03 - Persistență în Docker Swarm și Kong =====
 +
 +<note tip>​Exemplele din acest laborator se găsesc pe [[https://​gitlab.com/​mobylab-idp/​laborator3|repository-ul materiei]].</​note>​
  
 ==== Persistență în Docker Swarm ==== ==== Persistență în Docker Swarm ====
Line 234: Line 236:
 </​note>​ </​note>​
  
 +==== Kong API Gateway ====
 +
 +În cadrul scheletului de cod este implementat un API Gateway minimal sub forma de server de NodeJS. Acesta are următoarele funcționalități:​
 +  * expune rute din aplicație
 +  * funcționează ca un punct central de acces în sistem.
 +
 +Cu toate acestea, implementarea programatică a unui API Gateway necesită timp și, de multe ori, munca depusă implică scriere repetitivă de cod.
 +
 +[[https://​konghq.com/​|Kong]] este unul dintre liderii din domeniul Cloud în materie de soluții de API Gateway declarative. Kong este nativ Docker, este bazat pe Nginx si nu necesită scriere de cod, ci doar furnizarea unei configurații (sau configurarea on-the-fly prin cereri HTTP).
 +
 +Kong funcționează ca un serviciu de Docker și interceptează traficul venit, în funcție de regulile menționate,​ și apoi îl redirectează către alte servicii.
 +
 +În plus, Kong oferă o gamă variată de **plugins** ce aduc funcționalități extra precum //rate limiting//, //​compression//,​ //​logging//,​ etc.
 +
 +=== Arhitectura implementată ===
 +
 +Arhitectura este identică cu cea a exercițiului din laboratorul precedent, însă, în loc de API Gateway programatic,​ vom folosi Kong.
 +În plus, vom expune și serviciul Adminer tot prin intermediul Kong.
 +
 +{{:​cc:​laboratoare:​schema_lab.png?​600|}}
 +
 +Comportamentul dorit va fi ca, în urma apelului **IP_PUBLIC/​api/​books**,​ să interacționăm cu serviciul Books (POST/GET) și, în urma apelului **IP_PUBLIC/​adminer**,​ să interacționăm cu serviciul Adminer.
 +
 +=== Implementare Kong ==
 +
 +Kong poate fi rulat atât în modul **DB-on**, cât și în modul **DB-less**. Noi vom folosi abordarea **DB-less**,​ furnizând o configurație bazată pe un fișier **.yml**. În modul **DB-on**, Kong mai folosește o bază de date și configurația se face pe bază de cereri POST către API-ul intern de configurare.
 +
 +== Fișierul de configurație ==
 +
 +<code yaml>
 +_format_version:​ "​2.1"​
 +
 +services:
 +  - name: books-service
 +    url: http://​labkong_books-service/​api
 +    routes:
 +      - name: books-service-route
 +        paths: ​
 +          - /api/books
 +          ​
 +  - name: db-adminer
 +    url: http://​labkong_adminer:​8080
 +    routes:
 +      - name: adminer-service
 +        paths:
 +          - /adminer
 +
 +consumers:
 +  - username: lab-student
 +
 +plugins:
 +  - name: key-auth
 +    service: books-service
 +
 +keyauth_credentials:​
 +  - consumer: lab-student
 +    key: mobylab
 +    hide_credentials:​ true
 +</​code>​
 +
 +  * **services** - reprezintă ce servicii se vor conecta la Kong pentru interceptare și forwarding de trafic
 +  * **consumers** - reprezintă ce opțiuni se pot seta fiecărui serviciu, în funcție de plugin (este opțional și se folosește doar în contextul pluginurilor)
 +
 +<note tip>​Fiecare serviciu trebuie să aibă obligatoriu definite următoarele:​ //name//, //url//, //​routes//​.</​note>​
 +
 +  * **services -> name** - numele serviciului din punct de vedere al configurării rezultate, trebuie să fie unic
 +  * **services -> url** - //calea// de comunicare **cu serviciul de Docker**; în cazul nostru, reprezintă ruta **din interioriul** serviciilor de Docker unde se vor forwarda cererile HTTP
 +
 +<note tip>​Observați că în URL se precizează NUME-STIVA_NUME_SERVICIU_DOCKER în loc de IP.</​note>​
 +
 +  * **services -> routes** - rutele pe care se va mapa traficul din exterior
 +  * **services -> routes -> name** - numele rutei din punct de vedere al configurării rezultate, trebuie să fie unic
 +  * **services -> routes -> path** - //calea// de comunicare **din exterior**, care se va mapa pe ruta furnizată în URL
 +
 +<note tip>​Pluginurile sunt opționale, însă am vrut să demonstrăm utilizarea unui plugin de autorizare pe bază de cheie de API trimisă în header. Deoarece pluginul este activat doar pe serviciul Books, numai calea **/​api/​books** este securizată.</​note>​
 +
 +== Includerea în stiva de servicii Docker ==
 +
 +Ca oricare alt serviciu de Docker, Kong se adaugă în fișierul de configurație al stivei.
 +
 +<code yaml>
 +services:
 +  kong:
 +    image: kong:latest
 +    volumes:
 +      - ./​kong:/​usr/​local/​kong/​declarative # injectarea fișierului de configurare la calea specificată
 +    environment:​
 +      KONG_DATABASE:​ '​off'​ # obligatoriu,​ dacă se vrea modul DB-less
 +      KONG_DECLARATIVE_CONFIG:​ /​usr/​local/​kong/​declarative/​kong.yml # trebuie specificat unde anume se va găsi fișierul 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:
 +      - 8000:8000 # expunerea porturilor
 +      - 8443:8443
 +    deploy:
 +      placement:
 +        constraints:​ [node.role == manager] # constrângerea de rulare doar pe manager, pentru a nu exista conflict la nivel de volume
 +    networks:
 +      - internal
 +</​code>​
 +
 +<note tip>​Aveți grija să conectați toate serviciile pe care le vreți expuse în Kong în aceeași rețea cu el. Observați că, în cadrul configurației de mai sus, am folosit rețeaua //​internal//​. Atât serviciul Books cât și Adminer vor trebui să fie în rețeaua //​internal//​.</​note>​
 +
 +<note tip>Kong ascultă pe porturile 8000 și 8443. Pentru a expune în public 80 și 443, este nevoie de mapare explicită.</​note>​
 +
 +=== Comportament așteptat ===
 +
 +Dacă totul a decurs bine, apelarea rutei **IP_PUBLIC_PLAY_WITH_DOCKER/​adminer** va rezulta în panoul de administrare a bazei de date, iar cererile din Postman pe ruta **IP_PUBLIC_PLAY_WITH_DOCKER/​api/​books** vor eșua în cazul în care nu există o cheie API în header, sau să funcționeze dacă se pune cheia **mobylab** în header.
 +
 +{{:​cc:​laboratoare:​apikey_lab6.png?​600|}}
 +
 +=== Extindere Kong ===
 +
 +Bineînțeles,​ exemplul arătat în cadrul acestui laborator este unul simplu. Kong se poate folosi pentru mult mai multe lucruri utile în lucrul cu servicii distribuite și microservicii,​ precum //rate limiting//, //​distributed logging//, //IP restriction//,​ //3rd party authorization//,​ //CORS//, etc.
 +
 +Esențial, Kong se folosește ca un punct central de acces în sistem, care se introduce nativ în ecosistemul Docker. În plus, este indicat să dedicați cât mai multe funcționalități care au legătură cu traficul Web către API Gateway, pentru a nu îngreuna business logic-ul din interiorul serviciilor. ​
 +
 +În continuare, sa va ilustra aplicarea următoarelor pluginuri:
 +
 +  - [[https://​docs.konghq.com/​hub/​kong-inc/​rate-limiting/​|Rate Limiting]] - limitarea numărului de cereri pe anumite rute
 +  - [[https://​docs.konghq.com/​hub/​kong-inc/​jwt/​|JWT]] - autorizarea serviciilor pe baza unui JWT
 +  - [[https://​docs.konghq.com/​hub/​kong-inc/​cors/​|CORS]] - adaugărea politicilor CORS pe anumite servicii
 +  - [[https://​docs.konghq.com/​hub/​kong-inc/​bot-detection/​|Bot Detection]] - protecția împotriva boților web
 +  - [[https://​docs.konghq.com/​hub/​kong-inc/​prometheus/​|Prometheus Logging]] - suport pentru extragerea logurilor utilizând Prometheus.
 +
 +<code yaml>
 +_format_version:​ "​2.1"​
 +
 +services:
 +  - name: books-service
 +    url: http://​books-service/​api
 +    routes:
 +      - name: books-service-route
 +        paths: ​
 +          - /api/books
 +          ​
 +  - name: db-adminer
 +    url: http://​adminer:​8080
 +    routes:
 +      - name: adminer-service
 +        paths:
 +          - /adminer
 +
 +consumers:
 +  - username: lab-student
 +    ​
 +plugins:
 +  - name: rate-limiting
 +    config: ​
 +      minute: 10
 +      limit_by: ip
 +      policy: local
 +
 +  - name: cors
 +    service: books-service
 +    config:
 +      origins: ​
 +       - "​*"​
 +
 +  - name: bot-detection
 +
 +  - name: prometheus
 +
 +  - name: jwt
 +    service: books-service
 +    # config:
 +    #   ​claims_to_verify:​
 +    #     - exp
 +    #   ​maximum_expiration:​ 60
 +
 +jwt_secrets:​
 +  - consumer: lab-student
 +    key: Moby Labs IDP
 +    algorithm: HS256
 +    secret: mobylab
 +</​code>​
 +
 +=== Logging ===
 +
 +Fișierul //​docker-stack-kong-plugins.yml//​ integrează,​ pe lângă Kong-ul extins cu pluginuri, și Prometheus și Grafana pentru explorarea logurilor provenite din Kong.
  
 +Pentru a accesa Grafana, este nevoie să realizați următorii pași:
 +    - intrați pe **IP:3000**
 +    - conectați-vă cu //admin// / //admin//
 +    - setați sursa de date // http://​prometheus:​9090 //
 +    - importați [[https://​grafana.com/​grafana/​dashboards/​7424|dashboardul]] oferit de Kong.
idp/laboratoare/03.1681130554.txt.gz · Last modified: 2023/04/10 15:42 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