Gateway api 安装使用

Gateway api 安装使用

gateway的实现有很多方式

  • nginx
  • traefik
  • kong
  • istio

nginx只是其中的一种实现。

一、Gateway的nginx实现

1.安装网关api资源

nginx gateway的参考地址:

https://docs.nginx.com/nginx-gateway-fabric/install/secure-certificates/

gatewayapi官方的参考地址:

https://gateway-api.sigs.k8s.io/guides/#installing-a-gateway-controller

标准的yaml支持的资源有(来自官网链接的内容):

包括 GatewayClass、Gateway、HTTPRoute 和 ReferenceGrant。

实验频道:

实验性发布通道包含标准发布通道的所有内容,外加一些实验性资源和字段,包括 TCPRoute、TLSRoute 和 UDPRoute。

kubectl apply --server-side -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.0/standard-install.yaml


# nginx gateway文档中的提示的安装方式
cat kustomization.yaml 
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- https://github.com/kubernetes-sigs/gateway-api/config/crd?timeout=120&ref=v1.4.0

kubectl kustomize ./ > gateway-api-standard-v1.4.0.yaml

root@master1-22-137:~/nginx-gateway-fabric# kubectl create -f gateway-api-standard-v1.4.0.yaml 
customresourcedefinition.apiextensions.k8s.io/backendtlspolicies.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/gatewayclasses.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/gateways.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/grpcroutes.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/httproutes.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/referencegrants.gateway.networking.k8s.io created

2.安装nginx gateway

这个是控制平面的内容.

控制平面和数据平面默认使用自签名tls默认期限3年。可以使用下面几种方案替换。

kubectl -n nginx-gateway get secret
NAME         TYPE                DATA   AGE
agent-tls    kubernetes.io/tls   3      2d1h
server-tls   kubernetes.io/tls   3      2d1h
  • 自签名长时间证书替换。
  • 官网使用certmanager自动更新。
  • 重新运行生成的pod。
# nginx网关资源定义
wget https://raw.githubusercontent.com/nginx/nginx-gateway-fabric/v2.2.1/deploy/crds.yaml

kubectl apply --server-side -f crds.yaml

# nginx 控制平面网关,这里可以控制nginx控制平面的副本数
kubectl apply -f https://raw.githubusercontent.com/nginx/nginx-gateway-fabric/v2.2.1/deploy/default/deploy.yaml

# 安装结果
kubectl -n nginx-gateway get pod
NAME                             READY   STATUS    RESTARTS   AGE
nginx-gateway-7849b5d777-l6wcl   1/1     Running   0          2m7s

kubectl get gatewayclass
NAME    CONTROLLER                                   ACCEPTED   AGE
nginx   gateway.nginx.org/nginx-gateway-controller   True       2m23s

kubectl -n nginx-gateway get svc
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
nginx-gateway   ClusterIP   10.104.147.32   <none>        443/TCP   3m5s

3.数据平面网关

3.1 创建应用

kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: coffee
spec:
  replicas: 2
  selector:
    matchLabels:
      app: coffee
  template:
    metadata:
      labels:
        app: coffee
    spec:
      containers:
      - name: coffee
        image: nginx:1.22.1
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: coffee
spec:
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
    name: http
  selector:
    app: coffee
EOF

3.2 创建网关

一个 GatewayClass 可以有多个 Gateway:每个 Gateway 都会创建一个单独的 Service 和 NGINX 部署。

kubectl describe gateway cafe检查配置。

# 创建gateway
kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: cafe
spec:
  gatewayClassName: nginx  # 指定gatewayclass实现
  listeners:
  - name: http
    port: 80
    protocol: HTTP
EOF

在创建了cafe的网关之后会控制平面会自动创建nginx的svc和nginx的pod用来接收控制平面下发的配置。

Service的类型和流量分发的的pod数量由kubectl -n nginx-gateway edit nginxproxies nginx-gateway-proxy-config控制,修改这个配置可以决定用户端的流量用什么方式进入到集群中并做分发。

root@master1-22-137:~# kubectl -n nginx-gateway get nginxproxies nginx-gateway-proxy-config -o yaml
apiVersion: gateway.nginx.org/v1alpha2
kind: NginxProxy
metadata:
  annotations:
  creationTimestamp: "2025-11-24T07:16:14Z"
  generation: 2
  labels:
    app.kubernetes.io/instance: nginx-gateway
    app.kubernetes.io/name: nginx-gateway
    app.kubernetes.io/version: 2.2.1
  name: nginx-gateway-proxy-config
  namespace: nginx-gateway
  resourceVersion: "602022"
  uid: 09d37a6a-b913-4c92-96f8-ad281a7cbe35
spec:
  ipFamily: dual
  kubernetes:
    deployment:
      container:
        image:
          pullPolicy: IfNotPresent
          repository: ghcr.chenby.cn/nginx/nginx-gateway-fabric/nginx
          tag: 2.2.1
        resources:
          requests:
            cpu: 0.5
            memory: 500Mi
          limits:
            cpu: 2
            memory: 4096Mi
      replicas: 2 # 控制副本数量
    service:
      externalTrafficPolicy: Local
      type: NodePort # 控制service的类型

实际影响的效果NodePort,和两个副本的cafe-nginx .

root@master1-22-137:~# kubectl  get svc,pod
NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
service/cafe-nginx   NodePort    10.109.164.110   <none>        80:32368/TCP   23h

NAME                              READY   STATUS    RESTARTS   AGE
pod/cafe-nginx-6896f7c8df-27gbn   1/1     Running   0          123m
pod/cafe-nginx-6896f7c8df-l2dkp   1/1     Running   0          123m

3.3 创建路由

为coffee应用创建一个路由,

kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: coffee
spec:
  parentRefs:
  - name: cafe
  hostnames:
  - "cafe.example.com"
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /
    backendRefs:
    - name: coffee
      port: 80
EOF

创建路由之后,控制平面会根据控制平面下发的配置到nignx的pod中,后端服务器的服务发现使用的是app中的service,包括发现实际app pod的IP和端口。

root@master1-22-137:~# kubectl  get pod -owide | grep coffee
coffee-998dd47cd-cw8n8  1/1  Running  0  5h9m  10.244.90.6  node3-22-140  <none>  <none>
coffee-998dd47cd-p9b9h  1/1  Running  0  5h9m  10.244.38.4  node2-22-139  <none>  <none>

---
kubectl  exec -it cafe-nginx-6896f7c8df-27gbn -c nginx -- cat /etc/nginx/conf.d/http.conf

server {
    listen 80;
    listen [::]:80;

    server_name cafe.example.com;

.......

upstream default_coffee_80 {
    random two least_conn;
    zone default_coffee_80 512k;
    
    server 10.244.90.6:80; # app的pod IP
    server 10.244.38.4:80; # app的pod IP
}

访问测试

# service/cafe-nginx   NodePort    10.109.164.110

# 进入到两个pod执行
root@coffee-998dd47cd-p9b9h:/# echo 'Hello coffee!!!' > /usr/share/nginx/html/index.html
# 修改过的nginx主页信息
root@master1-22-137:~# curl -H "Host: cafe.example.com" 10.109.164.110
Hello coffee!!!
root@master1-22-137:~# curl -H "Host: cafe.example.com" 10.109.164.110
Hello coffee!!!

4.https终止

创建secret

openssl req -x509 -nodes -days 365 -newkey rsa:2048   -keyout example.com.key   -out example.com.crt   -subj "/C=CN/ST=Guangxi/L=Nanning/O=GXL/OU=IT/CN=*.example.com"

ls certs/
example.com.crt  example.com.key

kubectl -n certs create secret tls tls-example-com --cert=certs/example.com.crt --key=certs/example.com.key

对于HTTPS来说,我们需要一个证书和密钥,这些都存储在一个secret里。这个secert会存在于另一个命名空间,因此我们需要一个ReferenceGrant才能访问它。

kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
  name: access-to-cafe-secret
  namespace: certs
spec:
  to:
  - group: ""
    kind: Secret
    name: tls-example-com # if you omit this name, then Gateways in default namespace can access all Secrets in the certificate namespace
  from:
  - group: gateway.networking.k8s.io
    kind: Gateway
    namespace: default
EOF

创建tls终止。

kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: cafe
spec:
  gatewayClassName: nginx
  listeners:
  - name: http
    port: 80
    protocol: HTTP
  - name: https
    port: 443
    protocol: HTTPS
    tls:
      mode: Terminate
      certificateRefs:
      - kind: Secret
        name: tls-example-com
        namespace: certs
EOF

创建httpsroute资源

# 重定向和httproute
kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: cafe-tls-redirect
spec:
  parentRefs:
  - name: cafe
    sectionName: http # 这个配置gateway的哪个port受影响
  hostnames:
  - "cafe.example.com"
  rules:
  - filters:
    - type: RequestRedirect
      requestRedirect:
        scheme: https
        port: 443
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: coffee
spec:
  parentRefs:
  - name: cafe
    sectionName: https
  hostnames:
  - "cafe.example.com"
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /
    backendRefs:
    - name: coffee
      port: 80
EOF

验证结果

# 访问80是302跳转
root@master1-22-137:~# curl -H "Host: cafe.example.com" -k http://10.109.164.110
<html>
<head><title>302 Found</title></head>
<body>
<center><h1>302 Found</h1></center>
<hr><center>nginx</center>
</body>
</html>

# https访问
root@master1-22-137:~# curl -k --resolve cafe.example.com:443:10.109.164.110 https://cafe.example.com
Hello coffee!!!

压力测试

nginx单pod配置在2C4G单副本。

root@master1-22-137:~# ab -n 10000 -c 1000  https://hello.example.com/
This is ApacheBench, Version 2.3 <$Revision: 1879490 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking hello.example.com (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests


Server Software:        nginx
Server Hostname:        hello.example.com
Server Port:            443
SSL/TLS Protocol:       TLSv1.2,ECDHE-RSA-AES256-GCM-SHA384,2048,256
Server Temp Key:        X25519 253 bits
TLS Server Name:        hello.example.com

Document Path:          /
Document Length:        16 bytes

Concurrency Level:      1000
Time taken for tests:   19.269 seconds
Complete requests:      10000
Failed requests:        5865
   (Connect: 0, Receive: 0, Length: 5865, Exceptions: 0)
Total transferred:      5924865 bytes
HTML transferred:       3673135 bytes
Requests per second:    518.97 [#/sec] (mean)
Time per request:       1926.906 [ms] (mean)
Time per request:       1.927 [ms] (mean, across all concurrent requests)
Transfer rate:          300.27 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       15 1526 929.3   1267    6962
Processing:    14  270 277.4    190    1536
Waiting:        4  199 255.8    108    1473
Total:        302 1796 1065.1   1461    7177

Percentage of the requests served within a certain time (ms)
  50%   1461
  66%   1986
  75%   2364
  80%   2585
  90%   3240
  95%   3963
  98%   4822
  99%   5792
 100%   7177 (longest request)

二、Gatewayclass的traefik实现

1.安装traefik

traefik-37.4.0.tgz 使用的这个版本安装的。

与nginx不同的是,traefik的配置文件没有向nginx那样写在配置文件中,而是直接读取k8s定义的httproute资源,流量负载的方式是直接从traefik实现的pod转发到对应的后端pod上面。

每个版本之间的配置文件都不同

helm repo add traefik https://traefik.github.io/charts
 ~]# helm search repo traefik/traefik -l
 ~]# helm pull traefik/traefik --version 31.0.0

# 编辑values.yaml

# 镜像配置

ingressRoute:
  dashboard:
    enabled: true
    
  matchRule: Host(`traefik.example.com`) && PathPrefix(`/dashboard`) || PathPrefix(`/api`)

# 设置时间
env:
        - name: TZ
          value: Asia/Shanghai

# 根据实际需求设置,考虑导日志采集的问题。
logs:
  general:
    format: json
    level: INFO
    #
    #filePath: "/var/log/traefik/traefik.log"
    # noColor: true
  access:
    enabled: true
    format: json
    #filePath: "/var/log/traefik/access.log
    
persistence:
  enabled: true
  name: data
  accessMode: ReadWriteMany
  size: 128Mi
  storageClass: "nfs"
  path: /data
  annotations: {}
  
replicas: 2

# 启用gatewayclass
providers:
  kubernetesGateway:
    # -- Enable Traefik Gateway provider for Gateway API
    enabled: true

# dashboard的端口默认是8080,可以不动
ports:
  traefik:
    port: 8080
    expose:
      default: true

# 配置资源限制
resources:
  requests:
    cpu: 1
    memory: 2Gi
  limits:
    cpu: 2
    memory: 4Gi

# 亲和性
affinity:

# 配置自动发现的目录

# additionalArguments: [] 新版本

globalArguments:
.....
- "--providers.file.directory=/etc/traefik/dynamic"
- "--providers.file.watch=true"
# 客户端的真实IP
- "--entrypoints.web.forwardedheaders.insecure"
- "--entrypoints.websecure.forwardedheaders.insecure"

# router基于文件的配置发现
providers.file.enabled: true
# 必须提供默认配置
    content:
      "# this is dynamic configuration files."

# 安装在了traefik的名称空间
helm -n traefik install traefik ./traefik

root@master1-22-137:~# kubectl get gatewayclass
traefik   traefik.io/gateway-controller                True       28h

~/traefik# kubectl -n traefik get svc
NAME      TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)                                     AGE
traefik   LoadBalancer   10.100.54.65   <pending>     8080:30111/TCP,80:32466/TCP,443:31170/TCP   2d5h

参考配置:

# Enable experimental features
experimental:
  kubernetesGateway:  # 开启 gateway api 支持
    enabled: true

providers:
  kubernetesCRD:
    enabled: true
    allowCrossNamespace: true  # 是否允许跨命名空间
    allowExternalNameServices: true  # 是否允许使用 ExternalName 的服务

  kubernetesIngress:
    enabled: true
    allowExternalNameServices: true

监听端口

请注意,Gateway监听器端口必须与 Traefik 部署中配置的EntryPoint 端口匹配。如果不匹配,系统ERROR会记录一条消息,并相应地更新资源状态。

这里使用的入口就是traefik在初始化的时候指定的entrypoint.

root@master1-22-137:~/traefik# kubectl -n traefik get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
traefik LoadBalancer 10.100.54.65 8080:30111/TCP,80:32466/TCP,443:31170/TCP 2d1h

把gateway部署在其它名称空间也可以使用这个entrypoint.

创建一个网关

# 手动创建一个自签名证书的secret
root@master1-22-137:~# kubectl  -n app get secret
NAME              TYPE                DATA   AGE
tls-example-com   kubernetes.io/tls   2      18s

gateway配置yaml


~/traefik# cat traefik-gateway.yaml 
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: traefik
  namespace: app
spec:
  gatewayClassName: traefik

  # Same只允许当前名称空间的路由进来.
  # 这个也是默认的策略,支持三种策略All\Same\Selector.
  # All全部名称空间.
  # Selector 指定名称空间.
  listeners:
    - name: http
      protocol: HTTP
      port: 8000
      allowedRoutes:
        namespaces:
          from: Same 

    - name: https
      protocol: HTTPS
      port: 8443
      tls:
        mode: Terminate
        certificateRefs:
          - name: tls-example-com 

      allowedRoutes:
        namespaces:
          from: Same

    - name: tcp
      protocol: TCP
      port: 3000
      allowedRoutes:
        namespaces:
          from: Same

    - name: tls
      protocol: TLS
      port: 3443
      tls:
        mode: Terminate
        certificateRefs:
          - name: tls-example-com 

      allowedRoutes:
        namespaces:
          from: Same

2.创建测试应用

app名称空间创建测试的应用


kubectl  -n app create deploy hello --image=harbor.kailinesb.com/ops/nginx:1.22.1 --replicas=1
kubectl  -n app expose deploy hello --port=80 --target-port=80

# 把nginx的主页修改为“hello nginx in NS app!”

创建httproute

~/traefik# cat who-ami.yaml 
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: hello 
  namespace: app 
spec:
  parentRefs:
    - name: traefik
      sectionName: http
      kind: Gateway
  hostnames:
    - hello.example.com 
  rules:
     - matches:
        - path:
            type: PathPrefix
            value: /
       backendRefs:
        - name: hello
          namespace: app 
          port: 80

这种情况是在相同的名称空间下。

~/traefik# curl -H "Host: hello.example.com" 10.100.54.65
hello nginx in NS app!

3.跨namespace调用gateway

在部署的app名称空间下修改gateway的调用策略。

kubectl -n app edit gateway traefik
......
spec:
  gatewayClassName: traefik
  listeners:
  - allowedRoutes:
      namespaces:
        from: All  # 把相关资源的字段改为All,表示允许从哪里调用gateway资源
    name: http
    port: 8000
    protocol: HTTP
......

在default名称空间创建httproute资源。这里使用nginx gateway中的应用演示资源

root@master1-22-137:~/traefik# kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
coffee       ClusterIP   10.109.230.224   <none>        80/TCP                       17d


---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: hello-default
  namespace: default
spec:
  parentRefs:
    - name: traefik # 指定gateway实现
      sectionName: http # 指定使用哪个端口
      kind: Gateway
      namespace: app  # 这里一定要指定名称空间,gateway资源级别是在名称空间里面的
  hostnames:
    - hello-default.example.com 
  rules:
     - matches:
        - path:
            type: PathPrefix
            value: /
       backendRefs:
        - name: coffee
          port: 80
          
# 访问测试
~/traefik# curl -H "Host: hello-default.example.com" 10.100.54.65
Hello coffee!!!

使用tls的方式访问。

~# kubectl  -n traefik get secret
tls-example-com                 kubernetes.io/tls    2      9s

kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: hello-default-tls
spec:
  parentRefs:
  - name: traefik
    sectionName: https
    namespace: app
  hostnames:
  - "hello-default.example.com"
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /
    backendRefs:
    - name: coffee
      port: 80
EOF

访问测试

~# curl -H "Host: hello-default.example.com"  -k https://10.100.54.65/
Hello coffee!!!

image-20251215112206440

4.多证书绑定

~/certs/business# kubectl  -n app get secret
NAME               TYPE                DATA   AGE
tls-business-com   kubernetes.io/tls   2      6s
tls-example-com    kubernetes.io/tls   2      3d18h

# 编辑网关配置
spec:
  gatewayClassName: traefik
  listeners:
  - allowedRoutes:
      namespaces:
        from: All
    name: http
    port: 8000
    protocol: HTTP
  - allowedRoutes:
      namespaces:
        from: All
    hostname: '*.example.com' # 给监听器绑定证书
    name: https               # 名字不能重复
    port: 8443
    protocol: HTTPS
    tls:
      certificateRefs:
      - group: ""
        kind: Secret
        name: tls-example-com
      mode: Terminate
  - allowedRoutes:
      namespaces:
        from: All
    hostname: '*.business.com'
    name: https-1
    port: 8443
    protocol: HTTPS
    tls:
      certificateRefs:
      - group: ""
        kind: Secret
        name: tls-business-com
      mode: Terminate
  - allowedRoutes:
      namespaces:
        from: All
    name: tcp
    port: 3000
    protocol: TCP
  - allowedRoutes:
      namespaces:
        from: Same
    name: tls
    port: 3443
    protocol: TLS
    tls:
      certificateRefs:
      - group: ""
        kind: Secret
        name: tls-example-com
      mode: Terminate

在default名称空间创建测试应用

kubectl create deploy business --image=harbor.kailinesb.com/ops/nginx:1.22.1 --replicas=1
echo 'hello business!!!' > /usr/share/nginx/html/index.html

kubectl expose deploy business --port=80 --target-port=80

~# kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
business     ClusterIP   10.99.169.170    <none>        80/TCP                       3s
coffee       ClusterIP   10.109.230.224   <none>        80/TCP                       24d

~# curl 10.99.169.170
hello business!!!

~# curl 10.109.230.224
Hello coffee!!!

创建httproute

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: hello-tls
spec:
  hostnames:
  - hello.example.com
  parentRefs:
  - group: gateway.networking.k8s.io
    kind: Gateway
    name: traefik
    namespace: app
    sectionName: https
  rules:
  - backendRefs:
    - group: ""
      kind: Service
      name: coffee 
      port: 80
      weight: 1
    matches:
    - path:
        type: PathPrefix
        value: /
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: business-tls
spec:
  hostnames:
  - hello.business.com
  parentRefs:
  - group: gateway.networking.k8s.io
    kind: Gateway
    name: traefik
    namespace: app
    sectionName: https-1
  rules:
  - backendRefs:
    - group: ""
      kind: Service
      name: business
      port: 80
      weight: 1
    matches:
    - path:
        type: PathPrefix
        value: /

压力测试

traefik单pod配置在2C4G单副本。

root@master1-22-137:~# ab -n 10000 -c 1000  https://hello.example.com/
This is ApacheBench, Version 2.3 <$Revision: 1879490 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking hello.example.com (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests


Server Software:        nginx/1.22.1
Server Hostname:        hello.example.com
Server Port:            443
SSL/TLS Protocol:       TLSv1.2,ECDHE-RSA-AES128-GCM-SHA256,2048,128
Server Temp Key:        X25519 253 bits
TLS Server Name:        hello.example.com

Document Path:          /
Document Length:        16 bytes

Concurrency Level:      1000
Time taken for tests:   49.374 seconds
Complete requests:      10000
Failed requests:        0
Total transferred:      2280000 bytes
HTML transferred:       160000 bytes
Requests per second:    202.54 [#/sec] (mean)
Time per request:       4937.351 [ms] (mean)
Time per request:       4.937 [ms] (mean, across all concurrent requests)
Transfer rate:          45.10 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       16 2270 1145.9   2092    6483
Processing:    62 2385 1016.8   2410    7130
Waiting:        3 2329 1020.4   2339    7130
Total:        334 4655 1502.8   4480    9965

Percentage of the requests served within a certain time (ms)
  50%   4480
  66%   5110
  75%   5575
  80%   5930
  90%   6728
  95%   7322
  98%   8189
  99%   8548
 100%   9965 (longest request)

三、使用Envoy作为gatewayclass实现

1.安装envoy

https://github.com/envoyproxy/gateway/releases/tag/v1.6.1找到项目的版本tag

kubectl create -f \
https://github.com/envoyproxy/gateway/releases/download/v1.6.1/install.yaml

~/envoy-gateway# cat quickstart.yaml 
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: envoy
spec:
  controllerName: gateway.envoyproxy.io/gatewayclass-controller
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: eg
spec:
  gatewayClassName: envoy
  infrastructure:
  parametersRef:
    group: gateway.envoyproxy.io
    kind: EnvoyProxy
    name: custom-proxy-config  -- 使用自定义的配置 --
  listeners:
    - name: http
      protocol: HTTP
      port: 80
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: backend
---
apiVersion: v1
kind: Service
metadata:
  name: backend
  labels:
    app: backend
    service: backend
spec:
  ports:
    - name: http
      port: 80
      targetPort: 80
  selector:
    app: backend
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend
spec:
  replicas: 1
  selector:
    matchLabels:
      app: backend
      version: v1
  template:
    metadata:
      labels:
        app: backend
        version: v1
    spec:
      serviceAccountName: backend
      containers:
        - image: harbor.kailinesb.com/ops/nginx:1.22.1 
          imagePullPolicy: IfNotPresent
          name: backend
          ports:
            - containerPort: 80
          env:
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: backend
spec:
  parentRefs:
    - name: eg
  hostnames:
    - "www.example.com"
  rules:
    - backendRefs:
        - group: ""
          kind: Service
          name: backend
          port: 80
          weight: 1
      matches:
        - path:
            type: PathPrefix
            value: /
            
            
# 自定义的配置
## 这个配置和gateway需要在同一个名称空间
~/envoy-gateway# kubectl  get envoyproxy custom-proxy-config -o yaml
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
  name: custom-proxy-config
  namespace: default
spec:
  logging:
    level:
      default: warn
  provider:
    kubernetes:
      envoyDeployment:
        container:
          image: docker.1ms.run/envoyproxy/envoy:distroless-v1.36.3
          resources:
            limits:
              cpu: 2
              memory: 4Gi
            requests:
              cpu: 500m
              memory: 500Mi
        replicas: 1
      envoyService:
        externalTrafficPolicy: Local
        type: NodePort
    type: Kubernetes

2.管理面板

kubectl port-forward -n envoy-gateway-system deployment/envoy-gateway --address 0.0.0.0 19000:19000

3.扩展API

EnvoyGateway配置文件所有的字段参考:

https://gateway.envoyproxy.io/v0.6/api/extension_types/

admin管理界面

~# kubectl -n envoy-gateway-system get cm envoy-gateway-config -o yaml
apiVersion: v1
data:
  envoy-gateway.yaml: |
    apiVersion: gateway.envoyproxy.io/v1alpha1
    kind: EnvoyGateway
    extensionApis: {}
    gateway:
      controllerName: gateway.envoyproxy.io/gatewayclass-controller
    logging:
      level:
        default: info
    admin:
      address:
        host: 0.0.0.0
        port: 19000
      enableDumpConfig: true
      enablePprof: true
    provider:
      kubernetes:
        rateLimitDeployment:
          container:
            image: docker.1ms.run/envoyproxy/ratelimit:99d85510
          patch:
            type: StrategicMerge
            value:
              spec:
                template:
                  spec:
                    containers:
                    - imagePullPolicy: IfNotPresent
                      name: envoy-ratelimit
        shutdownManager:
          image: docker.1ms.run/envoyproxy/gateway:v1.6.1
      type: Kubernetes
kind: ConfigMap
metadata:
  name: envoy-gateway-config
  namespace: envoy-gateway-system

压力测试

同等配置2C4G单副本。

root@master1-22-137:~# ab -n 10000 -c 1000  https://www.example.com/
This is ApacheBench, Version 2.3 <$Revision: 1879490 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking www.example.com (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests


Server Software:        
Server Hostname:        www.example.com
Server Port:            443
SSL/TLS Protocol:       TLSv1.2,ECDHE-RSA-CHACHA20-POLY1305,2048,256
Server Temp Key:        X25519 253 bits
TLS Server Name:        www.example.com

Document Path:          /
Document Length:        16 bytes

Concurrency Level:      1000
Time taken for tests:   26.611 seconds
Complete requests:      10000
Failed requests:        0
Non-2xx responses:      10000
Total transferred:      1510000 bytes
HTML transferred:       160000 bytes
Requests per second:    375.78 [#/sec] (mean)
Time per request:       2661.107 [ms] (mean)
Time per request:       2.661 [ms] (mean, across all concurrent requests)
Transfer rate:          55.41 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       13 1321 738.2   1164    3771
Processing:  1004 1180 207.8   1114    3019
Waiting:        1  119 163.4     76    1671
Total:       1133 2501 779.1   2295    4818

Percentage of the requests served within a certain time (ms)
  50%   2295
  66%   2679
  75%   2945
  80%   3197
  90%   3769
  95%   4017
  98%   4260
  99%   4451
 100%   4818 (longest request)

结论

同等配置,同等性能压测参数,推荐使用envoy。性能介于nginx和traefik之间。返回延迟traefik>envoy>nignx,nginx存在请求失败的情况。

posted @ 2025-12-24 11:22  Gshelldon  阅读(3)  评论(0)    收藏  举报