1

在讲contour之前,我们先讲什么是ingress?

Ingress 公开了从集群外部到集群内 services 的 HTTP 和 HTTPS 路由。 流量路由由 Ingress 资源上定义的规则控制。

可以将 Ingress 配置为提供服务外部可访问的 URL、负载均衡流量、终止 SSL / TLS,以及提供基于名称的虚拟主机。

Ingress 不会公开任意端口或协议。 将 HTTP 和 HTTPS 以外的服务公开到 Internet 时,通常使用 Service.Type=NodePort 或者 Service.Type=LoadBalancer 类型的服务。

为了使Ingress资源正常工作,集群必须运行一个Ingress Controller。Ingress controller 通常负责通过负载均衡器来实现 Ingress,尽管它也可以配置边缘路由器或其他前端来帮助处理流量。

而今天我们讲到的contour就是一个基于envoy的ingress controller。

Contour

架构

Contour Ingress controller 主要有两部分组成:

  • Envoy,提供高性能的反向代理。
  • Contour,充当Envoy的管理服务器并为其提供配置。

尽管可以进行其他配置,但这些容器是分开部署的,contour 通过deployment形式部署,Envoy通过daemonset 形式部署。

在Envoy Pods中,Contour在引导模式下作为initcontainer运行,并将引导配置写入临时卷。该卷将传递到Envoy容器,并指示Envoy将Contour视为其管理服务器。

初始化完成后,Envoy容器启动,检索由Contour的引导模式编写的引导配置,并与Contour建立GRPC会话以接收配置。

如果管理服务器不可用,Envoy将正常重试,从而消除了任何容器启动订购问题。

Contour是Kubernetes API的客户端。 Contour监视Ingress,HTTPProxy,IngressRoute,Secret,Service和Endpoint对象,并通过将其对象的缓存转换为相关的JSON 来充当Envoy的管理服务器(Service objects for CDS, Ingress for RDS, Endpoint objects for SDS, and so on)。

从Kubernetes到Contour的信息传输是通过使用SharedInformer框架 Watch API来实现的。

对于Envoy,readiness probes 会检查Envoy是否已准​​备好接受连接。 将GET请求发送到Envoy管理端点中的/ready

对于Contour,liveness probes 会检查Pod的指标端口上运行的/healthz。 readiness probes 是对gRPC端口是否打开的TCP检查。

以下是Contour如何在Kubernetes集群中工作的几个高层架构图,并显示了到后端Pod的请求的数据路径。

projectcontour.io/blog的请求通过负载平衡器路由到Envoy代理的实例,然后将该请求发送到Pod。

特性

Contour 作为一款高性能的ingress 控制器,具备如下特性:

  • 动态更新负载均衡配置而无需drop 链接
  • 支持多租户k8s集群
  • 通过路由委托的方式支持跨命名空间的流量转发
  • 无需注解就可以灵活地定义服务的权重和负载均衡策略
  • TLS 证书委托(可以获取到其他命名空间的secret作为https 的证书,该功能对于证书的管理非常重要,实际场景中,我们可以把证书创建在管理命名空间中,其他空间通过委托来使用,减少了证书显露的风险)

那么contour 为什么要选择Envoy作为自己的数据层那?

  • 通过api的方式进行配置文件更新
  • 支持http2 和grpc
  • 在生产环境已经被证明

部署

在开始之前,您需要:

  • Kubernetes集群
  • 配置了对集群的管理员访问权限的kubectl
  • 必须在集群上启用RBAC

然后运行下面的命令,完成部署:

$ kubectl apply -f https://projectcontour.io/quickstart/contour.yaml

此命令创建:

  • 新的名称空间projectcontour
  • 名称空间中的两个Contour实例
  • 在集群的每个节点上运行的Envoy(Daemonset 方式部署)在主机端口80/443上侦听
  • 服务类型:LoadBalancer,它指向Contour的Envoy实例

示例

如果您尚未准备好与Contour一起运行的应用程序,则可以使用kuard

运行以下命令:

$ kubectl apply -f https://projectcontour.io/examples/kuard.yaml

本示例为所有主机指定默认后端,以便您可以测试Contour安装。不过,建议您仅将其用于探索和测试,因为它会响应所有请求,而与映射的传入DNS无关。

有很多方法可以验证一切正常。第一种方法是使用Envoy服务的外部地址,第二种方法是将端口转发到Envoy Pod。

一些最佳实践

我大量在生产环境使用到了Contour。有一些注意点,需要大家注意。

1:Envoy 通过daemonset 方式部署是否是最佳实践?

使用daemonset 方式部署的好处是可以保证每个node一点运行一个Envoy,首先满足了高可用,同时也减少了扩缩Envoy的心智负担。

但是如果你的k8s运行在公有云上,而你使用到了node 级别的扩缩。那么我们知道node在缩容的时候,并不会驱赶daemonset部署的pod。所以做到Envoy优雅退出比较难。

那么通过deployment方式部署,无需担心优雅退出。但是容量规划又是一个问题。可以尝试使用HPA来解决。另外可以设置POD的硬反亲和来实现一台主机只运行一个Envoy的目标。

2:接受流量的服务外部流量策略选择Local

主要为了高性能,可以避免流量的二跳。当然如果你的Pod网络是类似于ENI,负载均衡器的流量直接到POD,而不是nodeport ,那么可以忽视这点。

3:对于某些应用并发比较高,需要额外设置

Kubernetes服务映射到Envoy集群。 Envoy群集具有许多设置来控制特定行为。这些注释允许访问其中一些设置。

  • projectcontour.io/max-connections:单个Envoy实例允许与Kubernetes服务的最大连接数;默认为1024。
  • projectcontour.io/max-pending-requests:单个Envoy实例允许给Kubernetes服务的最大挂起请求数;默认为1024。
  • projectcontour.io/max-requests:单个Envoy实例向Kubernetes服务允许的最大并行请求;默认为1024。

当你的应用QPS比较高,必须设置一下这几个参数。

4:做好可观察性工作

主要是涉及到metrics和access log。

此处通过metrics 可以获取到应用的p99等延迟指标,但是该指标是一个sum,并不能获取到具体到某个POD。

那么我们可以通过对access log的分析,得到具体到Pod的延迟分析。


iyacontrol
1.4k 声望2.7k 粉丝

专注kubernetes,devops,aiops,service mesh。