Kubernetes Gateway による通信制御
NGINXをDataplaneとしてKubernetes Gatewayを利用する方法を紹介します。 Kubernetes Gatewayの情報は GitHub: nginx-gateway-fabric を参照してください
Note
本資料作成時点では、NGINX OSSを利用した動作確認となります
この章では、実際にデプロイしたNGINX Kubernetes Gatewayを使った通信制御方法を確認します 設定例は GitHub nginx-gateway-fabric/examples の内容となります
シンプルなWebアプリケーション
シンプルなWebアプリケーションをデプロイします。
https://github.com/nginxinc/nginx-gateway-fabric/tree/main/examples/cafe-example
サンプルアプリケーションをデプロイ
cd ~/nginx-gateway-fabric/examples/cafe-example/
kubectl apply -f cafe.yaml
kubectl apply -f gateway.yaml
kubectl apply -f cafe-routes.yaml
リソースの確認
作成したリソースの内容を確認します
cat gateway.yaml
1apiVersion: gateway.networking.k8s.io/v1beta1
2kind: Gateway
3metadata:
4 name: gateway
5 labels:
6 domain: k8s-gateway.nginx.org
7spec:
8 gatewayClassName: nginx
9 listeners:
10 - name: http
11 port: 80
12 protocol: HTTP
cat cafe-routes.yaml
1apiVersion: gateway.networking.k8s.io/v1beta1
2kind: HTTPRoute
3metadata:
4 name: coffee
5spec:
6 parentRefs:
7 - name: gateway
8 sectionName: http
9 hostnames:
10 - "cafe.example.com"
11 rules:
12 - matches:
13 - path:
14 type: PathPrefix
15 value: /coffee
16 backendRefs:
17 - name: coffee
18 port: 80
19---
20apiVersion: gateway.networking.k8s.io/v1beta1
21kind: HTTPRoute
22metadata:
23 name: tea
24spec:
25 parentRefs:
26 - name: gateway
27 sectionName: http
28 hostnames:
29 - "cafe.example.com"
30 rules:
31 - matches:
32 - path:
33 type: Exact
34 value: /tea
35 backendRefs:
36 - name: tea
正しくリソースが作成されたことを確認します
kubectl get gateway
1NAME CLASS ADDRESS PROGRAMMED AGE
2gateway nginx True 72s
httproute を確認します。 cafe.example.com のHostnameに対し、 coffee と tea がデプロイされています
kubectl get httproute
1NAME HOSTNAMES AGE
2coffee ["cafe.example.com"] 57s
3tea ["cafe.example.com"] 57s
coffee と tea の Podがデプロイされていることが確認できます
kubectl get pod
1NAME READY STATUS RESTARTS AGE
2coffee-7c86d7d67c-dxw9s 1/1 Running 1 (152m ago) 11h
3tea-5c457db9-wrtn6 1/1 Running 1 (3h34m ago) 11h
リソースの詳細を確認します
Gatewayは通信の待ち受けに関する設定です
kubectl describe gateway gateway
1Name: gateway
2Namespace: default
3Labels: domain=k8s-gateway.nginx.org
4Annotations: <none>
5API Version: gateway.networking.k8s.io/v1beta1
6Kind: Gateway
7Metadata:
8 Creation Timestamp: 2023-05-25T01:18:02Z
9 Generation: 1
10 Managed Fields:
11 API Version: gateway.networking.k8s.io/v1beta1
12 Fields Type: FieldsV1
13 fieldsV1:
14 f:metadata:
15 f:annotations:
16 .:
17 f:kubectl.kubernetes.io/last-applied-configuration:
18 f:labels:
19 .:
20 f:domain:
21 f:spec:
22 .:
23 f:gatewayClassName:
24 f:listeners:
25 .:
26 k:{"name":"http"}:
27 .:
28 f:allowedRoutes:
29 .:
30 f:namespaces:
31 .:
32 f:from:
33 f:name:
34 f:port:
35 f:protocol:
36 Manager: kubectl-client-side-apply
37 Operation: Update
38 Time: 2023-05-25T01:18:02Z
39 API Version: gateway.networking.k8s.io/v1beta1
40 Fields Type: FieldsV1
41 fieldsV1:
42 f:status:
43 f:addresses:
44 f:conditions:
45 k:{"type":"Accepted"}:
46 f:lastTransitionTime:
47 f:message:
48 f:observedGeneration:
49 f:reason:
50 f:status:
51 f:listeners:
52 .:
53 k:{"name":"http"}:
54 .:
55 f:attachedRoutes:
56 f:conditions:
57 .:
58 k:{"type":"Accepted"}:
59 .:
60 f:lastTransitionTime:
61 f:message:
62 f:observedGeneration:
63 f:reason:
64 f:status:
65 f:type:
66 k:{"type":"Conflicted"}:
67 .:
68 f:lastTransitionTime:
69 f:message:
70 f:observedGeneration:
71 f:reason:
72 f:status:
73 f:type:
74 k:{"type":"ResolvedRefs"}:
75 .:
76 f:lastTransitionTime:
77 f:message:
78 f:observedGeneration:
79 f:reason:
80 f:status:
81 f:type:
82 f:name:
83 f:supportedKinds:
84 Manager: gateway
85 Operation: Update
86 Subresource: status
87 Time: 2023-05-25T01:18:03Z
88 Resource Version: 204507
89 UID: b680933d-a7a2-4780-a89e-c5e751abb971
90Spec:
91 Gateway Class Name: nginx
92 Listeners:
93 Allowed Routes:
94 Namespaces:
95 From: Same
96 Name: http
97 Port: 80
98 Protocol: HTTP
99Status:
100 Addresses:
101 Type: IPAddress
102 Value: 192.168.127.2
103 Conditions:
104 Last Transition Time: 2023-05-25T01:18:08Z
105 Message: Gateway is accepted
106 Observed Generation: 1
107 Reason: Accepted
108 Status: True
109 Type: Accepted
110 Listeners:
111 Attached Routes: 2
112 Conditions:
113 Last Transition Time: 2023-05-25T01:18:08Z
114 Message: Listener is accepted
115 Observed Generation: 1
116 Reason: Accepted
117 Status: True
118 Type: Accepted
119 Last Transition Time: 2023-05-25T01:18:08Z
120 Message: All references are resolved
121 Observed Generation: 1
122 Reason: ResolvedRefs
123 Status: True
124 Type: ResolvedRefs
125 Last Transition Time: 2023-05-25T01:18:08Z
126 Message: No conflicts
127 Observed Generation: 1
128 Reason: NoConflicts
129 Status: False
130 Type: Conflicted
131 Name: http
132 Supported Kinds:
133 Group: gateway.networking.k8s.io
134 Kind: HTTPRoute
135Events: <none>
HTTP RouteはHTTP通信の転送に関連するリソースです。
coffee の HTTP Routeの内容が以下です
kubectl describe httproute coffee
1Name: coffee
2Namespace: default
3Labels: <none>
4Annotations: <none>
5API Version: gateway.networking.k8s.io/v1beta1
6Kind: HTTPRoute
7Metadata:
8 Creation Timestamp: 2023-05-25T01:18:06Z
9 Generation: 1
10 Managed Fields:
11 API Version: gateway.networking.k8s.io/v1beta1
12 Fields Type: FieldsV1
13 fieldsV1:
14 f:metadata:
15 f:annotations:
16 .:
17 f:kubectl.kubernetes.io/last-applied-configuration:
18 f:spec:
19 .:
20 f:hostnames:
21 f:parentRefs:
22 f:rules:
23 Manager: kubectl-client-side-apply
24 Operation: Update
25 Time: 2023-05-25T01:18:06Z
26 API Version: gateway.networking.k8s.io/v1beta1
27 Fields Type: FieldsV1
28 fieldsV1:
29 f:status:
30 .:
31 f:parents:
32 Manager: gateway
33 Operation: Update
34 Subresource: status
35 Time: 2023-05-25T01:18:07Z
36 Resource Version: 204508
37 UID: 126217a6-b7d4-4dc4-bceb-b969bdb94194
38Spec:
39 Hostnames:
40 cafe.example.com
41 Parent Refs:
42 Group: gateway.networking.k8s.io
43 Kind: Gateway
44 Name: gateway
45 Section Name: http
46 Rules:
47 Backend Refs:
48 Group:
49 Kind: Service
50 Name: coffee
51 Port: 80
52 Weight: 1
53 Matches:
54 Path:
55 Type: PathPrefix
56 Value: /coffee
57Status:
58 Parents:
59 Conditions:
60 Last Transition Time: 2023-05-25T01:18:08Z
61 Message: The route is accepted
62 Observed Generation: 1
63 Reason: Accepted
64 Status: True
65 Type: Accepted
66 Last Transition Time: 2023-05-25T01:18:08Z
67 Message: All references are resolved
68 Observed Generation: 1
69 Reason: ResolvedRefs
70 Status: True
71 Type: ResolvedRefs
72 Controller Name: k8s-gateway.nginx.org/nginx-gateway-controller
73 Parent Ref:
74 Group: gateway.networking.k8s.io
75 Kind: Gateway
76 Name: gateway
77 Namespace: default
78 Section Name: http
79Events: <none>
tea の HTTP Routeの内容が以下です
kubectl describe httproute tea
1Name: tea
2Namespace: default
3Labels: <none>
4Annotations: <none>
5API Version: gateway.networking.k8s.io/v1beta1
6Kind: HTTPRoute
7Metadata:
8 Creation Timestamp: 2023-05-25T01:18:06Z
9 Generation: 1
10 Managed Fields:
11 API Version: gateway.networking.k8s.io/v1beta1
12 Fields Type: FieldsV1
13 fieldsV1:
14 f:metadata:
15 f:annotations:
16 .:
17 f:kubectl.kubernetes.io/last-applied-configuration:
18 f:spec:
19 .:
20 f:hostnames:
21 f:parentRefs:
22 f:rules:
23 Manager: kubectl-client-side-apply
24 Operation: Update
25 Time: 2023-05-25T01:18:06Z
26 API Version: gateway.networking.k8s.io/v1beta1
27 Fields Type: FieldsV1
28 fieldsV1:
29 f:status:
30 .:
31 f:parents:
32 Manager: gateway
33 Operation: Update
34 Subresource: status
35 Time: 2023-05-25T01:18:08Z
36 Resource Version: 204509
37 UID: 901df757-fc2a-4d2d-9e9f-c36253cbdd19
38Spec:
39 Hostnames:
40 cafe.example.com
41 Parent Refs:
42 Group: gateway.networking.k8s.io
43 Kind: Gateway
44 Name: gateway
45 Section Name: http
46 Rules:
47 Backend Refs:
48 Group:
49 Kind: Service
50 Name: tea
51 Port: 80
52 Weight: 1
53 Matches:
54 Path:
55 Type: Exact
56 Value: /tea
57Status:
58 Parents:
59 Conditions:
60 Last Transition Time: 2023-05-25T01:18:08Z
61 Message: The route is accepted
62 Observed Generation: 1
63 Reason: Accepted
64 Status: True
65 Type: Accepted
66 Last Transition Time: 2023-05-25T01:18:08Z
67 Message: All references are resolved
68 Observed Generation: 1
69 Reason: ResolvedRefs
70 Status: True
71 Type: ResolvedRefs
72 Controller Name: k8s-gateway.nginx.org/nginx-gateway-controller
73 Parent Ref:
74 Group: gateway.networking.k8s.io
75 Kind: Gateway
76 Name: gateway
77 Namespace: default
78 Section Name: http
79Events: <none>
動作確認
cafe.example.com の /coffee に対してリクエストを送ります
curl -H "Host:cafe.example.com" http://localhost/coffee
1Server address: 192.168.127.60:8080
2Server name: coffee-7c86d7d67c-dxw9s
3Date: 25/May/2023:01:21:02 +0000
4URI: /coffee
5Request ID: 9fb7dcfd60d04a9dbb510ab7bda6583a
cafe.example.com の /tea に対してリクエストを送ります
curl -H "Host:cafe.example.com" http://localhost/tea
1Server address: 192.168.127.62:8080
2Server name: tea-5c457db9-wrtn6
3Date: 25/May/2023:01:21:16 +0000
4URI: /tea
5Request ID: d2caeeaa2fe6722b3df9b8cbf145b382
リソースの削除
cd ~/nginx-gateway-fabric/examples/cafe-example/
kubectl delete -f cafe.yaml
kubectl delete -f gateway.yaml
kubectl delete -f cafe-routes.yaml
HTTPSの処理
HTTPSの終端とWebアプリケーションをデプロイします。
https://github.com/nginxinc/nginx-gateway-fabric/tree/main/examples/https-termination
サンプルアプリケーションをデプロイ
cd ~/nginx-gateway-fabric/examples/https-termination
kubectl apply -f cafe.yaml
kubectl apply -f gateway.yaml
kubectl apply -f cafe-routes.yaml
kubectl apply -f certificate-ns-and-cafe-secret.yaml
kubectl apply -f reference-grant.yaml
リソースの確認
主要なリソースの内容を確認します
cat gateway.yaml
1apiVersion: gateway.networking.k8s.io/v1beta1
2kind: Gateway
3metadata:
4 name: gateway
5 labels:
6 domain: k8s-gateway.nginx.org
7spec:
8 gatewayClassName: nginx
9 listeners:
10 - name: http
11 port: 80
12 protocol: HTTP
13 - name: https
14 port: 443
15 protocol: HTTPS
16 tls:
17 mode: Terminate
18 certificateRefs:
19 - kind: Secret
20 name: cafe-secret
21 namespace: default
listeners 待ち受ける通信を記述しています。また、httpsの配下に tls を記述し、TLSを終端すること(Terminate)や、利用する証明書(certificateRefs)を記述しています。
HTTPRouteの内容を確認します
cat cafe-routes.yaml
1apiVersion: gateway.networking.k8s.io/v1beta1
2kind: HTTPRoute
3metadata:
4 name: cafe-tls-redirect
5spec:
6 parentRefs:
7 - name: gateway
8 sectionName: http
9 hostnames:
10 - "cafe.example.com"
11 rules:
12 - filters:
13 - type: RequestRedirect
14 requestRedirect:
15 scheme: https
16 port: 443
17---
18apiVersion: gateway.networking.k8s.io/v1beta1
19kind: HTTPRoute
20metadata:
21 name: coffee
22spec:
23 parentRefs:
24 - name: gateway
25 sectionName: https
26 hostnames:
27 - "cafe.example.com"
28 rules:
29 - matches:
30 - path:
31 type: PathPrefix
32 value: /coffee
33 backendRefs:
34 - name: coffee
35 port: 80
36---
37apiVersion: gateway.networking.k8s.io/v1beta1
38kind: HTTPRoute
39metadata:
40 name: tea
41spec:
42 parentRefs:
43 - name: gateway
44 sectionName: https
45 hostnames:
46 - "cafe.example.com"
47 rules:
48 - matches:
49 - path:
50 type: PathPrefix
51 value: /tea
52 backendRefs:
53 - name: tea
54 port: 80
HTTPRouteを3つ指定しています。
1つ目のHTTPRouteはHTTPのりクストをHTTPSにリダイレクトします。parentRefsでGatewayの http を参照しています。
2つ目が /coffee に関する設定、3つ目が /tea に関する設定となります。parentRefsでGatewayの https を参照しています。
作成されたリソースの情報を確認します
kubectl get pod
1NAME READY STATUS RESTARTS AGE
2coffee-7c86d7d67c-x8rc6 1/1 Running 0 62s
3tea-5c457db9-gbxlp 1/1 Running 0 62s
kubectl get secret
1default-token-rs5nm kubernetes.io/service-account-token 3 182d
kubectl get gateway
1NAME CLASS ADDRESS PROGRAMMED AGE
2gateway nginx True 100s
kubectl get httproute
1NAME HOSTNAMES AGE
2cafe-tls-redirect ["cafe.example.com"] 99s
3coffee ["cafe.example.com"] 99s
4tea ["cafe.example.com"] 99s
動作確認
http で cafe.example.com の /coffee に対してリクエストを送ります
curl -v --resolve cafe.example.com:80:127.0.0.1 http://cafe.example.com:80/coffee
1* Trying 127.0.0.1:80...
2* TCP_NODELAY set
3* Connected to localhost (127.0.0.1) port 80 (#0)
4> GET /coffee HTTP/1.1
5> Host:cafe.example.com
6> User-Agent: curl/7.68.0
7> Accept: */*
8>
9* Mark bundle as not supporting multiuse
10< HTTP/1.1 302 Moved Temporarily
11< Server: nginx/1.23.4
12< Date: Thu, 25 May 2023 04:08:09 GMT
13< Content-Type: text/html
14< Content-Length: 145
15< Connection: keep-alive
16< Location: https://cafe.example.com:443/coffee
17<
18<html>
19<head><title>302 Found</title></head>
20<body>
21<center><h1>302 Found</h1></center>
22<hr><center>nginx/1.23.4</center>
23</body>
24</html>
25* Connection #0 to host localhost left intact
httpでアクセスした場合には 302 Moved Temporarily が応答され、Location Header が Location: https://cafe.example.com:443/coffee と返されていることがわかります
次にHTTPSで通信ができることを確認します
https で cafe.example.com の /coffee に対してリクエストを送ります
curl -kv --resolve cafe.example.com:443:127.0.0.1 https://cafe.example.com:443/coffee
1* Added cafe.example.com:443:127.0.0.1 to DNS cache
2* Hostname cafe.example.com was found in DNS cache
3* Trying 127.0.0.1:443...
4* TCP_NODELAY set
5* Connected to cafe.example.com (127.0.0.1) port 443 (#0)
6* ALPN, offering h2
7* ALPN, offering http/1.1
8* successfully set certificate verify locations:
9* CAfile: /etc/ssl/certs/ca-certificates.crt
10 CApath: /etc/ssl/certs
11* TLSv1.3 (OUT), TLS handshake, Client hello (1):
12* TLSv1.3 (IN), TLS handshake, Server hello (2):
13* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
14* TLSv1.3 (IN), TLS handshake, Certificate (11):
15* TLSv1.3 (IN), TLS handshake, CERT verify (15):
16* TLSv1.3 (IN), TLS handshake, Finished (20):
17* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
18* TLSv1.3 (OUT), TLS handshake, Finished (20):
19* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
20* ALPN, server accepted to use http/1.1
21* Server certificate:
22* subject: CN=cafe.example.com
23* start date: Jul 14 21:52:39 2022 GMT
24* expire date: Jul 14 21:52:39 2023 GMT
25* issuer: CN=cafe.example.com
26* SSL certificate verify result: self signed certificate (18), continuing anyway.
27> GET /coffee HTTP/1.1
28> Host: cafe.example.com
29> User-Agent: curl/7.68.0
30> Accept: */*
31>
32* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
33* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
34* old SSL session ID is stale, removing
35* Mark bundle as not supporting multiuse
36< HTTP/1.1 200 OK
37< Server: nginx/1.23.4
38< Date: Thu, 25 May 2023 04:21:02 GMT
39< Content-Type: text/plain
40< Content-Length: 163
41< Connection: keep-alive
42< Expires: Thu, 25 May 2023 04:21:01 GMT
43< Cache-Control: no-cache
44<
45Server address: 192.168.127.9:8080
46Server name: coffee-7c86d7d67c-x8rc6
47Date: 25/May/2023:04:21:02 +0000
48URI: /coffee
49Request ID: f82492f218b7b865c2a9745e859cf394
50* Connection #0 to host cafe.example.com left intact
200 OK が応答されており、正しく通信ができることが確認できます
同様に https で cafe.example.com の /tea に対してリクエストを送ります
curl -kv --resolve cafe.example.com:443:127.0.0.1 https://cafe.example.com:443/tea
1* Added cafe.example.com:443:127.0.0.1 to DNS cache
2* Hostname cafe.example.com was found in DNS cache
3* Trying 127.0.0.1:443...
4* TCP_NODELAY set
5* Connected to cafe.example.com (127.0.0.1) port 443 (#0)
6* ALPN, offering h2
7* ALPN, offering http/1.1
8* successfully set certificate verify locations:
9* CAfile: /etc/ssl/certs/ca-certificates.crt
10 CApath: /etc/ssl/certs
11* TLSv1.3 (OUT), TLS handshake, Client hello (1):
12* TLSv1.3 (IN), TLS handshake, Server hello (2):
13* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
14* TLSv1.3 (IN), TLS handshake, Certificate (11):
15* TLSv1.3 (IN), TLS handshake, CERT verify (15):
16* TLSv1.3 (IN), TLS handshake, Finished (20):
17* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
18* TLSv1.3 (OUT), TLS handshake, Finished (20):
19* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
20* ALPN, server accepted to use http/1.1
21* Server certificate:
22* subject: CN=cafe.example.com
23* start date: Jul 14 21:52:39 2022 GMT
24* expire date: Jul 14 21:52:39 2023 GMT
25* issuer: CN=cafe.example.com
26* SSL certificate verify result: self signed certificate (18), continuing anyway.
27> GET /tea HTTP/1.1
28> Host: cafe.example.com
29> User-Agent: curl/7.68.0
30> Accept: */*
31>
32* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
33* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
34* old SSL session ID is stale, removing
35* Mark bundle as not supporting multiuse
36< HTTP/1.1 200 OK
37< Server: nginx/1.23.4
38< Date: Thu, 25 May 2023 04:22:10 GMT
39< Content-Type: text/plain
40< Content-Length: 155
41< Connection: keep-alive
42< Expires: Thu, 25 May 2023 04:22:09 GMT
43< Cache-Control: no-cache
44<
45Server address: 192.168.127.6:8080
46Server name: tea-5c457db9-gbxlp
47Date: 25/May/2023:04:22:10 +0000
48URI: /tea
49Request ID: dd548205c65fbbab524ccb3d0cce1ba8
50* Connection #0 to host cafe.example.com left intact
リソースの削除
cd ~/nginx-gateway-fabric/examples/https-termination
kubectl delete -f cafe.yaml
kubectl delete -f gateway.yaml
kubectl delete -f cafe-routes.yaml
kubectl delete -f reference-grant.yaml
kubectl delete -f certificate-ns-and-cafe-secret.yaml
通信内容の条件分岐(Advanced Routing)
より柔軟な通信の制御方法を確認します
https://github.com/nginxinc/nginx-gateway-fabric/tree/main/examples/advanced-routing
サンプルアプリケーションをデプロイ
## cd ~/nginx-gateway-fabric/examples/advanced-routing
kubectl apply -f cafe.yaml
kubectl apply -f gateway.yaml
kubectl apply -f cafe-routes.yaml
リソースの確認
cafe-route.yaml の内容を確認します。
## cd ~/nginx-gateway-fabric/examples/advanced-routing
cat cafe-routes.yaml
1apiVersion: gateway.networking.k8s.io/v1beta1
2kind: HTTPRoute
3metadata:
4 name: coffee
5spec:
6 parentRefs:
7 - name: gateway
8 hostnames:
9 - "cafe.example.com"
10 rules:
11 - matches:
12 - path:
13 type: PathPrefix
14 value: /coffee
15 backendRefs:
16 - name: coffee-v1-svc
17 port: 80
18 - matches:
19 - path:
20 type: PathPrefix
21 value: /coffee
22 headers:
23 - name: version
24 value: v2
25 - path:
26 type: PathPrefix
27 value: /coffee
28 queryParams:
29 - name: TEST
30 value: v2
31 backendRefs:
32 - name: coffee-v2-svc
33 port: 80
34---
35apiVersion: gateway.networking.k8s.io/v1beta1
36kind: HTTPRoute
37metadata:
38 name: tea
39spec:
40 parentRefs:
41 - name: gateway
42 hostnames:
43 - "cafe.example.com"
44 rules:
45 - matches:
46 - path:
47 type: PathPrefix
48 value: /tea
49 method: POST
50 backendRefs:
51 - name: tea-post-svc
52 port: 80
53 - matches:
54 - path:
55 type: PathPrefix
56 value: /tea
57 method: GET
58 backendRefs:
59 - name: tea-svc
60 port: 80
1つ目が /coffee 、2つ目が /tea の内容となります。双方 rules が定義されており、その配下に通信の転送条件を指定しています
設定の内容を読み解くと以下のようになります。
/cofee
type |
key |
value |
backend |
|---|---|---|---|
header |
version |
v2 |
coffee-v2-svc |
query |
TEST |
v2 |
coffee-v2-svc |
- |
- |
- |
coffee-v1-svc |
/tea
type |
value |
backend |
|---|---|---|
method |
POST |
tea-post-svc |
method |
GET |
tea-svc |
リソースを確認します
kubectl get pod
1NAME READY STATUS RESTARTS AGE
2coffee-v1-6b78998db9-25vv6 1/1 Running 0 24s
3coffee-v2-748cbbb49f-v4s47 1/1 Running 0 24s
4tea-5c457db9-fwxwm 1/1 Running 0 24s
5tea-post-7db8cd8bf-wz4sw 1/1 Running 0 24s
kubectl get svc | grep -v kubernetes
1NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
2coffee-v1-svc ClusterIP 10.98.220.232 <none> 80/TCP 34s
3coffee-v2-svc ClusterIP 10.98.18.61 <none> 80/TCP 33s
4tea-post-svc ClusterIP 10.101.63.1 <none> 80/TCP 33s
5tea-svc ClusterIP 10.105.150.72 <none> 80/TCP 33s
kubectl get gateway
1NAME CLASS ADDRESS PROGRAMMED AGE
2gateway nginx 192.168.127.2 23s
kubectl get httproute
1NAME HOSTNAMES AGE
2coffee ["cafe.example.com"] 22s
3tea ["cafe.example.com"] 22s
動作確認
先程の表に示した内容と同じ結果となることを確認します。
/coffee 宛のリクエストでHTTPヘッダーに値を指定します
curl -H "Host:cafe.example.com" http://localhost/coffee -H "version:v2"
1Server address: 192.168.127.7:8080
2Server name: coffee-v2-748cbbb49f-v4s47
3Date: 25/May/2023:07:51:49 +0000
4URI: /coffee
5Request ID: 49189037592857bbdb7d814c80a7bce2
/coffee 宛のリクエストでQuery Parameterを指定します
curl -H "Host:cafe.example.com" http://localhost/coffee?TEST=v2
1erver address: 192.168.127.7:8080
2Server name: coffee-v2-748cbbb49f-v4s47
3Date: 25/May/2023:07:52:04 +0000
4URI: /coffee?TEST=v2
5Request ID: 88ef837322389f2ef34fd70b8be890d9
/coffee 宛のリクエストで何も指定を行いません
curl -H "Host:cafe.example.com" http://localhost/coffee
1Server address: 192.168.127.10:8080
2Server name: coffee-v1-6b78998db9-25vv6
3Date: 25/May/2023:07:52:16 +0000
4URI: /coffee
5Request ID: e3c5a1e8a74193c71906583d4dcbb4b6
/tea 宛のリクエストでPOST Methodを指定します
curl -H "Host:cafe.example.com" http://localhost/tea -X POST
1Server address: 192.168.127.8:8080
2Server name: tea-post-7db8cd8bf-wz4sw
3Date: 25/May/2023:07:52:32 +0000
4URI: /tea
5Request ID: 1a6f6f4d8c205e70001769f8450a784c
/tea 宛のリクエストでGET Methodを指定します
curl -H "Host:cafe.example.com" http://localhost/tea -X GET
1Server address: 192.168.127.14:8080
2Server name: tea-5c457db9-fwxwm
3Date: 25/May/2023:07:52:42 +0000
4URI: /tea
5Request ID: 68272b109b4e7f0aaf82d2b0f8541b35
/tea 宛のリクエストでPUT Methodを指定します。こちらのMethodは条件に含まれていないためエラーとなります。
curl -H "Host:cafe.example.com" http://localhost/tea -X PUT
1<html>
2<head><title>404 Not Found</title></head>
3<body>
4<center><h1>404 Not Found</h1></center>
5<hr><center>nginx/1.23.4</center>
6</body>
7</html>
リソースの削除
## cd ~/nginx-gateway-fabric/examples/advanced-routing
kubectl delete -f cafe.yaml
kubectl delete -f gateway.yaml
kubectl delete -f cafe-routes.yaml
割合を指定した分散 (Traffic Split)
トラフィック分割を確認します
https://github.com/nginxinc/nginx-gateway-fabric/tree/main/examples/traffic-splitting
サンプルアプリケーションをデプロイ
cd ~/nginx-gateway-fabric/examples/traffic-splitting
kubectl apply -f cafe.yaml
kubectl apply -f gateway.yaml
kubectl apply -f cafe-route.yaml
リソースの確認
作成したリソースの内容を確認します
cat cafe-route.yaml
1apiVersion: gateway.networking.k8s.io/v1beta1
2kind: HTTPRoute
3metadata:
4 name: cafe-route
5spec:
6 parentRefs:
7 - name: gateway
8 sectionName: http
9 hostnames:
10 - "cafe.example.com"
11 rules:
12 - matches:
13 - path:
14 type: PathPrefix
15 value: /coffee
16 backendRefs:
17 - name: coffee-v1
18 port: 80
19 weight: 80
20 - name: coffee-v2
21 port: 80
22 weight: 20
backendRefs で通信の転送先サービスを指定する箇所で、 weight を指定しています。
coffee-v1 が weight 80 、 coffee-v2 が weight 20 となります
正しくリソースが作成されたことを確認します
kubectl get gateway
1NAME CLASS ADDRESS PROGRAMMED AGE
2gateway nginx 192.168.127.2 12s
kubectl get httproute
1NAME HOSTNAMES AGE
2cafe-route ["cafe.example.com"] 4s
kubectl get pod
1NAME READY STATUS RESTARTS AGE
2coffee-v1-6b78998db9-vtpvz 1/1 Running 0 56s
3coffee-v2-748cbbb49f-ndvp8 1/1 Running 0 56s
kubectl get svc | grep -v kubernetes
1NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
2coffee-v1 ClusterIP 10.111.57.103 <none> 80/TCP 66s
3coffee-v2 ClusterIP 10.97.133.169 <none> 80/TCP 66s
動作確認
Curlコマンドで複数回リクエストを送ると、 coffee-v1 、 coffee-v2 のそれぞれに転送されていることが確認できます
curl -s -H "Host: cafe.example.com" http://localhost/coffee
1Server address: 192.168.127.11:8080
2Server name: coffee-v2-748cbbb49f-ndvp8
3Date: 25/May/2023:08:19:17 +0000
4URI: /coffee
5Request ID: cc8c76a2a5e04c6dc43b99f7a740f8ae
curl -s -H "Host: cafe.example.com" http://localhost/coffee
1Server address: 192.168.127.13:8080
2Server name: coffee-v1-6b78998db9-vtpvz
3Date: 25/May/2023:08:19:20 +0000
4URI: /coffee
5Request ID: bb7154122f4fe64cccb002c113cdb364
以下コマンドを参考に複数回Curlを実行し、その結果をファイルに記録します。記録の内容より coffee-v1 に coffee-v2 転送した数を確認できます。 分散する割合は少しばらつきが発生しますが、参考として分散した数の結果を確認してください。
## cd ~/nginx-gateway-fabric/examples/traffic-splitting
> split.txt ;\
for i in {1..20}; \
do curl -s -H "Host: cafe.example.com" http://localhost/coffee | grep "Server name" >> split.txt ; \
done ; \
echo -n "v1:" ; grep v1 split.txt | wc -l ; echo -n "v2:" ; grep v2 split.txt | wc -l
1v1:16
2v2:4
実行タイミングによって結果は頻繁に変わりますが、大まかに 8:2 の割合で通信が転送できることがわかります。
割合の変更
割合を 8:2 から、 5:5(同じ割合) に変更します。
これから適用するHTTPRouteと現在設定している内容を比較します。
diff -u cafe-route.yaml cafe-route-equal-weight.yaml
1 --- cafe-route.yaml 2023-05-25 08:58:27.326066185 +0900
2 +++ cafe-route-equal-weight.yaml 2023-05-25 08:58:27.326066185 +0900
3 @@ -19,4 +19,4 @@
4 weight: 80
5 - name: coffee-v2
6 port: 80
7 - weight: 20
8 + weight: 80
差分から、 coffee-v2 を weight 80 とすることで、 1:1 の割合となるようにしています。
設定を反映します。
kubectl apply -f cafe-route-equal-weight.yaml
動作確認
Curlコマンドの結果に変化はありません。
curl -s -H "Host: cafe.example.com" http://localhost/coffee
以下コマンドを実行し、転送される割合を確認します。
## cd ~/nginx-gateway-fabric/examples/traffic-splitting
> split-equal.txt ;\
for i in {1..20}; \
do curl -s -H "Host: cafe.example.com" http://localhost/coffee | grep "Server name" >> split-equal.txt ; \
done ; \
echo -n "v1:" ; grep v1 split-equal.txt | wc -l ; echo -n "v2:" ; grep v2 split-equal.txt | wc -l
1v1:10
2v2:10
指定した割合となっていることが確認できます
リソースの削除
## cd ~/nginx-gateway-fabric/examples/traffic-splitting
kubectl delete -f gateway.yaml
kubectl delete -f cafe-route-equal-weight.yaml
kubectl delete -f cafe.yaml