Using an ingress to expose and external service
22 Mar 2021 | tags: KubernetesRationale TL;DR
Let’s suppose you would like to expose an external service by using a Kubernetes ingress. May be you want to expose a site hosted somewhere else using the nginx ingress as a proxy, for example.
The solution
First of all, we need to create an endpoint object. This object will present an endpoint which will be using an external IP as its upstream. This endpoint will work at the TCP/UDP level, simply forwarding the connection to the upstream host.
---
kind: "Endpoints"
apiVersion: "v1"
metadata:
name: "www"
subsets:
-
addresses:
- ip: "1.1.1.1"
ports:
-
port: 443
name: "www"
~
In this example, I’m defining an endpoint pointing to 1.1.1.1:443 (don’t try it at home, kids). After that, we can define a new service which will use that endpoint, this way we would be able to to expose the upstream service to the ingress controller (which needs a service):
After applying those manifests, we can describe the objects we just created:
# kubectl describe svc www
Name: www
Namespace: kube-system
Labels: <none>
Annotations: <none>
Selector: <none>
Type: ClusterIP
IP: 100.71.29.55
Port: www 443/TCP
TargetPort: 443/TCP
Endpoints: 18.196.54.137:443
Session Affinity: None
Events: <none>
#kubectl describe ep www
Name: www
Namespace: kube-system
Labels: <none>
Annotations: <none>
Subsets:
Addresses: 1.1.1.1
NotReadyAddresses: <none>
Ports:
Name Port Protocol
---- ---- --------
www 443 TCP
Events: <none>
Finally, we need to tell our ingress to expose that upstream service:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
name: www-example-com
spec:
rules:
- host: www.example.com
http:
paths:
- backend:
serviceName: www
servicePort: 443
path: /
In this example, I’m forcing the nginx ingress to talk to the upstream by using https. This is because my particular setup requires that, the upstream does a redirection to https when using plain old http.