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中模拟服务网络。这些资源--
GatewayClass、Gateway、HTTPRoute、TCPRoute、Service等--旨在通过表达式、可扩展和面向角色的接口来发展Kubernetes服务网络,这些接口由许多供应商实现,并得到了广泛的行业支持。
上述定义还提到了一个组织上的问题:不同的角色应该管理不同的对象集。
源于此。 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
- 和上面一样的命名空间
HTTPRoute对象- 引用上面创建的
Gateway - 规则匹配。在我们的案例中,我们是根据路径前缀来匹配的,但也有很多规则可用。你可以根据查询参数、头信息等进行匹配。
- 要转发的 "上游"。我们在之前的博文中定义了
left``Service。
检查它的工作
现在我们已经配置了我们的路由,我们可以检查它是否工作。
外壳
curl localhost:30800/left
当我们安装Helm图表时,我们告诉Apache APISIX在端口30800 ,创建一个NodePort 服务。因此,我们可以使用该端口来访问集群外的服务。
纯文本
left
总结
有很多方法可以从集群外访问pod。CNCF添加了其中的大部分,以改进之前的方案。
Gateway API是这方面的最新提议。该规范是一项进展中的工作,产品处于不同的实施阶段。由于这个原因,现在将你的生产建立在API上还为时过早。然而,你也许应该关注这个进展,因为它一定会比以前的方法有很大的改进。