Skip to content

Commit b091bad

Browse files
Jim Ryanpre-commit-ci[bot]
andauthored
Add IP to TransportServer Listener (#6367)
* add ip to transport listener * fix ci * add template test * remove space * add example readme to transportserver ip * add ipv6 * change ipv4ip to ipv4 * add back in nosec * python test transport server custom ip listener * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * add global config event check to test * fix ip4vip to ipv4 in tests --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent ea56c16 commit b091bad

File tree

23 files changed

+701
-60
lines changed

23 files changed

+701
-60
lines changed

charts/nginx-ingress/values.schema.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -995,15 +995,15 @@
995995
"dns-tcp"
996996
]
997997
},
998-
"ipv4ip": {
998+
"ipv4": {
999999
"type": "string",
10001000
"default": "",
10011001
"title": "The ipv4 ip",
10021002
"examples": [
10031003
"127.0.0.1"
10041004
]
10051005
},
1006-
"ipv6ip": {
1006+
"ipv6": {
10071007
"type": "string",
10081008
"default": "",
10091009
"title": "The ipv6 ip",

docs/content/configuration/global-configuration/globalconfiguration-resource.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ The `listeners:` key defines a listener (a combination of a protocol and a port)
7474
| *port* | The port of the listener. The port must fall into the range ``1..65535`` with the following exceptions: ``80``, ``443``, the [status port](/nginx-ingress-controller/logging-and-monitoring/status-page), the [Prometheus metrics port](/nginx-ingress-controller/logging-and-monitoring/prometheus). Among all listeners, only a single combination of a port-protocol is allowed. | *int* | Yes |
7575
| *protocol* | The protocol of the listener. Supported values: ``TCP``, ``UDP`` and ``HTTP``. | *string* | Yes |
7676
| *ssl* | Configures the listener with SSL. This is currently only supported for ``HTTP`` listeners. Default value is ``false`` | *bool* | No |
77-
| *ipv4* | Specifies the IPv4 address to listen on. This is currently only supported for ``HTTP`` or ``HTTPS`` listeners. | *string* | No |
78-
| *ipv6* | Specifies the IPv6 address to listen on. This is currently only supported for ``HTTP`` or ``HTTPS`` listeners. | *string* | No |
77+
| *ipv4* | Specifies the IPv4 address to listen on. | *string* | No |
78+
| *ipv6* | Specifies the IPv6 address to listen on. | *string* | No |
7979

8080
{{</bootstrap-table>}}
8181

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
# Custom IPv4 and IPv6 Address Listeners
2+
3+
In this example, we will configure a TransportServer resource with custom IPv4 and IPv6 Address using TCP/UDP listeners.
4+
5+
## Prerequisites
6+
7+
1. Follow the [installation](https://docs.nginx.com/nginx-ingress-controller/installation/installation-with-manifests/)
8+
instructions to deploy the Ingress Controller with custom resources enabled.
9+
2. Ensure the Ingress Controller is configured with the `-global-configuration` argument:
10+
11+
```console
12+
args:
13+
- -global-configuration=$(POD_NAMESPACE)/nginx-configuration
14+
```
15+
16+
**Note:**
17+
18+
- **No Updates for GC:** If a GlobalConfiguration resource already exists, delete the previous one before applying the new configuration.
19+
- **Single Replica:** Only one replica is allowed when using this configuration.
20+
21+
## Step 1 - Deploy the GlobalConfiguration resource
22+
23+
Similar to how listeners are configured in our [custom-listeners](../../custom-listeners) examples,
24+
here we deploy a GlobalConfiguration resource with the listeners we want to use in our VirtualServer.
25+
26+
```yaml
27+
apiVersion: k8s.nginx.org/v1
28+
kind: GlobalConfiguration
29+
metadata:
30+
name: nginx-configuration
31+
namespace: nginx-ingress
32+
spec:
33+
listeners:
34+
- name: tcp-ip-dns-listener
35+
port: 5353
36+
protocol: TCP
37+
ipv4: 127.0.0.1
38+
- name: udp-ip-dns-listener
39+
port: 5252
40+
protocol: UDP
41+
ipv4: 127.0.0.2
42+
ipv6: ::1
43+
```
44+
45+
```console
46+
kubectl create -f global-configuration.yaml
47+
```
48+
49+
## Step 2 - Deploy the DNS Application
50+
51+
Create the dns deployment and service:
52+
53+
```console
54+
kubectl create -f dns.yaml
55+
```
56+
57+
## Step 3 - Deploy the TransportServers with custom listeners
58+
59+
The first TransportServer is set to use the udp listener defined in the GlobalConfiguration resource
60+
that was deployed in Step 1. Below is the yaml of this example TransportServer:
61+
62+
```yaml
63+
apiVersion: k8s.nginx.org/v1
64+
kind: TransportServer
65+
metadata:
66+
name: dns-udp
67+
spec:
68+
listener:
69+
name: udp-ip-dns-listener
70+
protocol: UDP
71+
upstreams:
72+
- name: dns-app
73+
service: coredns
74+
port: 5252
75+
upstreamParameters:
76+
udpRequests: 1
77+
udpResponses: 1
78+
action:
79+
pass: dns-app
80+
```
81+
82+
Create the TransportServer resource:
83+
84+
```console
85+
kubectl create -f udp-transport-server.yaml
86+
```
87+
88+
The second TransportServer is set to use the tcp listener defined in the GlobalConfiguration resource.
89+
90+
```yaml
91+
apiVersion: k8s.nginx.org/v1
92+
kind: TransportServer
93+
metadata:
94+
name: tcp-dns
95+
spec:
96+
listener:
97+
name: tcp-ip-dns-listener
98+
protocol: TCP
99+
upstreams:
100+
- name: dns-app
101+
service: coredns
102+
port: 5353
103+
action:
104+
pass: dns-app
105+
```
106+
107+
Create the TransportServer resource:
108+
109+
```console
110+
kubectl create -f tcp-transport-server.yaml
111+
```
112+
113+
## Step 4 - Test the Configuration
114+
115+
1. Check that the configuration has been successfully applied by inspecting the events of the TransportServer and the GlobalConfiguration:
116+
117+
```console
118+
kubectl describe ts udp-dns
119+
```
120+
121+
Below you will see the events as well as the new `Listeners` field
122+
123+
```console
124+
. . .
125+
Spec:
126+
Listener:
127+
name: udp-ip-dns-listener
128+
protocol: UDP
129+
130+
. . .
131+
Routes:
132+
. . .
133+
Events:
134+
Type Reason Age From Message
135+
---- ------ ---- ---- -------
136+
Normal AddedOrUpdated 1s nginx-ingress-controller Configuration for default/udp-dns was added or updated
137+
```
138+
139+
```console
140+
kubectl describe globalconfiguration nginx-configuration -n nginx-ingress
141+
```
142+
143+
```console
144+
. . .
145+
Spec:
146+
Listeners:
147+
ipv4: 127.0.0.1
148+
Name: tcp-ip-dns-listener
149+
Port: 5353
150+
Protocol: TCP
151+
ipv4: 127.0.0.2
152+
ipv6: ::1
153+
Name: udp-ip-dns-listener
154+
Port: 5252
155+
Protocol: UDP
156+
157+
Events:
158+
Type Reason Age From Message
159+
---- ------ ---- ---- -------
160+
Normal Updated 10s nginx-ingress-controller GlobalConfiguration nginx-ingress/nginx-configuration was added or updated
161+
```
162+
163+
2. Since the deployed TransportServer is using port `5252` this example. you can see that the specific ips and ports
164+
are set and listening by using the below commands:
165+
166+
Access the NGINX Pod:
167+
168+
```console
169+
kubectl get pods -n nginx-ingress
170+
```
171+
172+
```text
173+
NAME READY STATUS RESTARTS AGE
174+
nginx-ingress-5cc9c8f66-4dg2t 1/1 Running 0 50s
175+
```
176+
177+
```console
178+
kubectl debug -it nginx-ingress-5cc9c8f66-4dg2t --image=busybox:1.28 --target=nginx-ingress
179+
```
180+
181+
```console
182+
/ # netstat -tulpn
183+
Active Internet connections (only servers)
184+
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
185+
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN -
186+
tcp 0 0 127.0.0.1:5353 0.0.0.0:* LISTEN -
187+
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN -
188+
tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN -
189+
tcp 0 0 :::9113 :::* LISTEN -
190+
tcp 0 0 :::80 :::* LISTEN -
191+
tcp 0 0 :::443 :::* LISTEN -
192+
tcp 0 0 :::8080 :::* LISTEN -
193+
tcp 0 0 :::8081 :::* LISTEN -
194+
udp 0 0 127.0.0.2:5252 0.0.0.0:* -
195+
udp 0 0 ::1:5252 :::* -
196+
/ #
197+
```
198+
199+
We can see here that the two IPv4 addresses (`127.0.0.1:5353` and `127.0.0.2:5252`) and the one IPv6 address (`::1:5252`) are listed.
200+
201+
3. Examine the NGINX config using the following command:
202+
203+
```console
204+
kubectl exec -it nginx-ingress-5cc9c8f66-4dg2t -n nginx-ingress -- cat /etc/nginx/stream-conf.d/ts_default_dns-udp.conf
205+
```
206+
207+
```console
208+
...
209+
server {
210+
listen 127.0.0.2:5252 udp;
211+
listen [::1]:5252 udp;
212+
213+
...
214+
}
215+
```
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
apiVersion: v1
2+
kind: ConfigMap
3+
metadata:
4+
name: coredns
5+
data:
6+
Corefile: |
7+
.:5353 {
8+
forward . 8.8.8.8:53
9+
log
10+
}
11+
---
12+
apiVersion: apps/v1
13+
kind: Deployment
14+
metadata:
15+
name: coredns
16+
spec:
17+
replicas: 2
18+
selector:
19+
matchLabels:
20+
app: coredns
21+
template:
22+
metadata:
23+
labels:
24+
app: coredns
25+
spec:
26+
containers:
27+
- name: coredns
28+
image: coredns/coredns:1.10.0
29+
args: [ "-conf", "/etc/coredns/Corefile" ]
30+
volumeMounts:
31+
- name: config-volume
32+
mountPath: /etc/coredns
33+
readOnly: true
34+
ports:
35+
- containerPort: 5353
36+
name: dns
37+
protocol: UDP
38+
- containerPort: 5353
39+
name: dns-tcp
40+
protocol: TCP
41+
securityContext:
42+
readOnlyRootFilesystem: true
43+
volumes:
44+
- name: config-volume
45+
configMap:
46+
name: coredns
47+
items:
48+
- key: Corefile
49+
path: Corefile
50+
---
51+
apiVersion: v1
52+
kind: Service
53+
metadata:
54+
name: coredns
55+
spec:
56+
selector:
57+
app: coredns
58+
ports:
59+
- name: dns
60+
port: 5353
61+
protocol: UDP
62+
- name: dns-tcp
63+
port: 5353
64+
protocol: TCP
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
apiVersion: k8s.nginx.org/v1
2+
kind: GlobalConfiguration
3+
metadata:
4+
name: my-release-nginx-ingress-controller
5+
spec:
6+
listeners:
7+
- name: tcp-ip-dns-listener
8+
port: 5353
9+
protocol: TCP
10+
ipv4: 127.0.0.1
11+
ipv6: ::1
12+
- name: udp-ip-dns-listener
13+
port: 5252
14+
protocol: UDP
15+
ipv4: 127.0.0.2
16+
ipv6: ::1
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
apiVersion: k8s.nginx.org/v1
2+
kind: TransportServer
3+
metadata:
4+
name: tcp-dns
5+
spec:
6+
listener:
7+
name: tcp-ip-dns-listener
8+
protocol: TCP
9+
upstreams:
10+
- name: dns-app
11+
service: coredns
12+
port: 5353
13+
action:
14+
pass: dns-app
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
apiVersion: k8s.nginx.org/v1
2+
kind: TransportServer
3+
metadata:
4+
name: dns-udp
5+
spec:
6+
listener:
7+
name: udp-ip-dns-listener
8+
protocol: UDP
9+
upstreams:
10+
- name: dns-app
11+
service: coredns
12+
port: 5353
13+
upstreamParameters:
14+
udpRequests: 1
15+
udpResponses: 1
16+
action:
17+
pass: dns-app

internal/configs/transportserver.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ type TransportServerEx struct {
2323
ExternalNameSvcs map[string]bool
2424
DisableIPV6 bool
2525
SecretRefs map[string]*secrets.SecretReference
26+
IPv4 string
27+
IPv6 string
2628
}
2729

2830
func (tsEx *TransportServerEx) String() string {
@@ -118,6 +120,8 @@ func generateTransportServerConfig(p transportServerConfigParams) (*version2.Tra
118120
ServerSnippets: serverSnippets,
119121
DisableIPV6: p.transportServerEx.DisableIPV6,
120122
SSL: sslConfig,
123+
IPv4: p.transportServerEx.IPv4,
124+
IPv6: p.transportServerEx.IPv6,
121125
},
122126
Match: match,
123127
Upstreams: upstreams,

0 commit comments

Comments
 (0)