17 October 2025

Add Encrypted TLS Access to a Kubernetes Web Service



Introduction

Web services utilizing encrypted connections for data access over a chosen port are increasingly becoming the standard for micro-services in this new world of containerized development in the cloud and on-premises. Often serving data in JSON format, these services use Transport Layer Security (TLS). TLS is the successor to the deprecated Secure Sockets Layer or SSL, being more secure and efficient. Here we'll explore an on-premises approach with a local container registry and TLS certificates.

Please note: A newer version of this story is available on Medium.


Approach

To make this happen in the world of Kubernetes orchestration, we need to configure ingress through an edge router (sometimes called a reverse-proxy) to our services. Here we'll use Traefik, the default router included with Rancher's lightweight Kubernetes, K3s. If you need help setting things up, earlier we discussed installing K3s.

To make this happen, we need to create ingress YAML and a Kubernetes secret to contain the certificate information. First we'll need a service, here's a sample definition:

apiVersion: v1
kind: Service
metadata:
  name: my-service-service
spec:
  ports:
    - name: http
      port: 7000
      targetPort: 7001
  selector:
    app: my-service

This sample service listens on port 7000 and forwards to containers listening on port 7001. Note how the service itself is utilizing HTTP internally, there's no need for HTTPs yet. Just in case you need pods to use for this service, let's show how to add them as a deployment:

apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: my-service-deployment
  labels:
    app: my-service
spec:
  replicas: 2 # tells deployment to run 2 pod(s) matching the template
  selector:
    matchLabels:
      app: my-service
  template:
    metadata:
      labels:
        app: my-service
    spec:
      containers:
      - name: my-service
        image: [registry and image]:[tag]
        envFrom:
        - configMapRef:
            name: my-service-configmap
        ports:
        - containerPort: 7001
      imagePullSecrets:
      - name: my-credentials

Now for the exciting part

This deployment uses containers that store registry credentials in a Kubernetes secret. We'll use the same mechanism to store our certificates. First let's add the registry secret via kubectl:


kubectl create secret docker-registry registry-credential --docker-server=[registry server FQDN] --docker-username=[service username] --docker-password=*** --docker-email=[service username]@example.com

Next let's add the TLS secret:

kubectl create secret tls my-tls-secret --cert=./[my cert file name] --key=./[my key file name]

Note that you'll need two files: a certificate and a key file. Next create the ingress YAML:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-service-ingress
  annotations:
    kubertes.io/ingress.class: "traefik"
    traefik.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - http:
     paths:
     - backend:
         serviceName: my-service-service
         servicePort: 7000
       path: /my-service
  tls:
    - secretName: my-tls-secret

In this ingress YAML we've accomplished a number of impressive things. First we've told Traefik in our rewrite rule that we want our service to be accessible externally via the URL "my-service" instead of via a port number. This is sometimes referred to as an API Gateway. Next, we've told Traefik we want to use TLS for access, so we've restricted connection externally to this service via an encrypted TLS connection! Also, it's worth noting, without any further setup, we're using Traefik's built in load-balancing across our cluster worker nodes!

Some useful commands to test things out

First try accessing the new web service in a browser with a url something like:

https://kubernetes-cluster/my-service

Next to verify your secrets and check pods try:

kubectl get secrets
kubectl get pods -A

That should do it for now! Please feel free to leave any questions or comments you have bellow.

No comments:

Post a Comment