使用Kubernetes Gateway API实现域名访问应用

Kubernetes Gateway API简介

Kubernetes Gateway API 是一组 API 类别,可提供动态基础设施制备和高级流量路由。Gateway API,能取代功能受限且维护停滞的传统 Ingress,以标准化、角色分离的方式实现更强大的流量路由与策略管理。

为了通过域名访问已部署的应用,本文介绍如何使用 Kubernetes Gateway API 来实现这一目标。

官方文档

复制代码
英文
https://gateway-api.sigs.k8s.io/docs/introduction/

中文
https://kubernetes.io/zh-cn/docs/concepts/services-networking/gateway/

Kubernetes Gateway API 具有四种稳定的 API 类别:

  • GatewayClass: 定义一组具有配置相同的网关,由实现该类的控制器管理。
  • Gateway: 定义流量处理基础设施(例如云负载均衡器)的一个实例。
  • HTTPRoute: 定义特定于 HTTP 的规则,用于将流量从 Gateway 监听器映射到后端网络端点的某种呈现。 这些端点通常表示为 Service
  • GRPCRoute: 定义特定于 gRPC 的规则,用于将流量从 Gateway 监听器映射到后端网络端点的某种呈现。 这些端点通常表示为 Service

一个 Gateway 对象只能与一个 GatewayClass 相关联;GatewayClass 描述负责管理此类 Gateway 的网关控制器。 各个(可以是多个)路由类别(例如 HTTPRoute)可以关联到此 Gateway 对象。 Gateway 可以对能够挂接到其 listeners 的路由进行过滤,从而与路由形成双向信任模型。

三个稳定的 Gateway API 类别之间的关系:

以下是使用 Gateway网关(反向代理的网关) 和 HTTPRoute 将 HTTP 流量路由到服务的简单示例:

在此示例中,实现为反向代理的 Gateway 的请求数据流如下:

  1. 客户端开始准备 URL 为 http://www.example.com 的 HTTP 请求。
  2. 客户端的 DNS 解析器查询目标名称并了解与 Gateway 关联的一个或多个 IP 地址的映射。
  3. 客户端向 Gateway IP 地址发送请求;反向代理接收 HTTP 请求并使用 Host: 标头来匹配基于 Gateway 和附加的 HTTPRoute 所获得的配置。
  4. 可选的,反向代理可以根据 HTTPRoute 的匹配规则进行请求头和(或)路径匹配。
  5. 可选地,反向代理可以修改请求;例如,根据 HTTPRoute 的过滤规则添加或删除标头。
  6. 最后,反向代理将请求转发到一个或多个后端。

Envoy Proxy 和 Gateway API 版本兼容关系如下

复制代码
https://gateway.envoyproxy.io/news/releases/matrix/

|---------------------------|-----------------------------|------------------------|-------------------------|----------------------------|-----------------|
| Envoy Gateway version | Envoy Proxy version | Rate Limit version | Gateway API version | Kubernetes version | End of Life |
| latest | dev-latest | master | v1.4.1 | v1.32, v1.33, v1.34, v1.35 | n/a |
| v1.8 | distroless-v1.38.0 | fe26676d | v1.5.1 | v1.32, v1.33, v1.34, v1.35 | 2026/11/08 |
| v1.7 | distroless-v1.37.0 | 3fb70258 | v1.4.1 | v1.32, v1.33, v1.34, v1.35 | 2026/08/05 |
| v1.6 | distroless-v1.36.4 | 3fb70258 | v1.4.0 | v1.30, v1.31, v1.32, v1.33 | 2026/05/13 |
| v1.5 | distroless-v1.35.0 | a90e0e5d | v1.3.0 | v1.30, v1.31, v1.32, v1.33 | 2026/02/13 |
| v1.4 | distroless-v1.34.1 | 3e085e5b | v1.3.0 | v1.30, v1.31, v1.32, v1.33 | 2025/11/13 |
| v1.3 | distroless-v1.33.0 | 60d8e81b | v1.2.1 | v1.29, v1.30, v1.31, v1.32 | 2025/07/30 |
| v1.2 | distroless-v1.32.1 | 28b1629a | v1.2.0 | v1.28, v1.29, v1.30, v1.31 | 2025/05/06 |
| v1.1 | distroless-v1.31.0 | 91484c59 | v1.1.0 | v1.27, v1.28, v1.29, v1.30 | 2025/01/22 |
| v1.0 | distroless-v1.29.2 | 19f2079f | v1.0.0 | v1.26, v1.27, v1.28, v1.29 | 2024/09/13 |
| v0.6 | distroless-v1.28-latest | b9796237 | v1.0.0 | v1.26, v1.27, v1.28 | 2024/05/02 |
| v0.5 | v1.27-latest | e059638d | v0.7.1 | v1.25, v1.26, v1.27 | 2024/01/02 |
| v0.4 | v1.26-latest | 542a6047 | v0.6.2 | v1.25, v1.26, v1.27 | 2023/10/24 |
| v0.3 | v1.25-latest | f28024e3 | v0.6.1 | v1.24, v1.25, v1.26 | 2023/08/09 |
| v0.2 | v1.23-latest | | v0.5.1 | v1.24 | 2023/04/20 |

本文使用的Kubernetes版本为1.31.1,根据上表版本兼容关系,Gateway API选用v1.3.0,Envoy Gateway选用v1.4.0。

安装 Gateway API

在Kubernetes集群中安装 Gateway API

复制代码
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.3.0/standard-install.yaml

操作过程

复制代码
[root@k8s-master01 ~]# kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.3.0/standard-install.yaml
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
[root@k8s-master01 ~]#

安装 Envoy Gateway 网关控制器

在Kubernetes集群中安装 Envoy Gateway 网关控制器

复制代码
kubectl apply --server-side -f https://github.com/envoyproxy/gateway/releases/download/v1.4.0/install.yaml

操作过程

复制代码
[root@k8s-master01 ~]# kubectl apply --server-side -f https://github.com/envoyproxy/gateway/releases/download/v1.4.0/install.yaml
customresourcedefinition.apiextensions.k8s.io/backendtlspolicies.gateway.networking.k8s.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/gatewayclasses.gateway.networking.k8s.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/gateways.gateway.networking.k8s.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/grpcroutes.gateway.networking.k8s.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/httproutes.gateway.networking.k8s.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/referencegrants.gateway.networking.k8s.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/tcproutes.gateway.networking.k8s.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/tlsroutes.gateway.networking.k8s.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/udproutes.gateway.networking.k8s.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/xbackendtrafficpolicies.gateway.networking.x-k8s.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/xlistenersets.gateway.networking.x-k8s.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/backends.gateway.envoyproxy.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/backendtrafficpolicies.gateway.envoyproxy.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/clienttrafficpolicies.gateway.envoyproxy.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/envoyextensionpolicies.gateway.envoyproxy.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/envoypatchpolicies.gateway.envoyproxy.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/envoyproxies.gateway.envoyproxy.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/httproutefilters.gateway.envoyproxy.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/securitypolicies.gateway.envoyproxy.io serverside-applied
namespace/envoy-gateway-system serverside-applied
serviceaccount/envoy-gateway serverside-applied
configmap/envoy-gateway-config serverside-applied
clusterrole.rbac.authorization.k8s.io/eg-gateway-helm-envoy-gateway-role serverside-applied
clusterrolebinding.rbac.authorization.k8s.io/eg-gateway-helm-envoy-gateway-rolebinding serverside-applied
role.rbac.authorization.k8s.io/eg-gateway-helm-infra-manager serverside-applied
role.rbac.authorization.k8s.io/eg-gateway-helm-leader-election-role serverside-applied
rolebinding.rbac.authorization.k8s.io/eg-gateway-helm-infra-manager serverside-applied
rolebinding.rbac.authorization.k8s.io/eg-gateway-helm-leader-election-rolebinding serverside-applied
service/envoy-gateway serverside-applied
deployment.apps/envoy-gateway serverside-applied
serviceaccount/eg-gateway-helm-certgen serverside-applied
clusterrole.rbac.authorization.k8s.io/eg-gateway-helm-certgen:envoy-gateway-system serverside-applied
clusterrolebinding.rbac.authorization.k8s.io/eg-gateway-helm-certgen:envoy-gateway-system serverside-applied
role.rbac.authorization.k8s.io/eg-gateway-helm-certgen serverside-applied
rolebinding.rbac.authorization.k8s.io/eg-gateway-helm-certgen serverside-applied
job.batch/eg-gateway-helm-certgen serverside-applied
mutatingwebhookconfiguration.admissionregistration.k8s.io/envoy-gateway-topology-injector.envoy-gateway-system serverside-applied
[root@k8s-master01 ~]#

持续监控 envoy-gateway-system 命名空间下所有 Pod 的状态变化。

复制代码
[root@k8s-master01 ~]# kubectl get pods -n envoy-gateway-system -w
NAME                             READY   STATUS    RESTARTS   AGE
envoy-gateway-65fc6784d4-ffwnn   1/1     Running   0          42s

当READY是1/1,STATUS为Running时为正常

按Ctrl + c返回命令行

配置域名访问应用步骤

0)准备工作

创建nginx-deployment.yaml

复制代码
vi nginx-deployment.yaml

内容如下

复制代码
apiVersion: apps/v1	#与k8s集群版本有关,使用 kubectl api-versions 即可查看当前集群支持的版本
kind: Deployment	#该配置的类型,使用的是 Deployment
metadata:	        #译名为元数据,即 Deployment 的一些基本属性和信息
  name: nginx-deployment	#Deployment 的名称
  labels:	    #标签,可以灵活定位一个或多个资源,其中key和value均可自定义,可以定义多组,目前不需要理解
    app: nginx	#为该Deployment设置key为app,value为nginx的标签
spec:	        #这是关于该Deployment的描述,可以理解为你期待该Deployment在k8s中如何使用
  replicas: 1	#使用该Deployment创建一个应用程序实例
  selector:	    #标签选择器,与上面的标签共同作用,目前不需要理解
    matchLabels: #选择包含标签app:nginx的资源
      app: nginx
  template:	    #这是选择或创建的Pod的模板
    metadata:	#Pod的元数据
      labels:	#Pod的标签,上面的selector即选择包含标签app:nginx的Pod
        app: nginx
    spec:	    #期望Pod实现的功能(即在pod中部署)
      containers:	#生成container,与docker中的container是同一种
      - name: nginx	#container的名称
        image: nginx:alpine	#使用镜像nginx:alpine创建container,该container默认80端口可访问  

创建nginx-service.yaml

复制代码
vi nginx-service.yaml  

内容如下

复制代码
apiVersion: v1
kind: Service
metadata:
  name: nginx-service	#Service 的名称
  labels:     	#Service 自己的标签
    app: nginx	#为该 Service 设置 key 为 app,value 为 nginx 的标签
spec:	    #这是关于该 Service 的定义,描述了 Service 如何选择 Pod,如何被访问
  selector:	    #标签选择器
    app: nginx	#选择包含标签 app:nginx 的 Pod
  ports:
  - name: nginx-port	#端口的名字
    protocol: TCP	    #协议类型 TCP/UDP
    port: 80	        #集群内的其他容器组可通过 80 端口访问 Service
    nodePort: 32600   #通过任意节点的 32600 端口访问 Service
    targetPort: 80	#将请求转发到匹配 Pod 的 80 端口
  type: NodePort	#Serive的类型,ClusterIP/NodePort/LoaderBalancer 

应用yaml文件

复制代码
[root@k8s-master01 1]# ls
nginx-deployment.yaml  nginx-service.yaml
[root@k8s-master01 1]# kubectl apply -f nginx-deployment.yaml
deployment.apps/nginx-deployment created
[root@k8s-master01 1]# kubectl apply -f nginx-service.yaml
service/nginx-service created

1)创建 GatewayClass

新建 gatewayclass.yaml

复制代码
[root@k8s-master01 ~]# vi gatewayclass.yaml

内容如下

复制代码
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: eg
spec:
  controllerName: gateway.envoyproxy.io/gatewayclass-controller

应用

复制代码
[root@k8s-master01 ~]# kubectl apply -f gatewayclass.yaml
gatewayclass.gateway.networking.k8s.io/eg created

查看

复制代码
[root@k8s-master01 ~]# kubectl get gatewayclasses
NAME   CONTROLLER                                      ACCEPTED   AGE
eg     gateway.envoyproxy.io/gatewayclass-controller   True       5s

2)创建 Gateway(绑定上面的 eg)

gateway.yaml:

复制代码
vi gateway.yaml

内容如下

复制代码
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: nginx-gateway
spec:
  gatewayClassName: eg
  listeners:
  - name: http
    port: 80
    protocol: HTTP
    allowedRoutes:
      namespaces: { from: All }

应用

复制代码
[root@k8s-master01 ~]# kubectl apply -f gateway.yaml
gateway.gateway.networking.k8s.io/nginx-gateway created
[root@k8s-master01 ~]# 

查看

复制代码
[root@k8s-master01 ~]# kubectl get gateway
NAME            CLASS   ADDRESS   PROGRAMMED   AGE
nginx-gateway   eg                False        7s
[root@k8s-master01 ~]# 

3)创建 HTTPRoute(绑定 nginx-service)

nginx-httproute.yaml:

复制代码
[root@k8s-master01 ~]# vi nginx-httproute.yaml

内容如下

复制代码
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: nginx-route
spec:
  parentRefs:
  - name: nginx-gateway
  hostnames:
  - "nginx.test.com"
  rules:
  - backendRefs:
    - name: nginx-service
      port: 80

应用

复制代码
[root@k8s-master01 ~]# kubectl apply -f nginx-httproute.yaml
httproute.gateway.networking.k8s.io/nginx-route created

查看

复制代码
[root@k8s-master01 ~]# kubectl get httproute
NAME          HOSTNAMES            AGE
nginx-route   ["nginx.test.com"]   59s
[root@k8s-master01 ~]#

4)修改hosts文件

因为使用Windows浏览器,所以修改Windowns的hosts文件,hosts文件所在路径如下

复制代码
C:\Windows\System32\drivers\etc

在最后一行添加IP与域名的映射

复制代码
192.168.204.101 nginx.test.com

注意:IP为k8s集群任意一台机器IP

保存

5)测试域名访问

测试域名访问

复制代码
nginx.test.com

看到浏览器访问不了

查看gateway

复制代码
[root@k8s-master01 ~]# kubectl get gateway
NAME            CLASS   ADDRESS   PROGRAMMED   AGE
nginx-gateway   eg                Unknown      17s

看到PROGRAMMED为Unknown,ADDRESS没有IP,说明 Gateway 资源已经创建,但对应的控制器还没有成功处理它。

6)排错优化及测试访问

经排错,优化后的yaml文件内容如下

复制代码
[root@k8s-master01 ~]# cat gatewayclass.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: eg
spec:
  controllerName: gateway.envoyproxy.io/gatewayclass-controller
  parametersRef:
    group: gateway.envoyproxy.io
    kind: EnvoyProxy
    name: np-config
    namespace: envoy-gateway-system
[root@k8s-master01 ~]# cat gateway.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: nginx-gateway
spec:
  gatewayClassName: eg
  listeners:
  - name: http
    port: 80
    protocol: HTTP
    allowedRoutes:
      namespaces:
        from: All
[root@k8s-master01 ~]# cat envoyproxy.yaml
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
  name: np-config
  namespace: envoy-gateway-system
spec:
  provider:
    type: Kubernetes
    kubernetes:
      envoyService:
        type: NodePort
[root@k8s-master01 ~]# cat nginx-httproute.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: nginx-route
spec:
  parentRefs:
  - name: nginx-gateway
  hostnames:
  - "nginx.test.com"
  rules:
  - backendRefs:
    - name: nginx-service
      port: 80
[root@k8s-master01 ~]#

按以上内容修改yaml文件,apply应用yaml后(所有修改的yaml文件都需要重新执行apply命令),查看gateway正常如下

复制代码
[root@k8s-master01 ~]# kubectl apply -f gatewayclass.yaml
gatewayclass.gateway.networking.k8s.io/eg created
[root@k8s-master01 ~]# kubectl get gatewayclass
NAME   CONTROLLER                                      ACCEPTED   AGE
eg     gateway.envoyproxy.io/gatewayclass-controller   True       3s
[root@k8s-master01 ~]# kubectl get pods -n envoy-gateway-system
NAME                                                    READY   STATUS    RESTARTS   AGE
envoy-default-nginx-gateway-42c88ea3-68f856cd4f-7vqg9   2/2     Running   0          32s
envoy-gateway-65fc6784d4-ffwnn                          1/1     Running   0          70m
[root@k8s-master01 ~]# kubectl get gateway nginx-gateway
NAME            CLASS   ADDRESS           PROGRAMMED   AGE
nginx-gateway   eg      192.168.204.101   True         7m1s

看到ADDRESS有IP地址,PROGRAMMED为True,说明 Gateway 已经成功部署并可用

复制代码
[root@k8s-master01 ~]# kubectl get svc -n envoy-gateway-system
NAME                                   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                                            AGE
envoy-default-nginx-gateway-42c88ea3   NodePort    10.13.200.139   <none>        80:30788/TCP                                       6m56s
envoy-gateway                          ClusterIP   10.15.174.179   <none>        18000/TCP,18001/TCP,18002/TCP,19001/TCP,9443/TCP   76m

找到 envoy-default-nginx-gateway-xxx 这行,格式为 80:3xxxx/TCP,记下后面的NodePort 端口,这里看到的端口是30788

浏览器访问域名:端口,访问成功如下

复制代码
nginx.test.com:30788

浏览器ip:端口,访问不了,如下

复制代码
192.168.204.101:30788

原因是:HTTPRoute 里只写了 hostnames: "nginx.test.com",它会严格匹配请求头里的 Host 字段

复制代码
[root@k8s-master01 ~]# cat nginx-httproute.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: nginx-route
spec:
  parentRefs:
  - name: nginx-gateway
  hostnames:
  - "nginx.test.com"
  rules:
  - backendRefs:
    - name: nginx-service
      port: 80

|-------------------------|-------------------------|----------------|---------------|
| 访问方式 | 请求的 Host 头 | HTTPRoute 匹配结果 | 结果 |
| nginx.test.com:30788 | Host: nginx.test.com | 匹配路由规则 | 正常返回 Nginx 页面 |
| 192.168.204.101:30788 | Host: 192.168.204.101 | 不匹配路由规则 | 404 找不到网页 |

如果需要同时保留IP也可以访问,需要修改nginx-httproute.yaml文件,在hostnames字段添加IP信息如下

复制代码
hostnames:
  - "nginx.test.com"
  - "192.168.204.101"

到此,可以实现域名访问应用了,但是访问域名后面还需要带上一个随机端口号,如果不想要这个随机端口,直接用http默认的80或者https默认的443端口访问,该怎么办?

配置默认端口访问

Loadbalancer介绍

为什么需要 LoadBalancer?

Kubernetes 默认的服务类型:

ClusterIP:只能在集群内部访问。

NodePort:会在每个节点上开放一个高位端口(例如 30788),用户必须通过 http://节点IP:30788 才能访问,无法直接使用 80/443 端口,且体验不佳。

而 LoadBalancer 可以申请一个独立的对外 IP,并让该 IP 上的 80/443 端口转发到后端 Pod 的对应端口。

这使得客户端可以像访问传统网站一样,直接输入 http://<IP> 或 http://域名(通过 DNS 解析到该 IP),无需加端口号。

在云环境中,LoadBalancer 会自动与云厂商的 LB 组件(如 阿里云SLB)集成。

但在裸金属(物理服务器)环境中没有这种集成能力,因此需要 MetalLB 来模拟实现 LoadBalancer 的功能。

MetalLB 会监听 Kubernetes 中 type: LoadBalancer 的服务。

它为这些服务分配一个来自你配置的地址池(例如 192.168.204.100-192.168.204.200)的外部 IP。然后 MetalLB 通过 Layer2(ARP/NDP)或 BGP 协议让该 IP 在集群节点上"可达",从而将外部流量引入集群。

在裸金属 K8s(物理机服务器安装的K8s)环境中,使用 MetalLB + Envoy Gateway LoadBalancer 实现使用默认端口(80/443,默认端口可不加端口号访问)直接访问。

修改kube-proxy configmap配置

复制代码
[root@k8s-master01 ~]# kubectl edit configmap -n kube-system kube-proxy
  • 把 mode: "" 改成:mode: "ipvs"
  • 把 strictARP: false 改成:strictARP: true

mode修改前

mode修改后如下

strictARP修改前

strictARP修改后

保存退出(和vi命令保存退出方法一致)

部署 MetalLB

复制代码
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.15.3/config/manifests/metallb-native.yaml

操作过程

复制代码
[root@k8s-master01 ~]# kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.15.3/config/manifests/metallb-native.yaml
namespace/metallb-system created
customresourcedefinition.apiextensions.k8s.io/bfdprofiles.metallb.io created
customresourcedefinition.apiextensions.k8s.io/bgpadvertisements.metallb.io created
customresourcedefinition.apiextensions.k8s.io/bgppeers.metallb.io created
customresourcedefinition.apiextensions.k8s.io/communities.metallb.io created
customresourcedefinition.apiextensions.k8s.io/configurationstates.metallb.io created
customresourcedefinition.apiextensions.k8s.io/ipaddresspools.metallb.io created
customresourcedefinition.apiextensions.k8s.io/l2advertisements.metallb.io created
customresourcedefinition.apiextensions.k8s.io/servicebgpstatuses.metallb.io created
customresourcedefinition.apiextensions.k8s.io/servicel2statuses.metallb.io created
serviceaccount/controller created
serviceaccount/speaker created
role.rbac.authorization.k8s.io/controller created
role.rbac.authorization.k8s.io/pod-lister created
clusterrole.rbac.authorization.k8s.io/metallb-system:controller created
clusterrole.rbac.authorization.k8s.io/metallb-system:speaker created
rolebinding.rbac.authorization.k8s.io/controller created
rolebinding.rbac.authorization.k8s.io/pod-lister created
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:controller created
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:speaker created
configmap/metallb-excludel2 created
secret/metallb-webhook-cert created
service/metallb-webhook-service created
deployment.apps/controller created
daemonset.apps/speaker created
validatingwebhookconfiguration.admissionregistration.k8s.io/metallb-webhook-configuration created
[root@k8s-master01 ~]#

空闲IP准备

IP准备,用作LoadBalancer 的对外 IP

查询ip是否被占用

复制代码
[root@k8s-master01 ~]# for i in {210..230}; do   ping -c 1 -W 1 192.168.204.$i > /dev/null && echo "❌ 已占用: 192.168.204.$i" || echo "✅ 空闲: 192.168.204.$i"; done
✅ 空闲: 192.168.204.210
✅ 空闲: 192.168.204.211
✅ 空闲: 192.168.204.212
✅ 空闲: 192.168.204.213
✅ 空闲: 192.168.204.214
✅ 空闲: 192.168.204.215
✅ 空闲: 192.168.204.216
✅ 空闲: 192.168.204.217
✅ 空闲: 192.168.204.218
✅ 空闲: 192.168.204.219
✅ 空闲: 192.168.204.220
✅ 空闲: 192.168.204.221
✅ 空闲: 192.168.204.222
✅ 空闲: 192.168.204.223
✅ 空闲: 192.168.204.224
✅ 空闲: 192.168.204.225
✅ 空闲: 192.168.204.226
✅ 空闲: 192.168.204.227
✅ 空闲: 192.168.204.228
✅ 空闲: 192.168.204.229
✅ 空闲: 192.168.204.230

看到192.168.204.210-192.168.204.230的IP都未被占用

新建 metallb-config.yaml

复制代码
vi metallb-config.yaml

内容如下

复制代码
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: default
  namespace: metallb-system
spec:
  addresses:
  - 192.168.204.210-192.168.204.230  # 和集群同网段、未占用
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: default
  namespace: metallb-system
spec:
  ipAddressPools:
  - default

应用

复制代码
[root@k8s-master01 ~]# kubectl apply -f metallb-config.yaml
ipaddresspool.metallb.io/default created
l2advertisement.metallb.io/default created
[root@k8s-master01 ~]#

验证

复制代码
[root@k8s-master01 ~]# kubectl get pods -n metallb-system
NAME                        READY   STATUS    RESTARTS   AGE
controller-cd8c9874-5vl4c   1/1     Running   0          7m21s
speaker-6vmp7               1/1     Running   0          7m21s
speaker-pqr96               1/1     Running   0          7m21s
speaker-pztv2               1/1     Running   0          7m21s
[root@k8s-master01 ~]#

修改envoyproxy.yaml

复制代码
[root@k8s-master01 ~]# vi envoyproxy.yaml

将type字段由原来的NodePort更改为LoadBalancer

修改前

修改后

应用

复制代码
[root@k8s-master01 ~]# kubectl apply -f envoyproxy.yaml
envoyproxy.gateway.envoyproxy.io/np-config configured
[root@k8s-master01 ~]#

查看gateway

复制代码
[root@k8s-master01 ~]# kubectl get gateway
NAME            CLASS   ADDRESS           PROGRAMMED   AGE
nginx-gateway   eg      192.168.204.210   True         57m

看到Address ip由原来的192.168.204.101变为了192.168.204.210

192.168.204.210属于此前设置的空闲IP池里的IP。

修改hosts文件

修改Windows的hosts文件

复制代码
192.168.204.210 nginx.test.com

浏览器访问域名

复制代码
nginx.test.com

如果访问域名的同时,还需要可以使用ip来访问,可修改nginx-httproute.yaml文件,在 hostnames 添加Gateway分配的ADDRESS IP:192.168.204.210

复制代码
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: nginx-route
spec:
  parentRefs:
  - name: nginx-gateway
  hostnames:
  - "nginx.test.com"
  - "192.168.204.210"
  rules:
  - backendRefs:
    - name: nginx-service
      port: 80

修改前

修改后

最新yaml文件内容

复制代码
[root@k8s-master01 ~]# cat gatewayclass.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: eg
spec:
  controllerName: gateway.envoyproxy.io/gatewayclass-controller
  parametersRef:
    group: gateway.envoyproxy.io
    kind: EnvoyProxy
    name: np-config
    namespace: envoy-gateway-system
[root@k8s-master01 ~]# cat gateway.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: nginx-gateway
spec:
  gatewayClassName: eg
  listeners:
  - name: http
    port: 80
    protocol: HTTP
    allowedRoutes:
      namespaces:
        from: All
[root@k8s-master01 ~]# cat envoyproxy.yaml
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
  name: np-config
  namespace: envoy-gateway-system
spec:
  provider:
    type: Kubernetes
    kubernetes:
      envoyService:
        type: LoadBalancer
[root@k8s-master01 ~]# cat nginx-httproute.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: nginx-route
spec:
  parentRefs:
  - name: nginx-gateway
  hostnames:
  - "nginx.test.com"
  - "192.168.204.210"
  rules:
  - backendRefs:
    - name: nginx-service
      port: 80
[root@k8s-master01 ~]# cat metallb-config.yaml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: default
  namespace: metallb-system
spec:
  addresses:
  - 192.168.204.210-192.168.204.230  # 和K8S集群同网段、未占用
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: default
  namespace: metallb-system
spec:
  ipAddressPools:
  - default
[root@k8s-master01 ~]#

应用yaml

重新应用

复制代码
[root@k8s-master01 ~]# kubectl apply -f nginx-httproute.yaml
httproute.gateway.networking.k8s.io/nginx-route configured
[root@k8s-master01 ~]#

访问测试

使用IP访问

复制代码
192.168.204.210

使用域名访问

复制代码
nginx.test.com

实现了域名直接访问,但是浏览器地址上看到不安全的提示,原因是使用HTTP访问不够安全,如果需要更安全访问可以配置使用HTTPS。

完成!enjoy it!

相关推荐
worilb4 小时前
Spring Cloud 学习与实践(9):Gateway + JWT 统一鉴权
学习·spring cloud·gateway
java_cj4 小时前
深入kubectl create源码:从YAML到Pod的完整链路拆解
运维·云原生·容器·kubernetes
源图客7 小时前
【AI向量数据库】Weaviate介绍与部署
运维·docker·容器
码云骑士10 小时前
28-Docker部署Django(下)-docker-compose编排与静态文件处理
docker·容器·django
木雷坞11 小时前
Firecrawl Docker Compose 自托管排查:镜像、Redis、队列和 Playwright
redis·docker·容器·firecrawl
whyfail11 小时前
Colima:把 Docker Desktop 从 Mac 上“瘦身”的那把刀
macos·docker·容器
人工智能培训12 小时前
数字孪生的未来发展方向探析
gpt·深度学习·机器学习·容器·知识图谱
大佐不会说日语~13 小时前
在 Windows 本地用 Docker 部署向量模型(bge-m3)
windows·docker·容器·llm·ollama
xsc-xyc13 小时前
CasaOS + Docker 挂载外接硬盘部署 Jellyfin 私人影院
运维·docker·容器