Hiển thị các bài đăng có nhãn gatewayapi. Hiển thị tất cả bài đăng
Hiển thị các bài đăng có nhãn gatewayapi. Hiển thị tất cả bài đăng

Thứ Tư, 29 tháng 4, 2026

GatewayAPI collection

https://oneuptime.com/blog/tag/gateway-api?page=4&pageSize=25 Contents GatewayAPI 2 001. GatewayAPI - 1.Cài đặt bản Standard 2 001. GatewayAPI - 1.Cài đặt bản Experimeltal 2 001. GatewayAPI - nginx từ HELM 3 001. Tạo GatewayClass 3 002. ingress2gateway 4 003. Tạo pod mẫu để test 4 TESTED-0: Create Gateway mới 4 TESTED-1 HttpRoute basic 5 TESTED-2: Tích hợp certmanager 5 TESTED-3: Multi Hostname và ssl - Basic 7 TESTED-4: ListenerSet 8 TESTED-5: Traffic Split 11 TESTED-6: Header Route 12 TESTED-7.1: Header Modify 13 TESTED-8: Method+Path route 15 TESTED-9: Path route only 16 TESTED-10 Method Route only 17 TESTED-11: Query Parameter Route 18 TESTED-12: URL rewrite 19 TESTED-13: Mirror request 20 TESTED-14 ReferenceGrant 21 TESTED-14.1: HttpRoute->Services khác namespace 21 TESTED-14.2: Gateway->Secret khác namespace 23 OK-15: ListenerSet->Secret 24 ReferenceGrant - Các ví dụ khác 25 TEST CHƯA OK-15: Increase timeout 25 TESTED-18: Redirect 301/302 26 TESTED-19: TLS Passthought 27 TESTED-20: TCP/UDP Route 29 TESTED-21: BackendTLSPolicy 30 22: CORS 32 (NOT)Ví dụ 26-A: mTLS Frontend 32 (NOT)Ví dụ 26-B: mTLS Backend 32 (NOT)Ví dụ 27: HTTP2.0 Support Backend 32 Ví dụ 31: basic authen 33 Nginx GW Fabric Advance 33 SnippetsPolicies 33 ClientSettingsPolicy 33 UpstreamSettingsPolicy 33 Session-persistence 33 Authenticationfilters 33 Nginxgateways 33 nginxproxies 33 observabilitypolicies 33 proxysettingspolicies 33 ratelimitpolicies 33 snippetsfilters 33 upstreamsettingspolicies 33 Kiến trúc GWAPI 33 Security cho GatewayAPI 34 1. Giới hạn NS cho GW và httpRoute 34 GatewayAPI 001. GatewayAPI - 1.Cài đặt bản Standard Tham khảo trong file cilium đã viết để cài đặt Toàn bộ tài liệu https://gateway-api.sigs.k8s.io/guides/getting-started/ https://docs.nginx.com/nginx-gateway-fabric/get-started/#install-the-helm-chart Kiểm tra bản mới nhất ở link này: https://gateway-api.sigs.k8s.io/guides/getting-started/introduction/ Bước 1: Cài CRD wget https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.5.1/standard-install.yaml k apply -f standard-install.yaml Bước 2: Cài gatewayclass: nginx Bản mới nhất ở đây https://docs.nginx.com/nginx-gateway-fabric/install/helm/#installing-the-gateway-api-resources Kiểm tra độ tương thích trước khi cài version: https://github.com/nginx/nginx-gateway-fabric#technical-specifications helm install ngf oci://ghcr.io/nginx/charts/nginx-gateway-fabric \ --namespace nginx-gateway \ --create-namespace \ --version 2.6.2 \ --wait cat <<EOF > gatewayclass.yaml apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass metadata: name: nginx spec: controllerName: gateway.nginx.org/nginx-gateway-controller EOF k apply -f gatewayclass.yaml k get gatewayclasses.gateway.networking.k8s.io 001. GatewayAPI - 1.Cài đặt bản Experimeltal Bước 1: Cài CRD với tính năng Experimental, thực chất bước này không cần cài nữa Tìm bản mới nhất trên này https://gateway-api.sigs.k8s.io/guides/getting-started/introduction/ và trên này https://github.com/kubernetes-sigs/gateway-api/releases wget https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.6.1/experimental-install.yaml k apply --server-side -f experimental-install.yaml root@cicd:~/install-gwapi# kubectl get crd | grep gateway.networking.k8s.io backendtlspolicies.gateway.networking.k8s.io 2026-07-19T17:14:23Z gatewayclasses.gateway.networking.k8s.io 2026-07-19T17:14:23Z gateways.gateway.networking.k8s.io 2026-07-19T17:14:24Z grpcroutes.gateway.networking.k8s.io 2026-07-19T17:14:24Z httproutes.gateway.networking.k8s.io 2026-07-19T17:14:24Z listenersets.gateway.networking.k8s.io 2026-07-19T17:14:24Z referencegrants.gateway.networking.k8s.io 2026-07-19T17:14:24Z tcproutes.gateway.networking.k8s.io 2026-07-19T17:14:24Z tlsroutes.gateway.networking.k8s.io 2026-07-19T17:14:24Z udproutes.gateway.networking.k8s.io 2026-07-19T17:14:25Z Bước 2: Cài Nginx gateway Fabric từ link Bản cài chính thức, đã test: https://docs.nginx.com/nginx-gateway-fabric/install/manifests/open-source-experimental/ Link git của nó: https://github.com/nginx/nginx-gateway-fabric/tree/main/config/crd/gateway-api kubectl kustomize "https://github.com/nginx/nginx-gateway-fabric/config/crd/gateway-api/experimental?ref=v2.6.7" | kubectl apply --server-side -f – nếu gặp lỗi thì hãy xóa kubectl delete crd tcproutes.gateway.networking.k8s.io kubectl delete crd udproutes.gateway.networking.k8s.io backendtlspolicies.gateway.networking.k8s.io gatewayclasses.gateway.networking.k8s.io gateways.gateway.networking.k8s.io grpcroutes.gateway.networking.k8s. httproutes.gateway.networking.k8s. listenersets.gateway.networking.k8s.io referencegrants.gateway.networking.k8s.io tcproutes.gateway.networking.k8s.io tlsroutes.gateway.networking.k8s.io udproutes.gateway.networking.k8s. xbackendtrafficpolicies.gateway.networking.x-k8s.io d xmeshes.gateway.networking.x-k8s.io Bước 3: Cài bổ xung CRD nâng cao rành riêng cho Nginx fabric https://docs.nginx.com/nginx-gateway-fabric/install/manifests/open-source-experimental/#deploy-the-custom-resource-definitions kubectl apply --server-side -f https://raw.githubusercontent.com/nginx/nginx-gateway-fabric/v2.6.7/deploy/crds.yaml authenticationfilters.gateway.nginx.org clientsettingspolicies.gateway.nginx.org nginxgateways.gateway.nginx.org nginxproxies.gateway.nginx.org serverside-applied observabilitypolicies.gateway.nginx.org serverside-applied proxysettingspolicies.gateway.nginx.org serverside-applied ratelimitpolicies.gateway.nginx.org serverside-applied snippetsfilters.gateway.nginx.org serverside-applied snippetspolicies.gateway.nginx.org serverside-applied upstreamsettingspolicies.gateway.nginx.org serverside-applied wafpolicies.gateway.nginx.org serverside-applied • authenticationfilters • clientsettingspolicies • nginxgateways • nginxproxies • observabilitypolicies • proxysettingspolicies • ratelimitpolicies • snippetsfilters • snippetspolicies • upstreamsettingspolicies Bước 4: Cài đặt deployment wget https://raw.githubusercontent.com/nginx/nginx-gateway-fabric/v2.6.7/deploy/experimental/deploy.yaml vim deploy.yaml, dòng cuối # NHỚ ĐỔI TỪ LOCAL-> CLUSTER cho svc, để vào được web externalTrafficPolicy: Cluster k apply -f deploy.yaml 001. GatewayAPI - nginx từ HELM Bản mới nhất ở đây https://docs.nginx.com/nginx-gateway-fabric/install/helm/#installing-the-gateway-api-resources Kiểm tra phiên bản: https://github.com/nginx/nginx-gateway-fabric/pkgs/container/charts%2Fnginx-gateway-fabric/versions?filters%5Bversion_type%5D=tagged Kiểm tra độ tương thích trước khi cài version: https://github.com/nginx/nginx-gateway-fabric#technical-specifications helm pull oci://ghcr.io/nginx/charts/nginx-gateway-fabric --version 0.0.0-edge tar –xvzf cd nginx-gateway-fabric helm install ngf . \ --namespace nginx-gateway \ --create-namespace \ --wait 001. Tạo GatewayClass cat <<EOF > gatewayclass.yaml apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass metadata: name: nginx spec: controllerName: gateway.nginx.org/nginx-gateway-controller EOF k apply -f gatewayclass.yaml k get gatewayclasses.gateway.networking.k8s.io Để xem GatewayAPI hỗ trợ những chức năng nào, ta gõ như sau # k get gatewayclasses.gateway.networking.k8s.io nginx -o yaml 002. ingress2gateway wget https://github.com/kubernetes-sigs/ingress2gateway/releases/download/v1.0.0/ingress2gateway_Linux_x86_64.tar.gz ingress2gateway print --providers=ingress-nginx --all-namespaces > gateway-api-manifests.yaml ingress2gateway print --providers=ingress-nginx --input-file=./ingress1.yaml 003. Tạo pod mẫu để test k create ns app-namespace1 k create ns app-namespace2 k -n app-namespace1 create deployment web1 --image=traefik/whoami --replicas=1 k -n app-namespace1 expose deployment web1 --name=svc-web1 --port=80 --target-port=80 --type=ClusterIP k -n app-namespace1 create deployment web1a --image=traefik/whoami --replicas=1 k -n app-namespace1 expose deployment web1a --name=svc-web1a --port=80 --target-port=80 --type=ClusterIP k -n app-namespace1 create deployment web1b --image=traefik/whoami --replicas=1 k -n app-namespace1 expose deployment web1b --name=svc-web1b --port=80 --target-port=80 --type=ClusterIP k -n app-namespace2 create deployment web2 --image=traefik/whoami --replicas=1 k -n app-namespace2 expose deployment web2 --name=svc-web2 --port=80 --target-port=80 --type=ClusterIP TESTED-0: Create Gateway mới https://gateway-api.sigs.k8s.io/guides/getting-started/simple-gateway/ ***Chú ý: có thể tạo nhiều gateway, mỗi gw sẽ có 1 ip LB riêng k create ns infra-gateway01 openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=HELLO-WORLD-gateway/O=HELLO-WORLDe" kubectl -n infra-gateway01 create secret tls default-cert --key tls.key --cert tls.crt cat << EOF > 01.simple-gateway.yaml apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: my-gateway namespace: infra-gateway01 spec: gatewayClassName: nginx listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: All - name: https protocol: HTTPS port: 443 tls: mode: Terminate certificateRefs: - name: default-cert #chú ý phải có tạo secret ở trên allowedRoutes: namespaces: from: All EOF k apply -f 01.simple-gateway.yaml TESTED-1 HttpRoute basic cat << EOF > 01.simple-httproute.yaml apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: app-http namespace: app-namespace1 spec: parentRefs: - name: my-gateway #chú ý trùng tên gateway namespace: infra-gateway01 sectionName: http #chú ý trùng tên section hostnames: - "test.tuan.name.vn" rules: - matches: - path: type: PathPrefix value: /v1/api #có thể để thành / nếu muốn route all traffic. backendRefs: - name: svc-web1 #chú ý trùng tên svc port: 80 EOF k apply -f 01.simple-httproute.yaml curl -v http://test.tuan.name.vn/v1/api curl -vk https://test.tuan.name.vn/v1/api TESTED-2: Tích hợp certmanager Xem mục chính CertManager, cài như bình thường https://freedium-mirror.cfd/https://faun.pub/kubernetes-gateway-api-a-complete-step-by-step-setup-guide-397d0ff5375f https://docs.nginx.com/nginx-gateway-fabric/traffic-security/integrate-cert-manager/ *** Chú ý Tuấn: ở đây ta phải tạo Certificate.yaml mới, sau đó mới add vào gateway cat << EOF > 02.certmanager-certificate.yaml apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: test-tuan-name-vn-tls namespace: nginx-gateway spec: secretName: test-tuan-name-vn-tls-secret duration: 2160h # 90 ngày renewBefore: 360h # Tự Gia hạn trước khi hết hạn 15 ngày (360 giờ) issuerRef: name: letsencrypt-stag kind: ClusterIssuer commonName: test.tuan.name.vn dnsNames: #có hỗ trợ multi ssl trên cùng 1 ssl file - test.tuan.name.vn EOF cat << EOF > 02.certmanager-gateway.yaml apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: my-gateway namespace: nginx-gateway annotations: # Tùy chọn: Một số controller dùng annotation này để tự động map cert cert-manager.io/cluster-issuer: letsencrypt-stag spec: gatewayClassName: nginx listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: All - name: https protocol: HTTPS port: 443 tls: mode: Terminate certificateRefs: - name: default-cert allowedRoutes: namespaces: from: All - name: https-test-tuan-name-vn protocol: HTTPS port: 443 hostname: "test.tuan.name.vn" tls: mode: Terminate certificateRefs: - name: test-tuan-name-vn-tls-secret allowedRoutes: namespaces: from: All EOF cat << EOF > 02.certmanager-httproute.yaml # HTTP apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: app-web1-http-redirect namespace: app-namespace1 spec: parentRefs: - name: my-gateway #chú ý trùng tên gateway namespace: nginx-gateway sectionName: http #chú ý trùng tên section hostnames: - "test.tuan.name.vn" rules: - filters: - type: RequestRedirect requestRedirect: scheme: https statusCode: 302 # Chuyển hướng tạm thời 302 sang 443 --- # HTTPS apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: app-web1-https-route namespace: app-namespace1 spec: parentRefs: - name: my-gateway namespace: nginx-gateway sectionName: https-test-tuan-name-vn # Khớp với 'name' của listener 443 trong Gateway hostnames: - "test.tuan.name.vn" rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: svc-web1 #chú ý trùng tên svc port: 80 EOF Kết quả: curl -v http://test.tuan.name.vn #< HTTP/1.1 302 Moved Temporarily #< Location: https://test.tuan.name.vn/ curl -v https://test.tuan.name.vn #* subject: CN=test.tuan.name.vn #* start date: May 1 16:43:03 2026 GMT #* expire date: Jul 30 16:43:02 2026 GMT #* issuer: C=US; O=(STAGING) Let's Encrypt; CN=(STAGING) Tenuous Tomato R13 TESTED-3: Multi Hostname và ssl - Basic k create ns infra-gateway03 k create ns app-namespace1 k create ns app-namespace2 k -n infra-gateway03 delete secret default-cert-domain1 k -n infra-gateway03 delete secret default-cert-domain2 k -n infra-gateway03 delete secret default-cert openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls1.key -out tls1.crt -subj "/CN=*.domain1.com/O=Default Certificate" kubectl create secret tls default-cert-domain1 --key tls1.key --cert tls1.crt -n infra-gateway03 openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls2.key -out tls2.crt -subj "/CN=*.domain2.com/O=Default Certificate" kubectl create secret tls default-cert-domain2 --key tls2.key --cert tls2.crt -n infra-gateway03 openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=default-gateway/O=Default Certificate" kubectl create secret tls default-cert --key tls.key --cert tls.crt -n infra-gateway03 cat << EOF > 03.multi-wildcard.yaml apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: wildcard-gateway namespace: infra-gateway03 annotations: cert-manager.io/cluster-issuer: letsencrypt-prod spec: gatewayClassName: nginx listeners: - name: http protocol: HTTP port: 80 # Đây là default allowedRoutes: namespaces: from: All - name: https protocol: HTTPS port: 443 # Đây là default tls: mode: Terminate certificateRefs: - name: default-cert allowedRoutes: namespaces: from: All - name: https-wildcard-domain1 protocol: HTTPS port: 443 hostname: "*.domain1.com" tls: mode: Terminate certificateRefs: - name: default-cert-domain1 allowedRoutes: namespaces: from: All - name: https-wildcard-domain2 protocol: HTTPS port: 443 hostname: "*.domain2.com" tls: mode: Terminate certificateRefs: - name: default-cert-domain2 allowedRoutes: namespaces: from: All --- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: app1-domain1-route namespace: app-namespace1 spec: parentRefs: - name: wildcard-gateway namespace: infra-gateway03 sectionName: https-wildcard-domain1 # Gắn đúng vào listener của domain1 hostnames: - "app1.domain1.com" # Chỉ định subdomain cụ thể rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: svc-web1 port: 80 --- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: app22-domain1-route namespace: app-namespace2 spec: parentRefs: - name: wildcard-gateway namespace: infra-gateway03 sectionName: https-wildcard-domain2 # Gắn đúng vào listener của domain1 hostnames: - "app2.domain2.com" # Chỉ định subdomain cụ thể rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: svc-web2 port: 80 EOF # Mục đích tạo thêm gw để dễ test. Còn thực tế gateway sẽ dùng chung k apply -f 03.multi-wildcard.yaml curl --resolve app1.domain1.com:443:192.168.88.151 -vk https://app1.domain1.com * subject: CN=*.domain1.com; O=Default Certificate curl --resolve app2.domain2.com:443:192.168.88.151 -vk https://app2.domain2.com * subject: CN=*.domain2.com; O=Default Certificate TESTED-4: ListenerSet https://gateway-api.sigs.k8s.io/guides/user-guides/listener-set/ Cách tiếp cận này giúp bạn giải quyết 2 vấn đề lớn: • Phân quyền (Self-service): Đội Platform chỉ cần quản lý 1 Gateway dùng chung. Từng đội phát triển ứng dụng ở các namespace khác nhau tự tạo ListenerSet để cài đặt domain và SSL của riêng họ. • Vượt giới hạn: Giúp cluster phá vỡ giới hạn cứng 64 listeners trên một Gateway duy nhất của Kubernetes. k delete ns team-1-ns ; k create ns team-1-ns k delete ns team-2-ns ; k create ns team-2-ns k delete ns infra-gateway04 ; k create ns infra-gateway04 kubectl create deployment team-1-app -n team-1-ns --image=traefik/whoami --port=80 kubectl expose deployment team-1-app -n team-1-ns --name=team-1-service --port=80 --target-port=80 kubectl create deployment team-2-app -n team-2-ns --image=traefik/whoami --port=80 kubectl expose deployment team-2-app -n team-2-ns --name=team-2-service --port=80 --target-port=80 openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls3.key -out tls3.crt -subj "/CN=*.first.foo.com/O=Default Certificate" kubectl create secret tls first-workload-cert --key tls3.key --cert tls3.crt -n team-1-ns openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls4.key -out tls4.crt -subj "/CN=*.second.foo.com/O=Default Certificate" kubectl create secret tls second-workload-cert --key tls4.key --cert tls4.crt -n team-2-ns cat << EOF > 04.listerner-set.yaml apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: shared-gateway namespace: infra-gateway04 spec: gatewayClassName: nginx allowedListeners: namespaces: from: All listeners: - name: foo hostname: foo.com protocol: HTTP port: 80 --- apiVersion: gateway.networking.k8s.io/v1 kind: ListenerSet metadata: name: first-workload-listeners namespace: team-1-ns spec: parentRef: namespace: infra-gateway04 name: shared-gateway kind: Gateway group: gateway.networking.k8s.io listeners: - name: first hostname: "*.first.foo.com" protocol: HTTPS port: 443 tls: mode: Terminate certificateRefs: - kind: Secret group: "" name: first-workload-cert --- apiVersion: gateway.networking.k8s.io/v1 kind: ListenerSet metadata: name: second-workload-listeners namespace: team-2-ns spec: parentRef: namespace: infra-gateway04 name: shared-gateway kind: Gateway group: gateway.networking.k8s.io listeners: - name: second hostname: "*.second.foo.com" protocol: HTTPS port: 443 tls: mode: Terminate certificateRefs: - kind: Secret group: "" name: second-workload-cert EOF # Mục đích tạo thêm gw để dễ test. Còn thực tế gateway sẽ dùng chung k apply -f 04.listerner-set.yaml sleep 5 k get gateway -A k get listenersets.gateway.networking.k8s.io –A k get svc –A cat << EOF > 041.httproute.yaml apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: team-1-route namespace: team-1-ns # Đặt cùng namespace với ListenerSet của Team 1 spec: parentRefs: - group: gateway.networking.k8s.io kind: ListenerSet # <--- Bắt buộc chỉ định là ListenerSet thay vì Gateway name: first-workload-listeners # Tên của ListenerSet tương ứng sectionName: first # Tên listener bên trong ListenerSet đó hostnames: - "*.first.foo.com" rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: team-1-service # Service backend nằm trong team-1-ns port: 80 --- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: team-2-route namespace: team-2-ns # Đặt cùng namespace với ListenerSet của Team 2 spec: parentRefs: - group: gateway.networking.k8s.io kind: ListenerSet # <--- Chỉ định ListenerSet làm cha name: second-workload-listeners sectionName: second hostnames: - "*.second.foo.com" rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: team-2-service # Service backend nằm trong team-2-ns port: 80 EOF k apply -f 041.httproute.yaml curl -vk --resolve test.first.foo.com:443:192.168.88.152 https://test.first.foo.com * issuer: CN=*.first.foo.com; O=Default Certificate curl -vk --resolve test.second.foo.com:443:192.168.88.152 https://test.second.foo.com * issuer: CN=*.second.foo.com; O=Default Certificate Xóa rác sau khi test k delete ns infra-gateway ; k delete ns team-1-ns ; k delete ns team-2-ns TESTED-5: Traffic Split https://gateway-api.sigs.k8s.io/guides/traffic-splitting/ k create ns app-namespace05 k -n app-namespace05 create deployment web1 --image=traefik/whoami --replicas=1 k -n app-namespace05 expose deployment web1 --name=svc-web1 --port=80 --target-port=80 --type=ClusterIP k -n app-namespace05 create deployment web1a --image=traefik/whoami --replicas=1 k -n app-namespace05 expose deployment web1a --name=svc-web1a --port=80 --target-port=80 --type=ClusterIP cat << EOF > 05.simple-gateway.yaml apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: my-gateway05 namespace: infra-gateway05 spec: gatewayClassName: nginx listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: All EOF k create ns infra-gateway05 k apply -f 05.simple-gateway.yaml # Mục đích tạo thêm gw để dễ test. Còn thực tế gateway sẽ dùng chung cat << EOF > 05.traffic-splitting-httproute.yaml apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: demo-route-split namespace: app-namespace05 spec: parentRefs: - name: my-gateway05 #chú ý trùng tên gateway namespace: infra-gateway05 sectionName: http #chú ý trùng tên section hostnames: - "test.tuan.name.vn" rules: - matches: - path: type: PathPrefix value: /test5 backendRefs: - name: svc-web1 #đây là svc1 của pod1 port: 80 weight: 75 - name: svc-web1a #đây là svc2 của pod1 port: 80 weight: 25 EOF k create ns app-namespace05 k apply -f 05.traffic-splitting-httproute.yaml curl -vk --resolve test.tuan.name.vn:80:192.168.88.153 http://test.tuan.name.vn/test5 # Run multiple requests for i in {1..20}; do curl -s --resolve test.tuan.name.vn:80:192.168.88.153 http://test.tuan.name.vn/test5| grep Hostname; done nên ưu tiên chia traffic như tỉ lệ sau TESTED-6: Header Route https://gateway-api.sigs.k8s.io/guides/traffic-splitting/#canary-traffic-rollout k create ns app-namespace06 k -n app-namespace06 create deployment web1 --image=traefik/whoami --replicas=1 k -n app-namespace06 expose deployment web1 --name=svc-web1 --port=80 --target-port=80 --type=ClusterIP k -n app-namespace06 create deployment web1a --image=traefik/whoami --replicas=1 k -n app-namespace06 expose deployment web1a --name=svc-web1a --port=80 --target-port=80 --type=ClusterIP cat << EOF > 06.simple-gateway.yaml apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: my-gateway06 namespace: infra-gateway06 spec: gatewayClassName: nginx listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: All EOF # Mục đích tạo thêm gw để dễ test. Còn thực tế gateway sẽ dùng chung k create ns infra-gateway06 k apply -f 06.simple-gateway.yaml cat << EOF > 06.traffic-splitting-header-route.yaml apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: demo-route-headers namespace: app-namespace06 spec: parentRefs: - name: my-gateway06 #chú ý trùng tên gateway namespace: infra-gateway06 sectionName: http #chú ý trùng tên section hostnames: - "test.tuan.name.vn" rules: - matches: - path: type: PathPrefix value: /test6 headers: - name: version #vị trí header nằm ở đây version=v2 value: v2 backendRefs: - name: svc-web1a port: 80 - matches: - path: type: PathPrefix value: /test6 backendRefs: - name: svc-web1 port: 80 EOF k create ns app-namespace06 k apply -f 06.traffic-splitting-header-route.yaml # Default request goes to v1 curl --resolve test.tuan.name.vn:80:192.168.88.154 http://test.tuan.name.vn/test6 Hostname: web1-888886b4d-tg4jv # Request with header goes to v2 curl -H "version: v2" --resolve test.tuan.name.vn:80:192.168.88.154 http://test.tuan.name.vn/test6 Hostname: web1-888886b4d-t6rbg  Kết quả cho ta thấy khi thêm Header thì sẽ route sang 1 pod khác Ví dụ khác về header route #tham khảo, chưa test https://oneuptime.com/blog/post/2026-02-09-httproute-traffic-routing/view # httproute-headers.yaml apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: header-routing namespace: default spec: parentRefs: - name: http-gateway hostnames: - "example.com" rules: # Route mobile users to mobile backend - matches: - headers: - name: User-Agent type: RegularExpression value: ".*(Mobile|Android|iPhone).*" backendRefs: - name: mobile-service port: 8080 # Route beta users to canary backend - matches: - headers: - name: X-Beta-User type: Exact value: "true" backendRefs: - name: canary-service port: 8080 # Default backend - matches: - path: type: PathPrefix value: "/" backendRefs: - name: stable-service port: 8080 TESTED-7.1: Header Modify https://gateway-api.sigs.k8s.io/guides/http-header-modifier/ k create ns app-namespace07 k -n app-namespace07 create deployment web1 --image=traefik/whoami --replicas=1 k -n app-namespace07 expose deployment web1 --name=svc-web1 --port=80 --target-port=80 --type=ClusterIP k -n app-namespace07 create deployment web1a --image=traefik/whoami --replicas=1 k -n app-namespace07 expose deployment web1a --name=svc-web1a --port=80 --target-port=80 --type=ClusterIP cat << EOF > 07.simple-gateway.yaml apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: my-gateway07 namespace: infra-gateway07 spec: gatewayClassName: nginx listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: All EOF # Mục đích tạo thêm gw để dễ test. Còn thực tế gateway sẽ dùng chung k create ns infra-gateway07 k apply -f 07.simple-gateway.yaml cat << EOF > 07.http-header-modifier.yaml apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: header-manipulation-route namespace: app-namespace07 # Namespace chứa ứng dụng của bạn spec: parentRefs: - name: my-gateway07 #chú ý trùng tên gateway namespace: infra-gateway07 sectionName: http #chú ý trùng tên section hostnames: - "test.tuan.name.vn" rules: - matches: - path: type: PathPrefix value: /test7 # 🛠️ CẤU HÌNH THAO TÁC VỚI HEADER NẰM Ở ĐÂY filters: # 1. Thao tác với REQUEST HEADERS (Gửi từ Client -> Backend) - type: RequestHeaderModifier requestHeaderModifier: # Thêm header mới (Nếu đã tồn tại sẽ bị ghi đè) set: - name: X-Environment-Type value: "Production" # Cộng dồn thêm giá trị vào header đã có add: - name: X-Forwarded-For-Custom value: "nginx-fabric-gateway" # Xóa bỏ header nhạy cảm trước khi đẩy vào Backend remove: - "X-Internal-Secret" - "Authorization-Debug" # 2. Thao tác với RESPONSE HEADERS (Trả từ Backend -> Client) - type: ResponseHeaderModifier responseHeaderModifier: # Thêm header chuẩn bảo mật cho Client set: - name: Strict-Transport-Security value: "max-age=999999; includeSubDomains" - name: X-Frame-Options value: "DENY" # Thêm thông tin định danh hệ thống add: - name: Server-Trace value: "gateway-node-01xxxx" # Ẩn bớt các header lộ thông tin hệ thống backend remove: - "X-Powered-By" - "X-AspNet-Version" backendRefs: - name: svc-web1 port: 80 EOF k apply -f 07.http-header-modifier.yaml curl --resolve test.tuan.name.vn:80:192.168.88.150 -v http://test.tuan.name.vn/test7 < Server-Trace: gateway-node-01xxxx < Strict-Transport-Security: max-age=999999; includeSubDomains #Header resposne mới đã được thêm vào. TESTED-8: Method+Path route https://gateway-api.sigs.k8s.io/guides/http-method-matching/ • A POST request to /v8/api will be routed to infra-backend-v1. • A GET request to /v8/api will be routed to infra-backend-v2. k create ns app-namespace08 k -n app-namespace08 create deployment web1 --image=traefik/whoami --replicas=1 k -n app-namespace08 expose deployment web1 --name=svc-web1 --port=80 --target-port=80 --type=ClusterIP k -n app-namespace08 create deployment web1a --image=traefik/whoami --replicas=1 k -n app-namespace08 expose deployment web1a --name=svc-web1a --port=80 --target-port=80 --type=ClusterIP cat << EOF > 08.simple-gateway.yaml apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: my-gateway08 namespace: infra-gateway08 spec: gatewayClassName: nginx listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: All EOF # Mục đích tạo thêm gw để dễ test. Còn thực tế gateway sẽ dùng chung k create ns infra-gateway08 k apply -f 08.simple-gateway.yaml cat << EOF > 08.http-method-matching.yaml apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: method-and-path-matching namespace: app-namespace08 spec: parentRefs: - name: my-gateway08 namespace: infra-gateway08 sectionName: http hostnames: - "test.tuan.name.vn" rules: # Quy tắc 1: Phải là POST VÀ đường dẫn bắt đầu bằng /v8/api - matches: - path: type: PathPrefix value: /v8/api method: POST backendRefs: - name: svc-web1 port: 80 # Quy tắc 2: Phải là GET VÀ đường dẫn bắt đầu bằng /v8/api - matches: - path: type: PathPrefix value: /v8/api method: GET backendRefs: - name: svc-web1a port: 80 EOF k apply -f 08.http-method-matching.yaml Kiểm tra curl --resolve test.tuan.name.vn:80:192.168.88.151 -v -XGET test.tuan.name.vn/v8/api Hostname: web1a-d5f6f44bf-nzl4d curl --resolve test.tuan.name.vn:80:192.168.88.151 -v -XPOST test.tuan.name.vn/v8/api Hostname: web1-84c9884bbb-7mmb8 k delete -f 08.http-method-matching.yaml k delete ns app-namespace08 k delete ns infra-gateway08 TESTED-9: Path route only k create ns app-namespace09 k -n app-namespace09 create deployment web1 --image=traefik/whoami --replicas=1 k -n app-namespace09 expose deployment web1 --name=svc-web1 --port=80 --target-port=80 --type=ClusterIP k -n app-namespace09 create deployment web1a --image=traefik/whoami --replicas=1 k -n app-namespace09 expose deployment web1a --name=svc-web1a --port=80 --target-port=80 --type=ClusterIP cat << EOF > 09.simple-gateway.yaml apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: my-gateway09 namespace: infra-gateway09 spec: gatewayClassName: nginx listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: All EOF # Mục đích tạo thêm gw để dễ test. Còn thực tế gateway sẽ dùng chung k create ns infra-gateway09 k apply -f 09.simple-gateway.yaml cat << EOF > 09.path-route-only.yaml apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: demo-route-paths namespace: app-namespace09 # Namespace chứa ứng dụng của bạn spec: parentRefs: - name: my-gateway09 #chú ý trùng tên gateway namespace: infra-gateway09 sectionName: http #chú ý trùng tên section hostnames: - "test.tuan.name.vn" rules: - matches: - path: type: PathPrefix value: /v1a backendRefs: - name: svc-web1a port: 80 - matches: - path: type: PathPrefix value: / backendRefs: - name: svc-web1 port: 80 EOF k apply -f 09.path-route-only.yaml Kiểm tra curl --resolve test.tuan.name.vn:80:192.168.88.150 -v test.tuan.name.vn curl --resolve test.tuan.name.vn:80:192.168.88.150 -v test.tuan.name.vn/v1a k delete -f 09.path-route-only.yaml k delete ns app-namespace09 k delete ns infra-gateway09 TESTED-10 Method Route only k create ns app-namespace10 k -n app-namespace10 create deployment web1 --image=traefik/whoami --replicas=1 k -n app-namespace10 expose deployment web1 --name=svc-web1 --port=80 --target-port=80 --type=ClusterIP k -n app-namespace10 create deployment web1a --image=traefik/whoami --replicas=1 k -n app-namespace10 expose deployment web1a --name=svc-web1a --port=80 --target-port=80 --type=ClusterIP cat << EOF > 10.simple-gateway.yaml apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: my-gateway10 namespace: infra-gateway10 spec: gatewayClassName: nginx listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: All EOF # Mục đích tạo thêm gw để dễ test. Còn thực tế gateway sẽ dùng chung k create ns infra-gateway10 k apply -f 10.simple-gateway.yaml cat << EOF > 10.method-route-only.yaml apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: method-matching namespace: app-namespace10 # Namespace chứa ứng dụng của bạn spec: parentRefs: - name: my-gateway10 #chú ý trùng tên gateway namespace: infra-gateway10 sectionName: http #chú ý trùng tên section hostnames: - "test.tuan.name.vn" rules: - matches: - method: POST backendRefs: - name: svc-web1 port: 80 - matches: - method: GET backendRefs: - name: svc-web1a port: 80 EOF k apply -f 10.method-route-only.yaml curl -XPOST --resolve test.tuan.name.vn:80:192.168.88.150 -v test.tuan.name.vn Hostname: web1-84c9884bbb-75lgc curl -XGET --resolve test.tuan.name.vn:80:192.168.88.150 -v test.tuan.name.vn/v1a Hostname: web1a-d5f6f44bf-dkl6x k delete -f 10.method-route-only.yaml k delete ns app-namespace10 k delete ns infra-gateway10 TESTED-11: Query Parameter Route https://gateway-api.sigs.k8s.io/guides/http-query-param-matching/ k create ns app-namespace11 k -n app-namespace11 create deployment web1 --image=traefik/whoami --replicas=1 k -n app-namespace11 expose deployment web1 --name=svc-web1 --port=80 --target-port=80 --type=ClusterIP k -n app-namespace11 create deployment web1a --image=traefik/whoami --replicas=1 k -n app-namespace11 expose deployment web1a --name=svc-web1a --port=80 --target-port=80 --type=ClusterIP k -n app-namespace11 create deployment web1b --image=traefik/whoami --replicas=1 k -n app-namespace11 expose deployment web1b --name=svc-web1b --port=80 --target-port=80 --type=ClusterIP cat << EOF > 11.simple-gateway.yaml apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: my-gateway11 namespace: infra-gateway11 spec: gatewayClassName: nginx listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: All EOF # Mục đích tạo thêm gw để dễ test. Còn thực tế gateway sẽ dùng chung k create ns infra-gateway11 k apply -f 11.simple-gateway.yaml cat << EOF > 11.httproute-query-params.yaml apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: query-routing namespace: app-namespace11 # Namespace chứa ứng dụng của bạn spec: parentRefs: - name: my-gateway11 #chú ý trùng tên gateway namespace: infra-gateway11 sectionName: http #chú ý trùng tên section hostnames: - "test.tuan.name.vn" rules: # Route debug requests to debug backend - matches: - queryParams: - name: debug type: Exact value: "true" backendRefs: - name: svc-web1a port: 80 # Route specific API versions - matches: - queryParams: - name: api_version type: Exact value: "2.0" backendRefs: - name: svc-web1b port: 80 # Default routing - backendRefs: - name: svc-web1 port: 80 EOF k apply -f 11.httproute-query-params.yaml Kiểm tra Nguyên lý grep -r 'api_version' /etc/nginx/conf.d/matches.json {"1_0":[{"redirectPath":"/_ngf-internal-rule0-route0","params":["debug=Exact=true"]},{"redirectPath":"/_ngf-internal-rule0-route1","params":["api_version=Exact=2.0"]},{"redirectPath":"/_ngf-internal-rule0-route2","any":true}]} curl --resolve test.tuan.name.vn:80:192.168.88.150 test.tuan.name.vn/v1a?debug=true curl --resolve test.tuan.name.vn:80:192.168.88.150 test.tuan.name.vn/v1a?debug=api_version=2.0 k delete -f 11.httproute-query-params.yaml k delete ns app-namespace11 k delete ns infra-gateway11 TESTED-12: URL rewrite k create ns app-namespace12 k -n app-namespace12 create deployment web1 --image=traefik/whoami --replicas=1 k -n app-namespace12 expose deployment web1 --name=svc-web1 --port=80 --target-port=80 --type=ClusterIP k -n app-namespace12 create deployment web1a --image=traefik/whoami --replicas=1 k -n app-namespace12 expose deployment web1a --name=svc-web1a --port=80 --target-port=80 --type=ClusterIP cat << EOF > 12.simple-gateway.yaml apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: my-gateway12 namespace: infra-gateway12 spec: gatewayClassName: nginx listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: All EOF # Mục đích tạo thêm gw để dễ test. Còn thực tế gateway sẽ dùng chung k create ns infra-gateway12 k apply -f 12.simple-gateway.yaml cat << EOF > 12.httproute-url-rewrite.yaml apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: url-rewrite namespace: app-namespace12 # Namespace chứa ứng dụng của bạn spec: parentRefs: - name: my-gateway12 #chú ý trùng tên gateway namespace: infra-gateway12 sectionName: http #chú ý trùng tên section hostnames: - "test.tuan.name.vn" rules: # Rewrite /v1/api/* to /api/* - matches: - path: type: PathPrefix value: "/v1/api" filters: - type: URLRewrite urlRewrite: path: type: ReplacePrefixMatch replacePrefixMatch: "/api" backendRefs: - name: svc-web1 port: 80 # Rewrite /old-path to /new-path - matches: - path: type: PathPrefix value: "/old-path" filters: - type: URLRewrite urlRewrite: path: type: ReplaceFullPath replaceFullPath: "/new-path" backendRefs: - name: svc-web1 port: 80 EOF k apply -f 12.httproute-url-rewrite.yaml k delete -f 12.httproute-url-rewrite.yaml k delete ns app-namespace12 k delete ns infra-gateway12 Kiểm tra curl --resolve test.tuan.name.vn:80:192.168.88.150 test.tuan.name.vn/v1/api/111 #Hostname: web1-888886b4d-tg4jv #GET /api/111 HTTP/1.1 <- đây là kết quả pod đang hiển thị curl --resolve test.tuan.name.vn:80:192.168.88.150 test.tuan.name.vn/old-path #Hostname: web1-888886b4d-tg4jv #GET /new-path HTTP/1.1 <- đây là kết quả pod đang hiển thị k delete -f 12.httproute-url-rewrite.yaml TESTED-13: Mirror request https://gateway-api.sigs.k8s.io/guides/http-request-mirroring/ https://docs.nginx.com/nginx-gateway-fabric/traffic-management/mirror/ k create ns app-namespace13 k -n app-namespace13 create deployment web1 --image=nginx:alpine --replicas=1 k -n app-namespace13 expose deployment web1 --name=svc-web1 --port=80 --target-port=80 --type=ClusterIP k -n app-namespace13 create deployment web1a --image=nginx:alpine --replicas=1 k -n app-namespace13 expose deployment web1a --name=svc-web1a --port=80 --target-port=80 --type=ClusterIP cat << EOF > 13.simple-gateway.yaml apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: my-gateway13 namespace: infra-gateway13 spec: gatewayClassName: nginx listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: All EOF # Mục đích tạo thêm gw để dễ test. Còn thực tế gateway sẽ dùng chung k create ns infra-gateway13 k apply -f 13.simple-gateway.yaml cat << EOF > 13.httproute-mirroring.yaml apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: traffic-mirroring namespace: app-namespace13 spec: parentRefs: - name: my-gateway13 #chú ý trùng tên gateway namespace: infra-gateway13 sectionName: http #chú ý trùng tên section hostnames: - "test.tuan.name.vn" rules: - matches: - path: type: PathPrefix value: "/" backendRefs: # Primary backend main pod - name: svc-web1 port: 80 filters: # Mirror to debug-pod - type: RequestMirror requestMirror: backendRef: name: svc-web1a port: 80 EOF k apply -f 13.httproute-mirroring.yaml Kiểm tra curl --resolve test.tuan.name.vn:80:192.168.88.150 test.tuan.name.vn/ curl --resolve test.tuan.name.vn:80:192.168.88.150 test.tuan.name.vn/ curl --resolve test.tuan.name.vn:80:192.168.88.150 test.tuan.name.vn/ k -n app-namespace1 logs web1a-xxxxxxxxxx #Ta thấy ở đây web1a cũng nhận được request tương tự 172.31.180.212 - - [01/Aug/2026:13:39:05 +0000] "GET / HTTP/1.1" 200 896 "-" "curl/8.5.0" "192.168.88.14" 172.31.180.212 - - [01/Aug/2026:13:39:10 +0000] "GET / HTTP/1.1" 200 896 "-" "curl/8.5.0" "192.168.88.14" k delete -f 13.httproute-mirroring.yaml TESTED-14 ReferenceGrant TESTED-14.1: HttpRoute->Services khác namespace https://oneuptime.com/blog/post/2026-02-09-gateway-api-referencegrant-cross-namespace/view Kịch bản là tạo HTTPRoute với 1 số /path đặc biệt: từ namespace AAA nhưng lại trỏ vào SVC của namespace BBB. Ta cần khai báo ReferenceGrant Tạo gateway k create ns infra-gateway141 openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=HELLO-WORLD-gateway/O=HELLO-WORLDe" kubectl -n infra-gateway141 create secret tls default-cert --key tls.key --cert tls.crt cat << EOF > 14.simple-gateway.yaml apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: my-gateway141 namespace: infra-gateway141 spec: gatewayClassName: nginx listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: All EOF # Mục đích tạo thêm gw để dễ test. Còn thực tế gateway sẽ dùng chung k apply -f 14.simple-gateway.yaml k create ns app-namespace14-aaa k create ns app-namespace14-bbb k -n app-namespace14-aaa create deployment web1 --image=traefik/whoami --replicas=1 k -n app-namespace14-aaa expose deployment web1 --name=svc-web1 --port=80 --target-port=80 --type=ClusterIP k -n app-namespace14-bbb create deployment web1b --image=traefik/whoami --replicas=1 k -n app-namespace14-bbb expose deployment web1b --name=svc-web1b --port=80 --target-port=80 --type=ClusterIP k -n app-namespace14-bbb create deployment web1c --image=traefik/whoami --replicas=1 k -n app-namespace14-bbb expose deployment web1c --name=svc-web1c --port=80 --target-port=80 --type=ClusterIP cat << EOF > 14.1.httproute-cross-namespace.yaml apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: cross-namespace-route namespace: app-namespace14-aaa spec: parentRefs: - name: my-gateway141 namespace: infra-gateway141 hostnames: - "test.tuan.name.vn" rules: - matches: - path: type: PathPrefix value: "/api-bbb" backendRefs: - name: svc-web1b namespace: app-namespace14-bbb port: 80 - matches: - path: type: PathPrefix value: "/api-aaa" backendRefs: - name: svc-web1 namespace: app-namespace14-aaa port: 80 --- # ReferenceGrant allowing cross-namespace reference apiVersion: gateway.networking.k8s.io/v1beta1 kind: ReferenceGrant metadata: name: allow-frontend-to-backend namespace: app-namespace14-bbb spec: from: - group: gateway.networking.k8s.io kind: HTTPRoute namespace: app-namespace14-aaa to: - group: "" kind: Service name: svc-web1b - group: "" kind: Service name: svc-web1c EOF k apply -f 14.1.httproute-cross-namespace.yaml curl --resolve test.tuan.name.vn:80:192.168.88.150 test.tuan.name.vn/api-bbb Hostname: web1b-78f579969d-fv7st curl --resolve test.tuan.name.vn:80:192.168.88.150 test.tuan.name.vn/api-aaa Hostname: web1-84c9884bbb-2dgk6 k -n app-namespace14-bbb delete referencegrants.gateway.networking.k8s.io allow-frontend-to-backend  Không gọi được nữa curl --resolve test.tuan.name.vn:80:192.168.88.150 test.tuan.name.vn/api-bbb <center><h1>500 Internal Server Error</h1></center> k delete ns app-namespace14-aaa k delete ns app-namespace14-bbb TESTED-14.2: Gateway->Secret khác namespace https://oneuptime.com/blog/post/2026-02-09-gateway-api-referencegrant-cross-namespace/view https://gateway-api.sigs.k8s.io/guides/tls/#cross-namespace-certificate-references # Certificate in certs namespace k create ns app-namespace142 k create ns infra-gateway142 k -n app-namespace142 create deployment web1 --image=traefik/whoami --replicas=1 k -n app-namespace142 expose deployment web1 --name=svc-web1 --port=80 --target-port=80 --type=ClusterIP openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=*.tuan.name.vn/O=Default Certificate" kubectl -n app-namespace142 create secret tls ssl-web1 --key tls.key --cert tls.crt cat << EOF > 142.cross-secret-referenceGrant.yaml # Grant access from infrastructure namespace apiVersion: gateway.networking.k8s.io/v1beta1 kind: ReferenceGrant metadata: name: allow-gateway-to-certs namespace: app-namespace142 spec: from: - group: gateway.networking.k8s.io kind: Gateway namespace: infra-gateway142 to: - group: "" kind: Secret name: ssl-web1 EOF k apply -f 142.cross-secret-referenceGrant.yaml openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=*.default.vn/O=Default Certificate" kubectl -n infra-gateway142 create secret tls ssl-web1 --key tls.key --cert tls.crt cat << EOF > 142.cross-secret.yaml apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: my-gateway142 namespace: infra-gateway142 annotations: cert-manager.io/cluster-issuer: letsencrypt-prod spec: gatewayClassName: nginx listeners: - name: http protocol: HTTP port: 80 # Đây là default allowedRoutes: namespaces: from: All - name: https protocol: HTTPS port: 443 # Đây là default tls: mode: Terminate certificateRefs: - name: default-cert allowedRoutes: namespaces: from: All - name: https-wildcard-domain1 protocol: HTTPS port: 443 hostname: "*.tuan.name.vn" tls: mode: Terminate certificateRefs: - name: ssl-web1 namespace: app-namespace142 allowedRoutes: namespaces: from: All --- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: tes-cross-secret namespace: app-namespace142 spec: parentRefs: - name: wildcard-gateway namespace: infra-gateway03 sectionName: https-wildcard-domain1 # Gắn đúng vào listener của domain1 hostnames: - "test.tuan.name.vn" # Chỉ định subdomain cụ thể rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: svc-web1 port: 80 EOF # Mục đích tạo thêm gw để dễ test. Còn thực tế gateway sẽ dùng chung k apply -f 142.cross-secret.yaml curl --resolve test.tuan.name.vn:443:192.168.88.150 -vk https://test.tuan.name.vn * subject: CN=*.tuan.name.vn; O=Default Certificate # Thực hiện xóa referenceGrant, Thì sẽ không gọi được nữa. k -n app-namespace142 delete referencegrants.gateway.networking.k8s.io allow-gateway-to-certs root@cicd:~/gatewayapi# curl --resolve test.tuan.name.vn:443:192.168.88.150 -vk https://test.tuan.name.vn * Added test.tuan.name.vn:443:192.168.88.150 to DNS cache * Hostname test.tuan.name.vn was found in DNS cache * Trying 192.168.88.150:443... * connect to 192.168.88.150 port 443 from 192.168.88.20 port 59690 failed: Connection refused * Failed to connect to test.tuan.name.vn port 443 after 1 ms: Couldn't connect to server * Closing connection curl: (7) Failed to connect to test.tuan.name.vn port 443 after 1 ms: Couldn't connect to server * subject: CN=*.domain2.com; O=Default Certificate OK-15: ListenerSet->Secret Tương tự giống Gateway đọc Secret Trường hợp này dành cho việc ListenerSet đặt ở 1 namespace khác với Secret. Nhưng không cần thiết làm như này cho lắm. Vì tiêu chuẩn google thiết kê theo mô hình sau: https://gateway-api.sigs.k8s.io/guides/user-guides/listener-set/ apiVersion: gateway.networking.k8s.io/v1beta1 kind: ReferenceGrant metadata: name: allow-teams-to-access-certs namespace: xxxx # <--- PHẢI đặt tại Namespace CHỨA tài nguyên đích (Secret) spec: from: - group: gateway.networking.k8s.io kind: ListenerSet namespace: yyyy # <--- PHẢI đặt tại Namespace CHỨA ListenerSet - group: gateway.networking.k8s.io kind: ListenerSet namespace: zzzz # <--- PHẢI đặt tại Namespace CHỨA ListenerSet to: - group: "" kind: Secret # Tài nguyên được phép truy cập chéo ReferenceGrant - Các ví dụ khác https://oneuptime.com/blog/post/2026-02-09-gateway-api-referencegrant-cross-namespace/view https://oneuptime.com/blog/post/2026-02-09-cross-namespace-referencegrant/view#multi-tenant-gateway-architecture TEST CHƯA OK-15: Increase timeout All of timeout Gateway Api https://oneuptime.com/blog/post/2026-02-09-httproute-timeout-policies/view#graceful-timeout-handling Đầu tiên ta tạo 1 web bằng python sleep 10 giây trễ mới trả lời client mesages. k create ns app-namespace15 cat << EOF > 15.deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: api-delay-python namespace: app-namespace15 labels: app: api-delay spec: spec: replicas: 1 selector: matchLabels: app: api-delay template: metadata: labels: app: api-delay spec: containers: - name: python-server image: python:3.10-alpine ports: - containerPort: 8080 command: ["python3", "-c"] args: - | import http.server import time class DelayedHandler(http.server.BaseHTTPRequestHandler): def do_GET(self): # Ép hệ thống dừng đúng 3 giây trước khi xử lý tiếp time.sleep(10) self.send_response(200) self.send_header("Content-type", "application/json") self.end_headers() self.wfile.write(b'{"status": "success", "message": "Delayed by 10 seconds"}') server = http.server.HTTPServer(('0.0.0.0', 8080), DelayedHandler) print("Server đang chạy tại port 8080...") server.serve_forever() EOF k apply -f 15.deployment.yaml k -n app-namespace15 expose deployment api-delay-python --name=svc-web1 --port=8080 --target-port=8080 --type=ClusterIP k -n app-namespace15 expose deployment api-delay-python --name=svc-web2 --port=8080 --target-port=8080 --type=LoadBalancer curl 192.168.88.151:8080 #{"status": "success", "message": "Delayed by 10 seconds"} k -n app-namespace15 delete svc svc-web2 cat << EOF > 15.simple-gateway.yaml apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: my-gateway15 namespace: infra-gateway15 spec: gatewayClassName: nginx listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: All EOF # Mục đích tạo thêm gw để dễ test. Còn thực tế gateway sẽ dùng chung k create ns infra-gateway15 k apply -f 15.simple-gateway.yaml cat << EOF > 15.httproute-timeouts.yaml apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: timeout-configuration namespace: app-namespace15 # Namespace chứa ứng dụng của bạn spec: parentRefs: - name: my-gateway15 #chú ý trùng tên gateway namespace: infra-gateway15 sectionName: http #chú ý trùng tên section hostnames: - "test.tuan.name.vn" rules: # Fast endpoints with short timeout - matches: - path: type: PathPrefix value: "/health" timeouts: request: 10s # Tổng thời gian request tối đa backendRequest: 2s # Thời gian chờ Backend phản hồi (tương tự proxy_read_timeout) backendRefs: - name: svc-web1 port: 8080 # Slow endpoints with longer timeout - matches: - path: type: PathPrefix value: "/reports" timeouts: request: 60s backendRequest: 55s backendRefs: - name: svc-web1 port: 8080 EOF k apply -f 15.httproute-timeouts.yaml Test curl -w '\n\n Thoi Gian Phan Hoi La: %{time_total} giay\n' -vk --resolve test.tuan.name.vn:80:192.168.88.152 http://test.tuan.name.vn/health Thoi Gian Phan Hoi La: 10.016382 giay curl -w '\n\n Thoi Gian Phan Hoi La: %{time_total} giay\n' -vk --resolve test.tuan.name.vn:80:192.168.88.152 http://test.tuan.name.vn/reports Thoi Gian Phan Hoi La: 10.016382 giay k delete ns app-namespace15 k delete ns infra-gateway15 TESTED-18: Redirect 301/302 k create ns app-namespace18 k -n app-namespace18 create deployment web1 --image=traefik/whoami --replicas=1 k -n app-namespace18 expose deployment web1 --name=svc-web1 --port=80 --target-port=80 --type=ClusterIP cat << EOF > 18.simple-gateway.yaml apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: my-gateway18 namespace: infra-gateway18 spec: gatewayClassName: nginx listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: All EOF # Mục đích tạo thêm gw để dễ test. Còn thực tế gateway sẽ dùng chung k create ns infra-gateway18 k apply -f 18.simple-gateway.yaml cat << EOF > 18.httproute-redirect.yaml apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: redirect-example namespace: app-namespace18 # Namespace chứa ứng dụng của bạn spec: parentRefs: - name: my-gateway18 #chú ý trùng tên gateway namespace: infra-gateway18 sectionName: http #chú ý trùng tên section hostnames: - "test.tuan.name.vn" #Ta có thể bỏ hostnames để redirect https cho toàn bộ GW rules: # Redirect to new domain - filters: - type: RequestRedirect requestRedirect: hostname: test.tuan.name.vn statusCode: 302 scheme: https EOF k apply -f 18.httproute-redirect.yaml Kết quả curl --resolve test.tuan.name.vn:80:192.168.88.150 -vk http://test.tuan.name.vn < HTTP/1.1 302 Moved Permanently < Location: https://test.tuan.name.vn/ TESTED-19: TLS Passthought https://oneuptime.com/blog/post/2026-02-09-gateway-api-tlsroute-passthrough-tls/view https://oneuptime.com/blog/post/2026-02-09-tlsroute-passthrough/view https://gateway-api.sigs.k8s.io/guides/tls-routing/ Cách hoạt động: Gateway hoàn toàn không giải mã dữ liệu. Nó chỉ đọc trường SNI (Server Name Indication) trong thông điệp TLS ClientHello của client để biết request muốn gửi tới domain nào, sau đó chuyển tiếp nguyên vẹn luồng traffic đã mã hóa xuống backend. • Yêu cầu: Việc giải mã TLS và quản lý chứng chỉ hoàn toàn do chính dịch vụ backend đảm nhận. Tầng Gateway điều hướng bằng tài nguyên TLSRoute thay vì HTTPRoute. Tiêu chí TLS Passthrough (Chuyển tiếp) TLS Termination (Chấm dứt) Bảo mật Bảo mật End-to-End tuyệt đối. Khóa bí mật nằm tại Pod ứng dụng, không bị lộ ra tầng Gateway chung. Tập trung khóa bí mật tại Gateway. Nếu Gateway bị tấn công, toàn bộ traffic của các ứng dụng có thể bị lộ. Quản lý Cert Phân tán: Các đội phát triển tự quản lý chứng chỉ trên từng ứng dụng của họ. Tập trung: Đội hạ tầng quản lý toàn bộ chứng chỉ tại Gateway. Hiệu năng Rất cao & Độ trễ thấp: Gateway không tốn tài nguyên CPU để giải mã/mã hóa lại dữ liệu. Tốn tài nguyên CPU của Gateway để xử lý quá trình bắt tay (handshake) và giải mã liên tục. Khả năng Định tuyến Hạn chế: Chỉ có thể định tuyến dựa trên tên miền (SNI). Không thể đọc Header, Path (/api), hay Cookie. Linh hoạt (Layer 7): Có thể định tuyến nâng cao dựa vào Cookie, HTTP Headers, Method, hoặc các đường dẫn cụ thể. An toàn (WAF/Ghi log) Kém: Gateway không thể kiểm tra mã độc hay áp dụng luật bảo mật WAF do dữ liệu bị mã hóa hoàn toàn. Tốt: Dễ dàng ghi log chi tiết URL, kiểm tra các lỗ hổng bảo mật trực tiếp tại tầng Gateway. Bước 1 . Chuẩn bị deployment, configmaps, sefcret k create ns app-namespace19 cat << EOF > 19.configmap.yaml apiVersion: v1 kind: ConfigMap metadata: name: nginx-config namespace: app-namespace19 data: nginx.conf: | server { listen 80; server_name localhost; # Tự động chuyển hướng từ HTTP sang HTTPS (Tùy chọn) return 301 https://$host$request_uri; } server { listen 443 ssl; server_name localhost; ssl_certificate /etc/nginx/ssl/tls.crt; ssl_certificate_key /etc/nginx/ssl/tls.key; location / { root /usr/share/nginx/html; index index.html index.htm; } } EOF k apply -f 19.configmap.yaml openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=*.tuan.name.vn/O=Default Certificate" kubectl -n app-namespace19 create secret tls nginx-ssl-secret --key tls.key --cert tls.crt cat << EOF > 19.deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment namespace: app-namespace19 labels: app: nginx spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 name: http - containerPort: 443 name: https volumeMounts: # Gắn file cấu hình NGINX vào container - name: config-volume mountPath: /etc/nginx/conf.d/default.conf subPath: nginx.conf # Gắn chứng chỉ SSL từ Secret vào container - name: ssl-volume mountPath: /etc/nginx/ssl readOnly: true volumes: - name: config-volume configMap: name: nginx-config - name: ssl-volume secret: secretName: nginx-ssl-secret EOF k apply -f 19.deployment.yaml kubectl -n app-namespace19 expose deployment nginx-deployment --name=nginx-service-http --port=80 --target-port=80 --type=ClusterIP kubectl -n app-namespace19 expose deployment nginx-deployment --name=nginx-service-https --port=443 --target-port=443 --type=ClusterIP cat << EOF > 19.gateway.yaml apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: nginx-gateway namespace: infra-gateway19 spec: gatewayClassName: nginx listeners: - name: tls-passthrough-listener protocol: TLS port: 443 tls: mode: Passthrough allowedRoutes: kinds: - kind: TLSRoute namespaces: from: All --- apiVersion: gateway.networking.k8s.io/v1 kind: TLSRoute metadata: name: nginx-tls-route namespace: app-namespace19 spec: parentRefs: - name: nginx-gateway namespace: infra-gateway19 sectionName: tls-passthrough-listener hostnames: - "test.tuan.name.vn" rules: - backendRefs: - name: nginx-service-https port: 443 EOF k create ns infra-gateway19 k apply -f 19.gateway.yaml curl -vk --resolve test.tuan.name.vn:443:192.168.88.150 https://test.tuan.name.vn * subject: CN=*.tuan.name.vn; O=Default Certificate TESTED-20: TCP/UDP Route https://oneuptime.com/blog/post/2026-02-09-gateway-api-tcproute-udproute-layer4/view https://gateway-api.sigs.k8s.io/guides/tcp/ k create ns app-namespace20 k -n app-namespace20 create deployment web1 --image=traefik/whoami --replicas=1 k -n app-namespace20 expose deployment web1 --name=svc-web1 --port=80 --target-port=80 --type=ClusterIP cat << EOF > 20.gateway.yaml apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: shared-tcp-gateway namespace: infra-gateway20 spec: gatewayClassName: nginx listeners: - name: tcp-web-listener protocol: TCP port: 8080 allowedRoutes: kinds: - kind: TCPRoute namespaces: from: All --- apiVersion: gateway.networking.k8s.io/v1alpha2 kind: TCPRoute metadata: name: web1-tcp-route namespace: app-namespace20 spec: parentRefs: - name: shared-tcp-gateway namespace: infra-gateway20 sectionName: tcp-web-listener rules: - backendRefs: - name: svc-web1 port: 80 EOF k apply -f 20.gateway.yaml k create ns infra-gateway20 curl 192.168.88.150:8080 Hostname: web1-84c9884bbb-2q882 TESTED-21: BackendTLSPolicy Việc dùng BackendTLSPolicy là cho trường hợp backend đằng sau có SSL https://gateway-api.sigs.k8s.io/api-types/backendtlspolicy/#:~:text=are%20not%20allowed.-,WellKnownCACertificates,of%20choice%20for%20more%20information. https://gateway-api.sigs.k8s.io/guides/tls/#using-system-certificates k create ns app-namespace21 cat << EOF > 21.configmap.yaml apiVersion: v1 kind: ConfigMap metadata: name: nginx-config namespace: app-namespace21 data: nginx.conf: | server { listen 80; server_name localhost; # Tự động chuyển hướng từ HTTP sang HTTPS (Tùy chọn) return 301 https://$host$request_uri; } server { listen 443 ssl; server_name test.tuan.name.vn; ssl_certificate /etc/nginx/ssl/tls.crt; ssl_certificate_key /etc/nginx/ssl/tls.key; location / { root /usr/share/nginx/html; index index.html index.htm; } } EOF k apply -f 21.configmap.yaml openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=*.tuan.name.vn/O=Default Certificate" kubectl -n app-namespace21 create secret tls nginx-ssl-secret --key tls.key --cert tls.crt cat << EOF > 21.deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment namespace: app-namespace21 labels: app: nginx spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 name: http - containerPort: 443 name: https volumeMounts: # Gắn file cấu hình NGINX vào container - name: config-volume mountPath: /etc/nginx/conf.d/default.conf subPath: nginx.conf # Gắn chứng chỉ SSL từ Secret vào container - name: ssl-volume mountPath: /etc/nginx/ssl readOnly: true volumes: - name: config-volume configMap: name: nginx-config - name: ssl-volume secret: secretName: nginx-ssl-secret EOF k apply -f 21.deployment.yaml kubectl -n app-namespace21 expose deployment nginx-deployment --name=nginx-service-http --port=80 --target-port=80 --type=ClusterIP kubectl -n app-namespace21 expose deployment nginx-deployment --name=nginx-service-https --port=443 --target-port=443 --type=ClusterIP apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: external-gateway namespace: infra-gateway21 spec: gatewayClassName: nginx listeners: - name: http-listener protocol: HTTP port: 80 allowedRoutes: namespaces: from: All --- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: nginx-http-route namespace: app-namespace21 spec: parentRefs: - name: external-gateway namespace: infra-gateway21 sectionName: http-listener hostnames: - "test.tuan.name.vn" rules: - backendRefs: - name: nginx-service-https port: 443 Lựa chọn 1 trong 2 cách: CÁCH 1: # Chú ý cert của deployment nên là cert xịn, nếu cert đểu thì gọi lỗi 502 bad gateway apiVersion: gateway.networking.k8s.io/v1 kind: BackendTLSPolicy metadata: name: gateway-to-backend-tls namespace: app-namespace21 spec: targetRefs: - group: "" kind: Service name: nginx-service-https validation: hostname: "test.tuan.name.vn" wellKnownCACertificates: System CÁCH 2: Nếu cert là đểu, thì dùng cách này # CHÚ Ý: BACKEND TLS không được tạo từ Secret, Mà phải được tạo từ configmap kubectl get secret nginx-ssl-secret -n app-namespace21 -o jsonpath='{.data.tls\.crt}' | base64 -d > ca.crt kubectl create configmap nginx-ca-cert --from-file=ca.crt=ca.crt -n app-namespace21 --- apiVersion: gateway.networking.k8s.io/v1 kind: BackendTLSPolicy metadata: name: nginx-backend-tls-policy namespace: app-namespace21 spec: targetRefs: - group: "" kind: Service name: nginx-service-https validation: caCertificateRefs: - group: "" kind: ConfigMap name: nginx-ca-cert hostname: test.tuan.name.vn 22: CORS https://gateway-api.sigs.k8s.io/guides/http-cors/ https://docs.nginx.com/nginx-gateway-fabric/traffic-security/cors/ Cần nghiên cứu thêm (NOT)Ví dụ 26-A: mTLS Frontend https://gateway-api.sigs.k8s.io/guides/tls/#basic-client-validation https://docs.nginx.com/nginx-gateway-fabric/traffic-security/client-validation/ (NOT)Ví dụ 26-B: mTLS Backend https://docs.nginx.com/nginx-gateway-fabric/traffic-security/secure-backend/ (NOT)Ví dụ 27: HTTP2.0 Support Backend https://gateway-api.sigs.k8s.io/guides/backend-protocol/ Ví dụ 31: basic authen https://docs.nginx.com/nginx-gateway-fabric/traffic-security/basic-authentication/ https://docs.nginx.com/nginx-gateway-fabric/traffic-security/integrate-cert-manager/ Nginx GW Fabric Advance SnippetsPolicies https://docs.nginx.com/nginx-gateway-fabric/traffic-management/snippets/ ClientSettingsPolicy https://docs.nginx.com/nginx-gateway-fabric/traffic-management/client-settings/ • client_max_body_size • client_body_timeout • keepalive_requests • keepalive_time • keepalive_timeout • keepalive_min_timeout UpstreamSettingsPolicy https://docs.nginx.com/nginx-gateway-fabric/traffic-management/upstream-settings/ Session-persistence https://docs.nginx.com/nginx-gateway-fabric/traffic-management/session-persistence/ Tương đương ip-hash để giữ phiên client connect đến backend Authenticationfilters Nginxgateways nginxproxies observabilitypolicies proxysettingspolicies ratelimitpolicies snippetsfilters upstreamsettingspolicies Kiến trúc GWAPI Security cho GatewayAPI 1. Giới hạn NS cho GW và httpRoute Không Nên nên

Nginx SNI

Nginx SNI SNI chia làm 2 loại là SNI server và SNI Client 1. Nginx reject non-SNI – server side # Khối server mặc định để c...