Kong Community Expose Admin Api — Kubernetes

1. Setup kong community with postgres and admin api config

Manifest: https://github.com/jjcallis/kong-admin-api/blob/main/kong.yaml will act as an all in one setup and most notably will:

  • Enable the ability to define plugins, consumers etc via a manifest (declaratively) see config with ‘Type: CustomResourceDefinition’ — starts line 7
  • Enable the kong proxy and create a network load balancer — see the kong-proxy service line 572
  • Create the kong service account — line 770
  • Create the postgres db — line 772 onwards
  • Set admin env env within the contain — line 640 onwards

Once this has been created you will have the kong base setup, you can then do

kubectl get pods -n kong

and see the respective pods

and the kong proxy service.

kubectl get svc -n kong

From this point you can define plugins and use them within routes or service, declaratively see: https://joshuajordancallis.medium.com/kong-in-kubernetes-locking-down-api-endpoints-via-auth-and-consumer-f17d9eb55a83 as an example.

2. Create the kong admin service — we will use this to port forward to access the admin api

Note that the kong-admin svc is exposed on port 8001. This is important as this is the port that Kong exposes this service on.

Manifest: https://github.com/jjcallis/kong-admin-api/blob/main/kong-admin-service.yaml

Once this has been applied and the service has been created, you can then port-forward the kong admin api service

kubectl port-forward svc/kong-admin 8000:8001 -n kong

To confirm it’s all in working order just hit the endpoint

The kong admin api is exposed locally! :)

At this point you should actually be able to hit the admin-api via the LB uri! eg:

curl -i GET abc.elb.eu-west-2.amazonaws.com/admin-api

As when you created the service you set the config to use the kong-ingress, i.e the kong proxy (load balancer).

You may be thinking, this is cool? but how do I lock it down so you can actually use it in production and not leave the endpoint exposed…

Note: it’s important to do the next steps while port-forwarding and not via the load balancer to prevent any weird complications.

As the LB is an aws network load balancer on layer 4, so could potentially interfere with the configuration. Better to play it safe and do the config locally, as it’ll all be saved in the database anyhow!

1. Create the admin-api service

curl -i POST http://localhost:8080/services \
--data name=admin-api \
--data host=kong-admin \
--data port=8001

2. Add a route to the service

curl -i POST http://localhost:8080/services/admin-api/routes \
--data 'paths[]=/admin-api'

Once the service and route is setup, we can then go via the kong proxy.

3. Kong proxy aka load balancer

e.g:

export KONG_API=$(kubectl get svc --namespace kong kong-proxy -o jsonpath='{.status.loadBalancer.ingress[*].hostname}')... curl -i GET $KONG_API/admin-api/

5. Enable the key-auth plugin: https://docs.konghq.com/hub/kong-inc/key-auth/ on the admin-api service

curl -i POST \
--url http://localhost:8080/services/admin-api/plugins/ \
--data 'name=key-auth'

6. Enable the ACL plugin: https://docs.konghq.com/hub/kong-inc/acl/

curl -i POST \
--url http://localhost:8080/services/admin-api/plugins/ \
--data "name=acl" \
--data "config.whitelist=admin-group" \
--data "config.hide_groups_header=true"

7. Create admin consumer

curl -i POST \
--url http://localhost:8080/consumers/ \
--data "username=admin"

8. Create credentials for the admin consumer

curl -i -X POST \
--url http://localhost:8080/consumers/admin/key-auth/ \
--data 'key=CHANGEMETOASUPERSECUREKEY'

9. Add admin consumer to the acl group

curl -i -X POST \
--url http://localhost:8080/consumers/admin/acls \
--data "group=admin-group"

Access the admin api with the api key

curl -i GET $ADMIN_API/admin-api

will result in:

curl -i GET $ADMIN_API/admin-api?apikey=CHANGEMETOASUPERSECUREKEY

valid key will result in being able to hit the api and hit any of the amazing api endpoints/config offered by kong.

e.g:

curl -i GET $KONG_API/admin-api/consumers/admin/acls?apikey=CHANGEMETOASUPERSECUREKEY

BONUS INFO!

Now that we’ve locked down the admin api and can access it via the load balancer you can either create an A record in Route53, Cloudflare or whatever provider you use to have a dedicated uri for the admin api such as:

admin-api.example.com

Or even create an ingress to expose the host, I’ve setup cert-manager: https://cert-manager.io/docs/installation/kubernetes/ and external-dns: https://github.com/kubernetes-sigs/external-dns to automatically create the certificate and record in route53.

Manifest: https://github.com/jjcallis/kong-admin-api/blob/main/admin-ingress

Software engineer, devops engineer in the evenings/weekends. Agnostic to tech, thoroughly enjoy all aspects of tech. It's my only hobby!