User Tools

Site Tools


wiki:nginx_proxy_pass_different_domain_k8s

nginx proxy pass to a different domain in k8s

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
	}


...

Tested on

  • kubectl v1.27.3
  • Pulumi v3.149.0

See also

References

wiki/nginx_proxy_pass_different_domain_k8s.txt · Last modified: 2025/02/19 15:12 by antisa

Except where otherwise noted, content on this wiki is licensed under the following license: CC0 1.0 Universal
CC0 1.0 Universal Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki