How to configure kong api gateway with service discovery?

Viewed 4131

I am working on a microservice architecture. I want to have a kong API gateway implemented at the front. I don't want to go into kong admin API and manually add all the exposed API. Can I take the help of any service discovery implementation like eureka to autoconfigure my APIs to Kong?

2 Answers

You can use a combination of OpenAPI spec generation using springdoc-openapi and a transformation to Kong's Declarative Configuration using Insomnia's Inso CLI. This approach frees you from the need to manually use Kong's admin API to add Spring Boot services (which I don't like to do):

enter image description here

This process is even automatable inside your (e.g. Maven) build - and would be updated automatically after every build or push (if configured inside your CI/CD pipeline).

I created a fully comprehensible blog post for this scenario, but here are the brief steps:

1. Generating the OpenAPI spec with the springdoc-openapi-maven-plugin

Add springdoc-openapi-ui to your pom.xml:

<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-ui</artifactId>
    <version>1.4.8</version>
</dependency>

Then add springdoc-openapi-maven-plugin and configure your spring-boot-maven-plugin to run it inside the pre-integration-test phase:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <executions>
        <execution>
            <id>pre-integration-test</id>
            <goals>
                <goal>start</goal>
            </goals>
        </execution>
        <execution>
            <id>post-integration-test</id>
            <goals>
                <goal>stop</goal>
            </goals>
        </execution>
    </executions>
</plugin>
<plugin>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-maven-plugin</artifactId>
    <version>1.1</version>
    <executions>
        <execution>
            <phase>integration-test</phase>
            <goals>
                <goal>generate</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Now a mvn verify already generates an openapi.json inside your target directory.

2. Generating Kong Declarative Configuration from OpenAPI spec

Install Insomnia Inso CLI via npm:

npm i -g insomnia-inso

Now use Insomnica Inso CLI to generate Kong Declarative Configuration from the OpenAPI json:

inso generate config weatherbackend/target/openapi.json --output kong/kong.yml --type declarative --verbose

This will generate a kong/kong.yml like this:

_format_version: "1.1"
services:
  - name: weatherbackend
    url: http://weatherbackend:8080
    plugins: []
    routes:
      - tags:
          - OAS3_import
        name: weatherbackend-path-get
        methods:
          - GET
        paths:
          - /weather/general/outlook
        strip_path: false
      - tags:
          - OAS3_import
        name: weatherbackend-path_1-post
        methods:
          - POST
        paths:
          - /weather/general/outlook
        strip_path: false
      - tags:
          - OAS3_import
        name: weatherbackend-path_2-get
        methods:
          - GET
        paths:
          - /weather/(?<name>\S+)$
        strip_path: false
    tags:
      - OAS3_import
upstreams:
  - name: weatherbackend
    targets:
      - target: weatherbackend:8080
    tags:
      - OAS3_import

3. Running Kong in DB-less Declarative Configuration Mode based on the generated kong.yml

You can use this file directly as Kong's configuration! See this Docker Compose deployment as an example on how to do that:

version: '3.7'

services:
  kong:
    image: kong:2.2.0
    environment:
      KONG_ADMIN_ACCESS_LOG: /dev/stdout
      KONG_ADMIN_ERROR_LOG: /dev/stderr
      KONG_ADMIN_LISTEN: '0.0.0.0:8001'
      KONG_DATABASE: "off"
      KONG_DECLARATIVE_CONFIG: /usr/local/kong/declarative/kong.yml
      KONG_PROXY_ACCESS_LOG: /dev/stdout
      KONG_PROXY_ERROR_LOG: /dev/stderr
    volumes:
      - ./kong/:/usr/local/kong/declarative
    networks:
      - kong-net
    ports:
      - "8000:8000/tcp"
      - "127.0.0.1:8001:8001/tcp"
      - "8443:8443/tcp"
      - "127.0.0.1:8444:8444/tcp"
    healthcheck:
      test: ["CMD", "kong", "health"]
      interval: 10s
      timeout: 10s
      retries: 10
    restart: on-failure
    deploy:
      restart_policy:
        condition: on-failure
 
  # no portbinding here - the actual services should be accessible through Kong
  weatherbackend:
    build: ./weatherbackend
    ports:
      - "8080"
    networks:
      - kong-net
    tty:
      true
    restart:
      unless-stopped

networks:
  kong-net:
    external: false

The whole process is automatable (e.g. using the exec-maven-plugin as described in my post).

If you're in doubt how this all works together you may also check out this example project which leverages every step mentioned here (incl. the CI/CD automation of every step): https://github.com/jonashackt/spring-boot-openapi-kong

I have no knowledge of anything automatic but you could build something yourself and add APIs using the Admin API: https://docs.konghq.com/getting-started-guide/latest/expose-services/

If you want a truely automatic gateway using Service Discovery, check out https://spring.io/projects/spring-cloud-netflix which uses Eureka and Zuul.

Alternatively, you could look at Traefik, which has many options to load configuration (including reading all the config from Docker labels you put on your container.

Related