内容简介:在 Kubernetes 中运行大规模以 Web 为中心的工作负载,最关键的需求之一就是在容器公司据
在 Kubernetes 中运行大规模以 Web 为中心的工作负载,最关键的需求之一就是在 L7
层实现高效流畅的入口流量管理。自从第一批 Kubernetes Ingress Controller
开发完成以来, Envoy
(由 Matt Klein 和 Lyft 团队开发)已经成为云原生生态系统中的新生力量。Envoy 之所以受到支持,因为它是一个 CNCF 托管的项目,与整个容器圈和云原生架构有着天然的支持。
容器公司 Heptio 开源的项目 Contour 使用 Envoy
作为 Kubernetes 的 Ingress Controller 实现,为大家提供了一条新的 Kubernetes 外部负载均衡实现思路。
据 官方博客 介绍, Heptio Contour
可以为用户提供以下好处:
Ingress
下面我们就来试用一下。
1. 安装步骤
首先克隆官方仓库,进入 manifest 清单目录:
$ git clone https://github.com/heptio/contour $ cd contour/deployment/deployment-grpc-v2
修改 Deployment
YAML 文件:
apiVersion: extensions/v1beta1 kind: Deployment metadata: labels: app: contour name: contour namespace: heptio-contour spec: selector: matchLabels: app: contour replicas: 1 template: metadata: labels: app: contour annotations: prometheus.io/scrape: "true" prometheus.io/port: "9001" prometheus.io/path: "/stats" prometheus.io/format: "prometheus" spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - "192.168.123.249" hostNetwork: true containers: - image: gcr.io/heptio-images/contour:master imagePullPolicy: Always name: contour command: ["contour"] args: - serve - --incluster - --envoy-http-port=80 - --envoy-https-port=443 - image: docker.io/envoyproxy/envoy-alpine:v1.7.0 name: envoy ports: - containerPort: 80 name: http - containerPort: 443 name: https command: ["envoy"] args: - --config-path /config/contour.yaml - --service-cluster cluster0 - --service-node node0 - --log-level info - --v2-config-only volumeMounts: - name: contour-config mountPath: /config initContainers: - image: gcr.io/heptio-images/contour:master imagePullPolicy: Always name: envoy-initconfig command: ["contour"] args: ["bootstrap", "/config/contour.yaml"] volumeMounts: - name: contour-config mountPath: /config volumes: - name: contour-config emptyDir: {} dnsPolicy: ClusterFirst serviceAccountName: contour terminationGracePeriodSeconds: 30
总共修改以下几处:
hostNetwork Listener
部署:
$ kubectl apply -f ./ namespace "heptio-contour" created serviceaccount "contour" created customresourcedefinition.apiextensions.k8s.io "ingressroutes.contour.heptio.com" created deployment.extensions "contour" created clusterrolebinding.rbac.authorization.k8s.io "contour" created clusterrole.rbac.authorization.k8s.io "contour" created service "contour" created
2. Ingress 测试
安装结束后,我们就可以来测试 Ingress 了。在 deployment
目录下包含一个示例应用,可以直接使用:
$ kubectl apply -f ../example-workload/kuard.yaml
查看创建好的资源:
$ kubectl get po,svc,ing -l app=kuard NAME READY STATUS RESTARTS AGE kuard-bcc7bf7df-6h55x 1/1 Running 0 4m kuard-bcc7bf7df-9sdnr 1/1 Running 0 4m kuard-bcc7bf7df-ws57j 1/1 Running 0 4m NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE svc/kuard 10.254.85.181 <none> 80/TCP 4m NAME HOSTS ADDRESS PORTS AGE ing/kuard * 192.168.123.249 80 4m
现在在浏览器中输入 Contour 运行节点的 IP 地址或 DNS 域名来访问示例应用程序了。
3. Contour 工作原理
Contour 同时支持 Ingress
资源对象和 IngressRoute
资源对象(通过 CRD 创建),这些对象都是为进入集群的请求提供路由规则的集合。这两个对象的结构和实现方式有所不同,但它们的核心意图是相同的,都是为进入集群的请求提供路由规则。如不作特殊说明,后面当我们描述 “Ingress” 时,它将同时适用于 Ingress
和 IngressRoute
对象。
通常情况下,当 Envoy 配置了 CDS
端点时,它会定期轮询端点,然后将返回的 JSON 片段合并到其运行配置中。如果返回到 Envoy 的集群配置代表当前的 Ingress 对象的集合,则可以将 Contour 视为从 Ingress
对象到 Envoy
集群配置的转换器。随着 Ingress 对象的添加和删除,Envoy 会动态添加并删除相关配置,而无需不断重新加载配置。
在实践中,将 Ingress 对象转换为 Envoy 配置更加微妙,需要将 Envoy 中的 xDS 配置(包括 CDS
, SDS
和 RDS
)映射到 Kubernetes 中。Contour 至少需要观察 Ingress
、 Service
和 Endpoint
这几个资源对象以构建这些服务的响应,它通过 client-go
的 cache/informer 机制免费获得这些 watchers
。这些机制提供添加,更新和删除对象的边缘触发通知,以及通过 watch API
执行查询对象的本地缓存的列表机制。
Contour 将收集到的这些对象处理为虚拟主机及其路由规则的 有向非循环图 (DAG),这表明 Contour 将有权构建路由规则的顶级视图,并将群集中的相应服务和TLS秘钥连接在一起。一旦构建了这个新的数据结构,我们就可以轻松实现 IngressRoute
对象的验证,授权和分发。改数据结构导出的 png
图片如下图所示:
Envoy API 调用和 Kubernetes API 资源之间的映射关系如下:
-
CDS : 集群发现服务。映射为 Kubernetes 中的
Service
以及一部分 Ingress 对象的TLS
配置。 -
SDS : 服务发现服务。映射为 Kubernetes 中的
Endpoint
。Envoy 使用 SDS 自动获取Cluster
成员,这与 Endpoint 对象中包含的信息非常匹配。Envoy 使用 Contour 在CDS
响应中返回的名称查询SDS
。 -
RDS : 路由发现服务。映射为 Kubernetes 中的
Ingress
。提供了虚拟主机名和前缀路由信息的 RDS 与 Ingress 匹配得更好。
4. 映射关系详情
CDS
CDS
更像是 Kubernetes 中的 Service
资源,因为 Service 是具体 Endpoint
(Pods)的抽象,Envoy Cluster 是指 Envoy 连接到的一组逻辑上相似的上游主机(参考下文的 RDS)。其中 TLS
配置也是 CDS 的一部分,而 Kubernetes 中的 TLS 信息由 Ingress 提供,所以这部分之间的映射关系会有些复杂。
SDS
SDS
更像是 Kubernetes 中的 Endpoint
资源,这部分映射关系的实现最简单。Contour 将 Endpoint 的响应对象转换为 SDS 的 { hosts: [] }
json 配置块。
RDS
RDS
更像是 Kubernetes 中的 Ingress
资源。RDS 将前缀,路径或正则表达式之一路由到 Envoy 群集。Envoy 集群的名称可以从 Ingress 的 IngressSpec
的配置项中获取(比如: namespace/serviceName_servicePort
),因为这是一个选择器,它会匹配 Service 对象被转换后返回的 CDS 对象。
5. Contour 架构分析
Contour Ingress controller 由两个组件组成:
Envoy Contour
这些容器以 Sidecar
的形式部署在同一个 Pod
中,当然也包括了一些其他的配置。
在 Pod 初始化期间,Contour 作为 Init
容器运行,并将引导程序配置写入一个 temporary volume。该 Volume
被传递给 Envoy 容器并告诉 Envoy 将其 Sidecar Contour 容器视为控制平面。
初始化完成后,Envoy 容器启动,检索 Contour 写入的引导程序配置,并开始轮询 Contour 以热更新配置。如果控制平面无法访问,Envoy 将会进行优雅重试。
Contour 相当于 Kubernetes API 的客户端。它监视 Ingress
, Service
和 Endpoint
对象,并通过将其对象缓存转换为相关的 JSON
字段来充当其 Envoy 的控制平面。
从 Kubernetes 到 Contour 的信息转换是通过 SharedInformer
框架 watching API 来完成的;而从 Contour 到 Envoy 的信息转换是通过 Envoy 定期轮询来实现的。
6. IngressRoute 介绍
Ingress 对象从 Kubernetes 1.1 版本开始被引进,用来描述进入集群的请求的 HTTP 路由规则。但迄今为止 Ingress 对象还停留在 beta
阶段,不同的 Ingress Controller 插件为了添加 HTTP 路由的额外属性,只能通过添加大量的 annotation
来实现,而且每个插件的 annotation 都不一样,非常混乱。
IngressRoute
CRD 的目标就是扩展 Ingress API 的功能,以便提供更丰富的用户体验以及解决原始设计中的缺点。
目前 Contour 是唯一支持 IngressRoute CRD 的 Kubernetes Ingress Controller。下面就来看看它与 Ingress 相比的优点:
annotation
从 Ingress 到 IngressRoute
一个基本的 Ingress
对象如下所示:
# ingress.yaml apiVersion: extensions/v1beta1 kind: Ingress metadata: name: basic spec: rules: - host: foo-basic.bar.com http: paths: - backend: serviceName: s1 servicePort: 80
这个 Ingress 对象名为 basic
,它将传入的 HTTP 流量路由到头文件中 Host:
字段值为 foo-basic.bar.com
且端口为 80 的 s1
服务。该路由规则通过 IngressRoute
来实现如下:
# ingressroute.yaml apiVersion: contour.heptio.com/v1beta1 kind: IngressRoute metadata: name: basic spec: virtualhost: fqdn: foo-basic.bar.com routes: - match: / services: - name: s1 port: 80
对应关系很简单,我就不再详细介绍了,更多功能配置可以参考官方仓库的文档: IngressRoute 。
可视化 Contour 的内部有向非循环图
Contour 使用 DAG 对其配置进行建模,可以通过以 DOT 格式输出 DAG 的调试端点对其进行可视化,当然需要先在系统中安装 graphviz
:
$ yum install -y graphviz
下载图表并将其另存为 PNG
:
# Port forward into the contour pod $ CONTOUR_POD=$(kubectl -n heptio-contour get pod -l app=contour -o jsonpath='{.items[0].metadata.name}') # Do the port forward to that pod $ kubectl -n heptio-contour port-forward $CONTOUR_POD 6060 # Download and store the DAG in png format $ curl localhost:6060/debug/dag | dot -T png > contour-dag.png
我自己保存的 PNG 图片如下所示:
7. 参考
- About Contour and Envoy
- Contour architecture
- Making it easy to use Envoy as a Kubernetes load balancer
以上所述就是小编给大家介绍的《初试 Kubernetes 集群中使用 Contour 反向代理》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- IntersectionObserve初试
- 初试 Helm 3
- Java 8 lambda初试
- 初试MongoDB数据库
- Podman 初试 - 容器发展史
- Nginx + Node + Vue 部署初试
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
The Information
James Gleick / Vintage / 2012-3-6 / USD 16.95
James Gleick, the author of the best sellers Chaos and Genius, now brings us a work just as astonishing and masterly: a revelatory chronicle and meditation that shows how information has become th......一起来看看 《The Information》 这本书的介绍吧!