How a Kubernetes Service with No Selector Simplified My Workflow

How a Kubernetes Service with No Selector Simplified My Workflow

Did you know Kubernetes can manage TLS certificates for applications running outside the cluster? If this is news to you, you're in for an insightful tutorial! This guide explains how I use Kubernetes to route traffic and manage certificates for external applications, solving key challenges along the way.

Prerequisites

Before diving in, ensure you have experience configuring an Ingress controller and Cert Manager. If you’re unfamiliar with these, no worries! Check out these step-by-step blog posts and come back when you're ready:

The Problem

Not all applications are Cloud Native, i.e. not all applications are designed to thrive in a containerized environment. I encountered this issue with Ghost, the open-source blog and newsletter platform I use for my websites.

Although I managed to deploy Ghost on Kubernetes, it wasn’t built with containers in mind, and tasks like upgrades and backups using the Ghost CLI were challenging. To avoid friction, I migrated my blogs to VMs using Terraform and Ansible.

While this solved some issues, it created two new ones:

  1. Reconfiguring the Load Balancer to route traffic to VMs added manual work I wanted to avoid.
  2. By bypassing Kubernetes, I lost the automated certificate management provided by Cert Manager, Let's Encrypt, and Cloudflare.

While I know there are tools like certbot, I didn't want to re-invent the wheel in the context of my environment where deployments on VM are the exception.

This led me to a critical question:
Can I route traffic from a Kubernetes Ingress to an external application?

Unwanted Scenario

The answer is yes—and it’s surprisingly simple!

The Solution

The official Kubernetes documentation offers a solution. By using a Service without a selector alongside an Endpoints object, you can abstract external backends, such as applications running outside the cluster.

Target Scenario

Here’s the setup:

Step 1: Create a Service Without a Selector

A Service without a selector prevents Kubernetes from associating it with Pods. Instead, you define the target manually.

apiVersion: v1
kind: Service
metadata:
  name: ghost-service
spec:
  type: ClusterIP
  ports:
    - name: http
      port: 80
      targetPort: 2368 # target port exposed by the external app
  selector: {} # empty selector

Note: The targetPort matches the port of your external application.

Step 2: Define the Endpoints

The Endpoints object specifies the external application’s address and port. Ensure the Endpoint name matches the Service name.

apiVersion: v1
kind: Endpoints
metadata:
  name: ghost-service # must match the service name
  namespace: default
subsets:
  - addresses:
      - ip: 192.168.68.171 # target host
    ports:
      - port: 2368 # target port

Step 3: Configure the Ingress

Finally, use an Ingress to route traffic to the Service without a selector. Here's a simple example:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod # triggers cert manager
  name: ghost-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: marcolenzo.eu
    http:
      paths:
      - backend:
          service:
            name: ghost-service # our service with no selector
            port:
              number: 2368
        path: /
        pathType: ImplementationSpecific
  tls:
  - hosts:
    - marcolenzo.eu
    secretName: ghost-cert # cert is stored here
status:
  loadBalancer: {}

This setup ensures Kubernetes manages your TLS certificates while directing traffic to your external application.

Testing the Configuration

To test, modify your hosts file to point your domain to a Kubernetes node, or to a Load Balancer in front of the cluster, should you have one.

sudo nano /etc/hosts
# Add this line
192.168.68.201 marcolenzo.eu # my HAProxy

Open the application in a browser. If everything is configured correctly, the traffic routes seamlessly, and the Let's Encrypt certificate is valid.

Cert Verification

Summary

In this tutorial, we’ve learned that:

  1. Not all applications are built to run in Kubernetes.
  2. You can route traffic from Kubernetes to external applications using an Ingress, Service without a selector, and Endpoints.
  3. Kubernetes can act as an API Gateway and manage TLS certificates, even for external workloads.

If you found this post helpful, great news! I’m creating a free Kubernetes course with nine modules and over 30 lessons. Subscribe to my YouTube Channel and this website to stay updated.

Thank you for reading—don’t forget to share this post to help others discover this approach!