There are various reasons why setting up external service proxying from a Kubernetes cluster becomes essential. For example:
- Managing a hybrid deployment where certain services operate within a Kubernetes cluster, while others remain on-premises.
- Handling services with specific requirements, such as object storage or databases, that need to stay outside the cluster.
- Dealing with a service situated in a different data center than the Kubernetes cluster.
- Undertaking significant restructuring or refactoring within the Kubernetes cluster, aiming to minimize downtime and establish a seamless traffic redirection during migration.
On this occasion, I have an external service, called code-server, which I had previously deployed on my blog here.
I intend to proxy/expose it using a Kubernetes service.
Proxy to external services with Kubernetes Service
Let’s start by creating a default ClusterIP Service:
cat<<EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
name: rj-codeserver-service
spec:
ports:
- port: 8080
targetPort: 8080
type: ClusterIP
EOF
Now, since we’re creating a Service without selectors, no Endpoint is being created for us so we need to create an Endpoint manually and provide an IP address of the external service/application that we want to proxy the requests to.
cat<<EOF | kubectl apply -f -
apiVersion: v1
kind: Endpoints
metadata:
name: rj-codeserver-service # Must be equal to Service name for automatic mapping
subsets:
- addresses:
- ip: 13.212.177.111 # IP address of your external service
ports:
- port: 8080 # Listen Port of your external service
EOF
Next, let’s create an Ingress resource in order to enable traffic routing to the newly created Service. If the backend service only accepts HTTPS traffic and using NGINX, in addition to updating the destination port accordingly we will need to add nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
annotation to the Ingress resource definition.
cat<<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt
nginx.ingress.kubernetes.io/rewrite-target: /
name: rj-codeserver-ingress
spec:
ingressClassName: nginx
rules:
- host: code.rjhaikal.my.id
http:
paths:
- backend:
service:
name: rj-codeserver-service
port:
number: 8080
path: /
pathType: Prefix
tls:
- hosts:
- 'code.rjhaikal.my.id'
secretName: code-rjhaikal-secret
EOF
The Flow would look something like this:
And it's done😎. Now go to https://code.rjhaikal.my.id