How to set up JHipster microservices with Istio service mesh on Kubernetes
如何在 Kubernetes 和 Istio 上轻松实现 JHipster 微服务?
Istio 是当前 DevOps 和云原生项目中最酷的一个。对于那些还没有特别了解 Istio 的人,简单地说几句吧,Istio is a service mesh Istio 是一个为分布式应用架构而生的服务网格( Service Mesh ),特别是为了在云上运行 kubernetes 应用。Istio 与 Kubernetes 配合得非常好,好到你会认为它可能就是 Kubernetes 的一部分。
假如你仍然不太清楚服务网格( Service Mesh ) 和 Istio 到底是什么?就让我们来介绍一下 Istio 吧。
Istio 在一个分布式应用架构中,提供了如下一些功能:
- 服务发现( Service Discovery ) - 也就是传统意义上由平台提供的功能,如: Netflix Eureka or Consul
- 自动负载平衡( Automatic load balancing ) - 同样地,你可能会用 Netflix Zuul 来实现
- 路由、断路器、重试、容错、错误注入攻击防范( Routing, circuit breaking, retries, fail-overs, fault injection ) - 同样,你可能会用 Netflix Ribbon, Hytrix 等等
- 监控指标、日志和跟踪( Metrics, logs, and traces ) - ELK or Stack driver
- 微服务之间安全通信( Secure service-to-service communication )
Istio 的架构图
它分为 2 个不同的 plane
Data plane 由 Envoy 构成,Envoy 是一个在应用容器( application containers ) 中被部署为 sidecar 的代理,他们控制着容器中所有输入 & 输出的信息。
Control plane 用 Pilot 来管理和配置代理,以便路由信息。同时也设置 Mixer 来保证配置的策略,并且收集数据。它也有其它的组件,如:Citadel 管理安全相关,Galley 管理配置等等。
Istio 默认会配置 Grafana, Prometheus and Jaeger 实例,实现系统监控和可观察性的功能。当然你用它默认的,也可以用你自己的系统监控栈。
我希望这些能让你对 Istio 有一个大概的了解,现在让我们回到文章的主题。
Devoxx 2018
我和 Julien Dubois 在 Devoxx 2018 演示了一些 Demo ,并且承诺会写一篇详细的博客来介绍它。
请观看 JHipster + Istio in action 的视频
同时,也可以在 Speaker Deck 上看到 slides
准备 Kubernetes 集群
首先,让我们准备 Kubernetes 集群来部署 Istio 以及我们的容器应用。下面的示例适合于你喜欢的任何平台。
先决条件
kubectl 用来与 Kubernetes 交互的命令行工具,请安装 & 配置好。
Create a cluster on Azure Kubernetes Service(AKS)
如想了解,请见原文 How to set up JHipster microservices with Istio service mesh on Kubernetes
Create a cluster on Google Kubernetes Engine(GKE)
如想了解,请见原文 How to set up JHipster microservices with Istio service mesh on Kubernetes
译者提示,下面的示例,假设你已经有了一个 Kubernetes 集群环境,无论在哪儿~
安装 & 配置 Istio
安装步骤
1 | cd ~/ |
1 | export ISTIO_VERSION=1.0.2 |
1 | curl -L https://git.io/getLatestIstio | sh - |
1 | ln -sf istio-$ISTIO_VERSION istio |
1 | export PATH=~/istio/bin:$PATH |
Make sure to use version 1.0.2 since the latest version seems to have issues connecting to the MySQL database containers.
( 译者注:当前的版本是 1.1.7 问题已经解决)
现在让我们将 Istio 安装到 Kubernetes 集群中,方法是通过 Istio 提供的 manifests 和 helm 模板。
1 | kubectl apply -f ~/istio/install/kubernetes/helm/istio/templates/crds.yaml |
然后,等待 pods 完成启动 & 运行,这些 pods 会部署到 istio-system
名称空间。
1 | watch kubectl get pods -n istio-system |
当 pods 完全启动后,退出循环 watch 并且运行下面的命令来获取 Ingress wateway 服务的详细信息。它是暴露外部 IP 的唯一服务。
1 | watch kubectl get pods -n istio-system |
1 | NAME TYPE CLUSTER-IP EXTERNAL-IPistio-ingressgateway LoadBalancer 10.27.249.83 35.195.81.130 |
这个外部 IP 非常重要,我们可以将它保存到一个环境变量中,以便在后续的步骤中方便地使用它。
1 | export \ |
现在 Kubernetes 集群已经准备好运行 Istio 了。
For advanced Istio setup options refer to https://istio.io/docs/setup/kubernetes/
创建微服务应用
我在之前的一篇博客中,演示了如何用 JHipster & JDL 快速创建全栈微服务应用,如果你想了解其中的细节,可以先读一读我的那篇博客 ( English:here 中文:30分钟创建全栈微服务应用 - JHipster Domain Language)。这个示例中,我们将沿用之前的应用,但我们将不会再用 Eureka 服务发现。同时,请注意 store
应用被分成了 Gateway
和 Product
2 个应用。
架构
下面就是我们今天要创建和部署的微服务架构
它由 1 个 Gateway 应用和 3 个微服务应用组成。其中每一个应用都有自己的数据库。你可以看到,每一个应用都有一个 Envoy 代理作为 sidecar ,绑定在其所在的容器上。Istio control plane 组件也同时部署到集群中,其中还包括了 Prometheus, Grafana, and Jaeger。
Istio 的 Ingress gateway 是外部流量的唯一入口,它将外部的请求分别路由到不同的微服务。同时,所有集群容器的遥测( Telemetry )数据被收集,其中包括应用、数据库以及 Istio 组件的所有信息。
相比较之前的架构 ( English:here 中文:30分钟创建全栈微服务应用 - JHipster Domain Language),你可以清楚地看到,我们将 JHipster registry 和 Netflix OSS 组件替换成了 Istio ,另外还有 ELK monitoring stack 被替换成了由 Istio 配置好的 Prometheus, Grafana and Jaeger。为方便查看、对比,下面给出原始的、没有 Istio 的架构。
Application JDL 应用 JDL
让我们看一看修改后的 JDL 声明,你可以看到我们定义了 serviceDiscoveryType no
,因为我们要用 Istio 来替换 Eureka 。
下面就是我们定义好的,用于 Kubernetes 部署的 JDL 文件。
1 | deployment { |
serviceDiscoveryType
被禁用,同时我们设置了 Istio 的 autoInjection
支持 –— Envoy sidecars 会自己加入到每一个应用容器中,通过 enable istioRoute
选项,Istio 会为每一个应用生成相关的路由。
kubernetesServiceType
设置为 Ingress
,这个非常重要,因为 Istio 只能通过 Ingress controller 的服务类型才能正常工作。对 Ingress 来说,我们需要设置领域的 DNS ,这也是为什么 Istio ingress gateway IP 是需要的。现在我们需要一个 DNS ,在实际的案例中,你应该用 DNS ( 自己的真实域名 )去映射 IP ,但只是为了测试和演示的目的,你可以用一个通配的 DNS 服务,如:nip.io 去解决 IP 的问题,增加 nip.io 到你的 IP ( 注:/etc/hosts ),并将它作为 Ingress 的域名。
生成 & 部署应用
现在我们已经准备好了。创建一个新的目录,并将上述 JDL 文件存入目录中,起名为 app-istio.jdl,然后运行 import-jdl
命令。
1 | mkdir istio-demo && cd istio-demo$ jhipster import-jdl app-istio.jdl |
命令会生成所有的应用代码,并且会分别下载所有的 NPM 依赖。当应用生成后,应用的部署清单也会生成,并且会有一些有用的、后续如何部署的指示文字呈现在屏幕上
你可以用你喜欢的 IDE/Editor 来查看生成的代码。
Kuberctl 将应用部署到 Kubernetes
现在让我们部署我们的应用,运行 ./gradlew bootWar -Pprod jibDockerBuild
命令,分别在 store, product, invoice, and notification 文件夹,来生成 docker 镜像。镜像生成后,运行以下命令将其 push 到 docker repo 。
1 | docker image tag store deepu105/store |
1 | docker push deepu105/store |
1 | docker image tag invoice deepu105/invoice |
1 | docker push deepu105/invoice |
1 | docker image tag notification deepu105/notification |
1 | docker push deepu105/notification |
1 | docker image tag product deepu105/product |
1 | docker push deepu105/product |
镜像全部推送到 docker repo 后,进入命令生成的 Kubernetes 目录,执行如下生成的 kubectl-apply .sh 文件 ( 假如你用的是 Windows 系统,你可以手动 kubectl-apply.sh 单步执行)
1 | cd kubernetes & ./kubectl-apply.sh |
运行
1 | watch kubectl get pods -n jhipster |
来查看状态
Deployed applications 部署完成
当所有 pods 都是正常运行状态时,我们就可以看一看部署的应用了。
Application gateway
Store gateway 是我们微服务应用的入口点。以下命令可以得到 Store 应用的 URL
1 | echo store.$INGRESS_IP.nip.io |
我们之前在创建 Istio 设置里,已经将 INGFRESS_IP 存在一个环境变量中,在浏览器中打开 URL ,查看一下我们的应用,并试着为微服务创建一些实体。
Monitoring 监控
Istio 的初始设置包括了已经配置好的 Grafana and Prometheus,以便收集应用容器的数据,让我们来看一看吧。
默认,只有 Ingress gateway 暴露外部 IP,所以我们需要用 Kuberctl 的 port forwarding 来创建一个安全的通道,以便获取需要的服务。
让我们来创建一个 Grafana 通道
1 | kubectl -n istio-system \port-forward $(kubectl -n istio-system get pod \ |
浏览器打开 localhost:3000 来查看 Grafana 面板。
Grafana 使用通过 Prometheus 获取的指标数据。当然,我们也可以通过创建一个安全通道,在浏览器打开 localhost:9090 来直接查看 Prometheus 的数据图表。
1 | kubectl -n istio-system \port-forward $(kubectl -n istio-system get pod -l \ |
Observability ( 微服务 )可观察性
关于微服务的可观察性,Istio (默认)配置 Jaeger 作为分布式跟踪和服务图表(指标) 的查看方式。
1 | kubectl -n istio-system \port-forward $(kubectl -n istio-system get pod -l \ |
你可以试着在应用里发送一些请求,然后就可以通过查询相关的服务,在跟踪面板( tracing dashboard ) 看到他们。你可以点击相关的请求( request )来查看跟踪的细节。
现在让我们为 Service graph 创建一个通道并在浏览器打开它。
1 | kubectl -n istio-system \port-forward $(kubectl -n istio-system get pod -l \ |
Conclusion 结论
Istio 提供了以更加 Kubernetes-native 的方式来构建分布式微服务的机制,并将维护这种机制的复杂性以及相关的责任一力承担,使您远离这些(与业务不相干的)事情的困扰,( 可以将精力放在业务代码上)。这意味着你不必再去考虑那些(非业务)模块的代码啊、部署啊什么的,例如:服务发现( Service discovery),分布式跟踪( tracing )等等。
Istio 官方文档中说:
Deploying a microservice-based application in an Istio service mesh allows one to externally control service monitoring and tracing, request (version) routing, resiliency testing, security and policy enforcement, etc., in a consistent way across the services, for the application as a whole.
Werner Vogels (CTO of AWS) quoted at AWS Re:Invent
“In the future, all the code you ever write will be business logic.”
未来,你写的所有代码,将会是 ( 也仅仅是 ) 你的业务逻辑!!!
英文原文:How to set up JHipster microservices with Istio service mesh on Kubernetes