How to implement proxy_pass with kong ingress?

We are currently in the process of moving over to kong Kubernetes ingress from NGINX ingress. Unfortunately, we are blocked by some challenges. Currently, in our NGINX ingress, we have some location blocks that need to be proxied to an external domain. We are using server-snippets to implement this.
` nginx.ingress.kubernetes.io/server-snippet: |

   location ~ ^/media/xyz/(.*)$ {
    internal;
    proxy_pass      https://media-files.s3.amazonaws.com/$1;
  }`

is there a way to implement this in kong?

You can convert some, but not all NGINX location+proxy_pass configuration into Kong service and route configuration. Your configuration is simple and should convert fine–more complex configuration that rearranges part of the client-facing path into different locations in the upstream path is where you can encounter issues.

In Kubernetes, you’ll need to create Service and Ingress resources. Since S3 doesn’t actually run in your K8S cluster, you’ll use an ExternalName Service. That only provides the hostname portion of the upstream service, but that should be sufficient for your configuration–if you wanted to append additional path components after, e.g. something like /foo/bar/$1, you’d also include a path annotation.

For the client-facing configuration, you’ll create an Ingress resource. Its rules will include a path, e.g. /media/xyz and typically a hostname (from the server_name of the server block that contains your location block). Since you don’t want to include the /media/xyz path in your upstream requests, you’ll include a strip-path annotation set to true.

Note that the latest K8S Ingress documentation covers v1 of the Ingress resource. While our controller supports both, you K8S cluster may only support the older v1beta format. K8S 1.18 supports v1 as a beta feature, and 1.19 supports it by default. If you’re on 1.17 or older, use the “Versions” menu at the top to switch to your version.

Thanks for the quick answer! Unfortunately, ExternalName Service is on layer 4 which will not work in this case because we need to pass in some information in the HTTP header. eg.

       proxy_set_header Authorization "";
       proxy_set_header Host  staging-media-files.s3.amazonaws.com;
       proxy_set_header X-Real-IP $remote_addr;

Sorry I forgot to include this in my original message.

The configuration for those headers is in a few different

Header transformations not handled by the base route/service configuration, are typically handled via plugins. https://docs.konghq.com/hub/kong-inc/request-transformer/ will allow you to remove existing Authorization headers.

Host headers are handled via Kong route and service configuration, however, and you cannot override them with a plugin: Kong will either send a header matching the route’s hostname (the default) or the service’s hostname. To override that default behavior and instead use the hostname of the service, you need to add a preserve_host annotation, set to false, on your Ingress.

Lastly, Kong will set X-Real-IP to the remote address by default for all proxied requests. Depending on your network layout, however, the client immediately in front of Kong is often a L4 or L7 load balancer. In that case you’d need to configure your load balancer to send information about the client contacting it and then configure Kong to trust their IP ranges. In most Kubernetes deployments, you’ll set those kong.conf settings via environment variables.


© 2019 Kong Inc.    Terms  •  Privacy  •  FAQ