NICによるTCP/UDPの通信制御
この章では、実際にデプロイしたNGINX Ingress Controllerを使い、TCP/UDPのアプリケーションに対する通信制御方法を確認します 設定例は NGINX Inc GitHubの examples/custom-resources/ に管理されております
TCP / UDP の分散設定
TCP / UDP を分散するためアプリケーションをデプロイします
https://github.com/nginxinc/kubernetes-ingress/tree/v3.1.1/examples/custom-resources/basic-tcp-udp
Deployment、NodePortの内容を修正しデプロイ
TCP / UDP を分散するため、NGINX Ingress Controller のDeployment、NodePortの内容を修正しデプロイします。 Deploymentのargsで指定するパラメータの詳細は Command-line Arguments を参照してください
cd ~/kubernetes-ingress/deployments
cp deployment/nginx-plus-ingress.yaml deployment/nginx-plus-ingress-tcpudp.yaml
vi deployment/nginx-plus-ingress-tcpudp.yaml
コメントを付与した行を参考に適切な内容に修正してください
1** 省略 **
2spec:
3 serviceAccountName: nginx-ingress
4 containers:
5 - image: registry.example.com/root/nic/nginxplus-ingress-nap-dos:2.1.0
6 imagePullPolicy: IfNotPresent
7 name: nginx-plus-ingress
8 ports:
9 - name: dns-tcp # DNS TCP を有効にします
10 containerPort: 5353
11 - name: dns-udp # DNS UDP を有効にします
12 containerPort: 53
13 protocol: UDP
14 #- name: http
15 # containerPort: 80
16 #- name: https
17 # containerPort: 443
18** 省略 **
19 args:
20 - -nginx-plus
21 - -nginx-configmaps=$(POD_NAMESPACE)/nginx-config
22 - -default-server-tls-secret=$(POD_NAMESPACE)/default-server-secret
23 #- -enable-app-protect
24 #- -enable-app-protect-dos
25 #- -v=3 # Enables extensive logging. Useful for troubleshooting.
26 #- -report-ingress-status
27 #- -external-service=nginx-ingress
28 #- -enable-prometheus-metrics
29 - -global-configuration=$(POD_NAMESPACE)/nginx-configuration # Global Configuration を有効にします
単一のNodePortでTCP/UDP双方を設定できないため、2つのファイルに分けて設定します。
## cd ~/kubernetes-ingress/deployments
cp service/nodeport.yaml service/nodeport-tcp.yaml
vi service/nodeport-tcp.yaml
以下の内容を参考に修正してください。
1apiVersion: v1
2kind: Service
3metadata:
4 name: nginx-ingress
5 namespace: nginx-ingress
6spec:
7 type: NodePort
8 ports:
9 - port: 5353 # DNS TCP を有効にします (ファイルからDNS UDPを削除します)
10 targetPort: 5353
11 protocol: TCP
12 name: dns-tcp
13 selector:
14 app: nginx-ingress
## cd ~/kubernetes-ingress/deployments
cp service/nodeport.yaml service/nodeport-udp.yaml
vi service/nodeport-udp.yaml
以下の内容を参考に修正してください。
1apiVersion: v1
2kind: Service
3metadata:
4 name: nginx-ingress-udp
5 namespace: nginx-ingress
6spec:
7 type: NodePort
8 ports:
9 - port: 53 # DNS UDP のポート番号を変更します (ファイルからDNS TCPを削除します)
10 targetPort: 53
11 protocol: UDP
12 name: dns-udp
13 selector:
14 app: nginx-ingress
TCP/UDPではGlobal Configurationにより外部から通信を待ち受ける設定を行います
cd ~/kubernetes-ingress/examples/custom-resources/basic-tcp-udp/
cp global-configuration.yaml global-configuration.yaml-bak
vi global-configuration.yaml
以下の内容を参考に修正してください。
1apiVersion: k8s.nginx.org/v1alpha1
2kind: GlobalConfiguration
3metadata:
4 name: nginx-configuration
5 namespace: nginx-ingress
6spec:
7 listeners:
8 - name: dns-udp
9 port: 53 # DNS UDP のポート番号を 5353 -> 53 に変更
10 protocol: UDP
11 - name: dns-tcp
12 port: 5353
13 protocol: TCP
その他、NGINX Ingress ControlleでTCP/UDPを転送するための設定、サンプルアプリケーションを確認します。
TCPの設定です。Kindで TransportServer を指定します。
1apiVersion: k8s.nginx.org/v1alpha1
2kind: TransportServer
3metadata:
4 name: dns-tcp
5spec:
6 listener:
7 name: dns-tcp
8 protocol: TCP
9 upstreams:
10 - name: dns-app
11 service: coredns
12 port: 5353
13 action:
14 pass: dns-app
UDPの設定です。TCPとほぼ同様です
1apiVersion: k8s.nginx.org/v1alpha1
2kind: TransportServer
3metadata:
4 name: dns-udp
5spec:
6 listener:
7 name: dns-udp
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
サンプルアプリケーションです。TCP/UDP共に5353で通信を待ち受けます。またDNSを 8.8.8.8:53 へと転送する動作となります。
修正した内容、各種リソースをデプロイします。 デプロイする内容に応じてディレクトリが変更となりますので注意ください
~/kubernetes-ingress/deployments 配下の内容を設定してください。(NICのDeployment, NodePort)
cd ~/kubernetes-ingress/deployments
kubectl apply -f service/nodeport-tcp.yaml
kubectl apply -f service/nodeport-udp.yaml
kubectl apply -f deployment/nginx-plus-ingress-tcpudp.yaml
~/kubernetes-ingress/examples/custom-resources/basic-tcp-udp 配下の内容を設定してください。(サンプルアプリケーション、分散設定等)
cd ~/kubernetes-ingress/examples/custom-resources/basic-tcp-udp
kubectl apply -f global-configuration.yaml
kubectl apply -f dns.yaml
kubectl apply -f transport-server-tcp.yaml
kubectl apply -f transport-server-udp.yaml
デプロイしたNodePortの内容を確認し、TCP/UDPの待ち受けているポートに対してリクエストを転送するようNGINXの設定を変更します。
kubectl get svc -n nginx-ingress
1NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
2nginx-ingress NodePort 10.108.250.160 <none> 5353:30292/TCP 6d14h
3nginx-ingress-udp NodePort 10.99.147.245 <none> 53:31482/UDP 16m
確認したNode Portで割り当てられたポート番号宛に通信を転送するように、NGINXを設定します。 転送するポート番号は、環境に合わせて適切に変更してください。
cd ~/
sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf-
cat << EOF > nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
# TCP/UDP load balancing
#
stream {
upstream tcp5353_backend {
server node1:30292; # DNS TCP(TCP/5353)に割り当てられたポート番号
}
upstream udp53_backend {
server node1:31482; # DNS UDP(UDP/53)に割り当てられたポート番号
}
server {
listen 5353; # DNS TCPを(TCP/5353)で待ち受けます
proxy_pass tcp5353_backend;
}
server {
listen 53 udp; # DNS UDPを(UDP/53)で待ち受けます
proxy_pass udp53_backend;
}
}
EOF
sudo cp nginx.conf /etc/nginx/nginx.conf
sudo nginx -s reload
デプロイした結果の確認
kubectl get pod -n nginx-ingress | grep nginx-ingress
1nginx-ingress-68949d7f46-qh9kp 1/1 Running 0 4s
NGINX Ingress ControllerのPodの詳細を確認します
## pod名は、kuebctl get pod -n nginx-ingress の出力結果を参照してください
kubectl describe pod nginx-ingress-68949d7f46-qh9kp -n nginx-ingress
1** 省略 **
2
3Containers:
4 nginx-plus-ingress:
5 Container ID: docker://f1aa9d4434ebda4817f9ff957987120c85808bcdcb9d64978e76814c20e422fe
6 Image: registry.example.com/root/nic/nginxplus-ingress-nap-dos:2.1.0
7 Image ID: docker-pullable://registry.example.com/root/nic/nginxplus-ingress-nap-dos@sha256:8c9a8ce1cdda45c2a289cb20ce37a60e25b4d4669c2c9c9d4d0831c353c6c668
8 Ports: 5353/TCP, 53/UDP, 8081/TCP, 9113/TCP
9 Host Ports: 0/TCP, 0/UDP, 0/TCP, 0/TCP
10 Args:
11 -nginx-plus
12 -nginx-configmaps=$(POD_NAMESPACE)/nginx-config
13 -default-server-tls-secret=$(POD_NAMESPACE)/default-server-secret
14 -global-configuration=$(POD_NAMESPACE)/nginx-configuration
15 State: Running
16
17** 省略 **
TCPは 5353/TCP 、UDP 53/UDP となっていることが確認できます。また global-configuration のargsが正しく記載されています
kubectl get globalconfiguration -n nginx-ingress
1NAME AGE
2nginx-configuration 8m3s
kubectl get svc coredns
1NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
2coredns ClusterIP 10.101.115.180 <none> 5353/UDP,5353/TCP 2m41s
kubectl get pod | grep coredns
1coredns-75466b69b7-8b7r5 1/1 Running 0 3m29s
2coredns-75466b69b7-8tgrc 1/1 Running 0 3m29s
先程確認したとおり、TCP/UDPそれぞれのNodePortの内容が確認できます
kubectl get svc -n nginx-ingress
1NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
2nginx-ingress NodePort 10.108.250.160 <none> 5353:30292/TCP 6d14h
3nginx-ingress-udp NodePort 10.99.147.245 <none> 53:31482/UDP 16m
動作確認
TCP/UDPのそれぞれで kubernetes.io の名前解決を行います。NGINX Ingress ControllerへQueryを送信します。
TCPでDNS Queryを送信します。Portは 5353 です。
dig node1 -p 5353 kubernetes.io +tcp
1; <<>> DiG 9.16.1-Ubuntu <<>> node1 -p 5353 kubernetes.io +tcp
2;; global options: +cmd
3;; connection timed out; no servers could be reached
4
5;; Got answer:
6;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 28171
7;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
8
9;; OPT PSEUDOSECTION:
10; EDNS: version: 0, flags:; udp: 4096
11;; QUESTION SECTION:
12;kubernetes.io. IN A
13
14;; ANSWER SECTION:
15kubernetes.io. 2474 IN A 147.75.40.148
16
17;; Query time: 23 msec
18;; SERVER: 127.0.0.53#5353(127.0.0.53)
19;; WHEN: Fri Jan 21 06:46:38 UTC 2022
20;; MSG SIZE rcvd: 71
21
22.. code-block:: cmdin
UDPでDNS Queryを送信します。Portは 53 です。
dig node1 -p 53 kubernetes.io
1; <<>> DiG 9.16.1-Ubuntu <<>> node1 -p 53 kubernetes.io
2;; global options: +cmd
3;; Got answer:
4;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2308
5;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
6
7;; OPT PSEUDOSECTION:
8; EDNS: version: 0, flags:; udp: 65494
9;; QUESTION SECTION:
10;node1. IN A
11
12;; ANSWER SECTION:
13node1. 0 IN A 10.1.1.9
14
15;; Query time: 3 msec
16;; SERVER: 127.0.0.53#53(127.0.0.53)
17;; WHEN: Fri Jan 21 06:46:48 UTC 2022
18;; MSG SIZE rcvd: 50
19
20;; Got answer:
21;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 22877
22;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
23
24;; OPT PSEUDOSECTION:
25; EDNS: version: 0, flags:; udp: 65494
26;; QUESTION SECTION:
27;kubernetes.io. IN A
28
29;; ANSWER SECTION:
30kubernetes.io. 210 IN A 147.75.40.148
31
32;; Query time: 0 msec
33;; SERVER: 127.0.0.53#53(127.0.0.53)
34;; WHEN: Fri Jan 21 06:46:48 UTC 2022
35;; MSG SIZE rcvd: 58
リソースの削除
サンプルアプリケーション、及び分散設定を削除します
cd ~/kubernetes-ingress/examples/custom-resources/basic-tcp-udp
kubectl delete -f global-configuration.yaml
kubectl delete -f dns.yaml
kubectl delete -f transport-server-tcp.yaml
kubectl delete -f transport-server-udp.yaml
HTTP/HTTPSを待ち受ける設定に戻す場合、以下の操作を参考に実施してください。
cd ~/kubernetes-ingress/deployments
kubectl delete -f service/nodeport-tcp.yaml
kubectl delete -f service/nodeport-udp.yaml
kubectl delete -f deployment/nginx-plus-ingress-tcpudp.yaml
kubectl apply -f service/nodeport.yaml
kubectl apply -f deployment/nginx-plus-ingress.yaml
## 手順を参考にnginx.confを変更してください