前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Kubernetes中的Service Mesh(第5部分):Dogfood环境和入口

Kubernetes中的Service Mesh(第5部分):Dogfood环境和入口

作者头像
Techeek
发布2018-01-10 15:58:18
1.1K0
发布2018-01-10 15:58:18
举报
文章被收录于专栏:云计算云计算

A Service Mesh for Kubernetes (Part 5): Dogfood Environments and Ingress

原文作者:Alex Leong

原文地址:https://dzone.com/articles/a-service-mesh-for-kubernetes-part-v-dogfood-envir

译者微博:@从流域到海域

译者博客:blog.csdn.net/solo95

Kubernetes中的Service Mesh(第5部分):Dogfood环境和入口

在这篇文章中,我们将向您展示如何使用链接实例的服务网格来处理Kubernetes上的入口流量,将流量分布到网格中的每个实例。我们还将通过一个示例来演示linkerd的高级路由功能,方法是创建一个 dogfood 环境,将某些请求路由到较新版本的基础应用程序,例如用于内部的发布前测试。

(删掉了原文中的某些链接,因为会被云+的编辑器识别为非法链接,包含所有链接的译文可以在译者博客里查看)

这篇文章是关于使用linkerd作为流量到Kubernetes网络的入口点。从0.9.1版本开始,linkerd将直接支持Kubernetes Ingress资源,这是本文中一些用例的一个替代的,可能更简单的起点。有关如何使用linkerd作为Kubernetes入口控制器的信息,请参阅Sarah的博客文章Linkerd作为入口控制器

这是关于linkerd,Kubernetes和service mesh的一系列文章中的一篇文章。本系列的其他部分包括:

  1. Service重要指标
  2. 以DaemonSet方式运行linkerd
  3. 加密所有的东西
  4. 通过流量切换进行连续部署
  5. Dogfood环境,入口和边缘路由(本文)
  6. 轻松发布微服务
  7. 如何使分布式跟踪变得容易
  8. 使用Linkerd作为入口控制器
  9. gRPC乐趣和收益
  10. 服务网格API
  11. 出口
  12. 重试预算,截止日期传播,和如何让失败变得优雅(原文:Retry budgets, deadline propagation, and failing gracefully)
  13. 通过顶层指标(top-line metrics)实现自动缩放

在本系列的前几期中,我们向您展示了如何使用linkerd来捕获顶层指标(top-line metrics),透明地在服务调用中添加TLS,并执行bluegreen部署。这些帖子展示了如何在像Kubernetes这样的环境中使用linkerd作为srevice mesh,为内部服务对服务调用增加了一层弹性和性能。在这篇文章中,我们将把这个模型扩展到入口路由。

尽管本文中的示例是针对Kubernetes的,但我们不会使用 Kubernetes提供的内置 Ingress Resource(对此请参阅 Sarah的文章)。虽然Ingress Resource是一种基本路径和基于主机路由的简便方法,但在撰写本文时,它们仍相当有限。在下面的例子中,我们做的将远远超出Ingress Resources所提供的功能。

步骤1:部署Linkerd Service Mesh

从前面的文章中我们针对Kubernetes中的基本linkerd service mesh配置开始,我们将进行两个更改以支持入口(ingress):我们将修改linkerd配置以添加一个额外的逻辑路由器,然后调整围绕着linkerd展开的Kubernetes服务对象中的VIP。(完整的配置在这里: linkerd-ingress.yml。)

以下是linkerd实例上新的ingress逻辑路由器,它将处理入口流量并将其路由到相应的服务:

代码语言:bash
复制
routers:
- protocol: http
  label: ingress
  dtab: |
    /srv                    => /#/io.l5d.k8s/default/http ;
    /domain/world/hello/www => /srv/hello ;
    /domain/world/hello/api => /srv/api ;
    /host                   => /$/io.buoyant.http.domainToPathPfx/domain ;
    /svc                    => /host ;
  interpreter:
    kind: default
    transformers:
    - kind: io.l5d.k8s.daemonset
      namespace: default
      port: incoming
      service: l5d
  servers:
  - port: 4142
    ip: 0.0.0.0

在这个配置中,我们使用linkerd的路由语法,dtabs来将请求从一个域转发到另一个服务中去- 在这种情况下,从“api.hello.world”到api服务,从“www.hello.world”到 world 服务。为了简单起见,我们为每个域添加了一条规则,这些映射可以很容易地被聚合以实现更复杂的设置。(如果你是一个linkerd配置爱好者,我们将通过组合linkerd默认的header token identifier在主机header上实现路由转发, the domainToPathPfx namer 把虚主机名转换成分级路径,和并且io.l5d.k8s.daemonset transforme将请求发送到相应的主机 本地的linkerd上。)

我们已经将此入口路由器添加到每个linkerd实例 - 以真正的service mesh方式,我们将在这些实例之间完全分配入口流量,以便没有哪一个实例成为单点故障。

我们还需要修改我们的 k8s 服务对象,以便用端口80上的outgoing VIP去替换ingress VIP。这将允许我们将入口流量直接发送到linkerd service mesh - 主要用于调试目的,因为在点击linkerd之前,流量不会被消毒。(下一步,我们将解决这个问题。)

Kubernetes变化看起来像这样:

代码语言:bash
复制
---
apiVersion: v1
kind: Service
metadata:
  name: l5d
spec:
  selector:
    app: l5d
  type: LoadBalancer
  ports:
  - name: ingress
    port: 80
    targetPort: 4142
  - name: incoming
    port: 4141
  - name: admin
    port: 9990

以上所有操作都可以通过运行以下命令来完成:使用完整的带入口的linkerd service mesh配置

代码语言:bash
复制
$ kubectl apply -f https://raw.githubusercontent.com/linkerd/linkerd-examples/master/k8s-daemonset/k8s/linkerd-ingress.yml

第2步:部署服务

对于在这个例子中的服务,我们将使用相同的hello and world configs 从以前的博客文章,我们将添加两个新的服务:一个API service,这就要求既 hello服务 和 world服务,以及word服务的新版本: world-v2,这将返回“earth”而不是“world”这个词 - 正在逐渐壮大的hacker团队已经向我们证明了,他们的A/B测试显示这一变化将使参与度提高10倍。

以下命令将把三个Hello World服务部署到默认名称空间:

代码语言:bash
复制
$ kubectl apply -f https://raw.githubusercontent.com/linkerd/linkerd-examples/master/k8s-daemonset/k8s/hello-world.yml
代码语言:bash
复制
$ kubectl apply -f https://raw.githubusercontent.com/linkerd/linkerd-examples/master/k8s-daemonset/k8s/api.yml
代码语言:bash
复制
$ kubectl apply -f https://raw.githubusercontent.com/linkerd/linkerd-examples/master/k8s-daemonset/k8s/world-v2.yml

在这一点上,我们应该能够通过Kubernetes的ingressVIP 发送流量来测试设置 。在没有使用DNS的情况下,我们将在请求中手动设置一个主机头:

代码语言:bash
复制
$ INGRESS_LB=$(kubectl get svc l5d -o jsonpath="{.status.loadBalancer.ingress[0].*}")
$ curl -s -H "Host: www.hello.world" $INGRESS_LB
Hello (10.0.5.7) world (10.0.4.7)!!
$ curl -s -H "Host: api.hello.world" $INGRESS_LB
{"api_result":"api (10.0.3.6) Hello (10.0.5.4) world (10.0.1.5)!!"}

成功!我们已经将linkerd设置为入口控制器,并且我们已经使用它将不同域中收到的请求路由转发到不同的服务。正如你所看到的,生产流量正在实现 world-v1 服务 - 我们还没有准备好把 world-v2 展示出来。

第3步:NGINX中的一层

到了这一步,我们有正在运作的入口(ingress)。但是,我们目前还没有准备好生产。首先,我们的入口路由器不会从请求中去掉头文件,这意味着外部请求可能包含我们不想接受的头文件。例如,linkerd允许每个请求应用路由规则设置将其header设置为l5d-dtab 。这对于新服务的临时分级是一个非常有用的功能,但这可能不是来自外部世界的合适调用!

例如,我们可以使用 l5d-dtab 标题来覆盖使用的路由逻辑 world-v2 而不是world-v1 外部的生产 服务:

代码语言:bash
复制
$ curl -H "Host: www.hello.world" -H "l5d-dtab: /host/world => /srv/world-v2;" $INGRESS_LB
Hello (10.100.4.3) earth (10.100.5.5)!!

在响应中请注意 earth,表示这是world-v2 服务的结果 。这很酷,但这种权限我们绝对不想给任何人!

我们可以通过添加NGINX 来解决这个问题和其他问题(例如如何服务静态文件) 。如果我们配置NGINX在其代理的请求到链接入口路由之前剥离传入的报头,我们将得到两全其美的好处:一个能够安全处理外部流量的入口层,还有linkerd进行的动态的,基于服务的路由。

让我们把nginx添加到集群。我们将使用这个nginx.conf来配置它 。我们将使用我们的虚拟服务器下的 www.hello.worldapi.hello.worldproxy_pass指令发送请求到linkerd实例,为了最大程度地发挥作用,我们将使用Headers More提供的more_clear_input_headers 指令(使用通配符匹配)。

(还有另外的方法,我们可以通过使用nginx的proxy_set_header 指令来避免使用第三方的Nginx模块来清除报文头。我们会需要为每个单独的条目剥离 l5d-ctx- 报文头还有 l5d-dtabl5d-sample 报文头。)

请注意,从 linkerd 0.9.0开始,我们可以通过设置clearContext: true清除在入口路由器服务器传入的 l5d-*报文头。然而,nginx还有很多我们可以使用的功能(就像你现在看到的那样),所以把nginx和linkerd结合使用仍然是有价值的。

对于你们这些家工作的人,我们已经发布了一个nginx的Docker镜像,其中把安装了 Headers More模块的(Dockerfile)称为buoyantio / nginx:1.11.5。我们可以使用这个Kubernetes配置文件把上面提到的配置用这个镜像部署:

代码语言:bash
复制
$ kubectl apply -f https://raw.githubusercontent.com/linkerd/linkerd-examples/master/k8s-daemonset/k8s/nginx.yml

在等待外部IP出现之后,我们可以通过点击nginx.conf中的简单测试终端来测试NGINX:

代码语言:bash
复制
$ INGRESS_LB=$(kubectl get svc nginx -o jsonpath="{.status.loadBalancer.ingress[0].*}")
$ curl $INGRESS_LB
200 OK

我们现在应该能够通过NGINX向我们的服务发送流量:

代码语言:bash
复制
$ curl -s -H "Host: www.hello.world" $INGRESS_LB
Hello (10.0.5.7) world (10.0.4.7)!!
$ curl -s -H "Host: api.hello.world" $INGRESS_LB
{"api_result":"api (10.0.3.6) Hello (10.0.5.4) world (10.0.1.5)!!"}

最后,让我们测试一下我们的报文头技巧并尝试一下与 world-v2 服务进行直接通信。

代码语言:bash
复制
$ curl -H "Host: www.hello.world" -H "l5d-dtab: /host/world => /srv/world-v2;" $INGRESS_LB
Hello (10.196.1.8) world (10.196.2.13)!!

第四步:Dogfood的优势时间

好吧,我们已经做好了准备:让我们建立一个使用world-v2 服务的dogfood环境 ,但仅限于使用某些流量!

为了简单起见,我们为目标流量设置一个特定的cookie, 即special_employee_cookie。在实践中,你可能想要比这更复杂的东西 - 要验证它,需要来自公司内部网络范围的IP等等。

在NGINX和linkerd安装之后,完成这些将会变得很简单。我们将使用NGINX来检查特定cookie(指special_employee_cookie)的存在,并为linkerd设置一个dtab重载头来调整其路由方向。相关的NGINX配置如下所示:

代码语言:bash
复制
if ($cookie_special_employee_cookie ~* "dogfood") {
  set $xheader "/host/world => /srv/world-v2;";
}

proxy_set_header 'l5d-dtab' $xheader;

如果您一直在遵循上述步骤,那么已部署的NGINX已经包含了这个配置。我们可以像这样测试它:

代码语言:bash
复制
$ curl -H "Host: www.hello.world" --cookie "special_employee_cookie=dogfood" $INGRESS_LB
Hello (10.196.1.8) earth (10.196.2.13)!!

系统成功运作!当这个cookie被设置时,你将进入dogfood模式。没有它,你就会进入正常生产环境的流量模式。最重要的是,dogfood模式可以包含出现在服务堆栈中的任何地方的新版本的服务 ,甚至是多层深度的服务代码,其中包括服务代码forwards linkerd context headers,linkerd service mesh将负责其余的工作。

结论

在这篇文章中,我们看到了如何使用linkerd为Kubernetes集群提供强大灵活的入口(ingress)。我们已经演示了如何部署正如其名的已经准备完毕的生产环境配置,该生产环境配置使用linkerd进行服务路由转发。我们已经演示了如何使用linkerd的一些高级路由功能来将 traffic-serving 拓扑与 deployment拓扑分离,从而允许创建dogfood环境而不需要单独的集群或耗费很多的部署时间。

有关在Kubernetes中运行linkerd的更多信息,或者如果您在配置入口时遇到任何问题,请随时通过我们的Linkerd社区Slack来查找相关信息,发送邮件到我们的邮件列表或直接与我们联系。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • A Service Mesh for Kubernetes (Part 5): Dogfood Environments and Ingress
  • Kubernetes中的Service Mesh(第5部分):Dogfood环境和入口
  • 步骤1:部署Linkerd Service Mesh
  • 第2步:部署服务
  • 第3步:NGINX中的一层
  • 第四步:Dogfood的优势时间
  • 结论
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档