Kong Ingress controller serve different path to the backend service

Can I create a custom path in my Ingress resource to work with kong-ingress-controller.
Currently I have:

apiVersion: configuration.konghq.com/v1
kind: KongIngress
metadata:
  name:  example-kongingress
  #namespace: example
proxy:
  path: /
route:
  methods:
  - POST
  - PUT
  - DELETE
  - PATCH
  - GET
  - OPTIONS
  protocols:
  - https
  - http
  strip_path: true
  preserve_host: true
proxy:
  protocol: http #https
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: zcrm365-sandbox-ingress
  annotations:
    kubernetes.io/ingress.class: "kong"
    certmanager.k8s.io/cluster-issuer: letsencrypt-staging
    configuration.konghq.com: example-kongingress
    certmanager.k8s.io/acme-challenge-type: http01
    kubernetes.io/tls-acme: "true"
    certmanager.k8s.io/acme-http01-edit-in-place: "true"
spec:
  rules:
  - host: zcrm365sand.possibilit.nl
    http:
      paths:
        - path: "/priva"
          backend:
            serviceName: zcrm365sandbox
            servicePort: 80
  tls:
  - hosts:
    - zcrm365sand.possibilit.nl
    secretName: letsencrypt-staging

And I want to go to http://zcrm365sand.possibilit.nl/priva looks like it works, but I get the following error in relation to my Swagger API which is the service that I want to reach

image

Is there something to keep in mind to work with a different path to our service?

Hi @bgarcial,

Not sure if I understand you correctly but do you wish to proxy /swagger/v1/swagger.json to /some/other/path/swagger/v1/swagger.json?

If that is what you want, it can be done using proxy.path parameter, which you’ve currently set to /.

1 Like

Hi @hbagdi, thanks for your answer

I’m trying to create a KongIngress resources for a single service so that I can specify a different proxy path for a specified path

proxy path: /
ingress path: /priva

So, my Kong-Ingress and Ingress resources are the following:

apiVersion: configuration.konghq.com/v1
kind: KongIngress
metadata:
  name: kong-sandbox-ingress-config
  namespace: kong
config:
    headers: [Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Auth-Token, Location, Authorization]
    exposed_headers: [X-Auth-Token, Location, Authorization]
upstream:
  name: zcrm365sand.possibilit.nl
  hash_on: ip
  hash_fallback: none
  hash_on_cookie_path: "/priva"
  healthchecks:
    active:
      concurrency: 10
      healthy:
        http_statuses:
        - 200
        - 302
        interval: 0
        successes: 0
      http_path: "/priva"
      timeout: 1
      unhealthy:
        http_failures: 0
        http_statuses:
        - 429
        - 404
        - 500
        - 501
        - 502
        - 503
        - 504
        - 505
        interval: 0
        tcp_failures: 0
        timeouts: 0
    passive:
      healthy:
        http_statuses:
        - 200
        - 201
        - 202
        - 203
        - 204
        - 205
        - 206
        - 207
        - 208
        successes: 0
      unhealthy:
        http_failures: 0
        http_statuses:
        - 429
        - 500
        - 503
        tcp_failures: 0
        timeouts: 0
    slot: 10
proxy:
  path: /swagger/v1/swagger.json
route:
  protocol: http
  methods:
  - POST
  - GET
  regex_priority: 0
  strip_path: true # change or not
  preserve_host: true
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: zcrm365-sandbox-ingress
  namespace: kong
  annotations:
    kubernetes.io/ingress.class: "kong"
    certmanager.k8s.io/cluster-issuer: letsencrypt-prod #letsencrypt-staging
    configuration.konghq.com: kong-sandbox-ingress-config
    certmanager.k8s.io/acme-challenge-type: http01
    kubernetes.io/tls-acme: "true"
    certmanager.k8s.io/acme-http01-edit-in-place: "true"
spec:
  tls:
  - hosts:
    - zcrm365sand.possibilit.nl
    secretName: letsencrypt-prod #-staging
  rules:
  - host: zcrm365sand.possibilit.nl
    http:
      paths:
        - path: "/priva"  #Navigator
          backend:
            serviceName: zcrm365-sandbox
            servicePort: 80

I got the following cases of behavior:

  • When I access the URL http://zcrm365sand.possibilit.nl/priva
    I get the content served from path: /; instead of path:/priva
    This means that I get access to http://zcrm365sand.possibilit.nl/ and I don’t want to configure routes there

  • When I access the URL http://zcrm365sand.possibilit.nl/priva/
    I get the content served from path: /priva/; instead of path:/priva
    But it happens that I have to add to my path the ‘/’ at the end this means path: /priva/

An also my KongIngress resource not found the swagger content json
indicating that the kong-sandbox-ingress KongIngress resource is not being configured right but I fail to see any misconfigurations with the Ingress definitions.

But when I try with httpie command I get a 200 status code from these two route

    ⟩ http http://zcrm365sand.possibilit.nl/priva
    HTTP/1.1 200 OK
    Connection: keep-alive
    Content-Type: application/json;charset=utf-8
    Date: Tue, 09 Apr 2019 12:52:45 GMT
    Server: Kestrel
    Transfer-Encoding: chunked
    Via: kong/1.0.0
    X-Kong-Proxy-Latency: 0
    X-Kong-Upstream-Latency: 2

    {
        "definitions": {},
        "info": {
            "title": "ZAccountSync API",
            "version": "v1"
        },
        "paths": {
            "/api/AccountSync": {
                "post": {
                    "consumes": [],
                    "operationId": "Post",
                    "parameters": [],
                    "produces": [],
                    "responses": {
                        "200": {
                            "description": "Success"
                        }
                    },
                    "tags": [
                        "AccountSync"
                    ]
                }
            }
        },
        "swagger": "2.0"
    }
⟩ http http://zcrm365sand.possibilit.nl/priva/
HTTP/1.1 200 OK
Connection: keep-alive
Content-Type: application/json;charset=utf-8
Date: Tue, 09 Apr 2019 12:57:07 GMT
Server: Kestrel
Transfer-Encoding: chunked
Via: kong/1.0.0
X-Kong-Proxy-Latency: 0
X-Kong-Upstream-Latency: 3

{
    "definitions": {},
    "info": {
        "title": "ZAccountSync API",
        "version": "v1"
    },
    "paths": {
        "/api/AccountSync": {
            "post": {
                "consumes": [],
                "operationId": "Post",
                "parameters": [],
                "produces": [],
                "responses": {
                    "200": {
                        "description": "Success"
                    }
                },
                "tags": [
                    "AccountSync"
                ]
            }
        }
    },
    "swagger": "2.0"
}

And I can see the path in my route table on kong database and is the /swagger/v1/swagger.json value

I am not sure if I am ignoring something in relation to indicate to kong what is my URL Swagger API address, and also here, I’ve found some similar situation reported like an issue, although looks like something expected https://github.com/Kong/kong/issues/4469

I am using Kong Ingress Controller v0.3.0 and Kong v 1.0.0

To best my knowledge the KongIngress rule and Ingress rule must have the same name or they will not get matched up together.

Also a thing used to be the KongIngress must be created before the Ingress rule (so if you’re using Helm that is something to remember, as Helm has it’s own ordering) I think this is still the case in the current version.

The proxy path - again to best my knowledge - applies to all ingress rules mapping to the same backend service. So if you have 2 ingress rules mapping to the same backend service, you cannot specify a different proxy path override for both.

We had to start using a URL rewrite plugin to accomodate that requirement. Not sure if that is your direct problem though but I figured I’d mention it in case you run into it.

Also you do not mention using this but I recommend a simple HTTP echo service that echos out your full request and headers as a response to troubleshoot these sorts of issues.

1 Like

Hi @jdevalk2

Thanks for the answer.

I have been performing specific tips these days according to your tips and advice I’ve updated the KongIngress and Ingress resources of this way:

apiVersion: configuration.konghq.com/v1
kind: KongIngress
metadata:
  name: sandbox-ingress-zcrm365
  # namespace: default
proxy:
  protocols:
    - http
    - https
  path: /
route:
  methods:
    - POST
    - GET
  strip_path: true #false
  preserve_host: true
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: sandbox-ingress-zcrm365
  #namespace: default
  annotations:
    kubernetes.io/ingress.class: "kong"
    certmanager.k8s.io/acme-challenge-type: http01
    kubernetes.io/tls-acme: "true"
    certmanager.k8s.io/acme-http01-edit-in-place: "true"
    certmanager.k8s.io/cluster-issuer: letsencrypt-prod # letsencrypt-staging
    configuration.konghq.com: sandbox-ingress-zcrm365
spec:
  rules:
    - host: zcrm365sand.possibilit.nl
      http:
        paths:
          - path: "/"
            backend:
              serviceName: zcrm365sandbox
              servicePort: 80
          - path: "/priva"
            backend:
              serviceName: zcrm365sandbox
              servicePort: 80
  tls:
    - hosts:
        - zcrm365sand.possibilit.nl
      secretName: letsencrypt-prod # letsencrypt-staging

This means that I have the route
https://zcrm365sand.possibilit.nl/priva/ and It’s works.

Why happens this redirect behavior if I remove the / at the end of the route?
It’s happening because I already have enabled thepath: / in my Ingress resource?

This means that the (/priva) route itself is working. (I think)

And also the first route
https://zcrm365sand.possibilit.nl/swagger/v1/swagger.json

  • Testing with some http rest clients

When I go to curl -sv https://zcrm365sand.possibilit.nl/priva/ I get the http 301 status code.
Is making this reference to the previous redirection?

⟩ curl -sv https://zcrm365sand.possibilit.nl/priva/
*   Trying 40.115.62.157...
* TCP_NODELAY set
* Connected to zcrm365sand.possibilit.nl (40.115.62.157) port 443 (#0)
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* Some TLS handshakes
* ALPN, server accepted to use http/1.1
* Server certificate:
*  Some certificate data

> GET /priva/ HTTP/1.1
> Host: zcrm365sand.possibilit.nl
> User-Agent: curl/7.63.0
> Accept: */*
> 
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
< HTTP/1.1 301 Moved Permanently
< Content-Length: 0
< Connection: keep-alive
< Date: Fri, 19 Apr 2019 08:52:44 GMT
< Server: Kestrel
< Location: index.html
< X-Kong-Upstream-Latency: 1
< X-Kong-Proxy-Latency: 0
< Via: kong/1.0.0
< 
* Connection #0 to host zcrm365sand.possibilit.nl left intact

But if I perform curl -sv https://zcrm365sand.possibilit.nl/priva/swagger/v1/swagger.json I get the 200 http status code

⟩ curl -sv https://zcrm365sand.possibilit.nl/priva/swagger/v1/swagger.json
*   Trying 40.115.62.157...
* TCP_NODELAY set
* Connected to zcrm365sand.possibilit.nl (40.115.62.157) port 443 (#0)
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*  Some TLS handshakes 
* ALPN, server accepted to use http/1.1
* Server certificate:
*  Some certificates data
*  SSL certificate verify ok.
> GET /priva/swagger/v1/swagger.json HTTP/1.1
> Host: zcrm365sand.possibilit.nl
> User-Agent: curl/7.63.0
> Accept: */*
> 
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
< HTTP/1.1 200 OK
< Content-Type: application/json;charset=utf-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< Date: Fri, 19 Apr 2019 08:51:15 GMT
< Server: Kestrel
< X-Kong-Upstream-Latency: 1
< X-Kong-Proxy-Latency: 1
< Via: kong/1.0.0
< 
* Connection #0 to host zcrm365sand.possibilit.nl left intact
{"swagger":"2.0","info":{"version":"v1","title":"ZAccountSync API"},"host":"zcrm365sand.possibilit.nl/","paths":{"/api/AccountSync":{"post":{"tags":["AccountSync"],"operationId":"Post","consumes":[],"produces":[],"parameters":[],"responses":{"200":{"description":"Success"}}}}},"definitions":{}}⏎ 

So, the logs of my service pod when I go to https://zcrm365sand.possibilit.nl/priva/ are always my root path domain

2019-04-19 08:54:42 INF "Request starting HTTP/1.1 GET http://10.244.3.10:5000/swagger/v1/swagger.json  "
2019-04-19 08:54:42 INF "Request finished in 0.8356ms 200 application/json;charset=utf-8"
2019-04-19 08:54:50 INF "Request starting HTTP/1.1 GET http://10.244.3.10:5000/swagger/v1/swagger.json  "
2019-04-19 08:54:50 INF "Request finished in 1.2997ms 200 application/json;charset=utf-8"
2019-04-19 08:54:52 INF "Request starting HTTP/1.1 GET http://10.244.3.10:5000/swagger/v1/swagger.json  "
2019-04-19 08:54:52 INF "Request finished in 0.6289ms 200 application/json;charset=utf-8"
2019-04-19 08:55:00 INF "Request starting HTTP/1.1 GET http://10.244.3.10:5000/swagger/v1/swagger.json  "
2019-04-19 08:55:00 INF "Request finished in 1.1153ms 200 application/json;charset=utf-8"
2019-04-19 08:55:02 INF "Request starting HTTP/1.1 GET http://10.244.3.10:5000/swagger/v1/swagger.json  "
2019-04-19 08:55:02 INF "Request finished in 1.1096ms 200 application/json;charset=utf-8"

such as follow here:

Mainly my doubt is why I have to add / at the end to the /priva route works (https://zcrm365sand.possibilit.nl/priva/)

It is related to the fact that I have two paths / and /priva in my Ingress?

Why happens this redirect behavior if I remove the / at the end of the route?

Try definining your path like this:

  rules:
  - http:
      paths:
      - path: 
          '/priva[/]{0,1}$'
1 Like