@@ -33,38 +33,24 @@ Current implementation relies on the client-native library and its models to con
3333apiVersion : ingress.v1.haproxy.org/v1
3434kind : TCP
3535metadata :
36- name : tcp-2
36+ name : tcp-1
37+ namespace : test
3738spec :
38- - name : tcp-http-echo-445
39+ - name : tcp-http-echo-8443
3940 frontend :
40- name : fe-http-echo-445
41+ name : fe-http-echo-8443
4142 tcplog : true
4243 log_format : " %{+Q}o %t %s"
4344 binds :
44- - name : v4ssl
45- # address: 1.2.3.4
46- port : 32769
47- ssl : true
48- ssl_certificate : tcp-test-cert
49- - name : v4acceptproxy
50- # address: 172.0.0.2
51- port : 32769
52- accept_proxy : true
53- service :
54- name : " http-echo"
55- port : 445
56- - name : tcp-http-echo-444
57- frontend :
58- name : fe-http-echo-444
59- tcplog : true
60- log_format : " %{+Q}o %t %s %v"
61- binds :
62- - name : v4acceptproxy-2
63- port : 32768
64- accept_proxy : true
45+ - name : v4
46+ port : 32766
47+ - name : v4v6
48+ address : " ::"
49+ port : 32766
50+ v4v6 : true
6551 service :
6652 name : " http-echo"
67- port : 444
53+ port : 8443
6854` ` `
6955
7056A ` TCP` CR contains a list of TCP services definitions.
@@ -75,27 +61,79 @@ Each of them has:
7561 - a list of `binds` : any setting from client-native bind model is allowed
7662- a `service` defintion that is an Kubernetes upstream Service/Port (the K8s Service has to be in the same namespace as the TCP CR is deployed)
7763
64+ # # Pod and Service definitions
65+
66+ with the following Kubernetes Service and Pod manifests :
67+
68+
69+ ` ` ` yaml
70+ ---
71+ kind: Deployment
72+ apiVersion: apps/v1
73+ metadata:
74+ name: http-echo
75+ namespace: test
76+ spec:
77+ replicas: 1
78+ selector:
79+ matchLabels:
80+ app: http-echo
81+ template:
82+ metadata:
83+ creationTimestamp: null
84+ labels:
85+ app: http-echo
86+ spec:
87+ containers:
88+ - name: http-echo
89+ image: haproxytech/http-echo:latest
90+ imagePullPolicy: Never
91+ args:
92+ - --default-response=hostname
93+ ports:
94+ - name: http
95+ containerPort: 8888
96+ protocol: TCP
97+ - name: https
98+ containerPort: 8443
99+ protocol: TCP
100+ ---
101+ kind: Service
102+ apiVersion: v1
103+ metadata:
104+ name: http-echo
105+ namespace: test
106+ spec:
107+ ipFamilyPolicy: RequireDualStack
108+ ports:
109+ - name: http
110+ protocol: TCP
111+ port: 8888
112+ targetPort: http
113+ - name: https
114+ protocol: TCP
115+ port: 8443
116+ targetPort: https
117+ selector:
118+ app: http-echo
119+ ---
120+
121+ ` ` `
122+
78123
79124# ## HAProxy configuration generated for this TCP CR
80125
81126# ### Frontend sections
82127
83128
84129```
85- frontend tcpcr_test_fe-http-echo-443
130+ frontend tcpcr_test_fe-http-echo-8443
86131 mode tcp
87132 bind :32766 name v4
88133 bind [ ::] :32766 name v4v6 v4v6
89134 log-format '%{+Q}o %t %s'
90135 option tcplog
91136 default_backend test_http-echo_https
92-
93- frontend tcpcr_test_fe-http-echo-444
94- mode tcp
95- bind :32767 name v4acceptproxy accept-proxy
96- log-format '%{+Q}o %t %s'
97- option tcplog
98- default_backend test_http-echo_https2
99137```
100138
101139The frontend name `tcpcr_test_fe-http-echo-443` follow the pattern:
@@ -110,95 +148,12 @@ backend test_http-echo_https
110148 no option abortonclose
111149 timeout server 50000
112150 default-server check
113- server SRV_1 10.244.0.64:8443 enabled
114- server SRV_2 127.0.0.1:8443 disabled
115- server SRV_3 127.0.0.1:8443 disabled
116- server SRV_4 127.0.0.1:8443 disabled
117-
118- backend test_http-echo_https2
119- mode tcp
120- balance roundrobin
121- no option abortonclose
122- timeout server 50000
123- default-server check
124- server SRV_1 10.244.0.64:8443 enabled
125- server SRV_2 127.0.0.1:8443 disabled
151+ server SRV_1 [ fd00:10:244::8] :8443 enabled
152+ server SRV_2 10.244.0.8:8443 enabled
126153 server SRV_3 127.0.0.1:8443 disabled
127154 server SRV_4 127.0.0.1:8443 disabled
128155```
129156
130- with the following Kubernetes Service and Ingress manifests:
131- <details>
132- <summary>Service</summary>
133-
134- ```yaml
135- kind: Service
136- apiVersion: v1
137- metadata:
138- name: http-echo
139- spec:
140- ports:
141- - name: http
142- protocol: TCP
143- port: 80
144- targetPort: http
145- - name: https
146- protocol: TCP
147- port: 443
148- targetPort: https
149- - name: https2
150- protocol: TCP
151- port: 444
152- targetPort: https
153- - name: https3
154- protocol: TCP
155- port: 445
156- targetPort: https
157- selector:
158- app: http-echo
159-
160- ```
161- </details >
162-
163- <details >
164- <summary >Ingress</summary >
165-
166- ``` yaml
167- kind : Ingress
168- apiVersion : networking.k8s.io/v1
169- metadata :
170- name : http-echo
171- annotations :
172- ingress.class : haproxy
173- spec :
174- rules :
175- - host : " echo.haproxy.local"
176- http :
177- paths :
178- - path : /
179- pathType : Prefix
180- backend :
181- service :
182- name : http-echo
183- port :
184- name : http
185- - path : /foo_s
186- pathType : Prefix
187- backend :
188- service :
189- name : http-echo
190- port :
191- name : https
192- - path : /foo_s2
193- pathType : Prefix
194- backend :
195- service :
196- name : http-echo
197- port :
198- name : https2
199-
200- ```
201- </details >
202157
203158## How to configure the backend ?
204159
@@ -244,16 +199,6 @@ backend test_http-echo_https
244199 server SRV_3 127.0.0.1:8443 disabled
245200 server SRV_4 127.0.0.1:8443 disabled
246201
247- backend test_http-echo_https2
248- mode tcp
249- balance leastconn
250- no option abortonclose
251- default-server check-sni example.com resolve-prefer ipv4 sni str(example.com) verify none
252- server SRV_1 10.244.0.64:8443 enabled
253- server SRV_2 127.0.0.1:8443 disabled
254- server SRV_3 127.0.0.1:8443 disabled
255- server SRV_4 127.0.0.1:8443 disabled
256-
257202```
258203
259204## Collisions
@@ -262,24 +207,53 @@ backend test_http-echo_https2
262207- collisions on frontend names
263208- collisions on bind address/port
264209
265- In case several TCPs (* in the same namespace* ) have this kind of collisions, we only apply the one that was created first based on the older CreationTimestamp of the CR.
210+ In case several TCPs (* accross all namespaces* ) have this kind of collisions, we only apply the one that was created first based on the older CreationTimestamp of the CR.
211+
212+ For example, with using the previous ` http-echo ` deployement and service, and the already deplyed TCP ` tcp-1 ` in namespace ` test ` , if we try to deploy the following TCP (that has a collision on Address/Port with the existing TCP ` tcp-1 ` ):
213+ ``` yaml
214+ apiVersion : ingress.v1.haproxy.org/v1
215+ kind : TCP
216+ metadata :
217+ name : tcp-2
218+ namespace : test
219+ spec :
220+ - name : tcp-http-echo-test2-8443
221+ frontend :
222+ name : fe-http-echo-test2-8443
223+ tcplog : true
224+ log_format : " %{+Q}o"
225+ binds :
226+ - name : v4
227+ port : 32766
228+ service :
229+ name : " http-echo"
230+ port : 8443
231+ ` ` `
232+
266233
267234There will also be an ERROR log
268235` ` `
269- │ 2024/05/22 15:40:42 ERROR handler/tcp-cr.go:61 [transactionID=e1bca8c7-8f8e-415c-b4b2-2746aa64a837] tcp-cr: skipping tcp 'test/tcp-2/tcp-http-echo-444' due to collision - Collistion FE.Name with test/tcp-1/tcp-http-echo-444
236+ 2024/06/19 13:47:05 ERROR handler/tcp-cr.go:61 [transactionID=dab63ebf-238d-4e04-b844-af668a86b024] tcp-cr : skipping tcp 'test/tcp-2/tcp-http-echo-test2-8443' due to collision - Colli │
237+ │ stion AddPort :32766 with test/tcp-1/tcp-http-echo-8443
270238```
271239
272- explaining in the TCP (in namespace ` test ` ) named ` tcp2 ` that a tcp service specification named ` tcp-htt-echo-444 ` that will not be applied (in favor of the oldest one in namespace ` test ` in TCP CR ` tcp1 ` named ` tcp-http-echo-444 ` ) due a collision on frontend names (` FE.Name ` )
240+ explaining that :
241+ - the TCP (in namespace ` test ` ) named ` tcp2 ` that a tcp service specification named ` tcp-htt-echo-444 `
242+ will not be applied
243+ -in favor of the oldest one in namespace ` test ` in TCP CR ` tcp1 ` named ` tcp-http-echo-444 ` ) due a collision on frontend names (` FE.Name ` )
244+
245+ * This works accross all namespaces*
273246
274247## Note on SSL
275248
276- To setup SSL in a TCP CR
249+ To setup SSL in a TCP CR (with the same Service and Pod defined above):
277250
278251``` yaml
279252apiVersion : ingress.v1.haproxy.org/v1
280253kind : TCP
281254metadata :
282255 name : tcp-1
256+ namespace : test
283257spec :
284258 - name : tcp-http-echo-443
285259 frontend :
@@ -298,8 +272,21 @@ spec:
298272 service :
299273 name : " http-echo"
300274 port : 443
275+ ---
276+ kind : Secret
277+ apiVersion : v1
278+ metadata :
279+ name : tcp-test-cert
280+ namespace : test
281+ data :
282+ tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURvekNDQW91Z0F3SUJBZ0lVY3NtV0pSZ2dtd2hxNjVsMnRUMFBlakZKS1dFd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1lURUxNQWtHQTFVRUJoTUNWVk14RFRBTEJnTlZCQWdNQkU5b2FXOHhFVEFQQmdOVkJBY01DRU52YkhWdApZblZ6TVJJd0VBWURWUVFLREFsTmVVTnZiWEJoYm5reEhEQWFCZ05WQkFNTUUyTnlaSFJqY0MxMFpYTjBMbWhoCmNISnZlSGt3SGhjTk1qUXdOVEl5TURneE1qUXlXaGNOTWpVd05USXlNRGd4TWpReVdqQmhNUXN3Q1FZRFZRUUcKRXdKVlV6RU5NQXNHQTFVRUNBd0VUMmhwYnpFUk1BOEdBMVVFQnd3SVEyOXNkVzFpZFhNeEVqQVFCZ05WQkFvTQpDVTE1UTI5dGNHRnVlVEVjTUJvR0ExVUVBd3dUWTNKa2RHTndMWFJsYzNRdWFHRndjbTk0ZVRDQ0FTSXdEUVlKCktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQU14MnQzdjRvWmRaaVZmVm1mZWVabU5Sc2N5MGowUUgKWDFMSWpzQXgxMGF6RUk3cWxDL3A1TVB1Z04zSElJazFRY1RPVEpvMlNGMGluLzZQODFNUGNtNUFvZ2ZpZUhnSApVSUhkcDF0aDR0bEN1NXEzOTdLT2hHSlZBZnhINUw5WmxyTTcraHFGTnAySGJPTUtrcTU0T29hTTgzL0V5U1lMCnFPZVArdFF0MzlCSEU2eEtCd0M0YWZ1bVAyckJMdWRPNVJ5NjFyZk5SLzBzbmZMUUFYNEhERzl6YVlONHZhSmcKLzF6aVFnR0FVcnY2NFgxS2Z2WlZMTkUxdm55d2M0OHlGYlQ5L1dGQzZKYnplbjFNdzd4YmM1M09sTEhWZVNCWgphSWU4UHkvOUJKSjQvdGtHVWROV2ZKWEFEcTRGM014eDMzczJvVS9xMXhITERDZk5OUGhlVzJzQ0F3RUFBYU5UCk1GRXdIUVlEVlIwT0JCWUVGRXJBWGJBMk1nb1UzZXU1dDJXOVF2OXp5UnRBTUI4R0ExVWRJd1FZTUJhQUZFckEKWGJBMk1nb1UzZXU1dDJXOVF2OXp5UnRBTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3RFFZSktvWklodmNOQVFFTApCUUFEZ2dFQkFIU1d2SE9WS3lEUkUrenlIbXVQeTQ0WjlyeHVwRkZUMENROTV4VnJsME9ERWo2eUJZdTlMTEE4CnBNYVNsM1kzK25ZV0U2NGpoaXFQSjdRS3l1Z2wyUHI0MUNLUWRBQ0tjbjUwRlZvRVpsQ2hiZFdPc3ZXWUtZcjQKbDlNdGFHQ0ZKTXNCWkp3SlQyZitXeHllL3U2emhyUjJVWE4zY2tSM3o4TmdhRkdtc20rYXcrUURndm5jclZ4MApmQ09aRmMreEVyTFp5RElrNEhXTXlRV3dDU1dMN1ZLWE4xVDNCMTZNd2x1MzB5OU8wWDc0UG1MNGxYZEU4ZFVrCkNRSXhBT29tT3NRek9pQ2QvRkJZSk83Smx2RC9CNjB0ZjRTZTdESWd2ZFhQZFp6MnIwSW5kS0RsR1pWcVdDdFQKM0h4R3RKZ3MrSnk3Vyt1V21vL1B4V2xkZ1hlSEwvOD0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
283+ tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2Z0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktnd2dnU2tBZ0VBQW9JQkFRRE1kcmQ3K0tHWFdZbFgKMVpuM25tWmpVYkhNdEk5RUIxOVN5STdBTWRkR3N4Q082cFF2NmVURDdvRGR4eUNKTlVIRXpreWFOa2hkSXAvKwpqL05URDNKdVFLSUg0bmg0QjFDQjNhZGJZZUxaUXJ1YXQvZXlqb1JpVlFIOFIrUy9XWmF6Ty9vYWhUYWRoMnpqCkNwS3VlRHFHalBOL3hNa21DNmpuai9yVUxkL1FSeE9zU2djQXVHbjdwajlxd1M3blR1VWN1dGEzelVmOUxKM3kKMEFGK0J3eHZjMm1EZUwyaVlQOWM0a0lCZ0ZLNyt1RjlTbjcyVlN6Uk5iNThzSE9QTWhXMC9mMWhRdWlXODNwOQpUTU84VzNPZHpwU3gxWGtnV1dpSHZEOHYvUVNTZVA3WkJsSFRWbnlWd0E2dUJkek1jZDk3TnFGUDZ0Y1J5d3duCnpUVDRYbHRyQWdNQkFBRUNnZ0VBSGJrOGRLeWJ3VEdSQW5zdVJqaDVlMWdnV0RsVTE4enRQS1JQVnYxbjVhMUQKd1BoZjBUOVlDY0Vkd1hWTFNPY1J4K3lURWtWd2xsUTI4aWpoeWd5NjAvQllIZEZSNEx2S0ptR2ZZaGVFTDVWcgpTZE5vdk8vSnF3bmZTZ1QyNmlKa3JXc1FzWDVLM0VmREQrdmZrR0dHRUpLNUZncWprS3V0UXZkRUV2TVZwYm9NCmwyT3FObTNlVzV6ajhaUDluSDRCTWVFRkRDWjRremh1ZU5WTjZQSTJ1MVNQYndrVVk4NVRJUUg2STlqTW03Z2cKM0RiUS94aU14TFBmck9Rc2tYS2pOK21MSzIxYlRjS0JHOGFLZFU2NWRBdDV5RzArUElFTkM2d0pObExnZ3BZWAozcTdYVm9KU0ZsODhQOTlZTHozaFVwQmtrNnlESEtBWXRHcFZUMVFqSVFLQmdRRCtMQTl0WjYySUV1NmwzN3FBCmFQeU1janNkb1kxNm1ybTVlUUlRS041T0hSbEZHQURkMmdXL0g2Mk1vOUo2YWFQbG9zUGZQZnpFeEdPWDFiYVoKU25pTm5YYmM5Q0p0dmlXSldTbmNlVFBKNVQ4Q2F6WDJpZ2syOU1EYzg3S1BRL1VmdzJYU2pNWHEvQWNEOTUwVQpnZWVUam5JbnNUOGNHWU9KdEMvYjIrRk8wd0tCZ1FETjd5UkJPb2VGUFR3WlY2YitCQTRvbHZNZExGNEZROEVKCjg5R0YrSmp4akZ0U2FnNm1CaWdDOElaYzB5cGlhM2hwbVlKUFlZZ0tzQkR0WE5ZcWNPSjJzMzg3enNJdW9aNVgKT05GYS9KMjZPL3Z6c1FBK0RyRStFMy9QdXZRemF2YVlKUU5xREQ5NkQ4V3duVVVVV24vUjdFRnhwWVV5QzVmagpFQVl6MHlGU0NRS0JnUUNNckhZZFp6UjBDNFpwNTltaEdIb3VnVXFXcThOU0NEQ2lwb2F0eXZDKzZ2d0JjYmVKCkVoSDhKZHczNnJPamJMUjVkQXhVa2twRDNTNEI2eGFVNE5LNERsNnJDN1BDYVdyOUNZeFJxZ012eXVHRXhUR28Kc2QxSHZVN0ErMS9vU3dSd0FBVnE4dDdYbjRXQ2ZKbERzR0lyR0x1MW5EUUJxVjFUNlpaVGFPN2FZUUtCZ0J5dgppQ1JSNjlqQ2UrR24xUW9qTkhtdzlUS0dJSjZwSG5XdGNlMHdnTlY4MEtlOVFFY2VLbXFtYUlEN3BUYktjNTU2CkZLM01EekExOEZXd0RlRWhrbG9vakx1ZkJHdU1kY3IramlNWGR6MGU1K3k5SmlSKzFXK3BOYStSQWowN1ZCaEQKWjZOWkMycU1VZVJWTSs4dTRBazAyTFRrOHBYVENaaEdmaWF2N1Q5SkFvR0JBSkFvNXRhMWZHZVppQ0dMRGQwMwplQS9WMTBXVXFnMUg4NDVtQnN2RjBoSDcxZEQ5aHEvQkh2R1VPKzZHSStZU01wRklvYVBmZEVkZDMrRFhjTUVHCmM0V2FjZGhtL1V6QjV0YW5aRUFyV1JzVXV4S05vU1lMKzY3azFMT3NUOXBESnpvckVXcDRhV3RiTk5VZXIybUsKSTNQRzQ4VTd3NW82djEwNDBjWXlMT0ZaCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
284+ type : kubernetes.io/tls
285+
301286` ` `
302287
288+
289+
303290Note that ` ssl_certificate` can be:
304291- the name of a Kubernetes Secret (**in the same namespace as the TCP CR**) containing the certificated and key
305292- or a filename on the pod local filesystem
@@ -310,3 +297,35 @@ It's for example possible to mount a SSL Secret in the Ingress Controller Pod on
310297Without change the Pod (/deployment manifest), you can use a Secret name in `ssl_certificate`.
311298Then the cert + key will be written in the Pod filesystem in :
312299- ` /etc/haproxy/certs/tcp`
300+
301+
302+ # ## Generated Frontend and Backend configuration:
303+
304+
305+ # ### Frontend sections
306+
307+ ```
308+ frontend tcpcr_test_fe-http-echo-443
309+ mode tcp
310+ bind :32766 name v4 crt /etc/haproxy/certs/tcp/test_tcp-test-cert.pem ssl
311+ bind [ ::] :32766 name v4v6 v4v6
312+ log-format '%{+Q}o %t %s'
313+ option tcplog
314+ default_backend test_http-echo_https
315+
316+ ```
317+
318+ #### Backend sections
319+
320+ ```
321+ backend test_http-echo_https
322+ mode tcp
323+ balance roundrobin
324+ no option abortonclose
325+ timeout server 50000
326+ default-server check
327+ server SRV_1 10.244.0.8:8443 enabled
328+ server SRV_2 [ fd00:10:244::8] :8443 enabled
329+ server SRV_3 127.0.0.1:8443 disabled
330+ server SRV_4 127.0.0.1:8443 disabled
331+ ```
0 commit comments