一、为什么会有 Gateway API?

传统 Ingress 有很多问题:

• 功能有限
• 不同厂商实现不统一
• TCP/UDP 支持差
• 权限控制粗糙
• 不适合大型平台

所以 Kubernetes 推出了:Gateway API

二、Gateway API 的核心组件

主要有 4 个资源:

资源 作用
GatewayClass 网关实现类型
Gateway 网关实例
HTTPRoute 路由规则
ReferenceGrant 跨命名空间授权

三、和 Ingress 对比

传统 Ingress:

Ingress
├── 域名
├── 路由
├── TLS
└── Controller
所有东西都混在一起

Gateway API:

Gateway
    负责监听端口

HTTPRoute
    负责路由规则

实现了解耦。
这也是它最大的优势。

四、安装、使用gateway发布服务

目前k8s本身是没有自带gateway的,我们需要安装他的一些组件

安装gateway API的CRD

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

然后我们还需要安装一个控制器,控制器类型较多,以下控制器都可以,我这里选择envoy

Controller 支持情况
Istio 很好
Cilium 很好
Nginx Gateway Fabric 支持
Envoy Gateway 官方推荐之一
Kong 支持
helm install eg oci://docker.io/envoyproxy/gateway-helm --version v1.8.0 -n envoy-gateway-system --create-namespace

这里需要上点手段,不然会因为网络问题导致下载失败进而无法安装成功

等几分钟让pod都正常running

[root@master gateway]# kubectl get pods -n envoy-gateway-system 
NAME                                                  READY   STATUS    RESTARTS      AGE
envoy-default-web-gateway-6a499eb1-6d6c8c9b99-s6dcg   2/2     Running   2 (74m ago)   13h
envoy-gateway-798d84ccb8-znxpd                        1/1     Running   1 (74m ago)   24h

都正常running之后咱们需要自己创建对应的gatewayclass,gateway了,当然也可以使用官方的yaml文件直接创建,这里采用手动编写yaml并创建的方式,一步步来更好理解,官网yaml文件地址envoy官网

4.1 创建gatewayClass

apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: envoy
spec:
  controllerName: gateway.envoyproxy.io/gatewayclass-controller

这里的controllerName,如果你也是安装的envoy那么就是这个,如果你是安装的其他控制器,那么你需要查对应的controllerName是什么,如果填错了将不会被控制器接管

kubectl apply -f gatewayClass.yaml

等待他创建完成之后我们查看

[root@master gateway]# kubectl get gatewayclasses.gateway.networking.k8s.io 
NAME    CONTROLLER                                      ACCEPTED   AGE
envoy   gateway.envoyproxy.io/gatewayclass-controller   True       13h

这里的ACCEPTED一定要是True,如果为false的话就是错的,要么控制器名写错了,要么控制器还没创建好,自己检查一下

4.2 创建gateway

有了gatewayClass之后,我们就可以创建gateway了

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: web-gateway
  namespace: default
spec:
  gatewayClassName: envoy
  listeners:
  - name: http
    protocol: HTTP
    port: 80
    hostname: "www.test.com"
    allowedRoutes:
      namespaces:
        from: Same

下面这一段的 allowedRoutes表示这个gateway将会接管那些路由,我这写的是 namespaces: from : Same 表示只会接管相同命名空间下的route,这里还有其他选项,如All 和Selector
生产环境建议使用选择器(selector),这种方式更灵活

kubectl apply -f gateway.yaml

接下来我们可以创建路由了

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: web-route
spec:
  parentRefs:
  - name: web-gateway
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /
    backendRefs:
    - name: nginx
      port: 80

backendRefs: 表示流量转发到哪个后端svc,现在我们的环境上没有后端,一会把他创建出来,我们先把路由给写出来

kubectl apply -f route.yaml

路由创建成功之后我们就可以来创建pod,svc了这一步非常简单

kubectl run nginx  --image ngnix
kubectl expose nginx --port 80 --target-port 80 --type ClusterIP

执行这2条命令即可创建出来,到这里,我们就可以访问了,只不过现在访问的方式有一些麻烦。不过我们依旧可以试一下
因为我们定义的域名是www.test.com,那么我们访问这个域名看看,记得修改hosts文件

curl www.test.com

此时你会发现,根本无法访问,或者访问出来的内容是你其他服务启动的80端口的内容,这是因为我们的gateway他还没有地址
或者使用另一种方式测试一下

curl -H "Host: www.test.com" http://IP

这种方式也行,意思就是我访问这个ip的时候加上 www.test.com这个请求头,这个可行的话接着往下看

[root@master gateway]# kubectl get gateway 
NAME          CLASS   ADDRESS          PROGRAMMED   AGE
web-gateway   envoy                    True         13h

这里的address是空的,原因是刚刚创建的gateway的svc的类型是loadBalancer,而我们不是云上的环境,没有提供loadBalancer的能力,所以这里没有被分配到地址。接下来我们安装第三方工具来实现loadBalancer

4.3 安装metalLB

之前的博客有写过,直接附上链接各位自行参考loadBalancer
要注意的是,博客里面的地址段你得写一个你真正能通的,比如你的k8s节点的地址是192.168.88.0/24的,那么你最好将loadBalancer的地址段也写成这个
安装完对应的插件之后再去查看

[root@master gateway]# kubectl get gateway 
NAME          CLASS   ADDRESS          PROGRAMMED   AGE
web-gateway   envoy   192.168.88.240   True         13h

此时就被分配到了一个地址段内的的IP了,接下来我们直接将hosts文件内的映射关系改为新的地址

[root@master gateway]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4

::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.88.100 harbor01.test.com
192.168.88.110 harbor02.test.com
192.168.88.240 www.test.com

这个时候我们再去访问www.test.com

[root@master gateway]# curl www.test.com



Welcome to nginx!



Welcome to nginx!

If you see this page, nginx is successfully installed and working. Further configuration is required for the web server, reverse proxy, API gateway, load balancer, content cache, or other features.

For online documentation and support please refer to nginx.org.
To engage with the community please visit community.nginx.org.
For enterprise grade support, professional services, additional security features and capabilities please refer to f5.com/nginx.

Thank you for using nginx.

此时就能拿到正确的结果了

到这k8s的gateway就已经正常工作了,目前我们只写了一个路由,假设我们有多条路由呢? 比如我访问www.test.com是转发到nginx这个pod上,我访问www.test.com/login会转到登录页面上,这个如何做呢?

4.4 多路由、重写

有了刚刚的想法之后我们直接开干,先创建一个pod来模拟登录业务

kubectl run login --image nginx
kubectl expose login --port 80 --target-port 80 --type ClusterIP
kubectl exec -it login -- bash
echo "Please login..." > /usr/share/nginx/html/index.html
exit

以上步骤的意思是,创建一个nignx容器并给他一个ClusterIP类型的svc,然后进入这个pod修改他的首页文件,使用这个pod来模拟登录功能,接下来直接上yaml文件

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: login-route
  namespace: default
spec:
  parentRefs:
  - name: web-gateway
  hostnames:
  - "www.test.com"
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /login
   # 这一段是之前没有的
    filters:
    - type: URLRewrite
      urlRewrite:
        path:
          type: ReplaceFullPath
          replaceFullPath: /
    backendRefs:
    - name: login
      port: 80

这一段yaml文件出现了一段新的内容,作用是重写url,因为如果不重写的话,我们访问www.test.com/login,那么gateway就会直接转发到pod内,请求的内容依旧是/login
但是我们的想法是你转发到login这个pod没有错,但是你得让他请求的是index.html这个文件才对,所以我们需要设置重写

kubectl apply -f rewrite.yaml

这个时候再去测试一下

[root@master gateway]# curl www.test.com



Welcome to nginx!



Welcome to nginx!

If you see this page, nginx is successfully installed and working. Further configuration is required for the web server, reverse proxy, API gateway, load balancer, content cache, or other features.

For online documentation and support please refer to nginx.org.
To engage with the community please visit community.nginx.org.
For enterprise grade support, professional services, additional security features and capabilities please refer to f5.com/nginx.

Thank you for using nginx.

访问www.test.com是没有问题的,接下来访问login

[root@master gateway]# curl www.test.com/login
Please login...

各位可以试试看不加上重写会是什么样的效果。
到此为止单路由以及多路由都提到过了,其他方式各位可以自行尝试了


原文地址: https://www.cveoy.top/t/topic/qGLZ 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录