Declarative Kong manifests to external site?

Hi, I’ve been trying to set up an ExternalName service for testing purposes, but can’t seem to find the up-do-date docs on what is required. I’ve pieced together things from different places, but can’t seem to get it all working. My current manifest is as follows:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: mockbin-ingress
  namespace: mockbin
  annotations:
    kubernetes.io/ingress.class: kong
    configuration.konghq.com: mockbin-kong-ingress
    request-transformer.plugin.konghq.com: |
      transform-request-to-mockbin
spec:
  rules:
  - host: foo.bar
    http:
      paths:
      - path: /
        backend:
          serviceName: proxy-to-mockbin
          servicePort: 80
---
apiVersion: configuration.konghq.com/v1
kind: KongIngress
metadata:
  name: mockbin-kong-ingress
  namespace: mockbin
proxy:
  path: /request
  protocol: http
---
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
plugin: request-transformer
metadata:
  name: transform-request-to-mockbin
  namespace: mockbin
config:
  remove:
    headers: host
---
kind: Service
apiVersion: v1
metadata:
  name: proxy-to-mockbin
  namespace: mockbin
  annotations:
    configuration.konghq.com: mockbin-kong-ingress
spec:
  ports:
  - protocol: TCP
    port: 80
  type: ExternalName
  externalName: mockbin.org

Result:

λ curl ${IP}/ -H "Host: foo.bar" -D-
HTTP/1.1 404 Not Found
Content-Type: application/json; charset=utf-8
Content-Length: 48
Connection: keep-alive
Date: Thu, 19 Mar 2020 12:28:15 GMT
Server: kong/1.3-enterprise-edition
Kong-Cloud-Request-ID: 12a1dbf947388789483c902f2cc58508
X-Kong-Upstream-Latency: 273
X-Kong-Proxy-Latency: 0
Via: kong/2.0.2

{"message":"no Route matched with those values"}

Any ideas would be very helpful, or a link to documentation describing the chain of required objects.

Can you remove host based routing and simply do path based routing?

Absolutely, anything goes as far as solving the setup. This meaning editing the Ingress to not using the host at all?

Yes
(this text is added to overcome min 20 char response. :laughing:)

1 Like

No good; I still get the same response when using the following manifest:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: mockbin-ingress
  namespace: mockbin
  annotations:
    kubernetes.io/ingress.class: kong
    configuration.konghq.com: mockbin-kong-ingress
    request-transformer.plugin.konghq.com: |
      transform-request-to-mockbin
spec:
  rules:
  - http:
      paths:
      - path: /request
        backend:
          serviceName: proxy-to-mockbin
          servicePort: 80
---
apiVersion: configuration.konghq.com/v1
kind: KongIngress
metadata:
  name: mockbin-kong-ingress
  namespace: mockbin
proxy:
  path: /request
  protocol: http
---
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
plugin: request-transformer
metadata:
  name: transform-request-to-mockbin
  namespace: mockbin
config:
  remove:
    headers: host
---
kind: Service
apiVersion: v1
metadata:
  name: proxy-to-mockbin
  namespace: mockbin
  annotations:
    configuration.konghq.com: mockbin-kong-ingress
spec:
  ports:
  - protocol: TCP
    port: 80
  type: ExternalName
  externalName: mockbin.org
λ curl ${IP}/request -D-
HTTP/1.1 404 Not Found
Content-Type: application/json; charset=utf-8
Content-Length: 48
Connection: keep-alive
Date: Fri, 20 Mar 2020 08:20:55 GMT
Server: kong/1.3-enterprise-edition
Kong-Cloud-Request-ID: 8d999c74b691cb6691d1135dca6079ec
X-Kong-Upstream-Latency: 122
X-Kong-Proxy-Latency: 0
Via: kong/2.0.2

{"message":"no Route matched with those values"}

The service and Ingress resources are in two different namespaces. You need to create the Ingress resource in the same namespace as your service.

Do you mean the same namespace as my Kong deployment? The resources in the manifest above all have metadata.namespace: mockbin, but I’ve been able to deploy a working routing chain in another namespace before.

My Kong deployment is done using the Helm Chart, and is defined as follows (if that helps):

image:
  # Kong 2.0 + nokia/kong-oidc plugin, created using kong/docker-kong/customize.
  repository: myrepo/kong-oidc
  tag: latest
  pullSecrets:
  - repo-cred
plugins: {}
admin:
  # Temporarily enabled to offer overview
  enabled: true
  useTLS: false
  type: ClusterIP

env:
  ssl_cert: /etc/secrets/secret-name/tls.crt
  ssl_cert_key: /etc/secrets/secret-name/tls.key
  plugins: bundled,oidc
secretVolumes:
- secret-name
ingressController:
  installCRDs: false

No.
mockbin-ingress and proxy-to-mockbin resources should both exists in the same namespace.

As far as I can see they are both in namespace: mockbin, still the same error.

Do you see anything in the logs of the ingress controller containers (there are 2 in the same pod)?

After a fresh installation of Kong (using the helm manifest above), and only the manifests listed below added for the route, the only thing I get from the logs is:

λ kubectl logs -n kong -f kong-kong-6598fdf87b-xmvvt -c ingress-controller
...
I0324 09:27:49.326187       1 kong.go:66] successfully synced configuration to Kong
I0324 09:27:52.516424       1 kong.go:57] no configuration change, skipping sync to Kong
I0324 09:28:26.781867       1 status.go:342] updating Ingress mockbin/mockbin-ingress status to [{162.70.215.7 }]
I0324 09:28:26.785895       1 kong.go:57] no configuration change, skipping sync to Kong
...

λ curl ${IP}/request
{"message":"no Route matched with those values"}

λ kubectl logs -n kong -f kong-kong-6598fdf87b-xmvvt -c proxy
...
2020/03/24 09:27:49 [notice] 22#0: *5155 [lua] cache.lua:332: purge(): [DB cache] purging (local) cache, client: 127.0.0.1, server: kong_admin, request: "POST /config?check_hash=1 HTTP/1.1", host: "localhost:8444"
127.0.0.1 - - [24/Mar/2020:09:27:49 +0000] "POST /config?check_hash=1 HTTP/1.1" 201 1804 "-" "Go-http-client/1.1"
10.40.0.0 - - [24/Mar/2020:09:29:25 +0000] "GET /request HTTP/1.1" 404 48 "-" "curl/7.55.1"

In case it can help shed some light, this is some of the output from the admin API, not sure what more could be releant from it:

$ curl http://localhost:8444/services/ | jq .
{
  "next": null,
  "data": [
    {
      "host": "proxy-to-mockbin.mockbin.80.svc",
      "created_at": 1585042069,
      "connect_timeout": 60000,
      "id": "a813fdef-435c-57f2-8525-d5e8e665967f",
      "protocol": "http",
      "name": "mockbin.proxy-to-mockbin.80",
      "read_timeout": 60000,
      "port": 80,
      "path": "/request",
      "updated_at": 1585042069,
      "client_certificate": null,
      "tags": null,
      "write_timeout": 60000,
      "retries": 5
    }
  ]
}

$ curl http://localhost:8444/routes/ | jq .
{
  "next": null,
  "data": [
    {
      "id": "35971f81-7b2e-5899-bd12-db3785aed082",
      "path_handling": "v0",
      "paths": [
        "/request"
      ],
      "destinations": null,
      "headers": null,
      "protocols": [
        "http",
        "https"
      ],
      "created_at": 1585042069,
      "snis": null,
      "service": {
        "id": "a813fdef-435c-57f2-8525-d5e8e665967f"
      },
      "name": "mockbin.mockbin-ingress.00",
      "tags": null,
      "preserve_host": true,
      "regex_priority": 0,
      "strip_path": true,
      "sources": null,
      "updated_at": 1585042069,
      "https_redirect_status_code": 426,
      "methods": null,
      "hosts": null
    }
  ]
}

$ curl http://localhost:8444/upstreams/ | jq .
{
  "next": null,
  "data": [
    {
      "healthchecks": {
        "active": {
          "https_verify_certificate": true,
          "https_sni": null,
          "http_path": "/",
          "timeout": 1,
          "concurrency": 10,
          "healthy": {
            "http_statuses": [
              200,
              302
            ],
            "interval": 0,
            "successes": 0
          },
          "unhealthy": {
            "http_statuses": [
              429,
              404,
              500,
              501,
              502,
              503,
              504,
              505
            ],
            "tcp_failures": 0,
            "timeouts": 0,
            "http_failures": 0,
            "interval": 0
          },
          "type": "http"
        },
        "threshold": 0,
        "passive": {
          "unhealthy": {
            "http_failures": 0,
            "http_statuses": [
              429,
              500,
              503
            ],
            "tcp_failures": 0,
            "timeouts": 0
          },
          "type": "http",
          "healthy": {
            "successes": 0,
            "http_statuses": [
              200,
              201,
              202,
              203,
              204,
              205,
              206,
              207,
              208,
              226,
              300,
              301,
              302,
              303,
              304,
              305,
              306,
              307,
              308
            ]
          }
        }
      },
      "hash_on": "none",
      "id": "8015841b-d4f7-537b-93e6-180d97242d1c",
      "algorithm": "round-robin",
      "name": "proxy-to-mockbin.mockbin.80.svc",
      "host_header": null,
      "hash_fallback_header": null,
      "tags": null,
      "hash_on_cookie": null,
      "hash_on_header": null,
      "hash_on_cookie_path": "/",
      "created_at": 1585042069,
      "hash_fallback": "none",
      "slots": 10000
    }
  ]
}

Manifest, same as before:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: mockbin-ingress
  namespace: mockbin
  annotations:
    kubernetes.io/ingress.class: kong
    configuration.konghq.com: mockbin-kong-ingress
    request-transformer.plugin.konghq.com: |
      transform-request-to-mockbin
spec:
  rules:
  - http:
      paths:
      - path: /request
        backend:
          serviceName: proxy-to-mockbin
          servicePort: 80
---
apiVersion: configuration.konghq.com/v1
kind: KongIngress
metadata:
  name: mockbin-kong-ingress
  namespace: mockbin
proxy:
  path: /request
  protocol: http
---
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
plugin: request-transformer
metadata:
  name: transform-request-to-mockbin
  namespace: mockbin
config:
  remove:
    headers: host
---
kind: Service
apiVersion: v1
metadata:
  name: proxy-to-mockbin
  namespace: mockbin
  annotations:
    configuration.konghq.com: mockbin-kong-ingress
spec:
  ports:
  - protocol: TCP
    port: 80
  type: ExternalName
  externalName: mockbin.org

What I really want to achieve is the beginning setup created here, in order to begin testing and learning the kong-oidc plugin, where the following resources are created via the API:

$ curl -s -X POST http://localhost:8001/services \
    -d name=mock-service \
    -d url=http://mockbin.org/request \
    | python -mjson.tool
{
    "host": "mockbin.org",
    "created_at": 1542332952,
    "connect_timeout": 60000,
    "id": "e71c82d3-2e53-469b-9beb-a232a15f86d4",
    ...
}
$ curl -s -X POST http://localhost:8001/routes \
    -d service.id=${service_id} \
    -d paths[]=/mock \
    | python -mjson.tool
{
    "created_at": 1542333285,
    "strip_path": true,
    "hosts": null,
    "preserve_host": false,
    ...
}

Leading to:

$ curl -s http://localhost:8000/mock
{
  "startedDateTime": "2018-11-16T01:55:03.115Z",
  "clientIPAddress": "172.21.0.1",
  "method": "GET",
  "url": "http://localhost/request",
  ...
}

The manifests I’ve supplied are an attempt to recreate this in a declarative way. I’ve been trying to set up a non-ingress controller instance as well so I could use the API for resource creation, using the bundled Postgres database included in the Helm manifest, but I have been unsuccessful in setting this up. I can’t find any documentation on how to set up a Kong+DB instance using the Helm Chart, but if I am successful in finding some or setting it up without documentation, that could be an alternative. However, since it should be possible to create resources in a declarative way, it would really be preferable to know how to do both.