暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

使用 Istio 解决 Kubernetes 中的 2 个常见部署难题

云原生CTO 2021-08-28
253

点击上方 云原生CTO,选择 设为星标

               优质文章,每日送达


「【只做懂你de云原生干货知识共享】」

使用 Istio 解决 Kubernetes 中的 2 个常见部署难题

如果您是一名使用容器的工程师,尤其是 Kubernetes 的工程师,您将会听说 Istio。对于新手来说简单讲,Istio是服务网格。而服务网格是一个网络层,允许您动态管理服务流量,并以安全且定义明确的方式进行。

充分利用 Istio 绝对超出了任何一篇博文的范围。但在这里,我将介绍它的一些特性,更重要的是,介绍一些可以利用它们来自动化解决一些现实世界问题的优雅解决方案的方法。

Istio 允许您使用一组自定义 Kubernetes 资源来管理网络流量,并可以帮助您保护和加密服务之间以及集群内外的网络流量。它与 Kubernetes API 的全面集成意味着您的 Istio 设置可以以与其余 Kubernetes 配置完全相同的方式进行定义和管理。

你决定使用它了吗?

如果你想开始使用 Istio,你应该先问问自己为什么。Istio 提供了一些非常有价值的功能,但是如果不增加一些复杂性,您就无法使用它们。它还需要合理的时间投资来获得必要的专业知识。也就是说,如果您的用例适合,您可以(并且应该)在您自己的集群中小心地逐步采用 Istio 的功能。

如果你正在从头开始构建一个新环境,并权衡利弊并决定继续使用 Istio,那么无论如何,从一开始就使用严格的相互 TLS 进行设置,拥抱它的力量,并且不要回望。这是如何做到这一点。

输入「containersol/k8s-deployment-strategies」

为了让这一切都有意义,我们需要在实际应用程序的上下文中考虑 Istio,但在没有快速免责声明的情况下这样做是不负责任的。如果您只需要在单个集群上管理少量服务,那么 Istio 可能会引入远远超出其价值的复杂性。

抛开这个警告,这里有一个小的单集群应用程序,它可能不值得使用 Istio——但有时用大锤敲击钉子很有趣,也很有教育意义。该应用程序非常简单:它提供一个网页,为您提供有关正在运行的 pod 的一些信息,并打印版本号,以便您知道正在为您提供服务的版本。

本文中的代码示例不会让您一路走好,但您需要的所有代码以及有关如何使用它的详细说明都可以在 GitLab 上找到。

「https://gitlab.com/ContainerSolutions/k8s-deployment-mtl/」

以下是您在云原生之旅中可能会遇到的两个常见问题,以及如何部署 Istio 来处理它们。

「https://twitter.com/unclebobmartin?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1135508568323629057%7Ctwgr%5E%7Ctwcon%5Es1_&ref_url=https%3A%2F%2Fblog.container-solutions.com%2Fsolving-2-common-deployment-dilemmas-in-istio」

问题 1:“我不相信我的测试”

如果您在测试覆盖率不完全的情况下对应用程序进行更改,您可能会快速移动,但也可能会破坏一些东西。

在理想的世界中,如果不确保每个代码路径都经过彻底测试,则永远不会将功能添加到软件项目中。但我们并不是生活在一个理想的世界里。截止日期已设定,功能得到优先考虑,并且测试不会被编写或更新。

解决方案:放慢你的推出(出) 那么我如何进行更改和部署新功能,同时确保(绝大多数)我的用户不受代码中任何不可预见的错误的影响?答案是通过首先将您的新版本部署到最少数量的用户来最小化这些小家伙的爆炸半径。

一旦您对更改按预期工作感到满意,您就可以慢慢增加新版本所服务的用户百分比。如果支持电话开始接踵而至,则很容易回滚您的更改,然后重试。

你能在没有 Istio 的情况下在 Kubernetes 上运行金丝雀部署吗?您当然可以,但是如果想要自动化该过程(并且您确实想要自动化该过程,对吗?),您将在 jq、Web 服务器代码和自定义自动化脚本方面发挥作用。这不是您应该添加到环境中的那种复杂性。

Istio 有一些非常优雅的流量分配解决方案,我们可以使用它们在正确的时间为正确的客户端提供正确的版本,而我们只需要担心调整一两个参数。

为了实现它,您需要设置一个入口网关、一个虚拟服务和一个目标规则。这将位于您通常的部署和服务之上,并为您处理流量分配。

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: http-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hos
ts:
    - "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: my-app
spec:
  hosts:
    - "*"
  gateways:
    - http-gateway
  http:
  - match:
    - uri:
        prefix: "/my-app"
    rewrite:
      uri: "/"
    route:
      - destination:
          host: my-app
          subset: v1
          port:
            number: 80
        weight: 90
      - destination:
          host: my-app
          subset: v2
          port:
            number: 80
        weight: 10
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: my-app
spec:
  host: my-app
  subsets:
  - name: v1
    labels:
      version: v1.0.0
  - name: v2
    labels:
      version: v2.0.0

从虚拟服务的权重字段可以看出,Istio 会根据指定的值在您的应用程序的两个版本之间分配流量。这些值必须加起来为 100%,否则 API 将拒绝应用该定义。

然后您(或者,理想情况下,您的持续集成/持续交付管道中的一个或多个手动步骤)将调整权重以将您的新版本推出给更多用户,直到所有请求都由新版本提供服务,并且以前的版本可以停产。

还可以将 Istio 集成到您的集成测试策略中,通过使用其故障注入功能来模拟实际流量的网络中断和性能下降。

如果在生产中进行测试的想法让您感到苦涩,那么您肯定做得还不够。例如,尝试将以下代码段添加到您的 VirtualService 规范中以增加一些混乱

spec:
  hosts:
  - my-app
  http:
  - fault:
      delay:
        fixedDelay: 7s
        percent: 100
   route:
    - destination:
        host: ratings
        subset: v2

问题 2:营销无法下定决心

通常有业务需要针对您的实际用户测试应用程序的多个版本。有时不清楚哪种营销策略会带来最好的转化率,或者哪种设计选择会导致最好的客户保留。

使用 vanilla Kubernetes,您可以在两个版本之间分配流量,但是从练习中获得任何有价值的见解将再次需要一大堆自定义代码来捕获相关信息并以非技术同事可以消化的方式对其进行处理。

解决方案:使用 Istio 进行实际 A/B 测试

Istio 的流量分配规则可以再次发挥作用,它与 Prometheus 和 Grafana 的紧密集成可以帮助您以引人注目且有意义的方式呈现 A/B 测试的结果。有几乎无限多种方法可以决定谁获取您的应用程序的哪个版本,通常基于传入数据包内容的某些部分。

在这个例子中,我们将使用 User-Agent 字段为不同的浏览器提供不同的版本。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: my-app
spec:
  hosts:
    - "*"
  gateways:
    - http-gateway
  http:
  - match:
    - headers:
        user-agent:
          regex: ".*Chrome.*"
      uri:
        prefix: "/my-app"
    rewrite:
      uri: "/"
    route:
      - destination:
          host: my-app
          subset: v1
          port:
            number: 80
  - match:
    - headers:
        user-agent:
          regex: ".*Mozilla.*"
      uri:
        prefix: "/my-app"
    rewrite:
      uri: "/"
    route:
      - destination:
          host: my-app
          subset: v2
          port:
            number: 80

从上面的代码可以看出,使用 Firefox 的人会得到应用程序的版本 1,而 Chrome 用户会得到版本 2。如果浏览器的 User-Agent 字段不包含“mozilla”或“chrome”,那么他们将都没有。

为了服务任何其他客户端,您需要添加一个默认路由——我将把它作为练习留给读者。

如果您不想安装不同的浏览器只是为了尝试一下,您可以使用带有标头标志的 curl 来伪装成您想要的任何浏览器。例如:

curl /my-app -H "User-Agent: Chrome"

通过更改用户代理的值,您可以从命令行测试所有不同的路由。

更多内容

这两个场景几乎没有触及您可以使用 Istio 做什么的表面,但希望它们让您体验了它的强大功能。如果没有 Istio,您仍然可以进行金丝雀部署和 A/B 测试,但是您必须自己实现流量分配,而这种东西无论如何都不属于您的应用程序代码。

我希望这能让你对 Istio 可以做的一些事情有一个很好的了解,并激励你自己尝试一下。如果您有兴趣了解更多信息,Istio 网站上有一些很棒的资源,将来不要忘记回来查看更多教程。

参考:

https://blog.container-solutions.com/solving-2-common-deployment-dilemmas-in-istio

                    

               更多好文推荐阅读

       Kubernetes 模式:InitContainers模式

          Kubernetes 日志监控工具

          kubernetes是如何工作的

      用于蓝/绿部署策略的 Kubectl 插件

         Kubernetes 监控:Kubeview

         kubernetes二次开发实战(阶段二)

                                                                                                                    嘿,你在看吗?


文章转载自云原生CTO,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论