istio 配置生效流程及源码简介

fudali 发表了文章 • 0 个评论 • 35 次浏览 • 1 天前 • 来自相关话题

istio 配置生效流程及源码简介

使用Istio微服务框架,业务逻辑写在哪里?有规定用什么语言写吗?

Online 回复了问题 • 2 人关注 • 1 个回复 • 167 次浏览 • 3 天前 • 来自相关话题

微服务前方有雷,服务网格帮你趟过通信安全这个坑!

小数 发表了文章 • 0 个评论 • 127 次浏览 • 5 天前 • 来自相关话题

翻译:狄卫华 (博客地址 : https://blog.do1618.com)

作者:Christian Posta

原文:How a Service Mesh Can Help With Microservices Security

地址:http://blog.christianposta.com ... rity/




导读:

我看到很多客户转向微服务(他们是否应该是另外一个帖子的主题(注1)),他们试图通过这种方式解决一些组织化的规模问题。但是,转向微服务架构的细节往往会为旧问题带来一些新问题。


我与之交谈的大多数客户采用一种策略:架构上既有内部部署,也有公有云部署。将应用程序分解为更小的服务并拥有多个部署站点/平台会带来一些更大的挑战。在我看来,像 Istio 这样的服务网格实现旨在解决这些挑战中的一些问题。对于 Istio 和 Service Mesh ,我确实有很多话要说(注2),所以请随时关注@christianposta(注3) 参与并跟踪最新状态。



在微服务化的过程中你将面临的一个挑战是:安全


我知道,作为开发人员,你可能已经对安全非常憎恨——微服务使其更加糟糕。当我们将应用程序分解为更小的服务时,我们会增加被攻击的范围。虽然这有很多安全方面的问题(应用程序漏洞,平台漏洞,数据保护,传输/网络等),但在本文中我将主要集中在微服务如何相互通信以及其出现的一些问题上。


传统上,我们认为网络边界足以保护我们;我们的应用程序在传输安全方面的问题不必考虑太多,因为我们处于 ”受保护的内部网络“。停下来思考一下,你是否使用 SSL/TLS 保护你的内部应用程序?


我们以前通过单体程序本地调用的所有通信都将暴露在开放的网络中。首先我们要做的就是加密所有的内部流量。如果你在实施微服务上没有使用 TLS 进行传输加密,那么你正在将面临着令人讨厌的安全问题。


部分成熟的客户已经实现了所有微服务通信加密,这并没有带来显著成本提升。搭建公钥基础设施、签发密钥和证书、安装、轮换等都是非常大的考验。尝试配置正确的信任库/密钥库(Java)、合适的SSL算法、确保拥有正确的证书链等都是让人感到头痛的事情。我个人试图让其能够正常工作浪费了很多天 。然后当其都能正常工作以后,你就不会再想去折腾它。


我也看到了开发人员使用了 SSL/TLS,然后将其代码部署到 IST/UAT 等测试环境中,但是最终发现相关的安全配置在底层环境中不能够正常工作;由于着急将产品部署到生产环境中,他们会执行诸如禁用 TLS 验证的操作。


像 Istio 这样的服务网格相当简化了这一点。借助 Istio,应用程序的所有实例都有自己的 Sidecar 容器。该 Sidecar 充当所有流入和流出网络通信的服务代理。


在使用服务代理可以获得的诸多好处(注4),与此文讨论相关的好处是能够透明地进行 TLS 加密。这意味着位于与应用程序请求路径中的代理承担了加密流量的责任。你的应用程序可以完全不用关心证书,信任库,密钥库等问题。 Istio 自动将证书和密钥关联到服务,代理使用它们来加密流量(提供双向TLS),并且 Istio 定期轮换密钥/证书,以减少泄露的风险。


举例来说,当 Istio 运行在 Kubernetes 上时(注5),无论你何时部署应用程序,只需要指定一个应用程序运行的服务帐户,之后,Istio 负责处理其余部分。Istio 将为你的服务帐户创建证书/密钥对,使用根 CA密钥 对证书签名,并在将证书/密钥作为 Kubernets 中的密码。密码将被挂载到你的应用程序和 Istio 服务代理运行的 Pod 中,代理将使用证书/密钥来建立双向 TLS。


微服务的另一个安全问题是责任混淆问题(注6)。在这种情况下,终端用户已经授权服务代表它做某件事。在这种情况下,服务可能被授权执行此操作,但特定用户可能不会。我们应该以某种方式将用户身份绑定,并基于身份来评估授权。方法之一就是使用像 JWT (注7) 的令牌。


相关的有以下几点:


首先,如果你传递明文的 JWT 令牌(不使用TLS/mTLS),那么你会遇到比较大的麻烦。令牌默认不进行加密(仅签名),他们很容易地被收集并重放(replay)到服务中。再次,这是 Istio mTLS 可以提供帮助的地方。但即使启用了 mTLS,令牌也可能以被其他的方式泄露(我看到令牌被硬编码到源代码中!)。如果你的所有服务都将 JWT 传递给其他所有服务,那么您将再次面临重放攻击问题。


其次,如果你试图在所有微服务器上进行 JWT 验证,则会遇到与弹性库相同的问题(注8)。每个服务都有自己的库和自己的 JWT 验证实现。尽管像 JBoss Keycloak(注9) 这样的项目提供了出色的多语言支持,但它对库维护人员以及依赖这些库的应用程序开发人员来说都是一种负担。确保它们全部实施正确,一致并统一是一个充满了问题的壮举。


值得庆幸的是,Istio 可以在这两个方面提供帮助。

首先,无论应用程序框架/语言如何,Istio 都可以为你自动进行 JWT 验证。你可以定义一个`EndUserAuthenticationPolicySpec`,它配置了将用于验证的身份/凭证提供者(注10):


---  apiVersion: config.istio.io/v1alpha2  kind: EndUserAuthenticationPolicySpec  metadata:        name: cars-api-auth-policy       namespace: tutorial  spec:        jwts:            - issuer: http://keycloak:8080/auth/realms/istio               jwks_uri: http://keycloak.tutorial:8080/ ... certs               audiences:                - cars-web然后你可以将它绑定到特定的服务:---   apiVersion: config.istio.io/v1alpha2  kind: EndUserAuthenticationPolicySpecBinding  metadata:       name: cars-api-auth-policy-binding       namespace: tutorial spec:       policies:         - name: cars-api-auth-policy             namespace: tutorial    services:         - name: cars-api             namespace: tutorial
 
注意:这个例子来自我的同事 Kamesh Sampath(注11)。在这个配置中,我们已经建立了 `Keycloak` 成为 JWT 令牌的身份管理者和发行者(遵循OpenID Connect)。有关更多信息,请参阅此博客(注12)。当请求进入服务时,如果它没有 JWT 持票人令牌,它将被拒绝。这个配置将安装 EnvoyJWT 过滤器(注13),该过滤器负责验证 JWT 的签名:



最后,JWT 令牌是如何地传播?


Istio 默认只会将 JWT 令牌传播一次,使用 JWT 令牌的主体,并将其传递到应用程序通过单独的 header 字段。 JWT 主体将通过 header 头部中的 `sec-istio-auth-userinfo` 携带信息。基于终端用户的身份和服务的身份,应用程序有责任重新提交新的令牌。通过这种方式,我们可以将令牌的范围限定为单次使用,而不是将 JWT 到处传播。对此的实施仍在发展中,我强烈建议遵循这里 (注14) 和这里(注15)。


现在就是这样。随着 Istio 内部安全性的加强,我会进一步跟进。关注我@christianposta (注16) 获取微服务,服务网格,Istio 等最新信息。



注:

1:http://blog.christianposta.com ... ices/

2:http://blog.christianposta.com/

3:https://twitter.com/christianposta

4:https://istio.io/docs/concepts ... .html

5:https://istio.io/docs/setup/ku ... .html

6:https://en.wikipedia.org/wiki/ ... oblem

7:https://jwt.io/

8:http://blog.christianposta.com ... ices/

9:http://www.keycloak.org/

10:https://istio.io/docs/referenc ... ySpec

11:https://twitter.com/kamesh_sampath

12:http://blog.keycloak.org/2018/ ... .html

13:https://github.com/istio/proxy ... ME.md

14:https://docs.google.com/docume ... lmyhf

15:https://docs.google.com/docume ... lmyhf

16:https://twitter.com/christianposta


  查看全部
翻译:狄卫华 (博客地址 : https://blog.do1618.com

作者:Christian Posta

原文:How a Service Mesh Can Help With Microservices Security

地址:http://blog.christianposta.com ... rity/




导读:

我看到很多客户转向微服务(他们是否应该是另外一个帖子的主题(注1)),他们试图通过这种方式解决一些组织化的规模问题。但是,转向微服务架构的细节往往会为旧问题带来一些新问题。


我与之交谈的大多数客户采用一种策略:架构上既有内部部署,也有公有云部署。将应用程序分解为更小的服务并拥有多个部署站点/平台会带来一些更大的挑战。在我看来,像 Istio 这样的服务网格实现旨在解决这些挑战中的一些问题。对于 Istio 和 Service Mesh ,我确实有很多话要说(注2),所以请随时关注@christianposta(注3) 参与并跟踪最新状态。



在微服务化的过程中你将面临的一个挑战是:安全


我知道,作为开发人员,你可能已经对安全非常憎恨——微服务使其更加糟糕。当我们将应用程序分解为更小的服务时,我们会增加被攻击的范围。虽然这有很多安全方面的问题(应用程序漏洞,平台漏洞,数据保护,传输/网络等),但在本文中我将主要集中在微服务如何相互通信以及其出现的一些问题上。


传统上,我们认为网络边界足以保护我们;我们的应用程序在传输安全方面的问题不必考虑太多,因为我们处于 ”受保护的内部网络“。停下来思考一下,你是否使用 SSL/TLS 保护你的内部应用程序?


我们以前通过单体程序本地调用的所有通信都将暴露在开放的网络中。首先我们要做的就是加密所有的内部流量。如果你在实施微服务上没有使用 TLS 进行传输加密,那么你正在将面临着令人讨厌的安全问题。


部分成熟的客户已经实现了所有微服务通信加密,这并没有带来显著成本提升。搭建公钥基础设施、签发密钥和证书、安装、轮换等都是非常大的考验。尝试配置正确的信任库/密钥库(Java)、合适的SSL算法、确保拥有正确的证书链等都是让人感到头痛的事情。我个人试图让其能够正常工作浪费了很多天 。然后当其都能正常工作以后,你就不会再想去折腾它。


我也看到了开发人员使用了 SSL/TLS,然后将其代码部署到 IST/UAT 等测试环境中,但是最终发现相关的安全配置在底层环境中不能够正常工作;由于着急将产品部署到生产环境中,他们会执行诸如禁用 TLS 验证的操作。


像 Istio 这样的服务网格相当简化了这一点。借助 Istio,应用程序的所有实例都有自己的 Sidecar 容器。该 Sidecar 充当所有流入和流出网络通信的服务代理。


在使用服务代理可以获得的诸多好处(注4),与此文讨论相关的好处是能够透明地进行 TLS 加密。这意味着位于与应用程序请求路径中的代理承担了加密流量的责任。你的应用程序可以完全不用关心证书,信任库,密钥库等问题。 Istio 自动将证书和密钥关联到服务,代理使用它们来加密流量(提供双向TLS),并且 Istio 定期轮换密钥/证书,以减少泄露的风险。


举例来说,当 Istio 运行在 Kubernetes 上时(注5),无论你何时部署应用程序,只需要指定一个应用程序运行的服务帐户,之后,Istio 负责处理其余部分。Istio 将为你的服务帐户创建证书/密钥对,使用根 CA密钥 对证书签名,并在将证书/密钥作为 Kubernets 中的密码。密码将被挂载到你的应用程序和 Istio 服务代理运行的 Pod 中,代理将使用证书/密钥来建立双向 TLS。


微服务的另一个安全问题是责任混淆问题(注6)。在这种情况下,终端用户已经授权服务代表它做某件事。在这种情况下,服务可能被授权执行此操作,但特定用户可能不会。我们应该以某种方式将用户身份绑定,并基于身份来评估授权。方法之一就是使用像 JWT (注7) 的令牌。


相关的有以下几点:


首先,如果你传递明文的 JWT 令牌(不使用TLS/mTLS),那么你会遇到比较大的麻烦。令牌默认不进行加密(仅签名),他们很容易地被收集并重放(replay)到服务中。再次,这是 Istio mTLS 可以提供帮助的地方。但即使启用了 mTLS,令牌也可能以被其他的方式泄露(我看到令牌被硬编码到源代码中!)。如果你的所有服务都将 JWT 传递给其他所有服务,那么您将再次面临重放攻击问题。


其次,如果你试图在所有微服务器上进行 JWT 验证,则会遇到与弹性库相同的问题(注8)。每个服务都有自己的库和自己的 JWT 验证实现。尽管像 JBoss Keycloak(注9) 这样的项目提供了出色的多语言支持,但它对库维护人员以及依赖这些库的应用程序开发人员来说都是一种负担。确保它们全部实施正确,一致并统一是一个充满了问题的壮举。


值得庆幸的是,Istio 可以在这两个方面提供帮助。

首先,无论应用程序框架/语言如何,Istio 都可以为你自动进行 JWT 验证。你可以定义一个`EndUserAuthenticationPolicySpec`,它配置了将用于验证的身份/凭证提供者(注10):


---  apiVersion: config.istio.io/v1alpha2  kind: EndUserAuthenticationPolicySpec  metadata:        name: cars-api-auth-policy       namespace: tutorial  spec:        jwts:            - issuer: http://keycloak:8080/auth/realms/istio               jwks_uri: http://keycloak.tutorial:8080/ ... certs               audiences:                - cars-web然后你可以将它绑定到特定的服务:---   apiVersion: config.istio.io/v1alpha2  kind: EndUserAuthenticationPolicySpecBinding  metadata:       name: cars-api-auth-policy-binding       namespace: tutorial spec:       policies:         - name: cars-api-auth-policy             namespace: tutorial    services:         - name: cars-api             namespace: tutorial
 
注意:这个例子来自我的同事 Kamesh Sampath(注11)。在这个配置中,我们已经建立了 `Keycloak` 成为 JWT 令牌的身份管理者和发行者(遵循OpenID Connect)。有关更多信息,请参阅此博客(注12)。当请求进入服务时,如果它没有 JWT 持票人令牌,它将被拒绝。这个配置将安装 EnvoyJWT 过滤器(注13),该过滤器负责验证 JWT 的签名:



最后,JWT 令牌是如何地传播?


Istio 默认只会将 JWT 令牌传播一次,使用 JWT 令牌的主体,并将其传递到应用程序通过单独的 header 字段。 JWT 主体将通过 header 头部中的 `sec-istio-auth-userinfo` 携带信息。基于终端用户的身份和服务的身份,应用程序有责任重新提交新的令牌。通过这种方式,我们可以将令牌的范围限定为单次使用,而不是将 JWT 到处传播。对此的实施仍在发展中,我强烈建议遵循这里 (注14) 和这里(注15)。


现在就是这样。随着 Istio 内部安全性的加强,我会进一步跟进。关注我@christianposta (注16) 获取微服务,服务网格,Istio 等最新信息。



注:

1:http://blog.christianposta.com ... ices/

2:http://blog.christianposta.com/

3:https://twitter.com/christianposta

4:https://istio.io/docs/concepts ... .html

5:https://istio.io/docs/setup/ku ... .html

6:https://en.wikipedia.org/wiki/ ... oblem

7:https://jwt.io/

8:http://blog.christianposta.com ... ices/

9:http://www.keycloak.org/

10:https://istio.io/docs/referenc ... ySpec

11:https://twitter.com/kamesh_sampath

12:http://blog.keycloak.org/2018/ ... .html

13:https://github.com/istio/proxy ... ME.md

14:https://docs.google.com/docume ... lmyhf

15:https://docs.google.com/docume ... lmyhf

16:https://twitter.com/christianposta


 

示例说明 | 想要正确使用Istio?这份sidecar说明书必不可少

小数 发表了文章 • 0 个评论 • 441 次浏览 • 2018-04-03 10:49 • 来自相关话题

作者:宋净超(Jimmy Song),Kubernetes、Cloud Native布道者、开源爱好者,个人博客https://jimmysong.io



我们知道 Istio 通过向 Pod 中注入一个 sidecar 容器来将 Pod 纳入到 Istio service mesh 中的,那么这些 sidecar 容器的注入遵循什么样的规范,需要给每个 Pod 增加哪些配置信息才能纳入 Istio service mesh 中呢?这篇文章将给您答案。


本文同时归档到 kubernetes-handbook中(注1),更新请以handbook为准。



Pod Spec 中需满足的条件

为了成为 Service Mesh 中的一部分,kubernetes 集群中的每个 Pod 都必须满足如下条件,这些规范不是由 Istio 自动注入的,而需要 生成 kubernetes 应用部署的 YAML 文件时需要遵守的:
Service 关联:每个 pod 都必须只属于某一个 Kubernetes Service(注2) (当前不支持一个 pod 同时属于多个 service)。命名的端口:Service 的端口必须命名。端口的名字必须遵循如下格式 <protocol>[-<suffix>],可以是 http、http2、 grpc、 mongo、 或者 redis 作为 <protocol> ,这样才能使用 Istio 的路由功能。例如 name: http2-foo 和 name: http 都是有效的端口名称,而 name: http2foo 不是。如果端口的名称是不可识别的前缀或者未命名,那么该端口上的流量就会作为普通的 TCP 流量来处理(除非使用 Protocol: UDP 明确声明使用 UDP 端口)。带有 app label 的 Deployment:我们建议 kubernetes 的Deploymenet 资源的配置文件中为 Pod 明确指定 applabel。每个 Deployment 的配置中都需要有个与其他 Deployment 不同的含有意义的 app label。app label 用于在分布式追踪中添加上下文信息。Mesh 中的每个 pod 里都有一个 Sidecar:最后,Mesh 中的每个 pod 都必须运行与 Istio 兼容的 sidecar。以下部分介绍了将 sidecar 注入到 pod 中的两种方法:使用istioctl 命令行工具手动注入,或者使用 Istio Initializer 自动注入。注意 sidecar 不涉及到流量,因为它们与容器位于同一个 pod 中。



将普通应用添加到 Istio service mesh 中

Istio 官方的示例 Bookinfo(注3)中并没有讲解如何将服务集成 Istio,只给出了 YAML 配置文件,而其中需要注意哪些地方都没有说明,假如我们自己部署的服务如何使用 Istio 呢?现在我们有如下两个普通应用(代码在 GitHub 上),它们都不具备微服务的高级特性,比如限流和熔断等,通过将它们部署到 kubernetes 并使用 Istio 来管理:
k8s-app-monitor-test:用来暴露 json 格式的 metricsk8s-app-monitor-agent:访问上面那个应用暴露的 metrics 并生成监控图


这两个应用的 YAML 配置如下,其中包含了 Istio ingress 配置,并且符合 Istio 对 Pod 的 spec 配置所指定的规范。


k8s-app-monitor-istio-all-in-one.yaml文件


apiVersion: extensions/v1beta1kind: Deploymentmetadata:

  annotations:

    kompose.cmd: kompose convert -f docker-compose.yaml    kompose.version: 1.10.0 ()  creationTimestamp: null

  labels:

    app: k8s-app-monitor-agent  name: k8s-app-monitor-agentspec:

  replicas: 1

  template:

    metadata:

      creationTimestamp: null

      labels:

        app: k8s-app-monitor-agent    spec:

      containers:

      - env:

        - name: SERVICE_NAME          value: k8s-app-monitor-test        image: jimmysong/k8s-app-monitor-agent:749f547        name: monitor-agent        ports:

        - containerPort: 8888

      restartPolicy: Always---apiVersion: v1kind: Servicemetadata:

  annotations:

    kompose.cmd: kompose convert -f docker-compose.yaml    kompose.version: 1.10.0 ()  creationTimestamp: null

  labels:

    app: k8s-app-monitor-agent  name: k8s-app-monitor-agentspec:

  ports:

  - name: "http"

    port: 8888

    targetPort: 8888

  selector:

    app: k8s-app-monitor-agent---apiVersion: extensions/v1beta1kind: Deploymentmetadata:

  annotations:

    kompose.cmd: kompose convert -f docker-compose.yaml    kompose.version: 1.10.0 ()  creationTimestamp: null

  labels:

    app: k8s-app-monitor-test  name: k8s-app-monitor-testspec:

  replicas: 1

  template:

    metadata:

      creationTimestamp: null

      labels:

        app: k8s-app-monitor-test    spec:

      containers:

      - image: jimmysong/k8s-app-monitor-test:9c935dd        name: monitor-test        ports:

        - containerPort: 3000

      restartPolicy: Always---apiVersion: v1kind: Servicemetadata:

  annotations:

    kompose.cmd: kompose convert -f docker-compose.yaml    kompose.version: 1.10.0 ()  creationTimestamp: null

  labels:

    app: k8s-app-monitor-test  name: k8s-app-monitor-testspec:

  ports:

  - name: "http"

    port: 3000

    targetPort: 3000

  selector:

    app: k8s-app-monitor-test---## Istio ingressapiVersion: extensions/v1beta1kind: Ingressmetadata:

  name: k8s-app-monitor-agent-ingress  annotations:

    kubernetes.io/ingress.class: "istio"spec:

  rules:

  - http:

      paths:

      - path: /k8s-app-monitor-agent        backend:

          serviceName: k8s-app-monitor-agent          servicePort: 8888


其中有两点配置需要注意。


Deployment 和 Service 中的 label 名字必须包含 app,zipkin 中的 tracing 需要使用到这个标签才能追踪

Service 中的 ports 配置和必须包含一个名为 http 的 port,这样在 Istio ingress 中才能暴露该服务


注意:该 YAML 文件中 annotations 是因为我们一开始使用 docker-compose 部署在本地开发测试,后来再使用 kompose 将其转换为 kubernetes 可识别的 YAML 文件。

然后执行下面的命令就可以基于以上的 YAML 文件注入 sidecar 配置并部署到 kubernetes 集群中。


kubectl apply -n default -f <(istioctl kube-inject -f manifests/istio/k8s-app-monitor-istio-all-in-one.yaml)


如何在本地启动 kubernetes 集群进行测试可以参考 kubernetes-vagrant-centos-cluster 中的说明(注4)。



Sidecar 注入说明


手动注入需要修改控制器的配置文件,如 deployment。通过修改 deployment 文件中的 pod 模板规范可实现该deployment 下创建的所有 pod 都注入 sidecar。添加/更新/删除 sidecar 需要修改整个 deployment。


自动注入会在 pod 创建的时候注入 sidecar,无需更改控制器资源。Sidecar 可通过以下方式更新:


手动选择删除 pod

系统得进行 deployment 滚动更新


手动或者自动注入都使用同样的模板配置。自动注入会从 istio-system 命名空间下获取 istio-inject 的 ConfigMap。手动注入可以通过本地文件或者 Configmap 。



参考

Installing Istio Sidecar(注5)


注:

1、https://jimmysong.io/kubernetes-handbook/

2、https://kubernetes.io/docs/con ... vice/

3、https://istio.io/docs/guides/bookinfo.html

4、https://github.com/rootsongjc/ ... uster

5、https://istio.io/docs/setup/ku ... .html
  查看全部
作者:宋净超(Jimmy Song),Kubernetes、Cloud Native布道者、开源爱好者,个人博客https://jimmysong.io



我们知道 Istio 通过向 Pod 中注入一个 sidecar 容器来将 Pod 纳入到 Istio service mesh 中的,那么这些 sidecar 容器的注入遵循什么样的规范,需要给每个 Pod 增加哪些配置信息才能纳入 Istio service mesh 中呢?这篇文章将给您答案。


本文同时归档到 kubernetes-handbook中(注1),更新请以handbook为准。



Pod Spec 中需满足的条件

为了成为 Service Mesh 中的一部分,kubernetes 集群中的每个 Pod 都必须满足如下条件,这些规范不是由 Istio 自动注入的,而需要 生成 kubernetes 应用部署的 YAML 文件时需要遵守的:
  1. Service 关联:每个 pod 都必须只属于某一个 Kubernetes Service(注2) (当前不支持一个 pod 同时属于多个 service)。
  2. 命名的端口:Service 的端口必须命名。端口的名字必须遵循如下格式 <protocol>[-<suffix>],可以是 http、http2、 grpc、 mongo、 或者 redis 作为 <protocol> ,这样才能使用 Istio 的路由功能。例如 name: http2-foo 和 name: http 都是有效的端口名称,而 name: http2foo 不是。如果端口的名称是不可识别的前缀或者未命名,那么该端口上的流量就会作为普通的 TCP 流量来处理(除非使用 Protocol: UDP 明确声明使用 UDP 端口)。
  3. 带有 app label 的 Deployment:我们建议 kubernetes 的Deploymenet 资源的配置文件中为 Pod 明确指定 applabel。每个 Deployment 的配置中都需要有个与其他 Deployment 不同的含有意义的 app label。app label 用于在分布式追踪中添加上下文信息。
  4. Mesh 中的每个 pod 里都有一个 Sidecar:最后,Mesh 中的每个 pod 都必须运行与 Istio 兼容的 sidecar。以下部分介绍了将 sidecar 注入到 pod 中的两种方法:使用istioctl 命令行工具手动注入,或者使用 Istio Initializer 自动注入。注意 sidecar 不涉及到流量,因为它们与容器位于同一个 pod 中。




将普通应用添加到 Istio service mesh 中

Istio 官方的示例 Bookinfo(注3)中并没有讲解如何将服务集成 Istio,只给出了 YAML 配置文件,而其中需要注意哪些地方都没有说明,假如我们自己部署的服务如何使用 Istio 呢?现在我们有如下两个普通应用(代码在 GitHub 上),它们都不具备微服务的高级特性,比如限流和熔断等,通过将它们部署到 kubernetes 并使用 Istio 来管理:
  • k8s-app-monitor-test:用来暴露 json 格式的 metrics
  • k8s-app-monitor-agent:访问上面那个应用暴露的 metrics 并生成监控图



这两个应用的 YAML 配置如下,其中包含了 Istio ingress 配置,并且符合 Istio 对 Pod 的 spec 配置所指定的规范。


k8s-app-monitor-istio-all-in-one.yaml文件


apiVersion: extensions/v1beta1kind: Deploymentmetadata:

  annotations:

    kompose.cmd: kompose convert -f docker-compose.yaml    kompose.version: 1.10.0 ()  creationTimestamp: null

  labels:

    app: k8s-app-monitor-agent  name: k8s-app-monitor-agentspec:

  replicas: 1

  template:

    metadata:

      creationTimestamp: null

      labels:

        app: k8s-app-monitor-agent    spec:

      containers:

      - env:

        - name: SERVICE_NAME          value: k8s-app-monitor-test        image: jimmysong/k8s-app-monitor-agent:749f547        name: monitor-agent        ports:

        - containerPort: 8888

      restartPolicy: Always---apiVersion: v1kind: Servicemetadata:

  annotations:

    kompose.cmd: kompose convert -f docker-compose.yaml    kompose.version: 1.10.0 ()  creationTimestamp: null

  labels:

    app: k8s-app-monitor-agent  name: k8s-app-monitor-agentspec:

  ports:

  - name: "http"

    port: 8888

    targetPort: 8888

  selector:

    app: k8s-app-monitor-agent---apiVersion: extensions/v1beta1kind: Deploymentmetadata:

  annotations:

    kompose.cmd: kompose convert -f docker-compose.yaml    kompose.version: 1.10.0 ()  creationTimestamp: null

  labels:

    app: k8s-app-monitor-test  name: k8s-app-monitor-testspec:

  replicas: 1

  template:

    metadata:

      creationTimestamp: null

      labels:

        app: k8s-app-monitor-test    spec:

      containers:

      - image: jimmysong/k8s-app-monitor-test:9c935dd        name: monitor-test        ports:

        - containerPort: 3000

      restartPolicy: Always---apiVersion: v1kind: Servicemetadata:

  annotations:

    kompose.cmd: kompose convert -f docker-compose.yaml    kompose.version: 1.10.0 ()  creationTimestamp: null

  labels:

    app: k8s-app-monitor-test  name: k8s-app-monitor-testspec:

  ports:

  - name: "http"

    port: 3000

    targetPort: 3000

  selector:

    app: k8s-app-monitor-test---## Istio ingressapiVersion: extensions/v1beta1kind: Ingressmetadata:

  name: k8s-app-monitor-agent-ingress  annotations:

    kubernetes.io/ingress.class: "istio"spec:

  rules:

  - http:

      paths:

      - path: /k8s-app-monitor-agent        backend:

          serviceName: k8s-app-monitor-agent          servicePort: 8888


其中有两点配置需要注意。


Deployment 和 Service 中的 label 名字必须包含 app,zipkin 中的 tracing 需要使用到这个标签才能追踪

Service 中的 ports 配置和必须包含一个名为 http 的 port,这样在 Istio ingress 中才能暴露该服务


注意:该 YAML 文件中 annotations 是因为我们一开始使用 docker-compose 部署在本地开发测试,后来再使用 kompose 将其转换为 kubernetes 可识别的 YAML 文件。

然后执行下面的命令就可以基于以上的 YAML 文件注入 sidecar 配置并部署到 kubernetes 集群中。


kubectl apply -n default -f <(istioctl kube-inject -f manifests/istio/k8s-app-monitor-istio-all-in-one.yaml)


如何在本地启动 kubernetes 集群进行测试可以参考 kubernetes-vagrant-centos-cluster 中的说明(注4)。



Sidecar 注入说明


手动注入需要修改控制器的配置文件,如 deployment。通过修改 deployment 文件中的 pod 模板规范可实现该deployment 下创建的所有 pod 都注入 sidecar。添加/更新/删除 sidecar 需要修改整个 deployment。


自动注入会在 pod 创建的时候注入 sidecar,无需更改控制器资源。Sidecar 可通过以下方式更新:


手动选择删除 pod

系统得进行 deployment 滚动更新


手动或者自动注入都使用同样的模板配置。自动注入会从 istio-system 命名空间下获取 istio-inject 的 ConfigMap。手动注入可以通过本地文件或者 Configmap 。



参考

Installing Istio Sidecar(注5)


注:

1、https://jimmysong.io/kubernetes-handbook/

2、https://kubernetes.io/docs/con ... vice/

3、https://istio.io/docs/guides/bookinfo.html

4、https://github.com/rootsongjc/ ... uster

5、https://istio.io/docs/setup/ku ... .html
 

Istio服务网格高级流量镜像,7种模式解决流量镜像难题

小数 发表了文章 • 0 个评论 • 241 次浏览 • 2018-03-28 10:41 • 来自相关话题

作者:Christian Posta

翻译:吕德路 (https://github.com/lvdelu)

原文:Advanced Traffic-shadowing Patterns for Microservices With Istio Service Mesh



导言:


微服务可以加快系统开发速度和降低时间成本(注1)。然而,不能天真地认为只进行快速开发和变更就足够了(注2)。

如何在微服务中降低开发和变更的风险,Istio Service Mesh 提供了一种有助于降低将变更带入生产风险的方法,即将生产流量镜像到测试群集或软件的新版本中,并在我们引导实时流量之前针对问题进行测试。

这使我们能够将实际的用例和模糊的使用情况发送到我们的代码中,而我们在非生产模拟中的测试可能不会被捕获到。


在我以前的文章中,我写了关于 Istio Service Mesh 有一个非常棒的功能对流量进行镜像(注3)。对于 Istio 和 Service Mesh,我确实有很多话要说(注4),所以请随时关注@christianposta(注5)参与并保持查看最新的文章。

今天的主要课程是:



流量镜像的难题

当我们将生产流量镜像到测试集群、或生产中的灰度集群时,我们将会面临一些挑战。

首先,
如何在不影响生产服务关键路径的情况下获得生产集群的流量?
 
是否需要过滤掉这些请求中的个人信息?如何让测试集群不干扰实时协作者服务?如果服务对数据进行了更改,如何隔离这些更改而不影响生产服务?


这些都是真正的挑战,或许会被用作不尝试流量镜像的理由。但恕我直言,镜像代表了安全发布中更重要、更强大的技术之一,所以让我们看看有哪些模式来解决这些问题。如下所示:
 
在不影响生产关键路径的前提下将生产流量镜像到测试集群将流量定义为流量镜像镜像之后的实时服务流量与测试群集流量对比为某些测试配置文件提供协作服务合成事务虚拟化测试集群的数据库实现测试集群的数据库

让我们继续深入研究。



在不影响生产关键路径的前提下将生产流量镜像到测试集群

这可以说是最重要的部分。如果,在不影响生产流量的情况下,不能可靠地将流量镜像到测试群集,那么就应该停止。 不能为我们的“奇思妙想”牺牲生产的可靠性和可用性。 


通常我们会使用代理来镜像此流量。 Envoy Proxy(注6)是一个可用于此操作的代理。 Istio 是一种服务网格,它使用 Envoy 作为启用此功能的默认代理。有关更多信息,请参阅 Istio 镜像任务。


所以基本上,服务网格(Istio)已经位于我们生产流量的关键路径,以实现弹性,安全性,策略规划,路由控制等之间,并且还可以将流量镜像到我们的测试集群。 


事实上,这就是我在上一篇博客中深入探讨的内容(注7)。 重要的是来自生产中的流量通过带外数据被异步镜像。 任何响应都会被忽略。






对于熟悉所谓“企业集成模式”的读者(谢谢 Gregor Hohpe!),你会注意到这种“镜像”的东西实际上是一种 flavor 或 EIP(注8)。



将流量定义为流量镜像

另一个重要的考虑是识别我们已经镜像的流量。 我们需要能够辨别出用于测试目的的实时生产流量。 使用 Istio / Envoy 时,被镜像的的流量会自动用额外的上下文进行标记。


例如,当 Istio 镜像流量时,它会追加(注9)-shdow 到主机或者权限头中。 对于某些实现来说,目前这是一个问题,因-shadow将被添加到主机的末尾,所以 foobar:8080 的 Host 头将以这样的头部结尾:foobar:8080-shadow,这在技术上并非有效 HTTP 1.X。


在 Envoy 中使用此修复程序后(注10),-shadow 后缀将被添加到主机名,以便 foobar:8080 变成 foobar-shadow:8080。









镜像之后的实时服务流量与测试群集流量对比

一旦依赖流量镜像就可以做一些有趣的事情,也许我们希望通过进入测试集群的流量和我们从生产实时看到的期望行为进行对比。

例如,我们可能希望将预期的请求结果或API合同中任何偏离的请求结果与向前和向后兼容性进行比较。我们可以插入一个负责这种类型的流量协调的代理,以及一个可以进行有趣比较的代理。Twitter Diffy(注11)是这些代理中的一个,它已经在 Twitter 应用到了生产(注12),并且其它地方也将会这么做。它基本上需要镜像流量(感谢 Istio 和 Envoy,我们已经做到了这一点),并调用实时服务和新服务并比较结果。它能够检测结果中的 “noise” 并忽略它(时间戳,单调增加计数器等),通过首先调用两个实时服务实例来检测 “noise",然后忽略那些用于测试服务调用的部分。






Diffy 还有一个非常棒的网页/仪表板,用于查看调用结果,它们的差异以及基于特定特征的过滤。 最后,Diffy 有一个很好的管理控制台,用于查看关于调用比较的指标和统计数据。







我在这里有一个演示(注13),非常感谢 Prashant Khanduri,Puneet Khanduri 和 Alex Soto。 在我制作过程中,留意观看此演示视频。



为某些测试配置文件提供协作服务

当我们部署一个新版本的服务并将流量镜像到测试集群时,我们需要注意对其他环境的影响。我们的服务通常需要与其他服务协作(查询数据,更新数据等)。如果与其他服务的协作仅仅是读取或 GET 请求,并且这些协作者能够承担额外的负载,这可能不成问题。但是,如果我们的服务在我们的协作者中改变了数据,我们需要确保这些调用指向测试流量而不是真正的生产流量。你可以为你的部署创建不同的安装配置,从而注入这些配置。


例如,我们注入了 test.prod.com,而不是 live.prod.com 作为下游服务。如果在 Kubernetes上部署,则可以使用不同的 maps(注14)配置来控制此功能。


另一个有趣的方法是使用诸如 Hoverfly(注15)或 Microcks(注16)之类的东西部署虚拟化测试流量。使用这些服务虚拟化工具,你可以策划预期的请求/响应对,并将值发生变化的流量导向这些返回预期响应的代理。








合成事务


在很多情况下,我们服务的新版本需要改变其本地数据存储中的数据。它可能会向协作者服务发出调用来改变数据,但也许我们不能(或不应该)使用先前的技术(服务虚拟化)来存储这些调用。


另一种方法是更明确地通过调用(比如在我们之前添加的镜像模式中我们添加了-shadow)来表明这些请求应该再一个“合成事务”结果中,即,这些不是真正的事务,并且再它们在请求结束时应该采取任何补偿来撤消他们。我们可以为我们的请求添加一个头文件,或者甚至可以使其成为请求主体的一部分,以表明某个事务是“合成的”。当我们这样做时,我们正在指示参与服务正常处理请求,包括所有数据操作,然后在提交之前回滚事务。请注意,这适用于事务性数据存储,但可能不适用于其他数据存储。在这些情况下,如果你已经有工作单元的概念,则可以将合成语义附加到该语义上。否则,最好不要试图通过合成事务来隔离和放弃更改。  








这种方法对于执行全路径请求很有用,包括数据存储,获得更好的时序保真度和双测试方法可能捕捉不到的数据干扰/不匹配问题。


这种方法的一大缺点是它按惯例实施,难以执行。 它可能与你拥有和控制的服务一起工作,但可能无法扩展到许多参与协作的合作者。 你不愿意试图在所有服务中强制执行这个约定,并且有一个单独的服务不能正确地实现这个回滚功能,然后把所有的东西混淆起来。 在严格控制和协调部署中使用此模式。



虚拟化测试集群的数据库


在针对镜像流量进行测试时,我们已经开始涉及与处理数据相关的问题。通常,如果你的测试集群使用数据存储,并且测试服务以某种形式更新/插入/变更数据,则需要隔离这些更改。当用信头或嵌入式标志等信号发送时,我们只是简单地回滚任何更改,但这并不总是个办法。


在镜像流量时处理数据问题的另一种方法是为测试群集使用可替代的数据存储。你可以使用一个空的数据存储并使用测试数据填充它,并针对该数据运行镜像流量。但是,如果你使用的是像 Diffy(上面提到的)之类的东西,则可能会在响应比较中收到大量误报,因为测试群集中的数据正在使用测试数据,而实时服务正在使用生产数据。处理这个问题的一个好方法就是虚拟化数据层。我们让测试集群使用一个与生产数据存储相同数据的数据存储。






当我们这样做时,我们可以获得生产数据的当前一致视图,也可以在不影响生产数据存储的情况下写入数据存储。 我们可以使用像 JBoss Teiid(注17)这样的工具轻松完成此操作。 Teiid 为所有类型的数据存储系统提供连接器,包括 RDBMS,No-SQL 系统,平面文件,hadoop,salesforce 等,并且可以为我们的测试集群虚拟化它们。 当你这样做时,任何时候变更的数据可以一次性写入数据库而服务无感知。 我有一系列博客讨论了这篇关于微服务迁移的博客文章(注18)。


实现测试集群的数据库

最后,另一种扩展先前数据虚拟化技术的方法是完全实现数据存储。这样,我们测试集群的数据存储基本上与生产集群的数据存储相同,并且通过流处理不断更新。工作方式是使用(CDC - 更改数据捕获)(注19)从生产数据库捕获更改,然后将这些更改发送到新数据库。一些数据存储允许将其作为内置的复制机制(想想 MySQL 的从节点或者其他),但很多时候这些是只读的。你可以使用像Debezium(注20)这样的更改数据捕获工具来构建简单的 CDC 系统,以便你的测试数据存储具有完全复制的生产数据库副本并且不受约束的使用它。 


Debezium 为不同的数据存储提供连接器(注21),并从这些数据库中获取更改事件(即读取事务日志)并将这些更改传送到 Apache Kafka(注22)。从那里,你可以使用任何流处理工具将这些流实现到你的测试数据库中。 FWIW,上面提到的 Teiid(注23)很快就会有这个功能。






此外,如果你已经拥有数据流管道,使用事件驱动架构或使用某种事件源数据机制,那么这个“实现”测试数据库将成为更好的选择。




总结

在实践中,将生产流量镜像到我们的测试群集(无论该群集是存在于生产环境还是非生产环境中)是降低新部署风险的非常有效的方法。 


多年来,推特和亚马逊这样的大型 webops 公司一直在这样做。 这种方法带来了一些挑战,但是上述模式中讨论的方法存在有效的解决方案。 


如果你认为我错过了某些东西,或者觉得有一个我没有涉及到的令人讨厌的问题,请与我联系,我会很乐意与你讨论并将其添加到此博客的更新中。 谢谢!





1、https://www.slideshare.net/cep ... -2017

2、 https://www.cnet.com/news/zuck ... more/

3、http://blog.christianposta.com ... ease/

4、http://blog.christianposta.com/

5、https://twitter.com/christianposta

6、https://www.envoyproxy.io/docs ... olicy

7、http://blog.christianposta.com ... ease/

8、http://www.enterpriseintegrati ... .html

9、https://www.envoyproxy.io/docs ... olicy

10、https://github.com/envoyproxy/envoy/pull/2600

11、https://github.com/twitter/diffy

12、https://blog.twitter.com/engin ... .html

13、https://github.com/christian-p ... me.md

14、https://kubernetes.io/docs/tas ... gmap/

15、https://hoverfly.io/

16、 http://microcks.github.io/

17、http://teiid.jboss.org/

18、 http://blog.christianposta.com ... -iii/

19、https://en.wikipedia.org/wiki/Change_data_capture

20、http://debezium.io/

21、http://debezium.io/docs/

22、http://kafka.apache.org/

23、http://teiid.jboss.org/ 



社区活动:

3月31日(周六),数人云联合ServiceComb社区,并由ServiceMesh社区支持,开启meetup系列活动 Building Microservice 第2期 北京站 :微服务,从架构到发布,已经开始报名啦,扫码报名!
 





  查看全部
作者:Christian Posta

翻译:吕德路 (https://github.com/lvdelu)

原文:Advanced Traffic-shadowing Patterns for Microservices With Istio Service Mesh



导言:


微服务可以加快系统开发速度和降低时间成本(注1)。然而,不能天真地认为只进行快速开发和变更就足够了(注2)。

如何在微服务中降低开发和变更的风险,Istio Service Mesh 提供了一种有助于降低将变更带入生产风险的方法,即将生产流量镜像到测试群集或软件的新版本中,并在我们引导实时流量之前针对问题进行测试。

这使我们能够将实际的用例和模糊的使用情况发送到我们的代码中,而我们在非生产模拟中的测试可能不会被捕获到。


在我以前的文章中,我写了关于 Istio Service Mesh 有一个非常棒的功能对流量进行镜像(注3)。对于 Istio 和 Service Mesh,我确实有很多话要说(注4),所以请随时关注@christianposta(注5)参与并保持查看最新的文章。

今天的主要课程是:



流量镜像的难题

当我们将生产流量镜像到测试集群、或生产中的灰度集群时,我们将会面临一些挑战。

首先,
  • 如何在不影响生产服务关键路径的情况下获得生产集群的流量?

 
  • 是否需要过滤掉这些请求中的个人信息?
  • 如何让测试集群不干扰实时协作者服务?
  • 如果服务对数据进行了更改,如何隔离这些更改而不影响生产服务?



这些都是真正的挑战,或许会被用作不尝试流量镜像的理由。但恕我直言,镜像代表了安全发布中更重要、更强大的技术之一,所以让我们看看有哪些模式来解决这些问题。如下所示:
 
  • 在不影响生产关键路径的前提下将生产流量镜像到测试集群
  • 将流量定义为流量镜像
  • 镜像之后的实时服务流量与测试群集流量对比
  • 为某些测试配置文件提供协作服务
  • 合成事务
  • 虚拟化测试集群的数据库
  • 实现测试集群的数据库


让我们继续深入研究。



在不影响生产关键路径的前提下将生产流量镜像到测试集群

这可以说是最重要的部分。如果,在不影响生产流量的情况下,不能可靠地将流量镜像到测试群集,那么就应该停止。 不能为我们的“奇思妙想”牺牲生产的可靠性和可用性。 


通常我们会使用代理来镜像此流量。 Envoy Proxy(注6)是一个可用于此操作的代理。 Istio 是一种服务网格,它使用 Envoy 作为启用此功能的默认代理。有关更多信息,请参阅 Istio 镜像任务。


所以基本上,服务网格(Istio)已经位于我们生产流量的关键路径,以实现弹性,安全性,策略规划,路由控制等之间,并且还可以将流量镜像到我们的测试集群。 


事实上,这就是我在上一篇博客中深入探讨的内容(注7)。 重要的是来自生产中的流量通过带外数据被异步镜像。 任何响应都会被忽略。

1.png


对于熟悉所谓“企业集成模式”的读者(谢谢 Gregor Hohpe!),你会注意到这种“镜像”的东西实际上是一种 flavor 或 EIP(注8)。



将流量定义为流量镜像

另一个重要的考虑是识别我们已经镜像的流量。 我们需要能够辨别出用于测试目的的实时生产流量。 使用 Istio / Envoy 时,被镜像的的流量会自动用额外的上下文进行标记。


例如,当 Istio 镜像流量时,它会追加(注9)-shdow 到主机或者权限头中。 对于某些实现来说,目前这是一个问题,因-shadow将被添加到主机的末尾,所以 foobar:8080 的 Host 头将以这样的头部结尾:foobar:8080-shadow,这在技术上并非有效 HTTP 1.X。


在 Envoy 中使用此修复程序后(注10),-shadow 后缀将被添加到主机名,以便 foobar:8080 变成 foobar-shadow:8080。


2.png




镜像之后的实时服务流量与测试群集流量对比

一旦依赖流量镜像就可以做一些有趣的事情,也许我们希望通过进入测试集群的流量和我们从生产实时看到的期望行为进行对比。

例如,我们可能希望将预期的请求结果或API合同中任何偏离的请求结果与向前和向后兼容性进行比较。我们可以插入一个负责这种类型的流量协调的代理,以及一个可以进行有趣比较的代理。Twitter Diffy(注11)是这些代理中的一个,它已经在 Twitter 应用到了生产(注12),并且其它地方也将会这么做。它基本上需要镜像流量(感谢 Istio 和 Envoy,我们已经做到了这一点),并调用实时服务和新服务并比较结果。它能够检测结果中的 “noise” 并忽略它(时间戳,单调增加计数器等),通过首先调用两个实时服务实例来检测 “noise",然后忽略那些用于测试服务调用的部分。

3.png


Diffy 还有一个非常棒的网页/仪表板,用于查看调用结果,它们的差异以及基于特定特征的过滤。 最后,Diffy 有一个很好的管理控制台,用于查看关于调用比较的指标和统计数据。

4.png



我在这里有一个演示(注13),非常感谢 Prashant Khanduri,Puneet Khanduri 和 Alex Soto。 在我制作过程中,留意观看此演示视频。



为某些测试配置文件提供协作服务

当我们部署一个新版本的服务并将流量镜像到测试集群时,我们需要注意对其他环境的影响。我们的服务通常需要与其他服务协作(查询数据,更新数据等)。如果与其他服务的协作仅仅是读取或 GET 请求,并且这些协作者能够承担额外的负载,这可能不成问题。但是,如果我们的服务在我们的协作者中改变了数据,我们需要确保这些调用指向测试流量而不是真正的生产流量。你可以为你的部署创建不同的安装配置,从而注入这些配置。


例如,我们注入了 test.prod.com,而不是 live.prod.com 作为下游服务。如果在 Kubernetes上部署,则可以使用不同的 maps(注14)配置来控制此功能。


另一个有趣的方法是使用诸如 Hoverfly(注15)或 Microcks(注16)之类的东西部署虚拟化测试流量。使用这些服务虚拟化工具,你可以策划预期的请求/响应对,并将值发生变化的流量导向这些返回预期响应的代理。

5.png




合成事务


在很多情况下,我们服务的新版本需要改变其本地数据存储中的数据。它可能会向协作者服务发出调用来改变数据,但也许我们不能(或不应该)使用先前的技术(服务虚拟化)来存储这些调用。


另一种方法是更明确地通过调用(比如在我们之前添加的镜像模式中我们添加了-shadow)来表明这些请求应该再一个“合成事务”结果中,即,这些不是真正的事务,并且再它们在请求结束时应该采取任何补偿来撤消他们。我们可以为我们的请求添加一个头文件,或者甚至可以使其成为请求主体的一部分,以表明某个事务是“合成的”。当我们这样做时,我们正在指示参与服务正常处理请求,包括所有数据操作,然后在提交之前回滚事务。请注意,这适用于事务性数据存储,但可能不适用于其他数据存储。在这些情况下,如果你已经有工作单元的概念,则可以将合成语义附加到该语义上。否则,最好不要试图通过合成事务来隔离和放弃更改。  


6.png



这种方法对于执行全路径请求很有用,包括数据存储,获得更好的时序保真度和双测试方法可能捕捉不到的数据干扰/不匹配问题。


这种方法的一大缺点是它按惯例实施,难以执行。 它可能与你拥有和控制的服务一起工作,但可能无法扩展到许多参与协作的合作者。 你不愿意试图在所有服务中强制执行这个约定,并且有一个单独的服务不能正确地实现这个回滚功能,然后把所有的东西混淆起来。 在严格控制和协调部署中使用此模式。



虚拟化测试集群的数据库


在针对镜像流量进行测试时,我们已经开始涉及与处理数据相关的问题。通常,如果你的测试集群使用数据存储,并且测试服务以某种形式更新/插入/变更数据,则需要隔离这些更改。当用信头或嵌入式标志等信号发送时,我们只是简单地回滚任何更改,但这并不总是个办法。


在镜像流量时处理数据问题的另一种方法是为测试群集使用可替代的数据存储。你可以使用一个空的数据存储并使用测试数据填充它,并针对该数据运行镜像流量。但是,如果你使用的是像 Diffy(上面提到的)之类的东西,则可能会在响应比较中收到大量误报,因为测试群集中的数据正在使用测试数据,而实时服务正在使用生产数据。处理这个问题的一个好方法就是虚拟化数据层。我们让测试集群使用一个与生产数据存储相同数据的数据存储。

7.png


当我们这样做时,我们可以获得生产数据的当前一致视图,也可以在不影响生产数据存储的情况下写入数据存储。 我们可以使用像 JBoss Teiid(注17)这样的工具轻松完成此操作。 Teiid 为所有类型的数据存储系统提供连接器,包括 RDBMS,No-SQL 系统,平面文件,hadoop,salesforce 等,并且可以为我们的测试集群虚拟化它们。 当你这样做时,任何时候变更的数据可以一次性写入数据库而服务无感知。 我有一系列博客讨论了这篇关于微服务迁移的博客文章(注18)。


实现测试集群的数据库

最后,另一种扩展先前数据虚拟化技术的方法是完全实现数据存储。这样,我们测试集群的数据存储基本上与生产集群的数据存储相同,并且通过流处理不断更新。工作方式是使用(CDC - 更改数据捕获)(注19)从生产数据库捕获更改,然后将这些更改发送到新数据库。一些数据存储允许将其作为内置的复制机制(想想 MySQL 的从节点或者其他),但很多时候这些是只读的。你可以使用像Debezium(注20)这样的更改数据捕获工具来构建简单的 CDC 系统,以便你的测试数据存储具有完全复制的生产数据库副本并且不受约束的使用它。 


Debezium 为不同的数据存储提供连接器(注21),并从这些数据库中获取更改事件(即读取事务日志)并将这些更改传送到 Apache Kafka(注22)。从那里,你可以使用任何流处理工具将这些流实现到你的测试数据库中。 FWIW,上面提到的 Teiid(注23)很快就会有这个功能。

8.png


此外,如果你已经拥有数据流管道,使用事件驱动架构或使用某种事件源数据机制,那么这个“实现”测试数据库将成为更好的选择。




总结

在实践中,将生产流量镜像到我们的测试群集(无论该群集是存在于生产环境还是非生产环境中)是降低新部署风险的非常有效的方法。 


多年来,推特和亚马逊这样的大型 webops 公司一直在这样做。 这种方法带来了一些挑战,但是上述模式中讨论的方法存在有效的解决方案。 


如果你认为我错过了某些东西,或者觉得有一个我没有涉及到的令人讨厌的问题,请与我联系,我会很乐意与你讨论并将其添加到此博客的更新中。 谢谢!





1、https://www.slideshare.net/cep ... -2017

2、 https://www.cnet.com/news/zuck ... more/

3、http://blog.christianposta.com ... ease/

4、http://blog.christianposta.com/

5、https://twitter.com/christianposta

6、https://www.envoyproxy.io/docs ... olicy

7、http://blog.christianposta.com ... ease/

8、http://www.enterpriseintegrati ... .html

9、https://www.envoyproxy.io/docs ... olicy

10、https://github.com/envoyproxy/envoy/pull/2600

11、https://github.com/twitter/diffy

12、https://blog.twitter.com/engin ... .html

13、https://github.com/christian-p ... me.md

14、https://kubernetes.io/docs/tas ... gmap/

15、https://hoverfly.io/

16、 http://microcks.github.io/

17、http://teiid.jboss.org/

18、 http://blog.christianposta.com ... -iii/

19、https://en.wikipedia.org/wiki/Change_data_capture

20、http://debezium.io/

21、http://debezium.io/docs/

22、http://kafka.apache.org/

23、http://teiid.jboss.org/ 



社区活动:

3月31日(周六),数人云联合ServiceComb社区,并由ServiceMesh社区支持,开启meetup系列活动 Building Microservice 第2期 北京站 :微服务,从架构到发布,已经开始报名啦,扫码报名!
 

promote.png

 

使用Istio简化微服务系列三:如何才能做“金丝雀部署”,并通过Istio增加流量?

小数 发表了文章 • 0 个评论 • 281 次浏览 • 2018-03-27 10:10 • 来自相关话题

作者:Nithin Mallya

原文:Simplifying Microservices with Istio in Google Kubernetes Engine — Part III


我写的关于 Istio 的文章是 Istio 网站上文档的一部分。请阅读官方文档以了解更多信息。


在本系列的第一部分中(使用Istio简化微服务系列一:如何用Isito解决Spring Cloud Netflix部署微服务的挑战?),我们看到了如何使用 Istio 来简化我们的微服务之间的沟通。


在本系列的第二部分中(使用Istio简化微服务系列二:如何通过HTTPS与外部服务进行通信?),我们学会了使用 Istio egress rules 来控制服务网格之外的服务的访问。

在这一部分中,我们将看到如何才能做“金丝雀部署”(Canary Deployments),并通过 Istio 增加流量。


背景:

在过去的文章中,我详细解释了我们如何使用 Kubernetes 进行蓝/绿部署。这是一种部署技术,在此技术中,我们部署了与应用程序当前版本和新版本相同的生产环境。这项技术使我们能够执行零停机时间部署(Zero Downtime Deployments, 简称:ZDD),以确保我们的用户在切换到新版本时不受影响。有了这两个版本(当前版本和新版本)也使我们能够在新版本出现任何问题时进行回滚。


我们还需要的是能够将流量增加(或下降)到我们的应用程序的新版本,并监控它以确保没有负面影响。实现这一点的一种方法是使用“金丝雀部署”或“金丝雀”发行版。


一个不太有趣的事实:当矿工们带着金丝雀进入矿场时,任何有毒气体都会首先杀死金丝雀,并以此警告矿工们离开矿井。


同样地,在应用程序部署世界中,使用“金丝雀部署”,我们可以将应用程序的新版本部署到生产中,并只向这个新部署发送一小部分流量。这个新版本将与当前版本并行运行,并在我们将所有流量切换到新版本之前提醒我们注意任何问题。


例如:我们应用程序的 v1 可以占到90%的流量,而 v2 可以得到另外的10%。如果一切看起来都很好,我们可以将 v2 流量增加到25%,50%,最终达到100%。Istio Canary 部署的另一个优势是,我们可以根据请求中的自定义标头来增加流量。例如,在我们的应用程序的v2中设置了一个特定 cookie 头值的流量的10%。


注意:虽然“金丝雀部署”“可以”与 A/B 测试一起使用,以查看用户如何从业务度量的角度对新版本做出反应,但其背后的真正动机是确保应用程序从功能角度上满意地执行。此外,企业所有者可能希望在更长的时间内(例如:许多天甚至几周)进行 A/B 测试,而不是金丝雀码头可能采取的措施。因此,把它们分开是明智的。


Let's see it in action

从第一部分我们知道,我们的 PetService 与 PetDetailsService(v1) 和 PetMedicalHistoryService(v1) 进行了会谈。对 PetService的调用的输出如下:

$ curl http://108.59.82.93/pet/123

{
  "petDetails": {
    "petName": "Maximus",
    "petAge": 5,
    "petOwner": "Nithin Mallya",
    "petBreed": "Dog"
  },
  "petMedicalHistory": {
    "vaccinationList": [
      "Bordetella, Leptospirosis, Rabies, Lyme Disease"
    ]
  }
}

在上面的回复中,你会注意到 petBreed 说“狗”。然而,Maximus 是德国牧羊犬,这时候我们需要修改 PetDetailsService,以便正确返回品种。


因此,我们创建了 PetDetailsService 的 v2,它将返回“德国牧羊犬”。但是,我们希望确保在将所有流量驱动到 v2 之前,我们可以使用一小部分用户来测试这个服务的 v2。


在下面的图1中,我们看到流量被配置成这样,50%的请求将被定向到 v1 和50%到 v2,我们的 “金丝雀部署”。(它可以是任意数字,取决于变化的大小,并尽量减少负面影响)。







      图1:我们可以将 PetDetailsServic e的 v2 部署为金丝雀部署和匝道流量。


步骤

1、创建 PetDetails Service 的 v2 版本并像以前一样部署它。 (请参阅 petdetailservice / kube 文件夹下的 petinfo.yaml)

$ kubectl get pods

NAME                                         READY     STATUS    RESTARTS      AGE

petdetailsservice-v1-2831216563-qnl10        2/2        Running      0          19h

petdetailsservice-v2-2943472296-nhdxt       2/2       Running       0           2h

petmedicalhistoryservice-v1-28468096-hd7ld   2/2       Running      0          19h

petservice-v1-1652684438-3l112               2/2       Running      0      19h




2、创建一个RouteRule,将流量分成 petdetailsservice 的50%(v1)和50%(v2),如下所示:

cat <<EOF | istioctl create -f -
apiVersion: config.istio.io/v1alpha2
kind: RouteRule
metadata:
  name: petdetailsservice-default
spec:
  destination:
    name: petdetailsservice
  route:
  - labels:
      version: v1
    weight: 50
  - labels:
      version: v2
    weight: 50
EOF

$ istioctl get routerule

NAME    KIND     NAMESPACE

petdetailsservice-default RouteRule.v1alpha2.config.istio.io default




3、现在,如果你访问 PetService,你应该看到替代请求分别返回“Dog”和“German Shepherd Dog”,如下所示:

$ curl http://108.59.82.93/pet/123

{
  "petDetails": {
    "petName": "Maximus",
    "petAge": 5,
    "petOwner": "Nithin Mallya",
    "petBreed": "Dog"
  },
  "petMedicalHistory": {
    "vaccinationList": [
      "Bordetella, Leptospirosis, Rabies, Lyme Disease"
    ]
  }
}

$ curl http://108.59.82.93/pet/123

{
  "petDetails": {
    "petName": "Maximus",
    "petAge": 5,
    "petOwner": "Nithin Mallya",
    "petBreed": "German Shepherd Dog"
  },
  "petMedicalHistory": {
    "vaccinationList": [
      "Bordetella, Leptospirosis, Rabies, Lyme Disease"
    ]
  }
}



It works!

这引出了一个问题:我们不能用 Kubernetes Canary Deployments 来做到这一点吗?简短的答案是肯定的。


然而,这样做的步骤更复杂,也有局限性:

你仍然需要创建 PetDetailsService  (v1和v2)的两个部署,但是你需要手动限制在部署过程中 v2 副本的数量,以维护 v1:v2 比。例如:你可以使用10个副本部署 v1,并将v2 部署到2个副本,以获得10:2的负载平衡,等等。


由于所有的 pod 无论版本是否相同,Kubernetes 集群中的流量负载平衡仍然受到随机性的影响。


基于业务量的自动伸缩 pods 也是有问题的,因为我们需要单独的 autoscale 的2个部署,它可以根据每个服务的流量负载分配来做出不同的行为。


如果我们想根据某些标准(如 request headers)仅允许某些用户使用/限制流量,则Kubernetes Canary Deployments可能无法实现此目标。


结论:你刚刚看到了创建一个“金丝雀部署”和增加 Istio 的流量是多么容易。马克西姆斯也很高兴!(小数:下图就是马克西姆斯...嗯...很帅气!)








资源:

1、Part I of this article series: https://medium.com/google-clou ... 922b8

2、Part II of this article series: https://medium.com/google-clou ... 33089

3、The Istio home page https://istio.io/

4、DevOxx Istio presentation by Ray Tsang: https://www.youtube.com/watch% ... D231s

5、Github link to this example: https://github.com/nmallya/istiodemo

6、All things Kubernetes: https://kubernetes.io/


ServiceMesh微信交流群:

添加微信xiaoshu062,备注:服务网格,即可加入Service Mesh微信交流群。


社区活动:

3月31日(周六),数人云联合ServiceComb社区,并由ServiceMesh社区支持,开启meetup系列活动 Building Microservice 第2期 北京站 :微服务,从架构到发布,已经开始报名啦,扫码报名!
 





 
  查看全部
作者:Nithin Mallya

原文:Simplifying Microservices with Istio in Google Kubernetes Engine — Part III


我写的关于 Istio 的文章是 Istio 网站上文档的一部分。请阅读官方文档以了解更多信息。


在本系列的第一部分中(使用Istio简化微服务系列一:如何用Isito解决Spring Cloud Netflix部署微服务的挑战?),我们看到了如何使用 Istio 来简化我们的微服务之间的沟通。


在本系列的第二部分中(使用Istio简化微服务系列二:如何通过HTTPS与外部服务进行通信?),我们学会了使用 Istio egress rules 来控制服务网格之外的服务的访问。

在这一部分中,我们将看到如何才能做“金丝雀部署”(Canary Deployments),并通过 Istio 增加流量。


背景:

在过去的文章中,我详细解释了我们如何使用 Kubernetes 进行蓝/绿部署。这是一种部署技术,在此技术中,我们部署了与应用程序当前版本和新版本相同的生产环境。这项技术使我们能够执行零停机时间部署(Zero Downtime Deployments, 简称:ZDD),以确保我们的用户在切换到新版本时不受影响。有了这两个版本(当前版本和新版本)也使我们能够在新版本出现任何问题时进行回滚。


我们还需要的是能够将流量增加(或下降)到我们的应用程序的新版本,并监控它以确保没有负面影响。实现这一点的一种方法是使用“金丝雀部署”或“金丝雀”发行版。


一个不太有趣的事实:当矿工们带着金丝雀进入矿场时,任何有毒气体都会首先杀死金丝雀,并以此警告矿工们离开矿井。


同样地,在应用程序部署世界中,使用“金丝雀部署”,我们可以将应用程序的新版本部署到生产中,并只向这个新部署发送一小部分流量。这个新版本将与当前版本并行运行,并在我们将所有流量切换到新版本之前提醒我们注意任何问题。


例如:我们应用程序的 v1 可以占到90%的流量,而 v2 可以得到另外的10%。如果一切看起来都很好,我们可以将 v2 流量增加到25%,50%,最终达到100%。Istio Canary 部署的另一个优势是,我们可以根据请求中的自定义标头来增加流量。例如,在我们的应用程序的v2中设置了一个特定 cookie 头值的流量的10%。


注意:虽然“金丝雀部署”“可以”与 A/B 测试一起使用,以查看用户如何从业务度量的角度对新版本做出反应,但其背后的真正动机是确保应用程序从功能角度上满意地执行。此外,企业所有者可能希望在更长的时间内(例如:许多天甚至几周)进行 A/B 测试,而不是金丝雀码头可能采取的措施。因此,把它们分开是明智的。


Let's see it in action

从第一部分我们知道,我们的 PetService 与 PetDetailsService(v1) 和 PetMedicalHistoryService(v1) 进行了会谈。对 PetService的调用的输出如下:

$ curl http://108.59.82.93/pet/123

{
  "petDetails": {
    "petName": "Maximus",
    "petAge": 5,
    "petOwner": "Nithin Mallya",
    "petBreed": "Dog"
  },
  "petMedicalHistory": {
    "vaccinationList": [
      "Bordetella, Leptospirosis, Rabies, Lyme Disease"
    ]
  }
}

在上面的回复中,你会注意到 petBreed 说“狗”。然而,Maximus 是德国牧羊犬,这时候我们需要修改 PetDetailsService,以便正确返回品种。


因此,我们创建了 PetDetailsService 的 v2,它将返回“德国牧羊犬”。但是,我们希望确保在将所有流量驱动到 v2 之前,我们可以使用一小部分用户来测试这个服务的 v2。


在下面的图1中,我们看到流量被配置成这样,50%的请求将被定向到 v1 和50%到 v2,我们的 “金丝雀部署”。(它可以是任意数字,取决于变化的大小,并尽量减少负面影响)。


微信图片_20180327100820.jpg


      图1:我们可以将 PetDetailsServic e的 v2 部署为金丝雀部署和匝道流量。


步骤

1、创建 PetDetails Service 的 v2 版本并像以前一样部署它。 (请参阅 petdetailservice / kube 文件夹下的 petinfo.yaml)

$ kubectl get pods

NAME                                         READY     STATUS    RESTARTS      AGE

petdetailsservice-v1-2831216563-qnl10        2/2        Running      0          19h

petdetailsservice-v2-2943472296-nhdxt       2/2       Running       0           2h

petmedicalhistoryservice-v1-28468096-hd7ld   2/2       Running      0          19h

petservice-v1-1652684438-3l112               2/2       Running      0      19h




2、创建一个RouteRule,将流量分成 petdetailsservice 的50%(v1)和50%(v2),如下所示:

cat <<EOF | istioctl create -f -
apiVersion: config.istio.io/v1alpha2
kind: RouteRule
metadata:
  name: petdetailsservice-default
spec:
  destination:
    name: petdetailsservice
  route:
  - labels:
      version: v1
    weight: 50
  - labels:
      version: v2
    weight: 50
EOF

$ istioctl get routerule

NAME    KIND     NAMESPACE

petdetailsservice-default RouteRule.v1alpha2.config.istio.io default




3、现在,如果你访问 PetService,你应该看到替代请求分别返回“Dog”和“German Shepherd Dog”,如下所示:

$ curl http://108.59.82.93/pet/123

{
  "petDetails": {
    "petName": "Maximus",
    "petAge": 5,
    "petOwner": "Nithin Mallya",
    "petBreed": "Dog"
  },
  "petMedicalHistory": {
    "vaccinationList": [
      "Bordetella, Leptospirosis, Rabies, Lyme Disease"
    ]
  }
}

$ curl http://108.59.82.93/pet/123

{
  "petDetails": {
    "petName": "Maximus",
    "petAge": 5,
    "petOwner": "Nithin Mallya",
    "petBreed": "German Shepherd Dog"
  },
  "petMedicalHistory": {
    "vaccinationList": [
      "Bordetella, Leptospirosis, Rabies, Lyme Disease"
    ]
  }
}



It works!

这引出了一个问题:我们不能用 Kubernetes Canary Deployments 来做到这一点吗?简短的答案是肯定的。


然而,这样做的步骤更复杂,也有局限性:

你仍然需要创建 PetDetailsService  (v1和v2)的两个部署,但是你需要手动限制在部署过程中 v2 副本的数量,以维护 v1:v2 比。例如:你可以使用10个副本部署 v1,并将v2 部署到2个副本,以获得10:2的负载平衡,等等。


由于所有的 pod 无论版本是否相同,Kubernetes 集群中的流量负载平衡仍然受到随机性的影响。


基于业务量的自动伸缩 pods 也是有问题的,因为我们需要单独的 autoscale 的2个部署,它可以根据每个服务的流量负载分配来做出不同的行为。


如果我们想根据某些标准(如 request headers)仅允许某些用户使用/限制流量,则Kubernetes Canary Deployments可能无法实现此目标。


结论:你刚刚看到了创建一个“金丝雀部署”和增加 Istio 的流量是多么容易。马克西姆斯也很高兴!(小数:下图就是马克西姆斯...嗯...很帅气!)


1_6uuUOOk5AVyeQ8QTkMFrrg.jpeg



资源:

1、Part I of this article series: https://medium.com/google-clou ... 922b8

2、Part II of this article series: https://medium.com/google-clou ... 33089

3、The Istio home page https://istio.io/

4、DevOxx Istio presentation by Ray Tsang: https://www.youtube.com/watch% ... D231s

5、Github link to this example: https://github.com/nmallya/istiodemo

6、All things Kubernetes: https://kubernetes.io/


ServiceMesh微信交流群:

添加微信xiaoshu062,备注:服务网格,即可加入Service Mesh微信交流群。



社区活动:

3月31日(周六),数人云联合ServiceComb社区,并由ServiceMesh社区支持,开启meetup系列活动 Building Microservice 第2期 北京站 :微服务,从架构到发布,已经开始报名啦,扫码报名!
 

promote.png

 
 

下发规则到集群istio是通过是什么方式保障事务的一致性的?

chym 回复了问题 • 2 人关注 • 2 个回复 • 177 次浏览 • 2018-03-25 17:26 • 来自相关话题

为什么我们需要Istio?四大组件助力Istio突围!

小数 发表了文章 • 0 个评论 • 477 次浏览 • 2018-03-21 10:29 • 来自相关话题

作者:Grace@grapesfrog

翻译:宋净超(Jimmy Song)

     Kubernetes、Cloud Native布道者、开源爱好者,个人博客https://jimmysong.io

原文:Istio why do I need it?



我最近没有多少时间去玩 K8S,并且我承认在 Istio 到底给 K8S 带来了什么这个问题上我有点迷失了。这是否会增加更多的运营开销?它是否简化了我们通常需要做的事情?这些问题都浮现在我的脑海里。

我怀疑在发布了这些内容之后,我团队中比我更懂 K8S 的人可能会想找我谈谈,估计我会跟团队中的成员辩论,但那将是我最喜欢的对话。


那么 Istio 究竟是什么?

Istio 网站(注1)上说:

Istio 带给你:
 
HTTP、gRPC、WebSocket 和 TCP 流量的自动负载均衡。通过丰富的路由规则、重试、故障转移和故障注入对流量行为进行细粒度控制。支持访问控制、速率限制和配额的可拔插策略层和配置 API。自动指标、日志和集群内所有流量的跟踪,包括集群入口和出口。通过集群中的服务之间的强身份断言来实现服务间的身份验证。


通过在整个环境中部署一个特殊的 sidecar 代理(辅助容器),你可以将 Istio 支持添加到服务中(这给我留下了深刻的印象,如果你想做到这一点,请参阅后面的内容)。安装了 sidecar 代理之后,(微)服务之间的所有网络通信都通过这个代理。此外,所有的网络通信都是使用 Istio 的控制平面功能进行配置和管理的。


Istio 是 Service Mesh(服务网格)。我认为的 service mesh 定义就是“它是一个专用的基础设施层,使得服务间的通信安全、高效和可靠”。


然而,如果像我一样,你从概念文档(注2)开始看的话,上面有这样的内容:“术语 service mesh 通常用于描述组成这些应用程序的微服务网络以及它们之间的交互。随着服务网格的大小和复杂程度不断增加,可能会变得难以理解和管理。可能出现包括服务发现、负载平衡、故障恢复、度量和监控,以及更复杂的需求,如A/B测试、金丝雀发布、速率限制、访问控制和端到端身份验证。Istio 提供了一个完整的解决方案,通过对整个服务网格提供行为分析和操作控制来满足微服务应用程序的各种需求。“


读完之后你可能会像我一样困惑!最后在网上查了一圈关于什么是服务网格之后,我终于搞明白了。我最后使用的可能是一个在所有搜索到的样本里一个非代表性的共识,但这是一个合理的选择。不过有个细节确实了,就是如何将它与 K8S 等编排工具分开。Istio 需要跟 K8S一起使用,没有 K8S 或其他容器编排工具的它就不存在了吗?它没有做编排,实际上它的是为解决管理基于微服务的解决方案中网络和操作复杂性而设计的。它涵盖的范围就像K8S一样!现在我真的需要继续这个帖子了。

所以我知道 Istio 是什么,给我们带来了什么,但它实际上解决了什么挑战呢?


从为什么使用 Istio 页面中(注3)可以看出,它在服务网络中统一提供了许多关键功能:


流量管理
 
可观察性强制策略服务身份标识和安全


对于我来说,要真正理解 Istio 的价值,所以我使用了 codelab(注四)。编写 code lab 的人真是太棒了!


Code lab 向我介绍了 Istio 控制平面的四个主要组件:
 
Pilot:处理代理 sidecar 的配置和编程。Mixer:为你的流量处理决策并收集遥测数据。Ingress:处理来自群集外部的传入请求。CA:证书颁发机构。


查看 Istio 架构概念(注5)页面了解这些组件如何协同工作的。

Code lab提供了路由规则(注6)——流量管理部分

我还尝试了 Istio.io 中的一些 task,因为我需要了解它如何处理那些领域的工作。

提示:如果你在完成 codelab 时也决定在四处看看,那么请将你的群集与应用程序一起启动并运行。无论如何,你会再次使用它。

所以我对它如何解决这些问题有了一个基本的了解,但是如果我使用像 GKE 这样的东西来托管K8S(你知道我会选它不是吗?)使用 Istio 是否合适?


注意:是的,这里有更多的细节,但我主要想弄明白为什么需要使用 Istio。



集群最终用户/开发人员访问

GKE 结合使用 IAM(注7) 和 RBAC(注8),是的,这里面有很多东西需要你了解。

要为你的集群用户授予比 Cloud IAM 更细粒度的权限,你可以使用 namespace 和 RBAC 来限制对特定 pod 的访问或排除对 secret 的访问。

Istio RBAC (注9)介绍了两个侧重于服务的角色
 
ServiceRole 定义用于访问网格中的服务的角色。ServiceRoleBinding 将角色授予主题(例如用户、组、服务)。

它们是 K8S 中的 CustomResourceDefinition(CRD)对象。但您仍然需要了解 IAM。


服务身份标识

GKE 可以使用 service account 来管理 GKE 上运行的应用程序(注10)可以使用哪些 GCP 服务。这些 service accout 的密钥使用 secret 存储。Pod 中运行的进程的身份标识是由 k8s service account (注11)与 RBAC 一起决定的。Istio 使用 istio-auth(注12),它使用双向 TLS 提供强大的服务间和最终用户身份验证,内置身份和凭证管理。Istio-auth 使用 k8s service account。

这些文档在解释其工作原理方面做得非常好,所以我只想在这里复制架构图的小图。详见这里。(注13)






 istio-auth架构的小图


Itsio 不提供任何使用 GCP service account 帮助。这还很早,但是它正在制定未来发展计划的路线图。

Istio-auth 很好,计划中的增强功能将值得等待。我对安全的复杂性感到厌烦,因为这不可避免地导致配置错误,所以我希望它与 service account 类型之间进行更加无缝的对齐!



网络控制


GKE(用于 K8S 版本1.7.6 +)使用 k8s网络策略(注14)来管理哪些 Pod 可以和服务通信。这是相对简单的配置。 Istio 也有网络策略,但他们不是你知道和喜欢的K8s策略,为什么会有这样的区别呢? 这篇文章(注15)很好地解释了这一点,所以我不会在这里重述,但是这个表格总结了不同之处以及为什么会有这样的不同。


项目 Istio策略 网络策略
层 Service(7层) Network(3、4层)
实现 Userspace Kernel
控制点 Pod Node

Istio 使用 envoy 作为 sidecar 代理。Envoy 在 OSI 模型的应用层运行,所以在第7层。我的这篇博客将为你详细解释。


你需要两种策略类型,这是纵深防御的方法。



多个集群

Istio 有个非常酷的功能是 mixer 适配器(注16)。简而言之,它可以从底层后端进行抽象以提供核心功能,例如日志记录、监控、配额、ACL 检查等。它公开了一个一致的 API,与使用的后端无关。就像 GCS 公开了一个 API,无论您使用什么存储类别!

我认为 mixer 适配器模型(注17)博客文章中的这张图片解释了 mixer 适配器中的全部要点。

有一个早期 demo(注18),我认为它是 Istio 最有用的特性之一,它实际上使用虚拟机来承载code lab 中使用的评分 dbase MySQL 数据库,并将其作为 GKE 集群所属网格的一部分。使用一个网格来管理它们!



流量管理

如果你使用了 codelab,你会看到使用 Istio 来引导使用路由规则的流量是多么容易。使用K8S,你还可以使用金丝雀部署进行流量管理,并以类似于 Istio 的方式将一定比例的流量引导至你应用的一个版本,但 Istio 在这种情况下更灵活,方法是允许你设置细粒度流量百分比并控制流量使用 code lab 中的其他标准。



服务发现

服务注册在 K8S 中完成。Istio 抽象出底层的服务发现机制,并将其转换为 envoy sidecar 可消费的标准格式。


审计记录和监控

如果是超出 GKE 提供的标准日志记录的话,可以将 GKE 与 StackDriver 日志记录(注19)集成来收集,在持久化存储中存储容器日志、系统日志和关于群集中的活动的事件,例如 Pod 的调度。还可以与 StackDriver Monitoring(注20)集成以收集系统度量指标(度量群集的基础设施,例如CPU或内存使用情况)和自定义指标(特定于应用程序的指标)。

 
Istio 利用 prometheus 与 grafana 一起作为仪表板进行记录和监控。我喜欢 service graph 配置(注21),它可以为你提供 service mesh 的图形表示。你也可以用 kibana 和 fluentd 来配合 Elasticsearch 使用。


那我需要Istio吗?

Istio 的流量管理非常棒,mixer 适配器模型可以轻松管理覆盖多个群集和虚拟机的网格。我喜欢 Istio 是因为它可以让你进中精力思考服务,而不是那么多的 pod 和节点,并不是说你不必担心这些,而是只关注服务就好了!


如果你需要管理一个分布式集群,那么 Istio 应该在你的选择列表里。如果您需要在流量管理方面有比 K8S 提供的更多的灵活性的化那么 Istio 也很值得关注。


如果你有足够的资源来处理处于发展早期的事物,那么尽早理解 Istio 是值得的。如果你已经在使用 K8S 的话那么 Istio 的学习曲线将很低。

记住它是一个建立在上层的东西,所以你仍然需要在 K8S 层做些事情,比如配置 K8S 网络策略来补充 Istio 网络策略。

Istio 还处于发展的早期阶段,所以它不会做你期望的所有事情,但我们希望它会。你将无法避免的在提供商 API 和 Istio 之间来回调用才能完成一个完整的工作,所以它不是你希望的那种一站式解决方案。


Dashboard 是可视化网格配置的一种很好的方式,因为编写 YAML 会让人很快疲惫!是的,你可以设置仪表板上的控制面板来可视化度量指标,但我希望看到它与 StackDriver 集成。


因此,在总体了解 Istio 之后,我实际上很喜欢它所承诺的内容。


注:

1、https://istio.io/

2、https://istio.io/docs/concepts ... .html

3、https://istio.io/docs/concepts ... .html

4、https://codelabs.developers.go ... /%230

5、https://istio.io/docs/concepts ... cture

6、https://istio.io/docs/concepts ... rules

7、https://cloud.google.com/kuber ... ation

8、https://cloud.google.com/kuber ... ntrol

9、https://istio.io/docs/concepts/security/rbac.html

10、https://cloud.google.com/kuber ... tform

11、https://kubernetes.io/docs/tas ... ount/

12、https://istio.io/docs/concepts ... .html

13、https://istio.io/docs/concepts ... .html

14、https://cloud.google.com/kuber ... olicy

15、https://istio.io/blog/2017/0.1 ... .html

16、https://istio.io/docs/concepts ... pters

17、https://istio.io/blog/2017/adapter-model.html

18、https://istio.io/docs/guides/integrating-vms.html

19、https://cloud.google.com/kuber ... gging

20、https://cloud.google.com/kuber ... oring

21、https://istio.io/docs/tasks/te ... .html



社区活动:

3月31日(周六),数人云联合ServiceComb社区,并由ServiceMesh社区支持,开启meetup系列活动 Building Microservice 第2期 北京站 :微服务,从架构到发布,已经开始报名啦,点击链接报名啦 查看全部
作者:Grace@grapesfrog

翻译:宋净超(Jimmy Song)

     Kubernetes、Cloud Native布道者、开源爱好者,个人博客https://jimmysong.io

原文:Istio why do I need it?



我最近没有多少时间去玩 K8S,并且我承认在 Istio 到底给 K8S 带来了什么这个问题上我有点迷失了。这是否会增加更多的运营开销?它是否简化了我们通常需要做的事情?这些问题都浮现在我的脑海里。

我怀疑在发布了这些内容之后,我团队中比我更懂 K8S 的人可能会想找我谈谈,估计我会跟团队中的成员辩论,但那将是我最喜欢的对话。


那么 Istio 究竟是什么?

Istio 网站(注1)上说:

Istio 带给你:
 
  • HTTP、gRPC、WebSocket 和 TCP 流量的自动负载均衡。
  • 通过丰富的路由规则、重试、故障转移和故障注入对流量行为进行细粒度控制。
  • 支持访问控制、速率限制和配额的可拔插策略层和配置 API。
  • 自动指标、日志和集群内所有流量的跟踪,包括集群入口和出口。
  • 通过集群中的服务之间的强身份断言来实现服务间的身份验证。



通过在整个环境中部署一个特殊的 sidecar 代理(辅助容器),你可以将 Istio 支持添加到服务中(这给我留下了深刻的印象,如果你想做到这一点,请参阅后面的内容)。安装了 sidecar 代理之后,(微)服务之间的所有网络通信都通过这个代理。此外,所有的网络通信都是使用 Istio 的控制平面功能进行配置和管理的。


Istio 是 Service Mesh(服务网格)。我认为的 service mesh 定义就是“它是一个专用的基础设施层,使得服务间的通信安全、高效和可靠”。


然而,如果像我一样,你从概念文档(注2)开始看的话,上面有这样的内容:“术语 service mesh 通常用于描述组成这些应用程序的微服务网络以及它们之间的交互。随着服务网格的大小和复杂程度不断增加,可能会变得难以理解和管理。可能出现包括服务发现、负载平衡、故障恢复、度量和监控,以及更复杂的需求,如A/B测试、金丝雀发布、速率限制、访问控制和端到端身份验证。Istio 提供了一个完整的解决方案,通过对整个服务网格提供行为分析和操作控制来满足微服务应用程序的各种需求。“


读完之后你可能会像我一样困惑!最后在网上查了一圈关于什么是服务网格之后,我终于搞明白了。我最后使用的可能是一个在所有搜索到的样本里一个非代表性的共识,但这是一个合理的选择。不过有个细节确实了,就是如何将它与 K8S 等编排工具分开。Istio 需要跟 K8S一起使用,没有 K8S 或其他容器编排工具的它就不存在了吗?它没有做编排,实际上它的是为解决管理基于微服务的解决方案中网络和操作复杂性而设计的。它涵盖的范围就像K8S一样!现在我真的需要继续这个帖子了。

所以我知道 Istio 是什么,给我们带来了什么,但它实际上解决了什么挑战呢?


从为什么使用 Istio 页面中(注3)可以看出,它在服务网络中统一提供了许多关键功能:


流量管理
 
  • 可观察性
  • 强制策略
  • 服务身份标识和安全



对于我来说,要真正理解 Istio 的价值,所以我使用了 codelab(注四)。编写 code lab 的人真是太棒了!


Code lab 向我介绍了 Istio 控制平面的四个主要组件:
 
  • Pilot:处理代理 sidecar 的配置和编程。
  • Mixer:为你的流量处理决策并收集遥测数据。
  • Ingress:处理来自群集外部的传入请求。
  • CA:证书颁发机构。



查看 Istio 架构概念(注5)页面了解这些组件如何协同工作的。

Code lab提供了路由规则(注6)——流量管理部分

我还尝试了 Istio.io 中的一些 task,因为我需要了解它如何处理那些领域的工作。

提示:如果你在完成 codelab 时也决定在四处看看,那么请将你的群集与应用程序一起启动并运行。无论如何,你会再次使用它。

所以我对它如何解决这些问题有了一个基本的了解,但是如果我使用像 GKE 这样的东西来托管K8S(你知道我会选它不是吗?)使用 Istio 是否合适?


注意:是的,这里有更多的细节,但我主要想弄明白为什么需要使用 Istio。



集群最终用户/开发人员访问

GKE 结合使用 IAM(注7) 和 RBAC(注8),是的,这里面有很多东西需要你了解。

要为你的集群用户授予比 Cloud IAM 更细粒度的权限,你可以使用 namespace 和 RBAC 来限制对特定 pod 的访问或排除对 secret 的访问。

Istio RBAC (注9)介绍了两个侧重于服务的角色
 
  • ServiceRole 定义用于访问网格中的服务的角色。
  • ServiceRoleBinding 将角色授予主题(例如用户、组、服务)。


它们是 K8S 中的 CustomResourceDefinition(CRD)对象。但您仍然需要了解 IAM。


服务身份标识

GKE 可以使用 service account 来管理 GKE 上运行的应用程序(注10)可以使用哪些 GCP 服务。这些 service accout 的密钥使用 secret 存储。Pod 中运行的进程的身份标识是由 k8s service account (注11)与 RBAC 一起决定的。Istio 使用 istio-auth(注12),它使用双向 TLS 提供强大的服务间和最终用户身份验证,内置身份和凭证管理。Istio-auth 使用 k8s service account。

这些文档在解释其工作原理方面做得非常好,所以我只想在这里复制架构图的小图。详见这里。(注13)

微信图片_20180321102010.jpg


 istio-auth架构的小图


Itsio 不提供任何使用 GCP service account 帮助。这还很早,但是它正在制定未来发展计划的路线图。

Istio-auth 很好,计划中的增强功能将值得等待。我对安全的复杂性感到厌烦,因为这不可避免地导致配置错误,所以我希望它与 service account 类型之间进行更加无缝的对齐!



网络控制


GKE(用于 K8S 版本1.7.6 +)使用 k8s网络策略(注14)来管理哪些 Pod 可以和服务通信。这是相对简单的配置。 Istio 也有网络策略,但他们不是你知道和喜欢的K8s策略,为什么会有这样的区别呢? 这篇文章(注15)很好地解释了这一点,所以我不会在这里重述,但是这个表格总结了不同之处以及为什么会有这样的不同。


项目 Istio策略 网络策略
层 Service(7层) Network(3、4层)
实现 Userspace Kernel
控制点 Pod Node

Istio 使用 envoy 作为 sidecar 代理。Envoy 在 OSI 模型的应用层运行,所以在第7层。我的这篇博客将为你详细解释。


你需要两种策略类型,这是纵深防御的方法。



多个集群

Istio 有个非常酷的功能是 mixer 适配器(注16)。简而言之,它可以从底层后端进行抽象以提供核心功能,例如日志记录、监控、配额、ACL 检查等。它公开了一个一致的 API,与使用的后端无关。就像 GCS 公开了一个 API,无论您使用什么存储类别!

我认为 mixer 适配器模型(注17)博客文章中的这张图片解释了 mixer 适配器中的全部要点。

有一个早期 demo(注18),我认为它是 Istio 最有用的特性之一,它实际上使用虚拟机来承载code lab 中使用的评分 dbase MySQL 数据库,并将其作为 GKE 集群所属网格的一部分。使用一个网格来管理它们!



流量管理

如果你使用了 codelab,你会看到使用 Istio 来引导使用路由规则的流量是多么容易。使用K8S,你还可以使用金丝雀部署进行流量管理,并以类似于 Istio 的方式将一定比例的流量引导至你应用的一个版本,但 Istio 在这种情况下更灵活,方法是允许你设置细粒度流量百分比并控制流量使用 code lab 中的其他标准。



服务发现

服务注册在 K8S 中完成。Istio 抽象出底层的服务发现机制,并将其转换为 envoy sidecar 可消费的标准格式。


审计记录和监控

如果是超出 GKE 提供的标准日志记录的话,可以将 GKE 与 StackDriver 日志记录(注19)集成来收集,在持久化存储中存储容器日志、系统日志和关于群集中的活动的事件,例如 Pod 的调度。还可以与 StackDriver Monitoring(注20)集成以收集系统度量指标(度量群集的基础设施,例如CPU或内存使用情况)和自定义指标(特定于应用程序的指标)。

 
Istio 利用 prometheus 与 grafana 一起作为仪表板进行记录和监控。我喜欢 service graph 配置(注21),它可以为你提供 service mesh 的图形表示。你也可以用 kibana 和 fluentd 来配合 Elasticsearch 使用。


那我需要Istio吗?

Istio 的流量管理非常棒,mixer 适配器模型可以轻松管理覆盖多个群集和虚拟机的网格。我喜欢 Istio 是因为它可以让你进中精力思考服务,而不是那么多的 pod 和节点,并不是说你不必担心这些,而是只关注服务就好了!


如果你需要管理一个分布式集群,那么 Istio 应该在你的选择列表里。如果您需要在流量管理方面有比 K8S 提供的更多的灵活性的化那么 Istio 也很值得关注。


如果你有足够的资源来处理处于发展早期的事物,那么尽早理解 Istio 是值得的。如果你已经在使用 K8S 的话那么 Istio 的学习曲线将很低。

记住它是一个建立在上层的东西,所以你仍然需要在 K8S 层做些事情,比如配置 K8S 网络策略来补充 Istio 网络策略。

Istio 还处于发展的早期阶段,所以它不会做你期望的所有事情,但我们希望它会。你将无法避免的在提供商 API 和 Istio 之间来回调用才能完成一个完整的工作,所以它不是你希望的那种一站式解决方案。


Dashboard 是可视化网格配置的一种很好的方式,因为编写 YAML 会让人很快疲惫!是的,你可以设置仪表板上的控制面板来可视化度量指标,但我希望看到它与 StackDriver 集成。


因此,在总体了解 Istio 之后,我实际上很喜欢它所承诺的内容。


注:

1、https://istio.io/

2、https://istio.io/docs/concepts ... .html

3、https://istio.io/docs/concepts ... .html

4、https://codelabs.developers.go ... /%230

5、https://istio.io/docs/concepts ... cture

6、https://istio.io/docs/concepts ... rules

7、https://cloud.google.com/kuber ... ation

8、https://cloud.google.com/kuber ... ntrol

9、https://istio.io/docs/concepts/security/rbac.html

10、https://cloud.google.com/kuber ... tform

11、https://kubernetes.io/docs/tas ... ount/

12、https://istio.io/docs/concepts ... .html

13、https://istio.io/docs/concepts ... .html

14、https://cloud.google.com/kuber ... olicy

15、https://istio.io/blog/2017/0.1 ... .html

16、https://istio.io/docs/concepts ... pters

17、https://istio.io/blog/2017/adapter-model.html

18、https://istio.io/docs/guides/integrating-vms.html

19、https://cloud.google.com/kuber ... gging

20、https://cloud.google.com/kuber ... oring

21、https://istio.io/docs/tasks/te ... .html



社区活动:

3月31日(周六),数人云联合ServiceComb社区,并由ServiceMesh社区支持,开启meetup系列活动 Building Microservice 第2期 北京站 :微服务,从架构到发布,已经开始报名啦,点击链接报名啦

使用Istio简化微服务系列二:如何通过HTTPS与外部服务进行通信?

小数 发表了文章 • 0 个评论 • 289 次浏览 • 2018-03-15 14:08 • 来自相关话题

作者:Nithin Mallya

翻译:狄卫华

原文:Simplifying Microservices with Istio in Google Kubernetes Engine — Part II

原文链接:https://medium.com/google-clou ... 33089


在本系列第一部分(使用Istio简化微服务系列一:如何用Isito解决Spring Cloud Netflix部署微服务),我们展示了如何使用 Istio 简化我们微服务间的通信。

在这一部分中,我们将看到 Istio 服务网格中的服务是如何通过HTTPS与外部服务进行通信的。





 
图1:微服务通信模型的逻辑视图

在上面的图1,PetService(直接与 PetDetailsService 和 PetMedicalHistoryService 服务进行通信)现在将也会调用外部的服务,外部服务位于 https://thedogapi.co.uk,返回 dog 图片的 url 地址。


Istio 服务网格与外部的服务通信展示在下面的图 2 所示。

与往常一样,在服务网格内的服务通信通过HTTP协议代理

与使用 HTTPS 协议的外部服务通信,内部服务仍然是发送 HTTP 请求,HTTP 请求会被以边车(sidecar)方式部署的代理所拦截,并作为 TLS 协议的发起方与外部的服务在加密通道上进行通信






图2: Istio 服务网格展示与外部服务通信


Github repo(https://github.com/nmallya/istiodemo)

petservice 代码如下所示:







备注:展示我们如何调用 DogAPI https,地址http://api.thedogapi.co.uk:443/v2/dog.php


让我们看一下当运行以下命令时会发生什么?其中 108.59.82.93 为 入口(Ingress)IP 地址 (参见 第一部分)


curl http://108.59.82.93/pet/123

响应内容如下:

{

  "petDetails": {

    "petName": "Maximus",

    "petAge": 5,

    "petOwner": "Nithin Mallya",

    "petBreed": "Dog"

  },

  "petMedicalHistory": {

    "vaccinationList": [

      "Bordetella, Leptospirosis, Rabies, Lyme Disease"

    ]

  },

  "dogAPIResponse": {

    "message": "request to https://api.thedogapi.co.uk/v2/dog.php failed, reason: read ECONNRESET",

    "type": "system",

    "errno": "ECONNRESET",

    "code": "ECONNRESET"

  }

}


你会注意到当 petservice 访问位于 https://api.thedogapi.co.uk 的外部服务时,上述的响应内容中 dogAPIResponse(不是最原始的名字)部分有一个错误信息。

这是因为所有外部的流量(egress)在默认情况下被阻止。在前面的文章中解释过边车(sidecar)代理只允许集群内的通信。


备注:正如我在第一部分提及的那样,当我们想要管控服务与外部服务通信的方式和阻止任何未经授权的访问的时候,这个限制非常有用。

> 医疗保健/金融系统可以特别利用此功能来保护 PHI / PII 数据不会被无意地甚至恶意地从内部服务中共享。

为了启用出口(egress)流量,你需要创建如下所示的出口规则(egress rule):

cat <<EOF | istioctl create -f -

apiVersion: config.istio.io/v1alpha2

kind: EgressRule

metadata:

  name: dogapi-egress-rule

spec:

  destination:

    service: api.thedogapi.co.uk

  ports:

    - port: 443

      protocol: https

EOF

为了检查该出口规则(egress rule)是否已被创建,你可以运行下面的命令,你应该看到出口规则(egress rule)dogapi-egress-rule 已经被创建。

kubectl get egressrule

NAME                 AGE

dogapi-egress-rule   5m

我们再次运行上面的 curl 命令:

$ curl http://108.59.82.93/pet/123

{

  "petDetails": {

    "petName": "Maximus",

    "petAge": 5,

    "petOwner": "Nithin Mallya",

    "petBreed": "Dog"

  },

  "petMedicalHistory": {

    "vaccinationList": [

      "Bordetella, Leptospirosis, Rabies, Lyme Disease"

    ]

  },

  "dogAPIResponse": {

    "count": 1,

    "api_version": "v2",

    "error": null,

    "data": [

      {

        "id": "rCaz-LNuzCC",

"url": "https://i.thedogapi.co.uk/rCaz-LNuzCC.jpg",

        "time": "2017-08-30T21:43:03.0",

        "format": "jpg",

        "verified": "1",

        "checked": "1"

      }

    ],

    "response_code": 200

  }

}

结论:我们看到如何通过创建明确规则,来启用从服务网格(service mesh )到外部服务的通信。

在后续的文章中,我们将会看到如何实施其他重要的任务比如流量路由(traffic routing)和流量变化(ramping),使用断路器(circuit breaker)等。


资源:
1. 本系列文章的第 I 部分:使用Istio简化微服务系列一:如何用Isito解决Spring Cloud Netflix部署微服务

2. Istio 官方地址 <https://istio.io/>

3. DevOxx 的RayTsang的Istio演讲材料: <https://www.youtube.com/watch% ... gt%3B

4. 案例的Github: <https://github.com/nmallya/istiodemo>

5. Kubernetes: <https://kubernetes.io/>

6. DogAPI 网址: <https://thedogapi.co.uk/>



ServiceMesh微信交流群:

添加微信xiaoshu062,备注:服务网格,即可加入Service Mesh微信交流群。

 
 
 
  查看全部
作者:Nithin Mallya

翻译:狄卫华

原文:Simplifying Microservices with Istio in Google Kubernetes Engine — Part II

原文链接:https://medium.com/google-clou ... 33089


在本系列第一部分(使用Istio简化微服务系列一:如何用Isito解决Spring Cloud Netflix部署微服务),我们展示了如何使用 Istio 简化我们微服务间的通信。

在这一部分中,我们将看到 Istio 服务网格中的服务是如何通过HTTPS与外部服务进行通信的。

1.jpeg

 
图1:微服务通信模型的逻辑视图

在上面的图1,PetService(直接与 PetDetailsService 和 PetMedicalHistoryService 服务进行通信)现在将也会调用外部的服务,外部服务位于 https://thedogapi.co.uk,返回 dog 图片的 url 地址。


Istio 服务网格与外部的服务通信展示在下面的图 2 所示。

与往常一样,在服务网格内的服务通信通过HTTP协议代理

与使用 HTTPS 协议的外部服务通信,内部服务仍然是发送 HTTP 请求,HTTP 请求会被以边车(sidecar)方式部署的代理所拦截,并作为 TLS 协议的发起方与外部的服务在加密通道上进行通信

2.jpeg


图2: Istio 服务网格展示与外部服务通信


Github repo(https://github.com/nmallya/istiodemo)

petservice 代码如下所示:


3.png


备注:展示我们如何调用 DogAPI https,地址http://api.thedogapi.co.uk:443/v2/dog.php


让我们看一下当运行以下命令时会发生什么?其中 108.59.82.93 为 入口(Ingress)IP 地址 (参见 第一部分)


curl http://108.59.82.93/pet/123

响应内容如下:

{

  "petDetails": {

    "petName": "Maximus",

    "petAge": 5,

    "petOwner": "Nithin Mallya",

    "petBreed": "Dog"

  },

  "petMedicalHistory": {

    "vaccinationList": [

      "Bordetella, Leptospirosis, Rabies, Lyme Disease"

    ]

  },

  "dogAPIResponse": {

    "message": "request to https://api.thedogapi.co.uk/v2/dog.php failed, reason: read ECONNRESET",

    "type": "system",

    "errno": "ECONNRESET",

    "code": "ECONNRESET"

  }

}


你会注意到当 petservice 访问位于 https://api.thedogapi.co.uk 的外部服务时,上述的响应内容中 dogAPIResponse(不是最原始的名字)部分有一个错误信息。

这是因为所有外部的流量(egress)在默认情况下被阻止。在前面的文章中解释过边车(sidecar)代理只允许集群内的通信。


备注:正如我在第一部分提及的那样,当我们想要管控服务与外部服务通信的方式和阻止任何未经授权的访问的时候,这个限制非常有用。

> 医疗保健/金融系统可以特别利用此功能来保护 PHI / PII 数据不会被无意地甚至恶意地从内部服务中共享。

为了启用出口(egress)流量,你需要创建如下所示的出口规则(egress rule):

cat <<EOF | istioctl create -f -

apiVersion: config.istio.io/v1alpha2

kind: EgressRule

metadata:

  name: dogapi-egress-rule

spec:

  destination:

    service: api.thedogapi.co.uk

  ports:

    - port: 443

      protocol: https

EOF

为了检查该出口规则(egress rule)是否已被创建,你可以运行下面的命令,你应该看到出口规则(egress rule)dogapi-egress-rule 已经被创建。

kubectl get egressrule

NAME                 AGE

dogapi-egress-rule   5m

我们再次运行上面的 curl 命令:

$ curl http://108.59.82.93/pet/123

{

  "petDetails": {

    "petName": "Maximus",

    "petAge": 5,

    "petOwner": "Nithin Mallya",

    "petBreed": "Dog"

  },

  "petMedicalHistory": {

    "vaccinationList": [

      "Bordetella, Leptospirosis, Rabies, Lyme Disease"

    ]

  },

  "dogAPIResponse": {

    "count": 1,

    "api_version": "v2",

    "error": null,

    "data": [

      {

        "id": "rCaz-LNuzCC",

"url": "https://i.thedogapi.co.uk/rCaz-LNuzCC.jpg",

        "time": "2017-08-30T21:43:03.0",

        "format": "jpg",

        "verified": "1",

        "checked": "1"

      }

    ],

    "response_code": 200

  }

}

结论:我们看到如何通过创建明确规则,来启用从服务网格(service mesh )到外部服务的通信。

在后续的文章中,我们将会看到如何实施其他重要的任务比如流量路由(traffic routing)和流量变化(ramping),使用断路器(circuit breaker)等。


资源:
1. 本系列文章的第 I 部分:使用Istio简化微服务系列一:如何用Isito解决Spring Cloud Netflix部署微服务

2. Istio 官方地址 <https://istio.io/>

3. DevOxx 的RayTsang的Istio演讲材料: <https://www.youtube.com/watch% ... gt%3B

4. 案例的Github: <https://github.com/nmallya/istiodemo>

5. Kubernetes: <https://kubernetes.io/>

6. DogAPI 网址: <https://thedogapi.co.uk/>



ServiceMesh微信交流群:

添加微信xiaoshu062,备注:服务网格,即可加入Service Mesh微信交流群。

 
 
 
 

使用Istio简化微服务系列一:如何用Isito解决Spring Cloud Netflix部署微服务的挑战?

小数 发表了文章 • 0 个评论 • 639 次浏览 • 2018-03-13 10:13 • 来自相关话题

作者:Nithin Mallya
翻译:姚炳雄
原文:Simplifying Microservices with Istio in Google Kubernetes Engine — Part I
概述
Istio 简化了服务间的通信,流量涨落,容错,性能监控,跟踪等太多太多。如何利用它来帮我们从各微服务中抽象萃取出基础架构和功能切面? 

我写的这些关于 Istio 的文章是 Istio官网文档的子集。读官网文档可了解更多。 

注意::如果你很熟悉微服务,请跳过背景介绍这段。


在本系列的第一部分,将涵盖如下内容:
背景: 单体应用及微服务介绍 
 
Spring Cloud Netflix Stack及其优势 
 
Istio 介绍
 
Istio的服务-服务通信举例 




背景

过去,我们运维着“能做一切”的大型单体应用程序。 这是一种将产品推向市场的很好的方式,因为刚开始我们也只需要让我们的第一个应用上线。而且我们总是可以回头再来改进它的。部署一个大应用总是比构建和部署多个小块要容易。


然而,这样的应用开发将导致“爆炸式的”工作量(我们经过数月的工作后将再次部署整个应用),并且增量变更将因为构建/测试/部署/发布周期等的复杂特性而来来回回折腾很长时间。但是,如果你是产品负责人,尤其是在部署一个新版本后发现一个严重的 Bug,那么这就不仅仅是多少钱的问题。 这甚至可能导致整个应用回滚。相对于比较小的组件来说,将这样的一个大型应用部署到云上并弹性扩展它们也并不容易。


进入微服务微服务是运行在自己的进程中的可独立部署的服务套件。 他们通常使用 HTTP 资源进行通信,每个服务通常负责整个应用中的某一个单一的领域。 在流行的电子商务目录例子中,你可以有一个商品条目服务,一个审核服务和一个评价服务,每个都只专注一个领域。


用这种方法来帮助分布式团队各自贡献各种服务,而不需要在每个服务变更时去构建/测试/部署整个应用,而且调试也无需进入彼此的代码。 将服务部署到云上也更容易,因为独立的服务就能按需进行自动弹性扩展。


用这种方法让多语言服务(使用不同语言编写的服务)也成为可能,这样我们就可以让 Java/C++  服务执行更多的计算密集型工作,让 Rails / Node.js 服务更多来支持前端应用等等。



Spring Cloud Netflix:

随着微服务的流行,简化服务的创建和管理的框架如雨后春笋。 我个人在2015年最喜欢的是 Netflix OSS 栈(Spring Cloud Netflix),它让我用一个非常简单的方式,通过 Spring Tool Suite IDE 来创建 Java 微服务。


我可以通过 Netflix 套件获得以下功能(图1):
通过 Eureka 进行服务注册- 用于注册和发现服务
 
用 Ribbon 做客户端的负载均衡- 客户端可以选择将其请求发送到哪个服务器。
 
声明 REST 客户端 Feign 与其他服务交谈。在内部,使用 Ribbon。
 
API 网关用 Zuul —单一入口点来管理所有 API 调用,并按路由规则路由到微服务。
 
Hystrix 做熔断器 — 处理容错能力以及在短时间内关闭通信信道(断开回路)并在目标服务宕机时返回用户友好的响应。
 
用 Hystrix 和 Turbine 做仪表板 —— 可视化流量和熔断







图1: Spring Cloud Netflix 实现微服务


当然,这种构建和部署应用的方法也带来了它的挑战。


挑战

部署:怎样才能通过一种统一一致的方式将我们的服务部署到云中,并确保它们始终可用,并让它们按需进行自动弹性扩展?

横切关注点:如何对每个微服务代码改动很少甚至不改代码的情况下能获得更多我们所看到的 Spring Cloud Netflix 中所实现的功能? 另外,如何处理用不同语言编写的服务?



解决方案

部署:Kubernetes 已经为在 Google Kubernetes Engine(GKE)中高效部署和编排 Docker 容器铺平了道路。 Kubernetes 抽象出基础架构,并让我们通过 API 与之进行交互。 请参阅本文末尾的链接以获取更多详细信息。


横切关注点:我们可以用 Istio。 Istio 官网上的解释称:“ Istio 提供了一种简单的方法,来创建一个提供负载均衡、服务间认证、监控等的服务网络,且不需要对服务代码进行任何更改。 通过在整个环境中部署专门的 sidecar 代理服务,来拦截微服务间的所有网络通信,整个配置和管理通过 Istio的控制面板来做。”


Istio介绍:换句话说,通过Istio,我们可以创建我们的微服务,并将它们与“轻量级 Sidecar 代理”一起部署(下图2),以处理我们的许多横切需求,例如:
 
服务到服务的通信
 
追踪
 
熔断(类 Hystrix 功能)和重试
 
性能监控和仪表板(类似于 Hystrix 和 Turbine 仪表板)
 
流量路由(例如:发送 x% 流量到 V2 版本的应用实例),金丝雀部署
 
一个额外的红利(特别是如果您正在处理医疗保健中的 PHI 等敏感数据时)出站(Istio 服务网格之外的外部可调用服务)需要明确配置,并且可以阻止在服务网格之外的做特殊调用的服务。






 
图2: 用 Envoy 代理来做多语言服务间的通信

在上图2中,我们已经去掉了图1中的许多组件,并添加了一个新组件(Envoy Proxy)。 任何服务(A)如需与另一个服务(B)交谈,则提前对它的代理做路由规则预配置,以路由到对方的代理进行通信。 代理与代理交谈。 由于所有通信都是通过代理进行的,所以很容易监控流量,收集指标,根据需要使用熔断规则等。对横切面的声明式的配置规则和策略,无需更改任何服务代码,让我们可以更专注于最重要的事情:构建高业务价值的高质量的服务。


从高的层面看,Istio 有如下组件:
Envoy:一个高性能,低空间占用的代理,支持服务之间的通信,并有助于负载平衡,服务发现等; 混合器:负责整个生态(服务网格)中所有服务的访问控制策略,并收集通过 Envoy 或其他服务发送的遥测信息;
 
Pilot:帮助发现服务,流量缓慢调整和容错(熔断,重试等);Istio-Auth :用于服务间认证以及都使用 TLS 的终端用户认证。本文中的示例不使用 Istio-Auth。

 
 
用Istio进行服务—服务通信:

让我们在练习中了解它!

我们将举一个简单的例子,展示3个通过 Envoy 代理进行通信的微服务。它们已经用 Node.js 写好,但如前述,你可以用任何语言。






图3: 用于提取宠物细节的3个微服务的逻辑视图
 
宠物服务:通过调用 PetDetailsService 和 PetMedicalHistoryService 来返回宠物的信息和病史。 它将在9080端口上运行。

宠物详细信息服务:返回宠物信息,如姓名,年龄,品种,拥有者等,它将在端口9081上运行。

宠物医疗历史信息服务:返回宠物的病史(疫苗接种)。 它将在9082端口运行。


步骤:
在 GKE中创建一个 Kubernetes 集群(我叫 nithinistiocluster)。 
确保缺省服务帐户具有以下权限:roles / container.admin(Kubernetes Engine Admin)。

按照 https://istio.io/docs/setup/ku ... .html  中的说明安装 istio。


1. 现在,我们准备将我们的应用程序(上述3个服务)部署到 GKE,并将边车代理注入到部署中。

2. 在 github 仓库中,您将看到4个目录(安装各种组件时创建的istio目录和我的微服务的3个目录)。

3.对于每个微服务,我在 petinfo.yaml 文件的 kube 目录中创建了相应的 Kubernete s部署和服务。 服务名为宠物服务,宠物详细信息服务和宠物医疗历史信息服务。 由于PetServic e可以公开访问,因此它有一个指向 petservice 的 Kubernetes Ingress。

4. 你可以转到每个服务目录,在 deploy.sh 文件中更新项目和群集名称并运行它。 它构建服务,创建 Docker 镜像,将其上传到Google Container Registry,然后运行 istioct l 以注入 Envoy 代理。 例如,对于 PetService,它看起来像:

#!/usr/bin/env bash
export PROJECT=nithinistioproject export CONTAINER_VERSION=feb4v2 export IMAGE=gcr.io/$PROJECT/petservice:$CONTAINER_VERSION export BUILD_HOME=.
gcloud config set project $PROJECT gcloud container clusters get-credentials nithinistiocluster --zone us-central1-a --project $PROJECT
echo $IMAGE docker build -t petservice -f "${PWD}/Dockerfile" $BUILD_HOME echo 'Successfully built ' $IMAGE
docker tag petservice $IMAGE echo 'Successfully tagged ' $IMAGE
#push to google container registry gcloud docker -- push $IMAGE echo 'Successfully pushed to Google Container Registry ' $IMAGE
# inject envoy proxy kubectl apply -f <(istioctl kube-inject -f "${PWD}/kube/petinfo.yaml")


在上面的代码中,高亮显示的行显示了我们如何使用 Istio 命令行工具(istioctl)来将代理注入到我们的各种 Kubernetes 部署中。


Petservice 目录下的 petinfo.yaml 文件包含服务、部署和 Ingress的配置。 看起来像:

apiVersion: v1 kind: Service metadata:  name: petservice  labels:    app: petservice spec:  ports:  - port: 9080    name: http  selector:    app: petservice --- apiVersion: extensions/v1beta1 kind: Deployment metadata:  name: petservice-v1 spec:  replicas: 1  template:    metadata:      labels:        app: petservice        version: v1    spec:      containers:      - name: petservice        image: gcr.io/nithinistioproject/petservice:feb4v2        imagePullPolicy: IfNotPresent        ports:        - containerPort: 9080 ---
########################################################################### # Ingress resource (gateway) ########################################################################## apiVersion: extensions/v1beta1 kind: Ingress metadata:  name: gateway  annotations:    kubernetes.io/ingress.class: "istio" spec:  rules:  - http:      paths:      - path: /pet/.*        backend:          serviceName: petservice          servicePort: 9080 ---


一旦运行了 deploy.sh,就可以通过执行以下命令来检查确认部署、服务和 Ingress 是否已经创建:

mallyn01$ kubectl get deployment
NAME                          DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
petdetailsservice-v1          1         1         1            1           1h
petmedicalhistoryservice-v1   1         1         1            1           58m
petservice-v1                 1         1         1            1           54m
mallyn01$ kubectl get service
NAME                       TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
kubernetes                 ClusterIP   10.51.240.1    <none>        443/TCP    2d
petdetailsservice          ClusterIP   10.51.255.10   <none>        9081/TCP   1h
petmedicalhistoryservice   ClusterIP   10.51.244.19   <none>        9082/TCP   59m
petservice                 ClusterIP   10.51.242.18   <none>        9080/TCP   1h
petservice mallyn01$ kubectl get ing
NAME      HOSTS     ADDRESS        PORTS     AGE
gateway   *         108.59.82.93   80        1h
mallyn01$ kubectl get pods
NAME                                           READY     STATUS    RESTARTS   AGE
petdetailsservice-v1-5bb8c65577-jmn6r          2/2       Running   0          12h
petmedicalhistoryservice-v1-5757f98898-tq5j8   2/2       Running   0          12h
petservice-v1-587696b469-qttqk                 2/2       Running   0          12h


当查看控制台中 pod 的信息,即使你只为每个容器部署了一项服务,但仍会注意到有2/2个容器正在运行。 另一个容器是 istioctl 命令注入的边车代理。

5. 一旦上述所有内容都运行完毕,您可以使用 Ingress 的 IP 地址去调用示例端点来获取 Pet 的详细信息。


mallyn01$ curl http://108.59.82.93/pet/123
{  "petDetails": {    "petName": "Maximus",    "petAge": 5,    "petOwner": "Nithin Mallya",    "petBreed": "Dog"  },  "petMedicalHistory": {    "vaccinationList": [      "Bordetella, Leptospirosis, Rabies, Lyme Disease"    ]  } }


注意: 由于 PetService 调用 PetDetailsService 和 PetMedicalHistoryService,实际的调用将如下所示:fetch('http://petdetailsservice:9081/pet/123/details')          .then(res => res.text())          .then(body => console.log(body));        ;
fetch('http://petmedicalhistoryservice:9082/pet/123/medicalhistory')          .then(res => res.text())          .then(body => console.log(body)); ;



结论:
我们覆盖了大量内容 (但这只是第一部分!!)

在随后的部分中,将详细介绍如何使用其他 Istio 特性,例如将流量逐步迁移到一个新升级的版本上,使用性能监控仪表板等等。

特别感谢 Ray Tsang 的关于 Istio 的演讲材料 。



资源:
1. The Istio home page https://istio.io/

2. DevOxx 的Ray Tsang的 Istio 演讲材料: https://www.youtube.com/watch% ... D231s

3. 案例的Github link: https://github.com/nmallya/istiodemo

4. Kubernetes: https://kubernetes.io/

5. 微服务:  https://martinfowler.com/artic ... .html

6. Spring Cloud Netflix: https://github.com/spring-clou ... tflix


原文链接:https://medium.com/google-clou ... 922b8









推荐阅读
采用Istio实现灰度发布,给运维人员一支强心剂
构建分布式微服务系统,如何基于代理的服务网格做“减法”?
实用指南 | 基于Kubernetes, GRPC 和 Linkerd 构建可扩展微服务
万字长文 | 如何构建安全的微服务应用,先要解决这两个问题
实例 | 当Istio遇见Jaeger,如何解决端到端分布式追踪问题?


ServiceMesh微信交流群:

添加微信xiaoshu062,备注:服务网格,即可加入Service Mesh微信交流群。


社区活动:

3月31日(周六),数人云联合ServiceComb社区,并由ServiceMesh社区支持,开启meetup系列活动 Building Microservice 第2期 北京站 :微服务,从架构到发布,已经开始报名啦,点击链接快来报名~ 查看全部
作者:Nithin Mallya
翻译:姚炳雄
原文:Simplifying Microservices with Istio in Google Kubernetes Engine — Part I
概述
Istio 简化了服务间的通信,流量涨落,容错,性能监控,跟踪等太多太多。如何利用它来帮我们从各微服务中抽象萃取出基础架构和功能切面? 

我写的这些关于 Istio 的文章是 Istio官网文档的子集。读官网文档可了解更多。 

注意::如果你很熟悉微服务,请跳过背景介绍这段。


在本系列的第一部分,将涵盖如下内容:
  • 背景: 单体应用及微服务介绍 

 
  • Spring Cloud Netflix Stack及其优势 

 
  • Istio 介绍

 
  • Istio的服务-服务通信举例 





背景

过去,我们运维着“能做一切”的大型单体应用程序。 这是一种将产品推向市场的很好的方式,因为刚开始我们也只需要让我们的第一个应用上线。而且我们总是可以回头再来改进它的。部署一个大应用总是比构建和部署多个小块要容易。


然而,这样的应用开发将导致“爆炸式的”工作量(我们经过数月的工作后将再次部署整个应用),并且增量变更将因为构建/测试/部署/发布周期等的复杂特性而来来回回折腾很长时间。但是,如果你是产品负责人,尤其是在部署一个新版本后发现一个严重的 Bug,那么这就不仅仅是多少钱的问题。 这甚至可能导致整个应用回滚。相对于比较小的组件来说,将这样的一个大型应用部署到云上并弹性扩展它们也并不容易。


进入微服务微服务是运行在自己的进程中的可独立部署的服务套件。 他们通常使用 HTTP 资源进行通信,每个服务通常负责整个应用中的某一个单一的领域。 在流行的电子商务目录例子中,你可以有一个商品条目服务,一个审核服务和一个评价服务,每个都只专注一个领域。


用这种方法来帮助分布式团队各自贡献各种服务,而不需要在每个服务变更时去构建/测试/部署整个应用,而且调试也无需进入彼此的代码。 将服务部署到云上也更容易,因为独立的服务就能按需进行自动弹性扩展。


用这种方法让多语言服务(使用不同语言编写的服务)也成为可能,这样我们就可以让 Java/C++  服务执行更多的计算密集型工作,让 Rails / Node.js 服务更多来支持前端应用等等。



Spring Cloud Netflix:

随着微服务的流行,简化服务的创建和管理的框架如雨后春笋。 我个人在2015年最喜欢的是 Netflix OSS 栈(Spring Cloud Netflix),它让我用一个非常简单的方式,通过 Spring Tool Suite IDE 来创建 Java 微服务。


我可以通过 Netflix 套件获得以下功能(图1):
  • 通过 Eureka 进行服务注册- 用于注册和发现服务

 
  • 用 Ribbon 做客户端的负载均衡- 客户端可以选择将其请求发送到哪个服务器。

 
  • 声明 REST 客户端 Feign 与其他服务交谈。在内部,使用 Ribbon。

 
  • API 网关用 Zuul —单一入口点来管理所有 API 调用,并按路由规则路由到微服务。

 
  • Hystrix 做熔断器 — 处理容错能力以及在短时间内关闭通信信道(断开回路)并在目标服务宕机时返回用户友好的响应。

 
  • 用 Hystrix 和 Turbine 做仪表板 —— 可视化流量和熔断



1.jpeg


图1: Spring Cloud Netflix 实现微服务


当然,这种构建和部署应用的方法也带来了它的挑战。


挑战

部署:怎样才能通过一种统一一致的方式将我们的服务部署到云中,并确保它们始终可用,并让它们按需进行自动弹性扩展?

横切关注点:如何对每个微服务代码改动很少甚至不改代码的情况下能获得更多我们所看到的 Spring Cloud Netflix 中所实现的功能? 另外,如何处理用不同语言编写的服务?



解决方案

部署:Kubernetes 已经为在 Google Kubernetes Engine(GKE)中高效部署和编排 Docker 容器铺平了道路。 Kubernetes 抽象出基础架构,并让我们通过 API 与之进行交互。 请参阅本文末尾的链接以获取更多详细信息。


横切关注点:我们可以用 Istio。 Istio 官网上的解释称:“ Istio 提供了一种简单的方法,来创建一个提供负载均衡、服务间认证、监控等的服务网络,且不需要对服务代码进行任何更改。 通过在整个环境中部署专门的 sidecar 代理服务,来拦截微服务间的所有网络通信,整个配置和管理通过 Istio的控制面板来做。”


Istio介绍:换句话说,通过Istio,我们可以创建我们的微服务,并将它们与“轻量级 Sidecar 代理”一起部署(下图2),以处理我们的许多横切需求,例如:
 
  • 服务到服务的通信

 
  • 追踪

 
  • 熔断(类 Hystrix 功能)和重试

 
  • 性能监控和仪表板(类似于 Hystrix 和 Turbine 仪表板)

 
  • 流量路由(例如:发送 x% 流量到 V2 版本的应用实例),金丝雀部署

 
  • 一个额外的红利(特别是如果您正在处理医疗保健中的 PHI 等敏感数据时)出站(Istio 服务网格之外的外部可调用服务)需要明确配置,并且可以阻止在服务网格之外的做特殊调用的服务。



2.jpeg

 
图2: 用 Envoy 代理来做多语言服务间的通信

在上图2中,我们已经去掉了图1中的许多组件,并添加了一个新组件(Envoy Proxy)。 任何服务(A)如需与另一个服务(B)交谈,则提前对它的代理做路由规则预配置,以路由到对方的代理进行通信。 代理与代理交谈。 由于所有通信都是通过代理进行的,所以很容易监控流量,收集指标,根据需要使用熔断规则等。对横切面的声明式的配置规则和策略,无需更改任何服务代码,让我们可以更专注于最重要的事情:构建高业务价值的高质量的服务。


从高的层面看,Istio 有如下组件:
  • Envoy:一个高性能,低空间占用的代理,支持服务之间的通信,并有助于负载平衡,服务发现等;
  •  混合器:负责整个生态(服务网格)中所有服务的访问控制策略,并收集通过 Envoy 或其他服务发送的遥测信息;

 
  • Pilot:帮助发现服务,流量缓慢调整和容错(熔断,重试等);
  • Istio-Auth :用于服务间认证以及都使用 TLS 的终端用户认证。本文中的示例不使用 Istio-Auth。


 
 
用Istio进行服务—服务通信:

让我们在练习中了解它!

我们将举一个简单的例子,展示3个通过 Envoy 代理进行通信的微服务。它们已经用 Node.js 写好,但如前述,你可以用任何语言。

3.jpeg


图3: 用于提取宠物细节的3个微服务的逻辑视图
 
宠物服务:通过调用 PetDetailsService 和 PetMedicalHistoryService 来返回宠物的信息和病史。 它将在9080端口上运行。

宠物详细信息服务:返回宠物信息,如姓名,年龄,品种,拥有者等,它将在端口9081上运行。

宠物医疗历史信息服务:返回宠物的病史(疫苗接种)。 它将在9082端口运行。


步骤:
在 GKE中创建一个 Kubernetes 集群(我叫 nithinistiocluster)。 
确保缺省服务帐户具有以下权限:roles / container.admin(Kubernetes Engine Admin)。

按照 https://istio.io/docs/setup/ku ... .html  中的说明安装 istio。


1. 现在,我们准备将我们的应用程序(上述3个服务)部署到 GKE,并将边车代理注入到部署中。

2. 在 github 仓库中,您将看到4个目录(安装各种组件时创建的istio目录和我的微服务的3个目录)。

3.对于每个微服务,我在 petinfo.yaml 文件的 kube 目录中创建了相应的 Kubernete s部署和服务。 服务名为宠物服务,宠物详细信息服务和宠物医疗历史信息服务。 由于PetServic e可以公开访问,因此它有一个指向 petservice 的 Kubernetes Ingress。

4. 你可以转到每个服务目录,在 deploy.sh 文件中更新项目和群集名称并运行它。 它构建服务,创建 Docker 镜像,将其上传到Google Container Registry,然后运行 istioct l 以注入 Envoy 代理。 例如,对于 PetService,它看起来像:

#!/usr/bin/env bash
export PROJECT=nithinistioproject export CONTAINER_VERSION=feb4v2 export IMAGE=gcr.io/$PROJECT/petservice:$CONTAINER_VERSION export BUILD_HOME=.
gcloud config set project $PROJECT gcloud container clusters get-credentials nithinistiocluster --zone us-central1-a --project $PROJECT
echo $IMAGE docker build -t petservice -f "${PWD}/Dockerfile" $BUILD_HOME echo 'Successfully built ' $IMAGE
docker tag petservice $IMAGE echo 'Successfully tagged ' $IMAGE
#push to google container registry gcloud docker -- push $IMAGE echo 'Successfully pushed to Google Container Registry ' $IMAGE
# inject envoy proxy kubectl apply -f <(istioctl kube-inject -f "${PWD}/kube/petinfo.yaml")


在上面的代码中,高亮显示的行显示了我们如何使用 Istio 命令行工具(istioctl)来将代理注入到我们的各种 Kubernetes 部署中。


Petservice 目录下的 petinfo.yaml 文件包含服务、部署和 Ingress的配置。 看起来像:

apiVersion: v1 kind: Service metadata:  name: petservice  labels:    app: petservice spec:  ports:  - port: 9080    name: http  selector:    app: petservice --- apiVersion: extensions/v1beta1 kind: Deployment metadata:  name: petservice-v1 spec:  replicas: 1  template:    metadata:      labels:        app: petservice        version: v1    spec:      containers:      - name: petservice        image: gcr.io/nithinistioproject/petservice:feb4v2        imagePullPolicy: IfNotPresent        ports:        - containerPort: 9080 ---
########################################################################### # Ingress resource (gateway) ########################################################################## apiVersion: extensions/v1beta1 kind: Ingress metadata:  name: gateway  annotations:    kubernetes.io/ingress.class: "istio" spec:  rules:  - http:      paths:      - path: /pet/.*        backend:          serviceName: petservice          servicePort: 9080 ---


一旦运行了 deploy.sh,就可以通过执行以下命令来检查确认部署、服务和 Ingress 是否已经创建:

mallyn01$ kubectl get deployment
NAME                          DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
petdetailsservice-v1          1         1         1            1           1h
petmedicalhistoryservice-v1   1         1         1            1           58m
petservice-v1                 1         1         1            1           54m
mallyn01$ kubectl get service
NAME                       TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
kubernetes                 ClusterIP   10.51.240.1    <none>        443/TCP    2d
petdetailsservice          ClusterIP   10.51.255.10   <none>        9081/TCP   1h
petmedicalhistoryservice   ClusterIP   10.51.244.19   <none>        9082/TCP   59m
petservice                 ClusterIP   10.51.242.18   <none>        9080/TCP   1h
petservice mallyn01$ kubectl get ing
NAME      HOSTS     ADDRESS        PORTS     AGE
gateway   *         108.59.82.93   80        1h
mallyn01$ kubectl get pods
NAME                                           READY     STATUS    RESTARTS   AGE
petdetailsservice-v1-5bb8c65577-jmn6r          2/2       Running   0          12h
petmedicalhistoryservice-v1-5757f98898-tq5j8   2/2       Running   0          12h
petservice-v1-587696b469-qttqk                 2/2       Running   0          12h


当查看控制台中 pod 的信息,即使你只为每个容器部署了一项服务,但仍会注意到有2/2个容器正在运行。 另一个容器是 istioctl 命令注入的边车代理。

5. 一旦上述所有内容都运行完毕,您可以使用 Ingress 的 IP 地址去调用示例端点来获取 Pet 的详细信息。


mallyn01$ curl http://108.59.82.93/pet/123
{  "petDetails": {    "petName": "Maximus",    "petAge": 5,    "petOwner": "Nithin Mallya",    "petBreed": "Dog"  },  "petMedicalHistory": {    "vaccinationList": [      "Bordetella, Leptospirosis, Rabies, Lyme Disease"    ]  } }


注意: 由于 PetService 调用 PetDetailsService 和 PetMedicalHistoryService,实际的调用将如下所示:fetch('http://petdetailsservice:9081/pet/123/details')          .then(res => res.text())          .then(body => console.log(body));        ;
fetch('http://petmedicalhistoryservice:9082/pet/123/medicalhistory')          .then(res => res.text())          .then(body => console.log(body)); ;



结论:
我们覆盖了大量内容 (但这只是第一部分!!)

在随后的部分中,将详细介绍如何使用其他 Istio 特性,例如将流量逐步迁移到一个新升级的版本上,使用性能监控仪表板等等。

特别感谢 Ray Tsang 的关于 Istio 的演讲材料 。



资源:
1. The Istio home page https://istio.io/

2. DevOxx 的Ray Tsang的 Istio 演讲材料: https://www.youtube.com/watch% ... D231s

3. 案例的Github link: https://github.com/nmallya/istiodemo

4. Kubernetes: https://kubernetes.io/

5. 微服务:  https://martinfowler.com/artic ... .html

6. Spring Cloud Netflix: https://github.com/spring-clou ... tflix


原文链接:https://medium.com/google-clou ... 922b8









推荐阅读
采用Istio实现灰度发布,给运维人员一支强心剂
构建分布式微服务系统,如何基于代理的服务网格做“减法”?
实用指南 | 基于Kubernetes, GRPC 和 Linkerd 构建可扩展微服务
万字长文 | 如何构建安全的微服务应用,先要解决这两个问题
实例 | 当Istio遇见Jaeger,如何解决端到端分布式追踪问题?


ServiceMesh微信交流群:

添加微信xiaoshu062,备注:服务网格,即可加入Service Mesh微信交流群。


社区活动:

3月31日(周六),数人云联合ServiceComb社区,并由ServiceMesh社区支持,开启meetup系列活动 Building Microservice 第2期 北京站 :微服务,从架构到发布,已经开始报名啦,点击链接快来报名~