{{tag>k8s kubernetes pulumi nginx}}
====== nginx proxy pass to a different domain in k8s ======
This is applicable when using the [[https://kubernetes.github.io/ingress-nginx/|nginx ingress controller]].
Since k8s already uses the proxy_pass from the ''backend'' directive, you can't overwrite this. The solution is to use [[https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#server-snippet|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 [[https://www.pulumi.com|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 ======
* [[wiki:create_docker_config_secret_private_image_pulling_pulumi|Create a Docker config Secret for private image pulling in Pulumi]]
====== References ======
* https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#server-snippet