Beliebte Suchanfragen

Cloud Native

DevOps

IT-Security

Agile Methoden

Java

//

API-Management mit Kong

23.11.2017 | 9 Minuten Lesezeit

+++Update: Die Inhalte dieses Blog Posts beziehen sich auf eine inzwischen teils veraltete Version von Kong+++

Die Verwendung von APIs zur Förderung von Innovationen und zur Schaffung neuer Geschäftsmöglichkeiten ist kein neues Konzept. Viele Success Stories von eBay, Netflix, Expedia, mobile.de und vielen anderen zeigen den wachsenden Trend API-getriebener Geschäftsmodelle. Die meisten Anbieter von API-Management-Lösungen sind bekannte Unternehmen wie IBM, Oracle oder MuleSoft, die versuchen, eine Lösung anzubieten, die an ihr bestehendes Ökosystem von Unternehmensprodukten gekoppelt ist. Eine der wenigen Ausnahmen ist Kong Inc (früher bekannt als Mashape Inc), ein in San Fransisco ansässiges Start-up, das in den letzten zwei Jahren durch Open-Sourcing seines Produktes , des Kong API Gateway, populär wurde. In diesem Artikel werde ich kurz das Thema API-Management vorstellen und zeigen, wie man ein Kong API Gateway aufbaut und verwendet.

Warum ist API-Management interessant?

Adaption und Geschwindigkeit zählen zu den wichtigsten Erfolgsfaktoren in der Softwarebranche. Die Ergebnisse dieser Faktoren sind Trends wie Microservices-Architekturen, Continuous Delivery, DevOps-Kultur, agile Softwareentwicklung und Cloud Computing. Um schnell zu sein, muss man ein System in unabhängige Dienste aufteilen und jeden Teil des Systems schnell und reibungslos ändern können. Daraus resultiert eine hohe Nachfrage nach Integrationen zwischen verschiedenen Anwendungen und Diensten. API-Management spielt bei dieser Integration eine wichtige Rolle : Sie schaffen klare Grenzen und Abstraktionen zwischen Systemen. Heutzutage entsteht eine Softwarelösung durch Einkauf und Integration verschiedener Services, statt dass man alles selbst von Grund auf programmiert. Mit dem wachsenden API-Trend haben viele Unternehmen ihr Geschäftsmodell geändert und einige haben sogar vollständig auf einen API-zentrierten Geschäftsansatz umgestellt. Expedia Inc generiert 90% des Umsatzes über das Expedia Affiliate Network, eine API-Plattform. Netflix hat ein Ökosystem von über 1000 APIs aufgebaut, um viele Endgeräte für seine Streaming-Plattform zu unterstützen. Salesforce, einer der am schnellsten wachsenden CRM-Anbieter, generiert über 50 % seines Umsatzes mit APIs. Andere häufige Anwendungen für APIs sind:

  • Nutzer erreichen oder ihre Inhalte erfassen
  • Traffic generieren
  • Partnernetzwerk erweitern
  • neue Einnahmequellen schaffen
  • mehr Geräte für ein Service unterstützen
  • Flexibilität für interne Projekte schaffen
  • Integrationsmöglichkeiten für andere Systeme anbieten

Aber APIs zu verwenden ist nicht besonders einfach, und es hat seinen Preis. Die Kosten für die Vorteile sind eine zunehmende technische und organisatorische Komplexität. In diesem Blogbeitrag werde ich Möglichkeiten zur Bewältigung der technischen Komplexität untersuchen und herausfinden, wie Kong API Gateway dabei helfen kann.

Kong-Architektur

Kong ist ein Open-Source-API-Gateway, um RESTful APIs zu verwalten. Es ist Teil von Kong Enterprise, einem Paket von Kong API Gateway, einem Entwicklerportal namens Gelato und einer Analyseplattform namens Galileo. Es richtet sich an Unternehmenskunden, die Tausende von APIs haben und einen dedizierten Support rund um die Uhr benötigen. Für kleine bis mittelgroße Unternehmen reicht das Kong API Gateway (Community Edition) aus, um erste Schritte in der API-Verwaltung zu machen.

Die fünf Komponenten der Kong-Architektur sind: nginx, OpenResty, Datastore, Plugins und eine RESTful Admin API. Die grundlegende Low-Level-Komponente ist nginx, ein bekannter und erprobter Webserver. Im Jahr 2017 nutzen 35,5% aller bekannten und 54,2% der Top 100.000 Websites weltweit nginx. Es kann bis zu 10.000 gleichzeitige Verbindungen auf einem Knoten mit geringem Speicherbedarf verarbeiten und wird häufig als Reverse-Proxy in Microservice-Architekturen, als Load-Balancer, als SSL-Terminierung-Proxy oder als Webserver für statische Inhalte verwendet. Abgesehen von diesen Anwendungsfällen hat nginx viele weitere Funktionen, die separate Blogbeiträge verdienen. OpenResty ist eine Webplattform, die nginx, LuaJIT- , Lua-Bibliotheken und nginx-Module von Drittanbietern vereint, um einen Webserver für skalierbare Webanwendungen und Webservices bereitzustellen. Es wurde ursprünglich von taobao.com gebaut, der größten Online-Auktionsplattform in Asien mit 368 Millionen aktiven Nutzern (2017), und 2011 freigegeben. Danach unterstützte und entwickelte Cloudflare Inc. die Plattform bis 2016. Seitdem entwickelt die OpenResty Software Foundation die Plattform weiter. Die Datastore-Komponente verwendet Apache Cassandra oder PostgreSQL, um die Konfigurationsdaten, Consumer und Plugins aller APIs zu persistieren. Die API-Konfiguration wird ebenfalls in nginx im Cache gespeichert, sodass die Last auf der Datenbank gering sein sollte. Plugins sind Lua-Module, die während eines Request-Response-Lebenszyklus ausgeführt werden. Sie erweitern das API-Gateway um Funktionalitäten für unterschiedliche Anwendungsfälle. Möchte man zum Beispiel eine API absichern, so verwendet man ein Sicherheits-Plugin, das nur diese Funktion während der Anfrage bereitstellt. Das Kong-Plugin-System ist offen, und man kann eigene Plugins schreiben und verwenden. Schließlich gibt es eine RESTful Admin API, um die APIs zu verwalten. Es fühlt sich am Anfang etwas seltsam an, keine Benutzeroberfläche zu haben. Aus Sicht des Entwicklers ist das akzeptabel, weil es ein notwendiges Werkzeug bietet, um die Arbeitsabläufe zu automatisieren, zum Beispiel mit Postman, httpie oder curl. Ich arbeite seit einigen Monaten mit Kong und habe nie das Bedürfnis nach einer Benutzeroberfläche verspürt, da ich auf alle Informationen schnell und zuverlässig zugreifen konnte. Wenn man jedoch ein Dashboard für APIs haben möchte, kann man Konga oder kong-dashboard verwenden, beides freie Open-Source-Community-Projekte.

Schauen wir uns nun an, wie man APIs mit Kong verwaltet und welche Plugins grundlegende Sicherheitsfunktionen bieten.

Kong API Gateway in action

Dieser Teil wird technischer als der vorherige sein. Zuerst zeige ich, wie man eine minimale Infrastruktur für Kong API Gateway erstellt. Dann werde ich eine API und ein Sicherheits-Plugin hinzufügen, um den Zugriff auf einen bestimmten Benutzer einzuschränken.

Um die Infrastruktur zu starten, verwende ich docker-compose mit dieser Service-Definition:

1version: '2.1'
2
3services:
4  kong-database:
5    container_name: kong-database
6    image: postgres:9.4
7    environment:
8      - POSTGRES_USER=kong
9      - POSTGRES_DB=kong
10    healthcheck:
11      test: ["CMD", "pg_isready", "-U", "postgres"]
12      interval: 10s
13      timeout: 5s
14      retries: 5
15  
16  kong-migration:
17    image: kong
18    depends_on:
19      kong-database:
20        condition: service_healthy
21    environment:
22      - KONG_DATABASE_postgres
23      - KONG_PG_HOST=kong-database
24    command: kong migrations up
25
26  kong:
27    container_name: kong
28    image: kong:0.11.0
29    depends_on:
30      kong-database:
31        condition: service_healthy
32      kong-migration:
33        condition: service_started
34    environment:
35      - KONG_DATABASE=postgres
36      - KONG_PG_HOST=kong-database
37      - KONG_PG_DATABASE=kong
38    expose:
39      - 8000
40      - 8001
41      - 8443
42      - 8444
43    ports:
44      - "8000-8001:8000-8001"
45    healthcheck:
46      test: ["CMD-SHELL", "curl -I -s -L http://127.0.0.1:8000 || exit 1"]
47      interval: 5s
48      retries: 10

Man kann Kong auch auf vielen Plattformen wie AWS , Google Cloud, Kubernetes, DC/OS und vielen anderen installieren. In meiner docker-compose-Definition gibt es drei Services: kong-database, kong und kong-migration. Ich verwende das PostgreSQL Docker-Image für die Datastore-Komponente, die in der Architekturübersicht erwähnt wurde. Der kong-service stellt vier verschiedene Ports für zwei Funktionalitäten bereit:

  • 8000, 8443: HTTP- und HTTPS-Zugriff auf die APIs (Consumer-Endpunkt)
  • 8001, 8444: HTTP- und HTTPS-Zugriff auf die Admin-API (Admin-Endpunkt)

Der kong-migration-Service wird zum initialen Erstellen der Objekte in der kong-database verwendet. Diese Bootstrap-Funktionalität wird vom kong-service nicht bereitgestellt, daher muss man kong-migration nur einmal innerhalb des Containers ausführen. Mit docker-compose up werden die Dienste gestartet. Der Container-Status sollte mit dem Befehl docker ps etwas so aussehen:

1CONTAINER ID        IMAGE               COMMAND                  CREATED                  STATUS                            PORTS                                                                NAMES
287eea678728f        kong:0.11.0         "/docker-entrypoin..."   Less than a second ago   Up 2 seconds (health: starting)   0.0.0.0:8000-8001->8000-8001/tcp, 0.0.0.0:8443-8444->8443-8444/tcp   kong
34e2bf871f0c7        postgres:9.4        "docker-entrypoint..."   3 hours ago              Up 4 minutes (healthy)            5432/tcp                                                             kong-database

Mit einer GET-Anfrage an die Admin-API kann man den Status der API überprüfen. Ich benutze dafür das Tool HTTPie , aber man kann auch curl oder Postman als Alternative verwenden.

1$ http localhost:8001/apis/
2 
3HTTP/1.1 200 OK
4Access-Control-Allow-Origin: *
5Connection: keep-alive
6Content-Type: application/json; charset=utf-8
7Date: Fri, 13 Oct 2017 14:59:25 GMT
8Server: kong/0.11.0
9Transfer-Encoding: chunked
10 
11{
12    "data": [],
13    "total": 0
14}

Die Kong-Admin-API funktioniert, aber es sind noch keine APIs konfiguriert. Ich füge nun ein Beispiel hinzu:

1$ http post localhost:8001/apis/ name=example_api upstream_url=https://example.com uris=/my_api
2 
3HTTP/1.1 201 Created
4Access-Control-Allow-Origin: *
5Connection: keep-alive
6Content-Type: application/json; charset=utf-8
7Date: Fri, 13 Oct 2017 15:03:55 GMT
8Server: kong/0.11.0
9Transfer-Encoding: chunked
10 
11{
12    "created_at": 1507907036000,
13    "http_if_terminated": false,
14    "https_only": false,
15    "id": "59d9749b-694a-4645-adad-d2c974b3df76",
16    "name": "example_api",
17    "preserve_host": false,
18    "retries": 5,
19    "strip_uri": true,
20    "upstream_connect_timeout": 60000,
21    "upstream_read_timeout": 60000,
22    "upstream_send_timeout": 60000,
23    "upstream_url": "https://example.com",
24    "uris": [
25        "/my_api"
26    ]
27}

Dazu sende ich einen POST-Request an localhost:8001/apis/ mit drei Parametern im http-Body:

  • name: API name
  • upstream_url: die Ziel-URL, die auf einen API-Server verweist
  • uris: URI Prefixe, die mit einem API-Server assoziiert werden

Es gibt natürlich mehr Parameter, wie z.B. für SSL, Timeouts, HTTP-Methoden und andere. Man kann alle Konfigurationen in der Dokumentation nachschlagen. Ich rufe nun die API auf:

1$ http localhost:8000/my_api
2 
3HTTP/1.1 200 OK
4Cache-Control: max-age=604800
5Connection: keep-alive
6Content-Encoding: gzip
7Content-Length: 606
8Content-Type: text/html; charset=UTF-8
9Date: Tue, 17 Oct 2017 09:02:26 GMT
10Etag: "359670651+gzip"
11Expires: Tue, 24 Oct 2017 09:02:26 GMT
12Last-Modified: Fri, 09 Aug 2013 23:54:35 GMT
13Server: ECS (dca/249F)
14Vary: Accept-Encoding
15Via: kong/0.11.0
16X-Cache: HIT
17X-Kong-Proxy-Latency: 592
18X-Kong-Upstream-Latency: 395
19 
20<!doctype html>
21...

In vielen Fällen möchte man seine API schützen und nur dedizierten Benutzern Zugriff geben. In Kong verwendet man dafür Plugins, die während eines Requests ausgeführt werden.

Consummers und Plugins

Consumer sind Objekte, die (technische) API-Benutzer sind. Die Datenstruktur ist ziemlich einfach gehalten und hat nur drei Felder: id, username und custom_id. Um einen Consumer zu erstellen, schicke man einen POST-Request an localhost:8001/consumer/

1$ http post localhost:8001/consumers/ username=John
2 
3HTTP/1.1 201 Created
4Access-Control-Allow-Origin: *
5Connection: keep-alive
6Content-Type: application/json; charset=utf-8
7Date: Tue, 17 Oct 2017 10:06:19 GMT
8Server: kong/0.11.0
9Transfer-Encoding: chunked
10 
11{
12    "created_at": 1508234780000,
13    "id": "bdbba9d1-5948-4e1a-94bd-55979b7117a3",
14    "username": "John"
15}

Man muss entweder das Feld username oder custom_id oder beides im Request-Body angeben. Zusätzlich kann man eine custom_id für eine Verknüpfung zwischen einem Consumer und einem Benutzer eines internen Systems festlegen, z. B. eine ID in einem CRM-System. Damit kann man Konsistenz zwischen den Consumern in Kong und einem externen System mit Benutzerdaten pflegen. Ich werde nun ein Sicherheits-Plugin zu meiner API hinzufügen und den Consumer mit diesem Plugin verbinden. Dadurch wird sichergestellt, dass nur dieser Benutzer mit einem bestimmten Schlüssel auf die API zugreifen kann. Ein Kong-Plugin ist eine Sammlung von Lua-Modulen, die während eines Request-Response-Lebenszyklus einer API ausgeführt werden. Plugins können zu allen APIs hinzugefügt oder nur nur für eine bestimmte API eingerichtet werden. Zusätzlich können Plugins für einen bestimmten Consumer konfiguriert werden. In meinem Fall füge ich das key authentication plugin hinzu:

1$ http post localhost:8001/apis/example_api/plugins name=key-auth
2 
3Access-Control-Allow-Origin: *
4Connection: keep-alive
5Content-Type: application/json; charset=utf-8
6Date: Tue, 17 Oct 2017 11:59:16 GMT
7Server: kong/0.11.0
8Transfer-Encoding: chunked
9 
10{
11    "api_id": "36d04e5d-436d-4132-abdc-e4d42dc67068",
12    "config": {
13        "anonymous": "",
14        "hide_credentials": false,
15        "key_in_body": false,
16        "key_names": [
17            "apikey"
18        ]
19    },
20    "created_at": 1508241556000,
21    "enabled": true,
22    "id": "8eecbe27-af95-49d2-9a0a-5c71b9d5d9bd",
23    "name": "key-auth"
24}

Der API-Name examlpe_api in der Request-URL beschränkt die Plugin-Ausführung nur auf diese API. Versucht man die API zu verwenden, erhält man folgende Antwort:

1$ http localhost:8000/my_api
2 
3hTTP/1.1 401 Unauthorized
4connection: keep-alive
5content-Type: application/json; charset=utf-8
6date: Tue, 17 Oct 2017 12:03:24 GMT
7server: kong/0.11.0
8transfer-Encoding: chunked
9WWW-Authenticate: Key realm="kong"
10 
11{
12    "message": "No API key found in request"
13}

Jetzt muss ich einen Schlüssel für meinen Consumer erstellen:

1$ http POST localhost:8001/consumers/John/key-auth key=secret_key
2 
3HTTP/1.1 201 Created
4Access-Control-Allow-Origin: *
5Connection: keep-alive
6Content-Type: application/json; charset=utf-8
7Date: Tue, 17 Oct 2017 12:35:11 GMT
8Server: kong/0.11.0
9Transfer-Encoding: chunked
10 
11{
12    "consumer_id": "bdbba9d1-5948-4e1a-94bd-55979b7117a3",
13    "created_at": 1508243712000,
14    "id": "02d2afd6-1fb6-4713-860f-704c52355780",
15    "key": "secret_key"
16}

Lässt man das Feld key weg, generiert Kong einen zufälligen Schlüssel. Mit dem konfigurierten Schlüssel rufe ich die API auf:

1$ http localhost:8000/my_api apikey=='secret_key'
2 
3HTTP/1.1 200 OK
4Cache-Control: max-age=604800
5Connection: keep-alive
6Content-Encoding: gzip
7Content-Length: 606
8Content-Type: text/html; charset=UTF-8
9Date: Tue, 17 Oct 2017 12:40:46 GMT
10Etag: "359670651+gzip"
11Expires: Tue, 24 Oct 2017 12:40:46 GMT
12Last-Modified: Fri, 09 Aug 2013 23:54:35 GMT
13Server: ECS (dca/249B)
14Vary: Accept-Encoding
15Via: kong/0.11.0
16X-Cache: HIT
17X-Kong-Proxy-Latency: 25
18X-Kong-Upstream-Latency: 374
19 
20<!doctype html>
21...

Das apikey wird als Query-Parameter oder als Header im API-Request mitgeschickt. Das Plugin hat auch Konfigurationen, um den Schlüssel zu verbergen, nachdem die Anfrage verarbeitet wurde oder um ihn in einer Liste von Schlüsseln nachzuschlagen. Es ist auch möglich, Plugins auf Consumer-Ebene zu konfigurieren, sodass jeder Konsument seine eigenen Einstellungen hat. Beispielsweise kann man pro API-Nutzer unterschiedliche Anfrage-Limits festlegen, sodass einige von ihnen häufiger auf Ihre API zugreifen können als die anderen.

Fazit

In diesem Blogpost habe ich das Thema API-Management vorgestellt und warum es für Ihr Unternehmen oder Projekt von Bedeutung sein könnte. Kong API Gateway ist ein großartiges Open-Source-Projekt, mit dem man APIs frei verwalten kann. Mit nur wenigen HTTP-Anfragen habe ich meine erste API erstellt und abgesichert. Die RESTful Admin-API von Kong ist sauber und einfach, was eine schnelle Integration in die meisten Continuous-Delivery-Pipelines ermöglicht. Im nächsten Blogbeitrag werde ich zeigen, wie man eigene Plugins erstellt und einen OpenID-Provider für die Verwaltung der API-Zugriffe integriert.

Beitrag teilen

Gefällt mir

0

//

Weitere Artikel in diesem Themenbereich

Entdecke spannende weiterführende Themen und lass dich von der codecentric Welt inspirieren.

//

Gemeinsam bessere Projekte umsetzen.

Wir helfen deinem Unternehmen.

Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.

Hilf uns, noch besser zu werden.

Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.