侧边栏壁纸
博主头像
一揽芳华 博主等级

行动起来,活在当下

  • 累计撰写 265 篇文章
  • 累计创建 24 个标签
  • 累计收到 4 条评论

目 录CONTENT

文章目录

KubernetesGatewayPAI

芳华是个男孩!
2024-10-15 / 0 评论 / 0 点赞 / 13 阅读 / 0 字
广告 广告

1、Gateway API介绍

1、简介

Gateway API(之前叫 Service API)是由 SIG-NETWORK 社区管理的开源项目,项目地址:https://gateway-api.sigs.k8s.io/ 主要原因是 Ingress 资源对象不能很好的满足网络需求,很多场景下 Ingress 控制器都需要通过定义 annotations 或者 crd 来进行功能扩展,这对于使用标准和支持是非常不利的,新推出的 Gateway API 旨在通过可扩展的面向角色的接口来增强服务网络。

Gateway APl是Kubernetes 中的一个 API资源集合,包括 GatewayClass、Gateway、HTTPRoute、CPRoute、Service等,这些资源共同为各种网络用例构建模型。

invalid image(图片无法加载)

Gateway API的改进比当前的 Ingress 资源对象有很多更好的设计:

  • 面向角色-Gateway 由各种 API资源组成,这些资源根据使用和配置Kubernetes 服务网络的角色进行建模。
  • 通用性·和 Ingress 一样是一个具有众多实现的通用规范,Gateway API是一个被设计成由许多实现支持的规范标准。更具表现力-Gateway A阶资源支持基于 Header 头的匹配、流量权重等核心功能,这些功能在 Ingress 中只能通过白定义注解才能实现。
  • 可扩展性-Gateway API允许自定义资源链接到 API的各个层,这就允许在 API结构的适当位置进行更精细的定制。还有一些其他值得关注的功能:
  • GatewayClasses·GatewayClases 将负载均衡实现的类型形式化,这些类使用户可以很容易了解到通过 Kubernetes 资源可以获得什么样的能力。
  • 共享网关和跨命名空间支持·它们允许共享负载均衡器和 VIP,允许独立的路由资源绑定到同一个网关,这使得团队可以安全地共享(包括跨命名空间)基础设施,而不需要直接协调。
  • 规范化路由和后端-GatewyAPI支持类型化的路由资源和不同类型的后端,这使得 API可以灵活地支持各种协议(如 HTTP和gRPC)和各种后端服务(如 Kubernetes Service、存储桶或函数)。

2、面向角色设计

无论是道路、电力、数据中心还是 Kubernetes 集群,基础设施都是为了共享而建的,然而共享基础设施提供了一个共同的挑战,那就是如何为基础设施用户提供灵活性的同时还能被所有者控制。

Gatewav API通过对 Kubernetes 服务网络进行面向角色的设计来实现这一目标,平衡了灵活性和集中控制。它允许共享的网络基础设施(硬件负载均衡器、云网络、集群托管的代理等)被许多不同的团队使用,所有这些都受到集群运维设置的各种策略和约束。下面的例子显示了是如何在实践中运行的。

invalid image(图片无法加载)

一个集群运维人员创建了一个基于 GatewayClass 的 Gateway 资源,这个 Gateway 部署或配置了它所代表的基础网络资源,集群运维和特定的团队必须沟通什么可以附加到这个 Gateway 上来暴露他们的应用。集中的策略,如 TLS,可以由集群运维在 Gateway 上强制执行,同时,Store 和 Site 应用在他们自己的命名空间中运行,但将他们的路由附加到相同的共享网关上,允许他们独立控制他们的路由逻辑。

这种关注点分离的设计可以使不同的团队能够管理他们自己的流量,同时将集中的策略和控制留给集群运维。

3、Gateway API概念

在整个 Gateway API 中涉及到3个角色:基础设施提供商、集群管理员、应用开发人员,在某些场景下可能还会涉及到应用管理员等角色。Gateway API 中定义了3种主要的资源模型:GatewayClass、Gateway、Route。

3.1、GatewayClass

GatewayClass 定义了一组共享相同配置和动作的网关。每个GatewayClass 由一个控制器处理,是一个集群范围的资源,必须至少有一个 GatewayClass 被定义。

这与 Ingress 的 IngressClass 类似,在 Ingress v1beta1 版本中,与 GatewayClass 类似的是 ingress-class 注解,而在Ingress V1 版本中,最接近的就是 IngressClass 资源对象。

3.2、Gateway

Gateway 网关描述了如何将流量转化为集群内的服务,也就是说,它定义了一个请求,要求将流量从不了解 Kubernetes 的地方转换到集群内的服务。例如,由云端负载均衡器、集群内代理或外部硬件负载均衡器发送到 Kubernetes 服务的流量。

它定义了对特定负载均衡器配置的请求,该配置实现了 GatewayClass 的配置和行为规范,该资源可以由管理员直接创建,也可以由处理 GatewayClass 的控制器创建。

Gateway 可以附加到一个或多个路由引用上,这些路由引用的作用是将流量的一个子集导向特定的服务。

3.3、Route 资源

路由资源定义了特定的规则,用于将请求从网关映射到 Kubernetes 服务。

从 v1alpha2 版本开始,API 中包含四种 Route 路由资源类型,对于其他未定义的协议,鼓励采用特定实现的自定义路由类型,当然未来也可能会添加新的路由类型。

3.3.1、HTTPRoute

HTTPRoute 适用于 HTTP 或 HTTPS 连接,适用于我们想要检查 HTTP 请求并使用 HTTP 请求进行路由或修改的场景,比如使用 HTTP Headers 头进行路由,或在请求过程中对它们进行修改。

3.3.2、TLSRoute

TLSRoute 用于 TLS 连接,通过 SNI 进行区分,它适用于希望使用 SNI 作为主要路由方法的地方,并且对 HTTP 等更高级别协议的属性不感兴趣,连接的字节流不经任何检查就被代理到后端。

3.3.3、TCPRoute 和 UDPRoute

TCPRoute(和UDPRoute)旨在用于将一个或多个端口映射到单个后端。在这种情况下,没有可以用来选择同一端口的不同后端的判别器,所以每个 TCPRoute 在监听器上需要一个不同的端口。你可以使用 TLS,在这种情况下,未加密的字节流会被传递到后端,当然也可以不使用 TLS,这样加密的字节流将传递到后端。

4、组合

GatewayClass、Gateway、xRoute 和 Service 的组合定义了一个可实施的负载均衡器。下图说明了不同资源之间的关系:
invalid image(图片无法加载)

使用反向代理实现的网关的典型客户端/网关 API 请求流程如下所示:

1.客户端向 http://foo.example.com 发出请求
2.DNS 将域名解析为 Gateway 网关地址
3.反向代理在监听器上接收请求,并使用 Host Header 来匹配HTTPRoute
4.(可选)反向代理可以根据 HTTPRoute 的匹配规则进行路由
5.(可选)反向代理可以根据 HTTPRoute 的过滤规则修改请求,即添加或删除 headers
6.最后,反向代理根据 HTTPRoute 的 forwardTo 规则,将请求转发给集群中的一个或多个对象,即服务。

2.1、Kubernetes gateway CRD安装


要在 Traefik 中使用 GatewayAP!,首先我们需要先手动安装 GatewaVAP的 CRDS,使用如下命令即可安装,这将安装包括 GatewavClass、Gateway、HTTPRoute、TCPRoute等CRDS:

[root@k8s-master01 ~]# kubectl apply -k "github.com/kubernetes-sigs/service-apis/config/crd?ref=v0.3.0"
customresourcedefinition.apiextensions.k8s.io/backendpolicies.networking.x-k8s.io created
customresourcedefinition.apiextensions.k8s.io/gatewayclasses.networking.x-k8s.io created
customresourcedefinition.apiextensions.k8s.io/gateways.networking.x-k8s.io created
customresourcedefinition.apiextensions.k8s.io/httproutes.networking.x-k8s.io created
customresourcedefinition.apiextensions.k8s.io/tcproutes.networking.x-k8s.io created
customresourcedefinition.apiextensions.k8s.io/tlsroutes.networking.x-k8s.io created
customresourcedefinition.apiextensions.k8s.io/udproutes.networking.x-k8s.io created

invalid image(图片无法加载)

2.2、为traefik授权(RBAC)


[root@k8s-master01 traefik]# vim traefik-gatewayapi-rbac.yaml
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: gateway-role
rules:
  - apiGroups:
      - ""
    resources:
      - services
      - endpoints
      - secrets
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - networking.x-k8s.io
    resources:
      - gatewayclasses
      - gateways
      - httproutes
      - tcproutes
      - tlsroutes
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - networking.x-k8s.io
    resources:
      - gatewayclasses/status
      - gateways/status
      - httproutes/status
      - tcproutes/status
      - tlsroutes/status
    verbs:
      - update
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: gateway-controller
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: gateway-role
subjects:
  - kind: ServiceAccount
    name: traefik-ingress-controller
    namespace: kube-system
[root@k8s-master01 traefik]# kubectl apply -f traefik-gatewayapi-rbac.yaml
clusterrole.rbac.authorization.k8s.io/gateway-role created
clusterrolebinding.rbac.authorization.k8s.io/gateway-controller created

2.3、Traefik开启gateway api的支持


在前面部署Traefik的时候已经开启了,检查你的是否开启

[root@k8s-master01 traefik]# cat traefik-configmap.yaml 
……
    providers:
      kubernetesCRD: ""  ## 启用 Kubernetes CRD 方式来配置路由规则
      kubernetesingress: ""  ## 启用 Kubernetes Ingress 方式来配置路由规则
      kubernetesGateway: "" ## 启用 Kubernetes Gateway API  ----> 检查是否存在此行
    experimental:  #----> 检查是否存在此行
      kubernetesGateway: true  ## 允许使用 Kubernetes Gateway API  ----> 检查是否存在此行
……
# 重新生效
[root@k8s-master01 traefik]# kubectl delete -f traefik-configmap.yaml 
[root@k8s-master01 traefik]# kubectl apply -f traefik-configmap.yaml 

invalid image(图片无法加载)

2.4、创建Gateway API的GatewayClass


[root@k8s-master01 traefik]# vim gatewayclass.yaml
apiVersion: networking.x-k8s.io/v1alpha1
kind: GatewayClass
metadata:
  name: traefik
spec:
  controller: traefik.io/gateway-controller
[root@k8s-master01 traefik]# kubectl apply -f gatewayclass.yaml 
gatewayclass.networking.x-k8s.io/traefik created
[root@k8s-master01 traefik]# kubectl get gatewayclasses.networking.x-k8s.io 
NAME      CONTROLLER                      AGE
traefik   traefik.io/gateway-controller   9s
[root@k8s-master01 traefik]# 

3.1、GatewayAPI高级应用-暴露Traefik dashboard


1、创建Gateway

[root@k8s-master01 traefik]# cat trafik-dashboard-gateway.yaml 
apiVersion: networking.x-k8s.io/v1alpha1
kind: Gateway
metadata:
  name: http-traefik
  namespace: kube-system
spec:
  gatewayClassName: traefik
  listeners:
    - protocol: HTTP
      port: 80
      routes:
        kind: HTTPRoute
        namespaces: 
          from: All
        selector:
          matchLabels:
            app: traefik
[root@k8s-master01 traefik]# kubectl apply -f trafik-dashboard-gateway.yaml
gateway.networking.x-k8s.io/http-traefik created

[root@k8s-master01 traefik]# kubectl get gateway -n kube-system 
NAME           CLASS     AGE
http-traefik   traefik   18s

2、创建HTTPRoute

[root@k8s-master01 traefik]# cat trafik-dashboard-httproute.yaml 
apiVersion: networking.x-k8s.io/v1alpha1
kind: HTTPRoute
metadata:
  name: traefik-dashboard-gateway-api-route
  namespace: kube-system
  labels:
    app: traefik
spec:
  hostnames:
    - "traefik.tkdashboard.com"
  rules:
    - matches:
        - path:
            type: Prefix
            value: /
      forwardTo:
        - serviceName: traefik
          port: 8080
          weight: 1
[root@k8s-master01 traefik]# kubectl apply -f trafik-dashboard-httproute.yaml 
httproute.networking.x-k8s.io/traefik-dashboard-gateway-api-route created

[root@k8s-master01 traefik]# kubectl get httproute  -n kube-system 
NAME                                  HOSTNAMES                     AGE
traefik-dashboard-gateway-api-route   ["traefik.tkdashboard.com"]   49s

3、集群外主机添加解析后,测试访问,本次在worker04上测试

[root@k8s-worker04 ~]# echo "192.168.122.11 traefik.tkdashboard.com" >> /etc/hosts

invalid image(图片无法加载)

invalid image(图片无法加载)

3.2、通过Gateway API方式暴露WEB应用


1、创建WEB应用

[root@k8s-master01 traefik]# cat nginx-web-gatewayapi.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-web-gatewayapi
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-web-gatewayapi
  template:
    metadata:
      labels:
        app: nginx-web-gatewayapi
    spec:
      containers:
      - name: nginx-web-gatewayapi
        image: nginx:1.24.0
        lifecycle:
          postStart:
            exec:
              command: ["/bin/bash", "-c", "echo nginx-web-gatewayapi > /usr/share/nginx/html/index.html"]
        ports:
        - containerPort: 80
          protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-web-gatewayapi
  namespace: default
spec:
  ports:
    - port: 80
      protocol: TCP
      targetPort: 80
  selector:
    app: nginx-web-gatewayapi
[root@k8s-master01 traefik]# kubectl apply -f nginx-web-gatewayapi.yaml 
deployment.apps/nginx-web-gatewayapi created
service/nginx-web-gatewayapi created
[root@k8s-master01 traefik]# kubectl get pod,svc
NAME                                         READY   STATUS    RESTARTS   AGE
pod/nfs-client-provisioner-856696f4c-cmlgq   1/1     Running   1          8d
pod/nginx-web-gatewayapi-5bfb495f6d-4njp8    1/1     Running   0          22s

NAME                           TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
service/kubernetes             ClusterIP   10.96.0.1     <none>        443/TCP   30d
service/nginx-web-gatewayapi   ClusterIP   10.104.77.1   <none>        80/TCP    22s

2、通过Gateway API方式暴露nginx

2.1、创建Gateway

[root@k8s-master01 traefik]# cat nginx-web-gateway.yaml 
apiVersion: networking.x-k8s.io/v1alpha1
kind: Gateway
metadata:
  name: nginx-web-gatewayapi
  namespace: default
spec:
  gatewayClassName: traefik
  listeners:
    - protocol: HTTP
      port: 80
      routes:
        kind: HTTPRoute
        namespaces: 
          from: All
        selector:
          matchLabels:
            app: nginx-web-gatewayapi
[root@k8s-master01 traefik]# kubectl apply -f nginx-web-gateway.yaml 
gateway.networking.x-k8s.io/nginx-web-gatewayapi created
[root@k8s-master01 traefik]# kubectl get gateway
NAME                   CLASS     AGE
nginx-web-gatewayapi   traefik   6s
[root@k8s-master01 traefik]# 

2.3、创建HTTPRoute

[root@k8s-master01 traefik]# cat nginx-web-gateway-httproute.yaml 
apiVersion: networking.x-k8s.io/v1alpha1
kind: HTTPRoute
metadata:
  name: nginx-web-gatewayapi
  namespace: default
  labels:
    app: nginx-web-gatewayapi
spec:
  hostnames:
    - "nginx.tkdashboard.com"
  rules:
    - matches:
        - path:
            type: Prefix
            value: /
      forwardTo:
        - serviceName: nginx-web-gatewayapi
          port: 80
          weight: 1
root@k8s-master01 traefik]# kubectl get httproutes.networking.x-k8s.io 
NAME                   HOSTNAMES                   AGE
nginx-web-gatewayapi   ["nginx.tkdashboard.com"]   14s

2.4、测试

集群外主机添加解析,并测试,本次在worker04上测试

[root@k8s-worker04 ~]# echo "192.168.122.11 nginx.tkdashboard.com" >> /etc/hosts

invalid image(图片无法加载)

invalid image(图片无法加载)

invalid image(图片无法加载)

3.3、通过GatewayAPI部署金丝雀发布


Gateway APIs 规范可以支持的另一个功能是金丝雀发布,假设你想在一个端点上运行两个不同的服务(或同一服务的两个版本),并将部分请求路由到每个端点,则可以通过修改你的 HTTPRoute 来实现

1、部署应用

[root@k8s-master01 traefik]# cat nginx-web01_or_web02.yaml 
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-web-01
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-web-01
  template:
    metadata:
      labels:
        app: nginx-web-01
    spec:
      containers:
      - name: nginx-web-01
        image: nginx:1.24.0
        lifecycle:
          postStart:
            exec:
              command: ["/bin/bash", "-c", "echo nginx-web-01 > /usr/share/nginx/html/index.html"]
        ports:
        - containerPort: 80
          protocol: TCP
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-web-02
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-web-02
  template:
    metadata:
      labels:
        app: nginx-web-02
    spec:
      containers:
      - name: nginx-web-02
        image: nginx:1.24.0
        lifecycle:
          postStart:
            exec:
              command: ["/bin/bash", "-c", "echo nginx-web-02 > /usr/share/nginx/html/index.html"]
        ports:
        - containerPort: 80
          protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-web-01
  namespace: default
spec:
  ports:
    - port: 80
      protocol: TCP
      targetPort: 80
  selector:
    app: nginx-web-01
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-web-02
  namespace: default
spec:
  ports:
    - port: 80
      protocol: TCP
      targetPort: 80
  selector:
    app: nginx-web-02
[root@k8s-master01 traefik]# kubectl apply -f nginx-web01_or_web02.yaml 
deployment.apps/nginx-web-01 created
deployment.apps/nginx-web-02 created
service/nginx-web-01 created
service/nginx-web-02 created
[root@k8s-master01 traefik]# 

[root@k8s-master01 traefik]# kubectl get pod,svc
NAME                                         READY   STATUS    RESTARTS   AGE
pod/nfs-client-provisioner-856696f4c-cmlgq   1/1     Running   1          8d
pod/nginx-web-01-95ddcb499-xfpbk             1/1     Running   0          19s
pod/nginx-web-02-6d95896b8-899bm             1/1     Running   0          19s
pod/nginx-web-gatewayapi-5bfb495f6d-4njp8    1/1     Running   0          16m

NAME                           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service/kubernetes             ClusterIP   10.96.0.1       <none>        443/TCP   30d
service/nginx-web-01           ClusterIP   10.98.196.223   <none>        80/TCP    19s
service/nginx-web-02           ClusterIP   10.98.81.62     <none>        80/TCP    19s
service/nginx-web-gatewayapi   ClusterIP   10.104.77.1     <none>        80/TCP    16m

2、部署Gateway

使用发布Traefik时候的Gateway,也可以在创建一个Gateway,这里使用前面的Gateway,相关配置信息如下,我们不动,只打开看看

[root@k8s-master01 traefik]# vim nginx-web01_or_web02-gateway.yaml
apiVersion: networking.x-k8s.io/v1alpha1
kind: Gateway
metadata:
  name: nginx-web01-or-web02
  namespace: default
spec:
  gatewayClassName: traefik
  listeners:
    - protocol: HTTP
      port: 80
      routes:
        kind: HTTPRoute
        namespaces: 
          from: All
        selector:
          matchLabels:
            app: nginx-web01-or-web02
[root@k8s-master01 traefik]# kubectl apply -f nginx-web01_or_web02-gateway.yaml
gateway.networking.x-k8s.io/nginx-web01-or-web02 created

[root@k8s-master01 traefik]# kubectl get gateway
NAME                   CLASS     AGE
nginx-web-gatewayapi   traefik   35m
nginx-web01-or-web02   traefik   22s

3、创建HTTPRoute

[root@k8s-master01 traefik]# cat nginx-web01_or_web02-httproute.yaml 
apiVersion: networking.x-k8s.io/v1alpha1
kind: HTTPRoute
metadata:
  name: nginx-web01-or-web02
  namespace: default
  labels:
    app: nginx-web01-or-web02
spec:
  hostnames:
    - "nginx01.tkdashboard.com"
  rules:
    - forwardTo:
        - serviceName: nginx-web-01
          port: 80
          weight: 3                # 3/4的请求转发到nginx-web-01
        - serviceName: nginx-web-02
          port: 80
          weight: 1                # 1/4的请求转发到nginx-web-02
[root@k8s-master01 traefik]# kubectl apply -f nginx-web01_or_web02-httproute.yaml
httproute.networking.x-k8s.io/nginx-web01-or-web02 created
[root@k8s-master01 traefik]# kubectl get httproutes.networking.x-k8s.io 
NAME                   HOSTNAMES                     AGE
nginx-web-gatewayapi   ["nginx.tkdashboard.com"]     34m
nginx-web01-or-web02   ["nginx01.tkdashboard.com"]   6s

4、验证

dashboard查看,在worker04上添加解析并查看

[root@k8s-worker04 ~]# echo "192.168.122.11 nginx01.tkdashboard.com" >> /etc/hosts

[root@k8s-worker04 ~]# curl http://nginx01.tkdashboard.com
nginx-web-02
[root@k8s-worker04 ~]# curl http://nginx01.tkdashboard.com
nginx-web-01
[root@k8s-worker04 ~]# curl http://nginx01.tkdashboard.com
nginx-web-01
[root@k8s-worker04 ~]# curl http://nginx01.tkdashboard.com
nginx-web-01
[root@k8s-worker04 ~]# curl http://nginx01.tkdashboard.com
nginx-web-02
[root@k8s-worker04 ~]# curl http://nginx01.tkdashboard.com
nginx-web-01
[root@k8s-worker04 ~]# curl http://nginx01.tkdashboard.com
nginx-web-01
[root@k8s-worker04 ~]# curl http://nginx01.tkdashboard.com
nginx-web-01
[root@k8s-worker04 ~]# curl http://nginx01.tkdashboard.com
nginx-web-02

invalid image(图片无法加载)
invalid image(图片无法加载)

invalid image(图片无法加载)

0
广告 广告

评论区