Bookinfo 应用

这个示例部署了一个用于演示多种 Istio 特性的应用,该应用由四个单独的微服务构成。

如果您使用入门安装了 Istio,说明您已经安装了 Bookinfo, 您可以跳过以下大多数步骤,直接跳到定义服务版本

这个应用模仿在线书店的一个分类,显示一本书的信息。 页面上会显示一本书的描述,书籍的细节(ISBN、页数等),以及关于这本书的一些评论。

Bookinfo 应用分为四个单独的微服务:

  • productpage:这个微服务会调用 detailsreviews 两个微服务,用来生成页面。
  • details:这个微服务中包含了书籍的信息。
  • reviews:这个微服务中包含了书籍相关的评论。它还会调用 ratings 微服务。
  • ratings:这个微服务中包含了由书籍评价组成的评级信息。

reviews 微服务有 3 个版本:

  • v1 版本不会调用 ratings 服务。
  • v2 版本会调用 ratings 服务,并使用 1 到 5 个黑色星形图标来显示评分信息。
  • v3 版本会调用 ratings 服务,并使用 1 到 5 个红色星形图标来显示评分信息。

下图展示了这个应用的端到端架构。

Bookinfo Application without Istio

Bookinfo Application without Istio

Bookinfo 应用中的几个微服务是由不同的语言编写的。 这些服务对 Istio 并无依赖,但是构成了一个有代表性的服务网格的例子: 它由多个服务、多个语言构成,并且 reviews 服务具有多个版本。

开始之前

如果您还没有开始,请遵循安装指南完成 Istio 的部署工作。

Istio 包括了对 Kubernetes Gateway API 的 Beta 支持, 打算未来使其成为流量管理的默认 API。 以下说明指导您在网格中配置流量管理时如何选择使用 Gateway API 或 Istio 配置 API。 请按照您的首选项遵循 Gateway APIIstio APIs 页签中的指示说明。

请注意,Kubernetes Gateway API CRD 不会默认安装在大多数 Kubernetes 集群上, 因此请确保在使用 Gateway API 之前已安装好这些 CRD:

  1. $ kubectl get crd gateways.gateway.networking.k8s.io &> /dev/null || \
  2. { kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref=v1.1.0" | kubectl apply -f -; }

部署应用

要在 Istio 中运行这一应用,无需对应用自身做出任何改变。 您只要简单的在 Istio 环境中对服务进行配置和运行,具体一点说就是把 Envoy Sidecar 注入到每个服务之中。 最终的部署结果将如下图所示:

Bookinfo Application

Bookinfo Application

所有的微服务都和 Envoy Sidecar 集成在一起,被集成服务所有的出入流量都被 Sidecar 所劫持, 这样就为外部控制准备了所需的 Hook,然后就可以利用 Istio 控制平面为应用提供服务路由、遥测数据收集以及策略实施等功能。

启动应用服务

如果运行的是 GKE,请确保您的集群至少具有四个标准 GKE 节点。如果使用的是 Minikube,应该有 4G 以上的内存。

  1. 进入 Istio 安装目录。

  2. Istio 默认自动注入 Sidecar. 请为 default 命名空间打上标签 istio-injection=enabled

    1. $ kubectl label namespace default istio-injection=enabled

    如果您使用 OpenShift,请确保按照 OpenShift 设置页面 中所述为命名空间上的服务帐户授予适当的权限

  3. 使用 kubectl 部署应用:

    Zip

    1. $ kubectl apply -f @samples/bookinfo/platform/kube/bookinfo.yaml@

    如果您在安装过程中禁用了 Sidecar 自动注入功能而选择手动注入 Sidecar, 请在部署应用之前使用 istioctl kube-inject 命令修改 bookinfo.yaml 文件。

    Zip

    1. $ kubectl apply -f <(istioctl kube-inject -f @samples/bookinfo/platform/kube/bookinfo.yaml@)

    上面的命令会启动全部的四个服务,其中也包括了 reviews 服务的三个版本(v1、v2 以及 v3)。

    在实际部署中,微服务版本的启动过程需要持续一段时间,并不是同时完成的。

  4. 确认所有的服务和 Pod 都已经正确的定义和启动:

    1. $ kubectl get services
    2. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    3. details ClusterIP 10.0.0.31 <none> 9080/TCP 6m
    4. kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 7d
    5. productpage ClusterIP 10.0.0.120 <none> 9080/TCP 6m
    6. ratings ClusterIP 10.0.0.15 <none> 9080/TCP 6m
    7. reviews ClusterIP 10.0.0.170 <none> 9080/TCP 6m

    还有:

    1. $ kubectl get pods
    2. NAME READY STATUS RESTARTS AGE
    3. details-v1-1520924117-48z17 2/2 Running 0 6m
    4. productpage-v1-560495357-jk1lz 2/2 Running 0 6m
    5. ratings-v1-734492171-rnr5l 2/2 Running 0 6m
    6. reviews-v1-874083890-f0qf0 2/2 Running 0 6m
    7. reviews-v2-1343845940-b34q5 2/2 Running 0 6m
    8. reviews-v3-1813607990-8ch52 2/2 Running 0 6m
  5. 要确认 Bookinfo 应用是否正在运行,请在某个 Pod 中用 curl 命令对应用发送请求,例如 ratings

    1. $ kubectl exec "$(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -c ratings -- curl -sS productpage:9080/productpage | grep -o "<title>.*</title>"
    2. <title>Simple Bookstore App</title>

确定 Ingress 的 IP 和端口

现在 Bookinfo 服务启动并运行中,您需要使应用程序可以从外部访问 Kubernetes 集群, 例如使用浏览器。可以使用网关实现这个目标。

  1. 为 Bookinfo 应用程序定义一个网关:

    使用以下命令创建 Istio Gateway

    Zip

    1. $ kubectl apply -f @samples/bookinfo/networking/bookinfo-gateway.yaml@
    2. gateway.networking.istio.io/bookinfo-gateway created
    3. virtualservice.networking.istio.io/bookinfo created

    确认网关创建完成:

    1. $ kubectl get gateway
    2. NAME AGE
    3. bookinfo-gateway 32s

    遵循这些指示说明 设置 INGRESS_HOSTINGRESS_PORT 变量来访问网关。设置好变量后,返回此处。

    这些说明假定您的 Kubernetes 集群支持外部负载均衡器(即 LoadBalancer 类型的服务)。 请参考 Ingress 控制了解详情。

    使用以下命令创建 Kubernetes Gateway

    Zip

    1. $ kubectl apply -f @samples/bookinfo/gateway-api/bookinfo-gateway.yaml@
    2. gateway.gateway.networking.k8s.io/bookinfo-gateway created
    3. httproute.gateway.networking.k8s.io/bookinfo created

    因为创建 Kubernetes Gateway 资源也会 部署关联的代理服务, 所以运行以下命令等待网关就绪:

    1. $ kubectl wait --for=condition=programmed gtw bookinfo-gateway

    从 bookinfo 网关资源处获取网关地址和端口:

    1. $ export INGRESS_HOST=$(kubectl get gtw bookinfo-gateway -o jsonpath='{.status.addresses[0].value}')
    2. $ export INGRESS_PORT=$(kubectl get gtw bookinfo-gateway -o jsonpath='{.spec.listeners[?(@.name=="http")].port}')
  2. 设置 GATEWAY_URL

    1. $ export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT

确认可以从集群外部访问应用

可以用 curl 命令来确认是否能够从集群外部访问 Bookinfo 应用程序:

  1. $ curl -s "http://${GATEWAY_URL}/productpage" | grep -o "<title>.*</title>"
  2. <title>Simple Bookstore App</title>

还可以用浏览器打开网址 http://$GATEWAY_URL/productpage,来浏览应用的 Web 页面。 如果刷新几次应用的页面,就会看到 productpage 页面中会随机展示 reviews 服务的不同版本的效果 (红色、黑色的星形或者没有显示)。reviews 服务出现这种情况是因为我们还没有使用 Istio 来控制版本的路由。

定义服务版本

在可以使用 Istio 控制 Bookinfo 版本路由之前,您需要定义可用的版本。

Istio 在目标规则中使用 subsets 定义服务的版本。运行以下命令为 Bookinfo 服务创建默认的目标规则:

Zip

  1. $ kubectl apply -f @samples/bookinfo/networking/destination-rule-all.yaml@

defaultdemo配置文件默认情况下启用了 自动双向 TLS。 要强制执行双向 TLS,请使用 samples/bookinfo/networking/destination-rule-all-mtls.yaml 中的目标规则。

等待几秒钟,以使目标规则生效。

您可以使用以下命令查看目标规则:

  1. $ kubectl get destinationrules -o yaml

不同于 Istio API 使用 DestinationRule 子集来定义服务的版本, Kubernetes Gateway API 将为此使用后端服务定义。

运行以下命令为三个版本的 reviews 服务创建后端服务定义:

Zip

  1. $ kubectl apply -f @samples/bookinfo/platform/kube/bookinfo-versions.yaml@

下一步

现在就可以使用这一应用来体验 Istio 的特性了,其中包括了流量的路由、错误注入、速率限制等。 接下来可以根据个人爱好去阅读和演练 Istio 实例。 这里为新手推荐智能路由功能作为起步课程。

清理

结束对 Bookinfo 示例应用的体验之后,就可以使用下面的命令来完成应用的删除和清理了:

Zip

  1. $ @samples/bookinfo/platform/kube/cleanup.sh@