This is applicable when using the nginx ingress controller.
Since k8s already uses the proxy_pass from the backend
directive, you can't overwrite this. The solution is to use server-snippet annotation.
Let's say you need to proxy pass the example.org/foo/ to other.domain.org. Regular location config for this would look like:
location /foo/ { proxy_pass https://other.domain.org/; # you may or may not need the below redirect, it depends on what the proxied server returns proxy_redirect https://anoother.domain.org https://www.yetanotherdomain.com/bar/; proxy_read_timeout 60; proxy_connect_timeout 60; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host other.domain.org; proxy_set_header X-NginX-Proxy true; proxy_set_header Connection ""; }
Your kubectl ingress yaml file should look like:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: external-proxy-ingress namespace: default annotations: nginx.ingress.kubernetes.io/server-snippet: | location /foo/ { proxy_pass https://other.domain.org/; proxy_set_header Host other.domain.org; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } spec: rules: - host: myapp.example.com http: paths: - pathType: Prefix path: / backend: service: name: dummy-service port: number: 80
You still need a dummy service even if there are no pods that are backing it:
apiVersion: v1 kind: Service metadata: name: dummy-service namespace: default spec: ports: - port: 80 targetPort: 80 clusterIP: None
When deployed, if you inspect the ingress controller with cmd like
kubectl -n ingress-nginx --kubeconfig=kubeconfig exec ingress-nginx-799008-controller-f67867867 -- cat /etc/nginx/nginx.conf
you will see that there should be at least 2 location
directives, one for the dummy-service
for the backend and another one for your custom location.
Here's the Pulumi go example :
... // Create the Ingress resource _, err := v1.NewIngress(ctx, ingressName, &v1.IngressArgs{ Metadata: &metav1.ObjectMetaArgs{ Name: pulumi.String(ingressName), Namespace: pulumi.String(serviceNamespace), Annotations: pulumi.StringMap{ "nginx.ingress.kubernetes.io/server-snippet": pulumi.String(fmt.Sprintf(` location /foo/ { proxy_pass https://other.domain.org/; # you may or may not need the below redirect, it depends on what the proxied server returns proxy_redirect https://anoother.domain.org https://www.yetanotherdomain.com/bar/; proxy_read_timeout 60; proxy_connect_timeout 60; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host other.domain.org; proxy_set_header X-NginX-Proxy true; proxy_set_header Connection ""; } location /bar/ { return 301 /foo/; } location /test/ { return 301 https://www.example.com/; } `)), }, }, Spec: &v1.IngressSpecArgs{ IngressClassName: pulumi.String("nginx"), Rules: v1.IngressRuleArray{ &v1.IngressRuleArgs{ Host: pulumi.String(domainName), Http: &v1.HTTPIngressRuleValueArgs{ Paths: v1.HTTPIngressPathArray{ &v1.HTTPIngressPathArgs{ Path: pulumi.String("/"), PathType: pulumi.String("Prefix"), Backend: &v1.IngressBackendArgs{ Service: &v1.IngressServiceBackendArgs{ Name: pulumi.String(serviceName), Port: &v1.ServiceBackendPortArgs{ Number: pulumi.Int(servicePort), }, }, }, }, }, }, }, }, }, }, pulumi.Provider(k8sProvider)) if err != nil { return err } ...