Ingress tutorials
Load balance TCP services
The HAProxy Kubernetes Ingress Controller can load balance TCP services.
Load balancing TCP services is different from load balancing HTTP services. With HTTP, the ingress controller listens on ports 80 and 443, receiving traffic for all backend services and then routing requests based on the requested DNS hostname or URL path. With TCP, however, you must expose entirely new ports and map them to backend services.
Choose one of the following methods, but use only one. Using both could cause port conflicts:
Define TCP services with a custom resource Jump to heading
Available since
- HAProxy Kubernetes Ingress Controller 3.0
- HAProxy Enterprise Kubernetes Ingress Controller 3.0
To define the mapping of TCP ports to backend services, you will create a YAML file that contains a TCP custom resource. We will name the file tcp-customresource.yaml.
-
Install the
TCPcustom resource definition.Skip if using Helm
If you installed the ingress controller with Helm, this CRD is installed and updated automatically. Once installed, to perform updates on this CRD with Helm see: Update CRDs.
nixkubectl apply -f https://www.haproxy.com/documentation/kubernetes-ingress/community/crd/v3-1/ingress.v1.haproxy.org_tcps.yamlnixkubectl apply -f https://www.haproxy.com/documentation/kubernetes-ingress/community/crd/v3-1/ingress.v1.haproxy.org_tcps.yaml -
Define the listening TCP port and the Kubernetes service to which it should be mapped:
tcp-customresource.yamlyamlapiVersion: ingress.v1.haproxy.org/v1kind: TCPmetadata:name: example-service1-tcpannotations:ingress.class: haproxyspec:- name: example-tcpfrontend:name: example-frontendtcplog: truebinds:- name: bind1port: 2000service:name: example-service1port: 3000tcp-customresource.yamlyamlapiVersion: ingress.v1.haproxy.org/v1kind: TCPmetadata:name: example-service1-tcpannotations:ingress.class: haproxyspec:- name: example-tcpfrontend:name: example-frontendtcplog: truebinds:- name: bind1port: 2000service:name: example-service1port: 3000In this example:
- Since version 3.1, you must add an
ingress.classannotation to match the class name set on the ingress controller. Otherwise, the TCP custom resource will be ignored. - The
frontendsection configure a new frontend in the ingress controller. You can add other frontend arguments. See the CRD reference page (/kubernetes-ingress/community/configuration-reference/tcps-crd/) for a list of supported keywords. - The
bindssection sets TCP port on which to listen for incoming connections. - The
servicesection sets the Kubernetes service to relay requests to.
- Since version 3.1, you must add an
-
Apply the custom resource:
nixkubectl apply -f tcp-customresource.yamlnixkubectl apply -f tcp-customresource.yaml -
Define your backend service:
example-service.yamlyamlapiVersion: v1kind: Servicemetadata:name: example-service1namespace: defaultspec:selector:app: example-service1ports:- protocol: TCPport: 3000targetPort: 3000example-service.yamlyamlapiVersion: v1kind: Servicemetadata:name: example-service1namespace: defaultspec:selector:app: example-service1ports:- protocol: TCPport: 3000targetPort: 3000In this example:
- The service’s
nameshould match the mapped service in the custom resource. For example,example-service1. - The
protocolshould beTCP. - The
portshould match the service’s port in the custom resource. For example,3000. - The
targetPortis your pod’s listening port.
- The service’s
-
Apply the service:
nixkubectl apply -f example-service.yamlnixkubectl apply -f example-service.yamloutputservice/example-service1 createdoutputservice/example-service1 created -
If you deployed the ingress controller as a NodePort service, which is the default, then in addition to publishing the listening ports on the ingress controller, you will also need to define NodePort port numbers. How you do this depends on whether you are using Helm.
-
Create or edit your Helm values file to set the
service.tcpPortssection:myvals.yamlyamlcontroller:name: controllerservice:tcpPorts:- name: example-service1port: 2000targetPort: 2000nodePort: 30000protocol: TCPmyvals.yamlyamlcontroller:name: controllerservice:tcpPorts:- name: example-service1port: 2000targetPort: 2000nodePort: 30000protocol: TCPIn this example, for each TCP service:
- Provide a name for the port. The name of the port cannot exceed 11 characters.
portandtargetPortare both the port at which the ingress controller is listening.nodePortis the port to publish for external access. Valid NodePorts are in the 30000-32767 range.- Set
protocoltoTCP.
-
Execute the
helm upgradecommand, providing the name of the YAML values file with-f:nixhelm upgrade haproxy-kubernetes-ingress -f myvals.yaml haproxytech/kubernetes-ingress --namespace haproxy-controllernixhelm upgrade haproxy-kubernetes-ingress -f myvals.yaml haproxytech/kubernetes-ingress --namespace haproxy-controlleroutputRelease "haproxy-kubernetes-ingress" has been upgraded. Happy Helming! NAME: haproxy-kubernetes-ingress [...] Service ports mapped are: - name: http containerPort: 8080 protocol: TCP - name: https containerPort: 8443 protocol: TCP - name: stat containerPort: 1024 protocol: TCP - name: quic containerPort: 8443 protocol: UDP - name: service-1-tcp containerPort: 2000 protocol: TCPoutputRelease "haproxy-kubernetes-ingress" has been upgraded. Happy Helming! NAME: haproxy-kubernetes-ingress [...] Service ports mapped are: - name: http containerPort: 8080 protocol: TCP - name: https containerPort: 8443 protocol: TCP - name: stat containerPort: 1024 protocol: TCP - name: quic containerPort: 8443 protocol: UDP - name: service-1-tcp containerPort: 2000 protocol: TCPThe
tcpPortswe specified in the YAMLmyvals.yamlfile are present in the output above. Note that to the ingress controller, the names of our ports have changed and have-tcpappended to the end of their names. This does not affect operation.
-
To view/edit the
haproxy-kubernetes-ingressservice, callkubectl edit service. The command will open the service file in your configured editor.You can define your default editor by using the
KUBE_EDITORorEDITORenvironment variables or, if neither are defined,viis used for Linux ornotepadfor Windows.nixkubectl -n haproxy-controller edit svc haproxy-kubernetes-ingressnixkubectl -n haproxy-controller edit svc haproxy-kubernetes-ingressAdd entries to the
portssection for each of your TCP services.yamlspec:[...]ports:[...]- name: example-service1nodePort: 30000port: 2000protocol: TCPtargetPort: 2000yamlspec:[...]ports:[...]- name: example-service1nodePort: 30000port: 2000protocol: TCPtargetPort: 2000In this example, for each TCP service:
- Name the port. For example,
example-service1. - Specify a
nodePort. Valid NodePorts are in the 30000-32767 range. - Set the
portandtargetPortto the port the ingress controller service will listen on. For example,2000. - Set the
protocoltoTCP.
- Name the port. For example,
-
Save the changes and close the file. The display shows that the file was edited:
outputservice/haproxy-kubernetes-ingress editedoutputservice/haproxy-kubernetes-ingress edited
You can connect to your TCP service through the load balancer on the port you specify as the
nodePort. -
Example: Load balance a TCP service using a custom resource Jump to heading
In the following example, we will deploy a Pod running BusyBox and we will configure the ingress controller for load balancing traffic to it over TCP. BusyBox provides several Linux utilities and is useful for troubleshooting and testing. We will use an instance of BusyBox to run netcat (nc) which will listen for the incoming traffic.
-
To deploy an instance of BusyBox in your Kubernetes cluster, copy the following YAML and save it to a file named
busybox.yaml:busybox.yamlyamlapiVersion: apps/v1kind: Deploymentmetadata:name: busybox-deploymentlabels:app: busyboxspec:replicas: 1selector:matchLabels:app: busyboxtemplate:metadata:labels:app: busyboxspec:containers:- name: busyboximage: busyboxcommand: ["sh", "-c", "while true; do nc -v -lk -p 5570; done"]ports:- containerPort: 5570protocol: TCP---apiVersion: v1kind: Servicemetadata:name: busybox-servicespec:selector:app: busyboxports:- protocol: TCPport: 5570targetPort: 5570busybox.yamlyamlapiVersion: apps/v1kind: Deploymentmetadata:name: busybox-deploymentlabels:app: busyboxspec:replicas: 1selector:matchLabels:app: busyboxtemplate:metadata:labels:app: busyboxspec:containers:- name: busyboximage: busyboxcommand: ["sh", "-c", "while true; do nc -v -lk -p 5570; done"]ports:- containerPort: 5570protocol: TCP---apiVersion: v1kind: Servicemetadata:name: busybox-servicespec:selector:app: busyboxports:- protocol: TCPport: 5570targetPort: 5570This YAML contains the definitions for:
- A Deployment for BusyBox named
busybox-deployment. We specify that we want to use the busybox image.- We specify a
containerPortof5570. We will run netcat on this port and connect to it through the load balancer. - The deployment includes a command that will run netcat (
nc) listening on TCP port5570.
- We specify a
- A Service named
busybox-servicethat will expose port5570. Note that in the next steps, we will configure the ingress controller to connect to this port.
- A Deployment for BusyBox named
-
Apply the changes to create the resources:
nixkubectl apply -f busybox.yamlnixkubectl apply -f busybox.yamloutputdeployment.apps/busybox-deployment created service/busybox-service createdoutputdeployment.apps/busybox-deployment created service/busybox-service created -
Install the
TCPcustom resource definition.nixkubectl apply -f https://www.haproxy.com/documentation/kubernetes-ingress/community/crd/v3-1/ingress.v1.haproxy.org_tcps.yamlnixkubectl apply -f https://www.haproxy.com/documentation/kubernetes-ingress/community/crd/v3-1/ingress.v1.haproxy.org_tcps.yaml -
Define the listening TCP port and the Kubernetes service to which it should be mapped:
tcp-customresource.yamlyamlapiVersion: ingress.v1.haproxy.org/v1kind: TCPmetadata:name: busybox-service-tcpannotations:ingress.class: haproxyspec:- name: busybox-tcpfrontend:name: busybox-frontendtcplog: truebinds:- name: bind1port: 2002service:name: busybox-serviceport: 5570tcp-customresource.yamlyamlapiVersion: ingress.v1.haproxy.org/v1kind: TCPmetadata:name: busybox-service-tcpannotations:ingress.class: haproxyspec:- name: busybox-tcpfrontend:name: busybox-frontendtcplog: truebinds:- name: bind1port: 2002service:name: busybox-serviceport: 5570 -
Apply the custom resource:
nixkubectl apply -f tcp-customresource.yamlnixkubectl apply -f tcp-customresource.yaml -
Edit the
haproxy-kubernetes-ingressservice to map the listening port2002to NodePort30000. Depending on whether you installed the ingress controller with Helm or Kubectl, you can edit these resources as follows:We will use the
helm upgradecommand to automatically update thehaproxy-kubernetes-ingressservice. We will provide a values file to the command using the-foption. This values file will configure our ports.-
Create a file named
myvals.yamland add the following:myvals.yamlyamlcontroller:name: controllerservice:tcpPorts:- name: busyboxport: 2002targetPort: 2002nodePort: 30000protocol: TCPmyvals.yamlyamlcontroller:name: controllerservice:tcpPorts:- name: busyboxport: 2002targetPort: 2002nodePort: 30000protocol: TCP -
Execute the
helm upgradecommand, providing the name of the YAML values file with-f:nixhelm upgrade haproxy-kubernetes-ingress -f myvals.yaml haproxytech/kubernetes-ingress --namespace haproxy-controllernixhelm upgrade haproxy-kubernetes-ingress -f myvals.yaml haproxytech/kubernetes-ingress --namespace haproxy-controller
-
To view/edit the
haproxy-kubernetes-ingressservice, callkubectl edit service. The command will open the service file in your configured editor:You can define your default editor by using the
KUBE_EDITORorEDITORenvironment variables or, if neither are defined,viis used for Linux ornotepadfor Windows.nixkubectl -n haproxy-controller edit svc haproxy-kubernetes-ingressnixkubectl -n haproxy-controller edit svc haproxy-kubernetes-ingress-
Add an entry in the
portssection with the following:yaml- name: busyboxport: 2002targetPort: 2002nodePort: 30000protocol: TCPyaml- name: busyboxport: 2002targetPort: 2002nodePort: 30000protocol: TCP -
Save the changes and close the file. The display shows that the file was edited:
outputservice/haproxy-kubernetes-ingress editedoutputservice/haproxy-kubernetes-ingress edited
-
-
-
Customize the backend service by defining a
Backendcustom resource. For example, below we change the load balancing algorithm to beleastconn.-
Create the custom resource. Below we set the load balancing algorithm to
leastconn:backend-crd.yamlyamlapiVersion: "ingress.v1.haproxy.org/v1"kind: Backendmetadata:name: example-backendnamespace: defaultspec:config:name: example-configbalance:algorithm: "leastconn"backend-crd.yamlyamlapiVersion: "ingress.v1.haproxy.org/v1"kind: Backendmetadata:name: example-backendnamespace: defaultspec:config:name: example-configbalance:algorithm: "leastconn" -
Apply the change:
nixkubectl apply -f backend-crd.yamlnixkubectl apply -f backend-crd.yamloutputbackend.ingress.v1.haproxy.org/example-backend createdoutputbackend.ingress.v1.haproxy.org/example-backend created -
Update your Service definition to use this custom resource by adding the
haproxy.org/cr-backendannotation:busybox.yamlyamlapiVersion: v1kind: Servicemetadata:name: busybox-servicenamespace: defaultannotations:haproxy.org/cr-backend: default/example-backendspec:selector:app: busyboxports:- protocol: TCPport: 5570targetPort: 5570busybox.yamlyamlapiVersion: v1kind: Servicemetadata:name: busybox-servicenamespace: defaultannotations:haproxy.org/cr-backend: default/example-backendspec:selector:app: busyboxports:- protocol: TCPport: 5570targetPort: 5570 -
Apply the service:
nixkubectl apply -f busybox.yamlnixkubectl apply -f busybox.yamloutputservice/busybox-service createdoutputservice/busybox-service created
In the end, the generated load balancer configuration inside the ingress controller pod will look like this:
haproxyfrontend tcpcr_default_busybox-frontendmode tcpbind :2002 name bind1option tcplogdefault_backend default_busybox-service_3000backend default_busybox-service_3000mode tcpbalance leastconnserver SRV_1 10.244.0.2:3000 enabledhaproxyfrontend tcpcr_default_busybox-frontendmode tcpbind :2002 name bind1option tcplogdefault_backend default_busybox-service_3000backend default_busybox-service_3000mode tcpbalance leastconnserver SRV_1 10.244.0.2:3000 enabled -
Test the connection through the load balancer (click to expand)
To test the connection to the BusyBox instance running netcat through the load balancer:
-
Get the name of the BusyBox pod by calling
kubectl get pod:nixkubectl get podnixkubectl get podExample outputNAME READY STATUS RESTARTS AGE busybox-deployment-6fbb645fd4-cfkwp 1/1 Running 0 12mExample outputNAME READY STATUS RESTARTS AGE busybox-deployment-6fbb645fd4-cfkwp 1/1 Running 0 12m -
From a server that has connection to your cluster, such as the server from which you run
kubectl, use netcat to connect to the port you specified as the NodePort for your TCP service when you configured the ingress controller. In this example, the NodePort we specified was30000.nixnc 127.0.0.1 30000nixnc 127.0.0.1 30000 -
Check the logs of the BusyBox pod to confirm that a connection was made:
nixkubectl logs busybox-deployment-6fbb645fd4-cfkwpnixkubectl logs busybox-deployment-6fbb645fd4-cfkwpoutputconnect to [::ffff:10.244.0.10]:5570 from 10-244-0-8.haproxy-kubernetes-ingress.haproxy-controller.svc.cluster.local:60598 ([::ffff:10.244.0.8]:60598)outputconnect to [::ffff:10.244.0.10]:5570 from 10-244-0-8.haproxy-kubernetes-ingress.haproxy-controller.svc.cluster.local:60598 ([::ffff:10.244.0.8]:60598)
Define TCP services with a ConfigMap Jump to heading
Available since
- HAProxy Kubernetes Ingress Controller 1.4
- HAProxy Enterprise Kubernetes Ingress Controller 1.4
To define the mapping of TCP ports to backend services, you will create a YAML file that contains a ConfigMap definition. We will name the file tcp-configmap.yaml.
-
Define the listening TCP ports and the Kubernetes services to which they should be mapped:
tcp-configmap.yamlyamlapiVersion: v1kind: ConfigMapmetadata:name: tcp-configmapnamespace: haproxy-controllerdata:2000:default/example-service1:30002001:mynamespace/example-service2:3001tcp-configmap.yamlyamlapiVersion: v1kind: ConfigMapmetadata:name: tcp-configmapnamespace: haproxy-controllerdata:2000:default/example-service1:30002001:mynamespace/example-service2:3001In this example:
- We set the ConfigMap’s
nametotcp-configmap, but you can use any name. Later, we will reference this name. - In the
datasection, add the ports that you will open on the ingress controller for receiving traffic, mapped to their associated backend services. Here, the ingress controller will listen on ports 2000 and 2001.
- We set the ConfigMap’s
-
Apply the ConfigMap:
nixkubectl apply -f tcp-configmap.yamlnixkubectl apply -f tcp-configmap.yamloutputconfigmap/tcp-configmap createdoutputconfigmap/tcp-configmap created -
Edit the ingress controller to use the
--configmap-tcp-servicesstartup argument to reference the ConfigMap. How you do this depends on whether you are using Helm.-
Create or edit your Helm values file to set the
--configmap-tcp-servicesargument under theextraArgskey:myvals.yamlyamlcontroller:extraArgs:- --configmap-tcp-services=haproxy-controller/tcp-configmapmyvals.yamlyamlcontroller:extraArgs:- --configmap-tcp-services=haproxy-controller/tcp-configmap -
Execute the
helm upgradecommand, providing the name of the YAML values file with-f:nixhelm upgrade haproxy-kubernetes-ingress -f myvals.yaml haproxytech/kubernetes-ingress --namespace haproxy-controllernixhelm upgrade haproxy-kubernetes-ingress -f myvals.yaml haproxytech/kubernetes-ingress --namespace haproxy-controlleroutputRelease "haproxy-kubernetes-ingress" has been upgraded. Happy Helming! NAME: haproxy-kubernetes-ingressoutputRelease "haproxy-kubernetes-ingress" has been upgraded. Happy Helming! NAME: haproxy-kubernetes-ingress
-
To view/edit the
haproxy-kubernetes-ingressdeployment, callkubectl edit deployment. The command will open the deployment file in your configured editor.You can define your default editor by using the
KUBE_EDITORorEDITORenvironment variables or, if neither are defined,viis used for Linux ornotepadfor Windows.nixkubectl -n haproxy-controller edit deployment haproxy-kubernetes-ingressnixkubectl -n haproxy-controller edit deployment haproxy-kubernetes-ingress -
Add the
--configmap-tcp-servicesargument inargsand set the value to the name of your ConfigMap (haproxy-controller/tcp-configmapin this example).yamlspec:containers:- args:- --default-ssl-certificate=haproxy-controller/kubernetes-ingress-default-cert- --configmap=haproxy-controller/kubernetes-ingress- --http-bind-port=8080- --https-bind-port=8443- --ingress.class=haproxy- --publish-service=haproxy-controller/kubernetes-ingress- --log=info- --configmap-tcp-services=haproxy-controller/tcp-configmap[...]yamlspec:containers:- args:- --default-ssl-certificate=haproxy-controller/kubernetes-ingress-default-cert- --configmap=haproxy-controller/kubernetes-ingress- --http-bind-port=8080- --https-bind-port=8443- --ingress.class=haproxy- --publish-service=haproxy-controller/kubernetes-ingress- --log=info- --configmap-tcp-services=haproxy-controller/tcp-configmap[...] -
Save the changes and close the file. The display shows that the file was edited:
outputdeployment.apps/haproxy-kubernetes-ingress editedoutputdeployment.apps/haproxy-kubernetes-ingress edited
-
-
Define your backend services. The example below defines two services:
example-services.yamlyamlapiVersion: v1kind: Servicemetadata:name: example-service1namespace: defaultspec:selector:app: example-service1ports:- protocol: TCPport: 3000targetPort: 3000---apiVersion: v1kind: Servicemetadata:name: example-service2namespace: mynamespacespec:selector:app: example-service2ports:- protocol: TCPport: 3001targetPort: 3001example-services.yamlyamlapiVersion: v1kind: Servicemetadata:name: example-service1namespace: defaultspec:selector:app: example-service1ports:- protocol: TCPport: 3000targetPort: 3000---apiVersion: v1kind: Servicemetadata:name: example-service2namespace: mynamespacespec:selector:app: example-service2ports:- protocol: TCPport: 3001targetPort: 3001In this example:
- The service’s
nameshould match the mapped entry in the ConfigMap. For example,example-service1. - The
protocolshould beTCP. - The
portshould match the service’s port in the ConfigMap. For example,3000. - The
targetPortis your pod’s listening port.
- The service’s
-
Apply the services:
nixkubectl apply -f example-services.yamlnixkubectl apply -f example-services.yamloutputservice/example-service1 created service/example-service2 createdoutputservice/example-service1 created service/example-service2 created -
If you deployed the ingress controller as a NodePort service, which is the default, then in addition to publishing the listening ports on the ingress controller, you will also need to define NodePort port numbers. How you do this depends on whether you are using Helm.
-
Create or edit your Helm values file to set the
service.tcpPortssection. Also, if you previously set the--configmap-tcp-servicesargument, keep that too.myvals.yamlyamlcontroller:name: controllerservice:tcpPorts:- name: example-service1port: 2000targetPort: 2000nodePort: 30000protocol: TCP- name: example-service2port: 2001targetPort: 2001nodePort: 30001protocol: TCPextraArgs:- --configmap-tcp-services=haproxy-controller/tcp-configmapmyvals.yamlyamlcontroller:name: controllerservice:tcpPorts:- name: example-service1port: 2000targetPort: 2000nodePort: 30000protocol: TCP- name: example-service2port: 2001targetPort: 2001nodePort: 30001protocol: TCPextraArgs:- --configmap-tcp-services=haproxy-controller/tcp-configmapIn this example, for each TCP service:
- Provide a name for the port. The name of the port cannot exceed 11 characters.
portandtargetPortare both the port at which the ingress controller is listening.nodePortis the port to publish for external access. Valid NodePorts are in the 30000-32767 range.- Set
protocoltoTCP.
-
Execute the
helm upgradecommand, providing the name of the YAML values file with-f:nixhelm upgrade haproxy-kubernetes-ingress -f myvals.yaml haproxytech/kubernetes-ingress --namespace haproxy-controllernixhelm upgrade haproxy-kubernetes-ingress -f myvals.yaml haproxytech/kubernetes-ingress --namespace haproxy-controlleroutputRelease "haproxy-kubernetes-ingress" has been upgraded. Happy Helming! NAME: haproxy-kubernetes-ingress [...] Service ports mapped are: - name: http containerPort: 8080 protocol: TCP - name: https containerPort: 8443 protocol: TCP - name: stat containerPort: 1024 protocol: TCP - name: quic containerPort: 8443 protocol: UDP - name: service-1-tcp containerPort: 2000 protocol: TCP - name: service-2-tcp containerPort: 2001 protocol: TCPoutputRelease "haproxy-kubernetes-ingress" has been upgraded. Happy Helming! NAME: haproxy-kubernetes-ingress [...] Service ports mapped are: - name: http containerPort: 8080 protocol: TCP - name: https containerPort: 8443 protocol: TCP - name: stat containerPort: 1024 protocol: TCP - name: quic containerPort: 8443 protocol: UDP - name: service-1-tcp containerPort: 2000 protocol: TCP - name: service-2-tcp containerPort: 2001 protocol: TCPThe
tcpPortswe specified in the YAMLmyvals.yamlfile are present in the output above. Note that to the ingress controller, the names of our ports have changed and have-tcpappended to the end of their names. This does not affect operation.
-
To view/edit the
haproxy-kubernetes-ingressservice, callkubectl edit service. The command will open the service file in your configured editor.You can define your default editor by using the
KUBE_EDITORorEDITORenvironment variables or, if neither are defined,viis used for Linux ornotepadfor Windows.nixkubectl -n haproxy-controller edit svc haproxy-kubernetes-ingressnixkubectl -n haproxy-controller edit svc haproxy-kubernetes-ingressAdd entries to the
portssection for each of your TCP services.yamlspec:[...]ports:[...]- name: example-service1nodePort: 30000port: 2000protocol: TCPtargetPort: 2000- name: example-service2nodePort: 30001port: 2001protocol: TCPtargetPort: 2001yamlspec:[...]ports:[...]- name: example-service1nodePort: 30000port: 2000protocol: TCPtargetPort: 2000- name: example-service2nodePort: 30001port: 2001protocol: TCPtargetPort: 2001In this example, for each TCP service:
- Name the port. For example,
example-service1. - Specify a
nodePort. Valid NodePorts are in the 30000-32767 range. - Set the
portandtargetPortto the port the ingress controller service will listen on. For example,2000. - Set the
protocoltoTCP.
- Name the port. For example,
-
Save the changes and close the file. The display shows that the file was edited:
outputservice/haproxy-kubernetes-ingress editedoutputservice/haproxy-kubernetes-ingress edited
You can connect to your TCP service through the load balancer on the port you specify as the
nodePort. -
Example: Load balance a TCP service using a ConfigMap Jump to heading
In the following example, we will deploy a Pod running BusyBox and we will configure the ingress controller for load balancing traffic to it over TCP. BusyBox provides several Linux utilities and is useful for troubleshooting and testing. We will use an instance of BusyBox to run netcat (nc) which will listen for the incoming traffic.
-
To deploy an instance of BusyBox in your Kubernetes cluster, copy the following YAML and save it to a file named
busybox.yaml:busybox.yamlyamlapiVersion: apps/v1kind: Deploymentmetadata:name: busybox-deploymentlabels:app: busyboxspec:replicas: 1selector:matchLabels:app: busyboxtemplate:metadata:labels:app: busyboxspec:containers:- name: busyboximage: busyboxcommand: ["sh", "-c", "while true; do nc -v -lk -p 5570; done"]ports:- containerPort: 5570protocol: TCP---apiVersion: v1kind: Servicemetadata:name: busybox-servicespec:selector:app: busyboxports:- protocol: TCPport: 5570targetPort: 5570---apiVersion: v1kind: ConfigMapmetadata:name: tcp-configmapnamespace: haproxy-controllerdata:2000:default/busybox-service:5570busybox.yamlyamlapiVersion: apps/v1kind: Deploymentmetadata:name: busybox-deploymentlabels:app: busyboxspec:replicas: 1selector:matchLabels:app: busyboxtemplate:metadata:labels:app: busyboxspec:containers:- name: busyboximage: busyboxcommand: ["sh", "-c", "while true; do nc -v -lk -p 5570; done"]ports:- containerPort: 5570protocol: TCP---apiVersion: v1kind: Servicemetadata:name: busybox-servicespec:selector:app: busyboxports:- protocol: TCPport: 5570targetPort: 5570---apiVersion: v1kind: ConfigMapmetadata:name: tcp-configmapnamespace: haproxy-controllerdata:2000:default/busybox-service:5570This YAML contains the definitions for:
- A Deployment for BusyBox named
busybox-deployment. We specify that we want to use the busybox image.- We specify a
containerPortof5570. We will run netcat on this port and connect to it through the load balancer. - The deployment includes a command that will run netcat (
nc) listening on TCP port5570.
- We specify a
- A Service named
busybox-servicethat will expose port5570. Note that in the next steps, we will configure the ingress controller to connect to this port. - A ConfigMap named
tcp-configmap. This provides the ingress controller with connection information. Note that this ConfigMap belongs to thehaproxy-controllernamespace (the namespace created when you installed the ingress controller), whereas the other BusyBox components belong to thedefaultnamespace. This ConfigMap specifies that the ingress controller will make connection to the service namedbusybox-serviceon port5570. We will map port2000to a NodePort in ourhaproxy-kubernetes-ingressservice.
- A Deployment for BusyBox named
-
Apply the changes to create the resources:
nixkubectl apply -f busybox.yamlnixkubectl apply -f busybox.yamloutputdeployment.apps/busybox-deployment created service/busybox-service created configmap/tcp-configmap createdoutputdeployment.apps/busybox-deployment created service/busybox-service created configmap/tcp-configmap created -
Edit the
haproxy-kubernetes-ingressdeployment and thehaproxy-kubernetes-ingressservice to configure the ingress controller to make connection to the Service namedbusybox-serviceon port5570. Depending on whether you installed the ingress controller with Helm or Kubectl, you can edit these resources as follows:We will use the
helm upgradecommand to automatically update thehaproxy-kubernetes-ingressdeployment and service. We will provide a values file to the command using the-foption. This values file will specify an additional argument for the ingress controller deployment and it will configure our ports.-
Create a file named
myvals.yamland add the following:myvals.yamlyamlcontroller:name: controllerservice:tcpPorts:- name: busyboxport: 2000targetPort: 2000nodePort: 30000protocol: TCPextraArgs:- --configmap-tcp-services=haproxy-controller/tcp-configmapmyvals.yamlyamlcontroller:name: controllerservice:tcpPorts:- name: busyboxport: 2000targetPort: 2000nodePort: 30000protocol: TCPextraArgs:- --configmap-tcp-services=haproxy-controller/tcp-configmap -
Execute the
helm upgradecommand, providing the name of the YAML values file with-f:nixhelm upgrade haproxy-kubernetes-ingress -f myvals.yaml haproxytech/kubernetes-ingress \--namespace haproxy-controllernixhelm upgrade haproxy-kubernetes-ingress -f myvals.yaml haproxytech/kubernetes-ingress \--namespace haproxy-controlleroutputRelease "haproxy-kubernetes-ingress" has been upgraded. Happy Helming! NAME: haproxy-kubernetes-ingress [...] Service ports mapped are: - name: http containerPort: 8080 protocol: TCP - name: https containerPort: 8443 protocol: TCP - name: stat containerPort: 1024 protocol: TCP - name: quic containerPort: 8443 protocol: UDP - name: busybox-tcp containerPort: 2000 protocol: TCPoutputRelease "haproxy-kubernetes-ingress" has been upgraded. Happy Helming! NAME: haproxy-kubernetes-ingress [...] Service ports mapped are: - name: http containerPort: 8080 protocol: TCP - name: https containerPort: 8443 protocol: TCP - name: stat containerPort: 1024 protocol: TCP - name: quic containerPort: 8443 protocol: UDP - name: busybox-tcp containerPort: 2000 protocol: TCP
-
To view/edit the
haproxy-kubernetes-ingressdeployment, callkubectl edit deployment. The command will open the deployment file in your configured editor:nixkubectl -n haproxy-controller edit deployment haproxy-kubernetes-ingressnixkubectl -n haproxy-controller edit deployment haproxy-kubernetes-ingress-
Add the
--configmap-tcp-servicesargument inargsand set the value to the name of your ConfigMap (haproxy-controller/tcp-configmap).yamlspec:containers:- args:- --default-ssl-certificate=haproxy-controller/kubernetes-ingress-default-cert- --configmap=haproxy-controller/kubernetes-ingress- --http-bind-port=8080- --https-bind-port=8443- --ingress.class=haproxy- --publish-service=haproxy-controller/kubernetes-ingress- --log=info- --configmap-tcp-services=haproxy-controller/tcp-configmap[...]yamlspec:containers:- args:- --default-ssl-certificate=haproxy-controller/kubernetes-ingress-default-cert- --configmap=haproxy-controller/kubernetes-ingress- --http-bind-port=8080- --https-bind-port=8443- --ingress.class=haproxy- --publish-service=haproxy-controller/kubernetes-ingress- --log=info- --configmap-tcp-services=haproxy-controller/tcp-configmap[...] -
Save the changes and close the file. The display shows that the file was edited:
outputdeployment.apps/haproxy-kubernetes-ingress editedoutputdeployment.apps/haproxy-kubernetes-ingress edited
-
-
To view/edit the
haproxy-kubernetes-ingressservice, callkubectl edit service. The command will open the service file in your configured editor:nixkubectl -n haproxy-controller edit svc haproxy-kubernetes-ingressnixkubectl -n haproxy-controller edit svc haproxy-kubernetes-ingress-
Add an entry in the
portssection with the following:yaml- name: busyboxport: 2000targetPort: 2000nodePort: 30000protocol: TCPyaml- name: busyboxport: 2000targetPort: 2000nodePort: 30000protocol: TCP -
Save the changes and close the file. The display shows that the file was edited:
outputservice/haproxy-kubernetes-ingress editedoutputservice/haproxy-kubernetes-ingress edited
-
You can define your default editor by using the
KUBE_EDITORorEDITORenvironment variables or, if neither are defined,viis used for Linux ornotepadfor Windows. -
Test the connection through the load balancer (click to expand)
To test the connection to the BusyBox instance running netcat through the load balancer:
-
Get the name of the BusyBox pod by calling
kubectl get pod:nixkubectl get podnixkubectl get podExample outputNAME READY STATUS RESTARTS AGE busybox-deployment-6fbb645fd4-cfkwp 1/1 Running 0 12mExample outputNAME READY STATUS RESTARTS AGE busybox-deployment-6fbb645fd4-cfkwp 1/1 Running 0 12m -
From a server that has connection to your cluster, such as the server from which you run
kubectl, use netcat to connect to the port you specified as the NodePort for your TCP service when you configured the ingress controller. In this example, the NodePort we specified was30000.nixnc 127.0.0.1 30000nixnc 127.0.0.1 30000 -
Check the logs of the BusyBox pod to confirm that a connection was made:
nixkubectl logs busybox-deployment-6fbb645fd4-cfkwpnixkubectl logs busybox-deployment-6fbb645fd4-cfkwpoutputconnect to [::ffff:10.244.0.10]:5570 from 10-244-0-8.haproxy-kubernetes-ingress.haproxy-controller.svc.cluster.local:60598 ([::ffff:10.244.0.8]:60598)outputconnect to [::ffff:10.244.0.10]:5570 from 10-244-0-8.haproxy-kubernetes-ingress.haproxy-controller.svc.cluster.local:60598 ([::ffff:10.244.0.8]:60598)
Example: Load balance an external endpoint using a ConfigMap Jump to heading
In the following example, we will load balance traffic to an external endpoint at ifconfig.info. This service displays your IP address.
We will create a Service and then map an Endpoint to it at port 80.
-
Copy the following YAML and save it to a file named
ifconfig.yaml:ifconfig.yamlyamlapiVersion: v1kind: Servicemetadata:name: ifcservicespec:ports:- port: 80protocol: TCPname: http---apiVersion: v1kind: Endpointsmetadata:name: ifcservicesubsets:- addresses:- ip: 104.21.4.246ports:- port: 80protocol: TCPname: http---apiVersion: v1kind: ConfigMapmetadata:name: tcp-configmapnamespace: haproxy-controllerdata:1981:default/ifcservice:80ifconfig.yamlyamlapiVersion: v1kind: Servicemetadata:name: ifcservicespec:ports:- port: 80protocol: TCPname: http---apiVersion: v1kind: Endpointsmetadata:name: ifcservicesubsets:- addresses:- ip: 104.21.4.246ports:- port: 80protocol: TCPname: http---apiVersion: v1kind: ConfigMapmetadata:name: tcp-configmapnamespace: haproxy-controllerdata:1981:default/ifcservice:80This YAML contains the definitions for:
- A Service named
ifcservicethat will expose port80. Note that in the next steps, we will configure the ingress controller to connect to this port. - An Endpoint mapped to
ifcservice. Note that this Endpoint must have the same name as the Service. - A ConfigMap named
tcp-configmap. This provides the ingress controller with connection information. Note that this ConfigMap belongs to thehaproxy-controllernamespace (the namespace created when you installed the ingress controller), whereas the other components belong to thedefaultnamespace. This ConfigMap specifies that the ingress controller will make connection to the service namedifcserviceon port80. We will map port1981to a NodePort in ourhaproxy-kubernetes-ingressservice.
- A Service named
-
Apply the changes to create the resources:
nixkubectl apply -f busybox.yamlnixkubectl apply -f busybox.yamloutputservice/ifcservice created endpoints/ifcservice created configmap/tcp-configmap createdoutputservice/ifcservice created endpoints/ifcservice created configmap/tcp-configmap created -
Edit the
haproxy-kubernetes-ingressdeployment and thehaproxy-kubernetes-ingressservice to configure the ingress controller to make connection to the Service namedifcserviceon port80. Depending on whether you installed the ingress controller with Helm or Kubectl, you can edit these resources as follows:We will use the
helm upgradecommand to automatically update thehaproxy-kubernetes-ingressdeployment and service. We will provide a values file to the command using the-foption. This values file will specify an additional argument for the ingress controller deployment and it will configure our ports.-
Create a file named
myvals.yamland add the following:myvals.yamlyamlcontroller:name: controllerservice:tcpPorts:- name: ifconnport: 1981targetPort: 1981nodePort: 30681protocol: TCPextraArgs:- --configmap-tcp-services=haproxy-controller/tcp-configmapmyvals.yamlyamlcontroller:name: controllerservice:tcpPorts:- name: ifconnport: 1981targetPort: 1981nodePort: 30681protocol: TCPextraArgs:- --configmap-tcp-services=haproxy-controller/tcp-configmap -
Execute the
helm upgradecommand, providing the name of the YAML values file with-f:nixhelm upgrade haproxy-kubernetes-ingress -f myvals.yaml haproxytech/kubernetes-ingress \--namespace haproxy-controllernixhelm upgrade haproxy-kubernetes-ingress -f myvals.yaml haproxytech/kubernetes-ingress \--namespace haproxy-controlleroutputRelease "haproxy-kubernetes-ingress" has been upgraded. Happy Helming! NAME: haproxy-kubernetes-ingress [...] Service ports mapped are: - name: http containerPort: 8080 protocol: TCP - name: https containerPort: 8443 protocol: TCP - name: stat containerPort: 1024 protocol: TCP - name: quic containerPort: 8443 protocol: UDP - name: ifconn-tcp containerPort: 1981 protocol: TCPoutputRelease "haproxy-kubernetes-ingress" has been upgraded. Happy Helming! NAME: haproxy-kubernetes-ingress [...] Service ports mapped are: - name: http containerPort: 8080 protocol: TCP - name: https containerPort: 8443 protocol: TCP - name: stat containerPort: 1024 protocol: TCP - name: quic containerPort: 8443 protocol: UDP - name: ifconn-tcp containerPort: 1981 protocol: TCP
-
To view/edit the
haproxy-kubernetes-ingressdeployment, callkubectl edit deployment. The command will open the deployment file in your configured editor:nixkubectl -n haproxy-controller edit deployment haproxy-kubernetes-ingressnixkubectl -n haproxy-controller edit deployment haproxy-kubernetes-ingress-
Add the
--configmap-tcp-servicesargument inargsand set the value to the name of your ConfigMap (haproxy-controller/tcp-configmap).yamlspec:containers:- args:- --default-ssl-certificate=haproxy-controller/kubernetes-ingress-default-cert- --configmap=haproxy-controller/kubernetes-ingress- --http-bind-port=8080- --https-bind-port=8443- --ingress.class=haproxy- --publish-service=haproxy-controller/kubernetes-ingress- --log=info- --configmap-tcp-services=haproxy-controller/tcp-configmap[...]yamlspec:containers:- args:- --default-ssl-certificate=haproxy-controller/kubernetes-ingress-default-cert- --configmap=haproxy-controller/kubernetes-ingress- --http-bind-port=8080- --https-bind-port=8443- --ingress.class=haproxy- --publish-service=haproxy-controller/kubernetes-ingress- --log=info- --configmap-tcp-services=haproxy-controller/tcp-configmap[...] -
Save the changes and close the file. The display shows that the file was edited:
outputdeployment.apps/haproxy-kubernetes-ingress editedoutputdeployment.apps/haproxy-kubernetes-ingress edited
-
-
To view/edit the
haproxy-kubernetes-ingressservice, callkubectl edit service. The command will open the service file in your configured editor:nixkubectl -n haproxy-controller edit svc haproxy-kubernetes-ingressnixkubectl -n haproxy-controller edit svc haproxy-kubernetes-ingress-
Add an entry in the
portssection with the following:yaml- name: busyboxport: 1981targetPort: 1981nodePort: 30681protocol: TCPyaml- name: busyboxport: 1981targetPort: 1981nodePort: 30681protocol: TCP -
Save the changes and close the file. The display shows that the file was edited:
outputservice/haproxy-kubernetes-ingress editedoutputservice/haproxy-kubernetes-ingress edited
-
You can define your default editor by using the
KUBE_EDITORorEDITORenvironment variables or, if neither are defined,viis used for Linux ornotepadfor Windows. -
Test the connection through the load balancer (click to expand)
To test the connection to the external Endpoint through the load balancer:
-
From a server that has connection to your cluster, such as the server from which you run
kubectl, usecurlto connect to the port you specified as the NodePort for your TCP service when you configured the ingress controller. In this example, the NodePort we specified was30681.nixcurl -H "host: ifconfig.info" 127.0.0.1:30681nixcurl -H "host: ifconfig.info" 127.0.0.1:30681Your IP address should display.
output172.31.35.253output172.31.35.253
Do you have any suggestions on how we can improve the content of this page?