快速浏览Kubernetes网关API

267 阅读7分钟

Kubernetes网关API速览

有很多方法可以从集群外部访问一个pod。网关API是这个领域的新秀,也是这篇文章的主题。

我最近的一篇博文中,我描述了访问Kubernetes pods的几种方法。人们可以通过其IP来访问一个pod,但pod自然是瞬息万变的。名义上的方法是配置一个Service :它的IP是稳定的,而Kubernetes的工作是保持一个Service 和它的底层pod之间的映射是最新的。有不同种类的服务可供选择:只有内部的,NodePort ,最终允许从集群外部访问,以及依赖于第三方组件的LoadBalancer ,一般来说,是云提供商的。最后,我提到了Ingress 对象,它也允许路由。

我故意漏掉了一个新的孩子,网关API。它是这篇文章的主题。

从Ingress到Gateway API

对Kubernetes pods的外部访问经历了几个演变步骤;例如,Ingress 是对LoadBalancer 中缺乏路由问题的回答。Ingress 的最大问题是它对 "专有 "对象的依赖性。作为提醒,下面是使用Apache APISIX创建路由的片段。

YAML

apiVersion: apisix.apache.org/v2beta3            #1
kind: ApisixRoute                                #1
metadata:
  name: apisix-route
spec:
  http:
  - name: left
    match:
      paths:
      - "/left"
    backends:
      - serviceName: left
        servicePort: 80
  - name: right
    match:
      paths:
        - "/right"
    backends:
      - serviceName: right
        servicePort: 80
  • #1: 专有对象

专有对象是迁移时的一个问题。虽然从一个供应商迁移到另一个供应商可能并不常见,但它应该尽可能地无缝。当使用专有对象时,你首先需要从旧对象映射到新对象。有可能这不是一个一对一的映射。然后,你需要将规范翻译成新的模型:这可能是一个完整的项目。

Gateway API背后的想法是,在标准对象和专有实现之间有一个干净的分离。

Gateway API

Gateway API是一个由SIG-NETWORK社区管理的开源项目。它是一个资源的集合,在Kubernetes中模拟服务网络。这些资源--GatewayClassGatewayHTTPRouteTCPRouteService 等--旨在通过表达式、可扩展和面向角色的接口来发展Kubernetes服务网络,这些接口由许多供应商实现,并得到了广泛的行业支持。

-Kubernetes网关API介绍

上述定义还提到了一个组织上的问题:不同的角色应该管理不同的对象集。

源于此。 Kubernetes网关API介绍

事实上,集群操作员和开发者的关注点是相当不同的。这与以前的Java EE应用服务器很相似,后者提供了一个围绕角色组织的规范:开发者、部署者和操作员。IMHO,最重要的区别是,该规范主要关注开发者的体验;其余的由实施者决定。Gateway API似乎关心所有的角色。

通过网关API配置Pod访问

让我们用Gateway API替换我们之前配置的Ingress 。有几个步骤是必要的。

安装新的Gateway CRD

外壳

k apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v0.5.0/standard-install.yaml

安装一个实现

我将会使用Apache APISIX。另外,SIG网站上有一个实施方案的列表

外壳

helm install apisix apisix/apisix \
  --namespace ingress-apisix \
  --create-namespace \
  --devel \                                                                #1
  --set gateway.type=NodePort \                                            #2
  --set gateway.http.nodePort=30800 \                                      #2
  --set ingress-controller.enabled=true \                                  #2
  --set ingress-controller.config.kubernetes.enableApiGateway=true \       #3
  --set ingressPublishService="ingress-apisix/apisix-gateway"              #4
  • #1:如果没有--devel 选项,Helm会安装最新的版本,这与Gateway的API兼容。
  • #2:无论如何,Gateway需要在集群之外被访问。
  • #3:神奇的事情发生在这里!
  • #4:我稍后再谈这个问题。

让我们检查一下一切是否正常。

外壳

k get all -n ingress-apisix

纯文本

pod/apisix-5fc9b45c69-cf42m                      1/1     Running   0          14m         #1
pod/apisix-etcd-0                                1/1     Running   0          14m         #2
pod/apisix-etcd-1                                1/1     Running   0          14m         #2
pod/apisix-etcd-2                                1/1     Running   0          14m         #2
pod/apisix-ingress-controller-6f8bd94d9d-wkzfn   1/1     Running   0          14m         #3

NAME                                TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)
service/apisix-admin                ClusterIP   10.96.69.19     <none>        9180/TCP
service/apisix-etcd                 ClusterIP   10.96.226.79    <none>        2379/TCP,2380/TCP
service/apisix-etcd-headless        ClusterIP   None            <none>        2379/TCP,2380/TCP
service/apisix-gateway              NodePort    10.96.101.224   <none>        80:30800/TCP#4
service/apisix-ingress-controller   ClusterIP   10.96.141.230   <none>        80/TCP
  • #1:Apache APISIX本身
  • #2:Apache APISIX将其配置存储在etcd 。图中默认安排了三个pod--这是处理分布式系统中故障的好做法。
  • #3:Apache APISIX控制器。Kubernetes控制器是一个控制循环,它将现有的状态向期望的状态移动。
  • #4:Apache APISIX网关服务。这是我们通过Helm Chart安装的NodePort``Service 。这也是我们在Helm Chart安装过程中引用的名字ingressPublishService 。在这一点上,基础设施已经准备好了。

声明网关的实现

正如我在上面提到的,API在规范和实现之间做了干净的分离。然而,我们需要以某种方式将其绑定。这就是GatewayClass 对象的责任。

YAML

apiVersion: gateway.networking.k8s.io/v1alpha2          #1
kind: GatewayClass                                      #2
metadata:
  name: apisix-gateway-class                            #3
spec:
  controllerName: apisix.apache.org/gateway-controller  #4
  • #1:我们故意不使用最新的版本,因为Apache APISIX使用这个版本。请注意,它将在(不久的)将来演变。
  • #2:GatewayClass 对象
  • #3: 随你怎么命名;但是,我们以后会用它来引用网关类。
  • #4:控制器的名字取决于实现。这里,我们使用的是Apache APISIX的。

请注意,GatewayClass 有一个集群范围。这种模式允许我们声明不同的Gateway API实现,并在同一集群内并行使用它们。

创建网关

使用Apache APISIX,这是很直接的。

YAML

apiVersion: gateway.networking.k8s.io/v1alpha2          #1
kind: Gateway                                           #2
metadata:
  name: apisix-gateway
spec:
  gatewayClassName: apisix-gateway-class                #3
  listeners:                                            #4
    - name: http
      protocol: HTTP
      port: 80
  • #1:与上述命名空间相同
  • #2:Gateway 对象
  • #3:引用前面声明的网关类
  • #4:在这一层允许一些限制,以便集群操作员可以避免不需要的使用

**警告。**网关API指定了在操作员端动态改变端口的选项。在写这篇文章的时候,Apache APISIX的端口分配是静态的。计划是在未来将其变成动态的。请订阅这个GitHub问题以关注进展。

路由,路由,到处都是路由

到目前为止,所有的东西都是基础设施;我们终于可以配置路由了。

我想要和上一篇文章中一样的路由;一个/left 分支和一个right 。为了简洁起见,我将跳过后者。

命名空间(YAML)

apiVersion: gateway.networking.k8s.io/v1alpha2          #1
kind: HTTPRoute                                         #2
metadata:
  name: left
spec:
  parentRefs:
    - name: apisix-gateway                              #3
  rules:
    - matches:                                          #4
      - path:                                           #4
          type: PathPrefix                              #4
          value: /left
      backendRefs:                                      #5
        - name: left                                    #5
          port: 80                                      #5
  1. 和上面一样的命名空间
  2. HTTPRoute 对象
  3. 引用上面创建的Gateway
  4. 规则匹配。在我们的案例中,我们是根据路径前缀来匹配的,但也有很多规则可用。你可以根据查询参数、头信息等进行匹配。
  5. 要转发的 "上游"。我们在之前的博文中定义了left``Service

检查它的工作

现在我们已经配置了我们的路由,我们可以检查它是否工作。

外壳

curl localhost:30800/left

当我们安装Helm图表时,我们告诉Apache APISIX在端口30800 ,创建一个NodePort 服务。因此,我们可以使用该端口来访问集群外的服务。

纯文本

left

总结

有很多方法可以从集群外访问pod。CNCF添加了其中的大部分,以改进之前的方案。

Gateway API是这方面的最新提议。该规范是一项进展中的工作,产品处于不同的实施阶段。由于这个原因,现在将你的生产建立在API上还为时过早。然而,你也许应该关注这个进展,因为它一定会比以前的方法有很大的改进。