Setting Up Ingress in Minikube for TCP and UDP

Introduction

Ingress is an addon available in minikube. It helps developers route traffic from their host (Laptop, Desktop, etc) to a Kubernetes service running inside their minikube cluster. The ingress addon uses the ingress nginx controller which by default is only configured to listen on ports 80 and 443. By default Ingress doesn’t support TCP and UDP. However we could enable ingress to listen to ports used by TCP and UDP.

Prerequisites

Before starting the tutorial it is assumed that the reader is already aware about Kubernetes, Minikube and Configmaps. To use this tutorial we need the below software/tools.

  • Minikube
  • Telnet
  • kubectl
  • A Text Editor

Steps to achieve

  1. Enable Ingress Addon in Minikube cluster
  2. Update TCP and UDP ConfigMaps
  3. Create a redis deployment inside Minikube cluster
  4. Create a redis service for the redis deployment
  5. Allow traffic to redis from outside

Enable Ingress

To enable ingress you need to execute the following command.

minikube addons enable ingress

Update TCP/UDP ConfigMaps

As mentioned earlier Ingress doesn’t support TCP/UDP by default. We need to edit the existing configmaps for our purpose. Below are the examples of configmap content for TCP and UDP.

apiVersion: v1
kind: ConfigMap
metadata:
  name: tcp-services
  namespace: ingress-nginx
apiVersion: v1
kind: ConfigMap
metadata:
  name: udp-services
  namespace: ingress-nginx

Create a redis deployment

To create a redis deployment we first need a .yaml file to provide the deployment details.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-deployment
  namespace: default
  labels:
    app: redis
spec:
  replicas: 1
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
      - image: redis
        imagePullPolicy: Always
        name: redis
        ports:
        - containerPort: 6379
          protocol: TCP

Create a file redis-deployment.yaml and paste the contents above. Then install the redis deployment with the following command:

kubectl apply -f redis-deployment.yaml

The above command would install the redis deployment. Then we need to expose the deployment as a service so that it could be consumed.

Create Redis Service from the deployment

We need to create file called redis-service.yaml with the below content.

apiVersion: v1
kind: Service
metadata:
  name: redis-service
  namespace: default
spec:
  selector:
    app: redis
  type: ClusterIP
  ports:
    - name: tcp-port
      port: 6379
      targetPort: 6379
      protocol: TCP

Once the file is ready,install the redis service with the following command:

kubectl apply -f redis-service.yaml

Allow traffic to redis deployment

To allow traffic to the redis service from outside the pod we need to patch the tcp service in the kube-system and then patch the ingress-ngnix-controller to kube-systemWe could redo the same steps for UDP.

To add a TCP service to the nginx ingress controller you can run the following command:

kubectl patch configmap tcp-services -n kube-system --patch '{"data":{"6379":"default/redis-service:6379"}}'

Where:

  • 6379 : the port your service should listen to from outside the minikube virtual machine
  • default : the namespace that your service is installed in
  • redis-service : the name of the service

We can verify that our resource was patched with the following command:

kubectl get configmap tcp-services -n kube-system -o yaml

We should see something like this as output of the above command:

apiVersion: v1
data:
  "6379": default/redis-service:6379
kind: ConfigMap
metadata:
  creationTimestamp: "2019-10-01T16:19:57Z"
  labels:
    addonmanager.kubernetes.io/mode: EnsureExists
  name: tcp-services
  namespace: kube-system
  resourceVersion: "2857"
  selfLink: /api/v1/namespaces/kube-system/configmaps/tcp-services
  uid: 4f7fac22-e467-11e9-b543-080027057910

The only value you need to validate is that there is a value under the data property that looks like this:

  "6379": default/redis-service:6379

Patch the ingress-nginx-controller

There is one final step that must be done in order to obtain connectivity from the outside cluster. We need to patch our nginx controller so that it is listening on port 6379 and can route traffic to your service. To do this we need to create a patch file.

nginx-ingress-controller-patch.yaml

spec:
  template:
    spec:
      containers:
      - name: nginx-ingress-controller
        ports:
         - containerPort: 6379
           hostPort: 6379

Create a file called nginx-ingress-controller-patch.yaml and paste the contents above.

Next apply the changes with the following command:

kubectl patch deployment nginx-ingress-controller --patch "$(cat nginx-ingress-controller-patch.yaml)" -n kube-system

Test your connection

Test that you can reach your service with telnet via the following command:

telnet $(minikube ip) 6379

You should see the following output:

Trying 192.168.99.179...
Connected to 192.168.99.179.
Escape character is '^]'

To exit telnet enter the Ctrl key and ] at the same time. Then type quit and press enter.

Summary

These are the steps required to set up one redis service in a minikube cluster and it could listen outside traffic at port 6379. The same steps could be repeated for UDP.

Further Readings:

  1. Ingress Setup for TCP/UDP

Author: Aditya Bhuyan

I am an IT Professional with close to two decades of experience. I mostly work in open source application development and cloud technologies. I have expertise in Java, Spring and Cloud Foundry.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s