How to expose custom TCP/UDP port with Traefik Ingress on GKE?

How to expose custom TCP/UDP port with Traefik Ingress on GKE?

Information about the demo environment

  • Kubernetes cluster on Google Kubernetes Engine

    • version: 1.26
  • Type: private cluster

    • Nodes have private IP addresses. They are not accessible from the Internet directly.

    • Access from the outside to the applications on the cluster is done using Google Load Balancers

    • Access from inside is done using NAT Gateway

  • Traefik deployed as the Helm chart from https://helm.traefik.io/traefik

  • Traefik Helm chart version: 23.1.0

Goal

Expose ports: 8081 TCP and 8082 UDP outside, through Traefik and GCP Load Balancer.

Configuration

The following code is for the values.yaml file. Here is the original file with default values: https://github.com/traefik/traefik-helm-chart/blob/master/traefik/values.yaml

deployment:
  # GCP health check sends requests to all nodes in the cluster.
  # Thus we need to run Traefik on all nodes, because Traefik receives and
  # answers on GCPs requests.
  kind: DaemonSet

# Values based on my experience and my cluster needs
resources:
  requests:
    cpu: "100m"
    memory: "100Mi"

service:
  type: LoadBalancer
  # Create separate LB for TCP and UDP.
  # Traefik will make sure that GCP creates separate LBs.
  single: false
  spec:
    # Required by K8s to preserve client's original IP
    externalTrafficPolicy: Local
    # First create static IP in GCP and then use it here
    loadBalancerIP: _CHANGE_ME_

additionalArguments:
  - --api.insecure=true
  - --ping.entrypoint=web

# Enable Prometheus metrics
metrics:
  prometheus:
    service:
      enabled: true
    serviceMonitor:
      enabled: true

logs:
  general:
    format: json
    level: ERROR
  access:
    enabled: true
    format: json
    fields:
      general:
        defaultmode: keep
      headers:
        defaultmode: keep

providers:
  kubernetesCRD:
    ingressClass: traefik

  kubernetesIngress:
    ingressClass: traefik

ingressRoute:
  dashboard:
    annotations:
      # Set IngressClass for Traefik dashboard
      kubernetes.io/ingress.class: traefik

# The most important part
ports:
  # Configure port for health checks.
  # entrypoint: web
  traefik:
    healthchecksPort: 8000
  # Custom TCP port
  test-tcp:
    port: 8081
    expose: true
    protocol: TCP
  # Custom UDP port
  test-udp:
    port: 8082
    expose: true
    protocol: UDP

How to use custom ports?

apiVersion: v1
kind: Service
metadata:
  name: my-svc-expose-tcp
spec:
  ports:
    - name: my-port-tcp
      protocol: TCP
      port: 8081
      targetPort: my-port-tcp
  type: LoadBalancer
---
apiVersion: v1
kind: Service
metadata:
  name: my-svc-expose-udp
spec:
  ports:
    - name: my-port-udp
      protocol: UDP
      port: 8082
      targetPort: my-port-udp
  type: LoadBalancer