---
layout: docs
page_title: Split traffic between multi-port services 
description: Learn how to configure Consul to split TCP traffic between two ports of a multi-port service using the TCPRoute resource and the v2 catalog API
---

# Split TCP traffic between multi-port services

<Warning>

The v2 catalog API is currently in beta. This documentation supports testing and development scenarios. Do not use the v2 catalog API in secure production environments.

</Warning>

This page describes the process for splitting TCP, HTTP, and gRPC traffic between two ports of a multi-port service. It includes an example TCPRoute resource configuration to demonstrate Consul's multi-port features.

## Prerequisites

Splitting traffic between two ports of a multi-port service requires the [v2 catalog API](/consul/docs/architecture/v2/catalog).

In addition, they are two different workflows for registering Services in Kubernetes using the v2 catalog API. The instructions on this page offer examples for two configuration methods:

- **Method 1**: Register a Kubernetes service that select workloads which expose multiple ports
- **Method 2**: Register multiple Kubernetes Services that direct traffic to an explicit port on the same workload

For guidance on enabling the v2 catalog, deploying multi-port services using these methods, and applying traffic permissions to the services, refer to [configure multi-port services](/consul/docs/k8s/multiport/configure).

## Overview

Complete the following steps to implement a split in TCP traffic between two services:

1. Define the resource's behavior in a custom resource definition (CRD).
1. Apply the resource to your cluster.

## Define route resource

The following example splits traffic for the `api` service. TCP traffic for services registered to the Consul catalog that are available at the `api-workload` port is split so that 50% of the traffic routes to the service at the `api-workload` port and 50% routes to the service at the `admin-workload` port.

<CodeBlockConfig filename="api-split.yaml">

```yaml
apiVersion: mesh.consul.hashicorp.com/v2beta1
kind: TCPRoute
metadata:
  name: api-split
spec:
  parentRefs:
    - ref:
        type:
          group: catalog
          groupVersion: v2beta1
          kind: Service
        name: api
      # The virtual port number for the "api-workload" target port.
      port: "80"
  rules:
    - backendRefs:
      - backendRef:
          ref:
            type:
              group: catalog
              groupVersion: v2beta1
              kind: Service
            name: api
          # The virtual port number for the "api-workload" target port.
          port: "80"
        weight: 50
      - backendRef:
          ref:
            type:
              group: catalog
              groupVersion: v2beta1
              kind: Service
            name: api
          # The virtual port number for the "admin-workload" target port.
          port: "90"
        weight: 50
```

</CodeBlockConfig>

## Apply the resource

Use the `kubectl` command to apply the resource to your Consul cluster.

```shell-session
$ kubectl apply -f api-split.yaml
```

<Tabs>

<Tab heading="Method 1" group="method1">

Then, open a shell session in the `web` container and test the `api` service on port 90.

```shell-session
$ kubectl exec -it ${WEB_POD} -c web -- curl api:90
```

</Tab>

<Tab heading="Method 2" group="method2">

Then, open a shell session in the `web` container and test the `api-admin` service on port 90.

```shell-session
$ kubectl exec -it ${WEB_POD} -c web -- curl api-admin:90
```

</Tab>
</Tabs>

Half of the traffic should respond with the `hello world` response from port 80, instead of port 90's response of `hello world from 9090 admin`. Repeat the command several times to verify that you receive both responses.
