Create a mixed-protocol external load balancer

Preview

This feature is subject to the "Pre-GA Offerings Terms" in the General Service Terms section of theService Specific Terms. Pre-GA features are available "as is" and might have limited support. For more information, see thelaunch stage descriptions.

This document shows you how to expose an application running in aGoogle Kubernetes Engine (GKE) cluster to the internet by using a mixed-protocol,external LoadBalancer Service for both TCP and UDP traffic.

To learn more about external passthrough Network Load Balancers, seeBackendservice-based external passthrough Network Load Balancer.

Overview

You can expose applications that use both TCP and UDP protocols by using twoseparate GKE LoadBalancer Services with a manually coordinated,shared IP address. However, this approach is inefficient because it requiresmanaging multiple Services for a single application and might lead to issuessuch as configuration errors or exhausted IP address quotas.

Mixed-protocol LoadBalancer Services let you use a single Service to managetraffic for both TCP and UDP. Using a single Service simplifies yourconfiguration by letting you use a single IPv4 address and a consolidatedset of forwarding rules for both protocols. This feature is supported forexternal passthrough Network Load Balancer.

Before you begin

Before you start, make sure that you have performed the following tasks:

  • Enable the Google Kubernetes Engine API.
  • Enable Google Kubernetes Engine API
  • If you want to use the Google Cloud CLI for this task,install and theninitialize the gcloud CLI. If you previously installed the gcloud CLI, get the latest version by running thegcloud components update command. Earlier gcloud CLI versions might not support running the commands in this document.Note: For existing gcloud CLI installations, make sure to set thecompute/regionproperty. If you use primarily zonal clusters, set thecompute/zone instead. By setting a default location, you can avoid errors in the gcloud CLI like the following:One of [--zone, --region] must be supplied: Please specify location. You might need to specify the location in certain commands if the location of your cluster differs from the default that you set.

Requirements

To create an external LoadBalancer Service that uses mixed protocols, yourcluster must meet the following requirements:

  • Mixed-protocol load balancing is available only on newly-created clusters onversion 1.34.1-gke.2190000 or later.
  • You must have theHttpLoadBalancing addon enabled on your cluster.
  • For new external LoadBalancer Services, to implement the load balancer, setthespec.loadBalancerClass field tonetworking.gke.io/l4-regional-external in the Service manifest. Forexisting Services, your manifest already has thecloud.google.com/l4-rbs:"enabled" annotation, and you can leave the annotation as is.

Limitations

  • Mixed-protocol load balancers support only IPv4 addresses.
  • You can't use mixed protocols in a Service manifest with the following finalizers:

    • gke.networking.io/l4-ilb-v1
    • gke.networking.io/l4-netlb-v1

    If your manifest has these finalizers, you must delete and re-create theService according to the preceding requirements.

Pricing

Google Cloud bills you per forwarding rule, for any external IP addresses,and for data sent. The following table describes the number of forwarding rulesand external IP addresses used for specified configurations. For moreinformation, seeVPC network pricing.

TypeTransport LayerInternet LayerNumber of Forwarding RulesNumber of External IP Addresses
ExternalSingle (Either TCP or UDP)IPv411
IPv611
IPv4 and IPv6(DualStack)22
Mixed (Both TCP and UDP)IPv421

Deploy a workload

This section shows how to deploy a sample workload that listens on both TCP andUDP ports. Note that the Deployment configuration is the same whether you are using amixed-protocol LoadBalancer Service or two separate single-protocol LoadBalancerServices.

  1. The following manifest is for a sample application that listens on port 8080for both TCP and UDP traffic. Save the following manifest asmixed-app-deployment.yaml:

    apiVersion:apps/v1kind:Deploymentmetadata:name:mixed-app-deploymentspec:replicas:3selector:matchLabels:app:mixed-apptemplate:metadata:labels:app:mixed-appspec:containers:-image:gcr.io/kubernetes-e2e-test-images/agnhost:2.6name:agnhostargs:["serve-hostname","--port=8080","--tcp=true","--udp=true","--http=false"]ports:-name:tcp8080protocol:TCPcontainerPort:8080-name:udp8080protocol:UDPcontainerPort:8080
  2. Apply the manifest to your cluster:

    kubectlapply-fmixed-app-deployment.yaml

Create a mixed-protocol load balancer

Create a Service of typeLoadBalancer that exposes the deployment to both TCPand UDP traffic.

  1. Save the following manifest asmixed-protocol-lb.yaml:

    apiVersion:v1kind:Servicemetadata:name:mixed-protocol-lbspec:loadBalancerClass:"networking.gke.io/l4-regional-external"type:LoadBalancerselector:app:mixed-appports:-name:tcp-portprotocol:TCPport:8080-name:udp-portprotocol:UDPport:8080

    The preceding Service has two ports, one for TCP and one for UDP, both onport 8080.

  2. Apply the manifest to your cluster:

    kubectlapply--server-side-fmixed-protocol-lb.yaml
Note: If you created the Service with thecloud.google.com/l4-rbs: "enabled" annotation instead, you might see a warning event from the legacy service controller:mixed-protocol is not supported for LoadBalancer. You can safely ignore this message because the new controller, which supports mixed-protocols, correctly provisions the load balancer.

Verify the mixed-protocol load balancer

After you create the Service, verify that GKE created the loadbalancer successfully.

  1. Inspect the Service:

    kubectldescribeservicemixed-protocol-lb

    The output shows the external IP address of the load balancer and theforwarding rules for both TCP and UDP. Verify the following details in theoutput:

    • Thestatus.loadBalancer.ingress.ip field is populated.
    • Verify that the following annotations for your external load balancer are present:
      • service.kubernetes.io/tcp-forwarding-rule
      • service.kubernetes.io/udp-forwarding-rule
    • TheEvents section contains no error messages.

Update the mixed-protocol load balancer

You can update the ports on a mixed-protocol load balancer by editing theService manifest. To edit the Service, run the following command:

kubectleditserviceSERVICE_NAME

ReplaceSERVICE_NAME with the name of your Service.

Update ports

To update the ports on a mixed-protocol load balancer, modify theportssection of the Service manifest. You can add, remove, or modify ports.

The following example adds a UDP port for streaming and a TCP port forgame-server metadata:

apiVersion:v1kind:Servicemetadata:name:mixed-protocol-lbspec:loadBalancerClass:"networking.gke.io/l4-regional-external"type:LoadBalancerselector:app:mixed-appports:-name:tcp-portprotocol:TCPport:8080-name:streamingprotocol:UDPport:10100-name:gameserver-metadataprotocol:TCPport:10400-name:httpsprotocol:TCPport:443

Update a single-protocol load balancer to mixed-protocol

To change a single-protocol load balancer to a mixed-protocol load balancer,edit the Service to include ports for both the TCP and UDP protocols.

The following example adds a UDP port for DNS to an existing TCP-only loadbalancer:

apiVersion:v1kind:Servicemetadata:name:already-existing-single-protocol-lbspec:loadBalancerClass:"networking.gke.io/l4-regional-external"type:LoadBalancerselector:app:mixed-appports:-name:httpprotocol:TCPport:80-name:httpsprotocol:TCPport:443-name:dnsprotocol:UDPport:53

Update a mixed-protocol load balancer to single-protocol

To change a mixed-protocol load balancer to a single-protocol load balancer,remove all ports for one of the protocols.

The following example removes the UDP port for DNS, which converts the loadbalancer to TCP-only:

apiVersion:v1kind:Servicemetadata:name:already-existing-mixed-protocol-lbspec:loadBalancerClass:"networking.gke.io/l4-regional-external"type:LoadBalancerselector:app:mixed-appports:-name:httpprotocol:TCPport:80-name:httpsprotocol:TCPport:443

Delete the mixed-protocol LoadBalancer

To delete themixed-protocol-lb external LoadBalancer Service, run thefollowing command:

kubectldeleteservicemixed-protocol-lb

GKE automatically removes all load balancer resourcescreated for the Service.

Troubleshooting

This section describes how to resolve common issues with mixed-protocolLoadBalancer Services.

Check for error events

The first step in troubleshooting is to check the events associated with yourService.

  1. Get the details of your Service:

    kubectldescribeservicemixed-protocol-lb
  2. Review theEvents section at the end of the output for any errormessages.

Error: Mixed Protocol is not supported for LoadBalancer

If you created the Service with thecloud.google.com/l4-rbs: "enabled"annotation, you might see a warning event from the original service controllerafter you create the mixed-protocol load balancer:mixed-protocol is notsupported for LoadBalancer.

You can safely ignore this message because the new controller, which supportsmixed-protocols, correctly provisions the load balancer.

Port definition is missing after an update

Symptom:

When you update a Service that uses the same port for both TCP and UDP (forexample, port 8080), one of the port definitions is missing from the updatedService.

Cause:

This is a known issue in Kubernetes. When you update a Service with multipleprotocols on the same port, the client-side patch calculation can incorrectlymerge the port list, which causes one of the port definitions to be removed.This issue affects clients that use client-side patching, such askubectl apply andthe Go client with merge patches.

Solution:

The workaround for this issue depends on your client.

  • For kubectl: Use the--server-side flag withkubectl apply:

    kubectlapply--server-side-fYOUR_SERVICE_MANIFEST.yaml

    ReplaceYOUR_SERVICE_MANIFEST with the name of yourService manifest.

  • For go-client: Don't use merge patches. Instead, use an update call toreplace the Service. This requires an HTTPPUT request with the entireService object specification.

What's next

Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2025-12-16 UTC.