Expose TCP and UDP services

Available since MKE 3.7.0

Note

  • You must have MKE admin access to configure TCP and UDP services.

  • Prior to setting up TCP and UDP services, verify that you have correctly configured kubectl.

Kubernetes Ingress only supports services over HTTP and HTTPS. Using NGINX Ingress Controller, though, you can circumvent this limitation to enable situations in which it may be necessary to expose TCP and UDP services.

The following example procedure exposes a TCP service on port 9000 and a UDP service on port 5005:

  1. Deploy a sample TCP service listening on port 9000, to echo back any text it receives with the prefix hello.

    cat <<EOF | kubectl apply -f -
    apiVersion: v1
    kind: Service
    metadata:
      name: tcp-echo
      labels:
        app: tcp-echo
        service: tcp-echo
    spec:
      selector:
        app: tcp-echo
      ports:
      - name: tcp
        port: 9000
    
    ---
    
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: tcp-echo
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: tcp-echo
      template:
        metadata:
          labels:
            app: tcp-echo
        spec:
          containers:
          - name: tcp-echo
            image: docker.io/istio/tcp-echo-server:1.2
            imagePullPolicy: IfNotPresent
            args: [ "9000", "hello" ]
            ports:
            - containerPort: 9000
    EOF
    
  2. Deploy a sample UDP service listening on port 5005.

    cat <<EOF | kubectl apply -f -
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: udp-listener
    
    ---
    
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: udp-listener
      labels:
        app: udp-listener
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: udp-listener
      template:
        metadata:
          labels:
            app: udp-listener
        spec:
          containers:
          - name: udp-listener
            image: mendhak/udp-listener
            ports:
            - containerPort: 5005
              protocol: UDP
              name: udp
    
    ---
    
    apiVersion: v1
    kind: Service
    metadata:
      name: udp-listener
    spec:
      ports:
      - port: 5005
        targetPort: 5005
        protocol: UDP
        name: udp
      selector:
        app: udp-listener
    EOF
    
  3. Verify that the two services are running correctly.

    1. Run kubectl get deploy tcp-echo udp-listener to verify that the deployment was created.

      Example output:

      NAME           READY   UP-TO-DATE   AVAILABLE   AGE
      tcp-echo       1/1     1            1           39s
      udp-listener   1/1     1            1           31s
      
    2. Run kubectl get service tcp-echo udp-listener to list the services created.

      Example output:

      NAME           TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
      tcp-echo       ClusterIP   10.96.172.90   <none>        9000/TCP   46s
      udp-listener   ClusterIP   10.96.19.229   <none>        5005/UDP   37s
      
  4. Configure Ingress Controller to expose the TCP and UDP services.

    1. Verify that the enabled parameter for the cluster_config.ingress_controller option in the MKE configuration file is set to true.

    2. Modify the MKE configuration file to expose the newly created TCP and UDP services, as shown below:

      [cluster_config.ingress_controller]
          enabled = true
      
      ...
      
      [[cluster_config.ingress_controller.ingress_exposed_ports]]
          name = "proxied-tcp-9000"
          port = 9000
          target_port = 9000
          node_port = 33011
          protocol = "TCP"
      
      [[cluster_config.ingress_controller.ingress_exposed_ports]]
          name = "proxied-udp-5005"
          port = 5005
          target_port = 5005
          node_port = 33012
          protocol = "UDP"
      
      ...
      
      [cluster_config.ingress_controller.ingress_tcp_services]
        9000 = "default/tcp-echo:9000"
      [cluster_config.ingress_controller.ingress_udp_services]
        5005 = "default/udp-listener:5005"
      
      ...
      
    3. Upload the modified MKE configuration file to complete the operation. For more information, refer to Use an MKE configuration file.

    Note

    To configure NGINX Ingress Controller using the MKE web UI, in the left-side navigation panel, navigate to <user name> > Admin Settings > Ingress.

  5. Test the TCP service.

    1. Send the text world. The service should respond with hello world:

      export MKE_HOST=<mke host>
      
      echo "world" | netcat $MKE_HOST 33011
      hello world
      
    2. Check the tcp-echo logs:

      kubectl get pods --selector=app=tcp-echo
      

      Example output:

      NAME                        READY   STATUS    RESTARTS   AGE
      tcp-echo-5cf4d68d76-p2c9b   1/1     Running   0          6m6s
      
      kubectl logs tcp-echo-5cf4d68d76-p2c9b
      

      Example output:

      listening on [::]:9000, prefix: hello
      request: world
      response: hello world
      
  6. Test the UDP service.

    1. Send the text UDP Datagram Message:

      echo "UDP Datagram Message" | netcat -v -u $MKE_HOST 33012
      
    2. Check the udp-listneer logs to verify that receipt:

      kubectl get pods --selector=app=udp-listener
      

      Example output:

      NAME                            READY   STATUS    RESTARTS   AGE
      udp-listener-59cdc755d7-qr2bl   1/1     Running   0          93m
      
      kubectl logs udp-listener-59cdc755d7-qr2bl
      

      Example output:

      Listening on UDP port 5005
      UDP Datagram Message
      
      UDP Datagram Message
      
  7. Remove the Kubernetes resources, as they are no longer needed.

    kubectl delete service tcp-echo
    kubectl delete deployment tcp-echo
    kubectl delete service udp-listener
    kubectl delete deployment udp-listener
    

Important

If the services are not reachable:

  • Verify that ports 33011 and 33012 are open on both the node and on the firewall of the cloud platform.

  • Review the logs of the sample applications for error messages:

    kubectl logs -l app=tcp-echo and kubectl logs -l app=ucp-listener
    
  • Review the NGINX Ingress Controller logs for error messages:

    kubectl logs -l app.kubernetes.io/name=ingress-nginx -n ingress-nginx