实战项目
更新于:2024年1月24日
实战项目
目录
[toc]
前言
接下来我们将用一个完整的项目来进行 Istio 实战。这里我们选择比较经典的 Online Boutique微服务项目来进行说明。
Online Boutique
是一个微服务演示应用程序,该应用程序是一个基于网络的电子商务应用程序,用户可以在其中浏览商品、将其添加到购物车并购买。
说明
本节实战因镜像未拉取下来,导致测试失败,仅记录文档;
项目架构
该项目由不同编程语言编写的 11 个微服务组成,微服务之间主要通过 gRPC 进行互相通信。
每个微服务的功能如下表所示:
服务名称 | 语言 | 描述 |
---|---|---|
frontend | Go | 暴露一个 HTTP 服务器以服务网站。不需要注册/登录并为所有用户自动生成会话 ID |
cartservice | C# | 在 Redis 中存储用户购物车中的商品,并检索它 |
productcatalogservice | Go | 提供一个来自 JSON 文件的产品列表和搜索产品及获取单个产品的能力 |
currencyservice | Node.js | 将一种货币金额转换为另一种货币,它是最高 QPS 的服务。 |
paymentservice | Node.js | 向(模拟的)给定信用卡信息收费,并返回一个交易 ID |
shippingservice | Go | 根据购物车提供运费估算,并将商品运送到(模拟的)指定地址 |
emailservice | Python | 发送用户订单确认电子邮件(模拟) |
checkoutservice | Go | 检索用户购物车,准备订单并协调支付、快递和邮件通知 |
recommendationservice | Python | 根据购物车中的内容推荐其他产品 |
adservice | Java | 根据给定上下文词提供文本广告 |
loadgenerator | Python/Locust | 持续发送请求以模仿真实用户购物流量 |
了解项目的架构对我们理解应用的运行方式非常重要,我们可以看到该项目中有 11 个微服务,每个微服务都是一个独立的进程,它们之间通过 gRPC 进行通信,这样就保证了微服务之间的解耦。
项目部署
接下来我们需要将该项目部署到 Kubernetes 集群中,每个服务的部署资源清单文件位于项目的 kubernetes-manifests
目录下面:
但是需要注意的是该目录中提供的清单不能直接部署到集群中,它们需要与 Skaffold
命令一起使用以去替换对应的镜像地址。我们可以使用一个打包到一起的完整资源清单文件来部署该项目,该文件位于项目的 release
目录下面:https:$kubectlapply-fkubernetes-manifests/namespaces/
正常会输出下面的信息:
namespace/adcreatednamespace/cartcreatednamespace/checkoutcreatednamespace/currencycreatednamespace/emailcreatednamespace/frontendcreatednamespace/loadgeneratorcreatednamespace/paymentcreatednamespace/rediscreatednamespace/product-catalogcreatednamespace/recommendationcreatednamespace/shippingcreated
- 然后接下来可以部署 ServiceAccount 和 Deployment:
kubectlapply-fkubernetes-manifests/deployments/
不过需要注意该清单文件中的镜像地址是 gcr.io/
开头的,我们可以将其替换为 gcr.dockerproxy.com/
开头的地址,否则会拉取不到镜像。
预期会输出如下结果:
serviceaccount/adcreateddeployment.apps/adservicecreatedserviceaccount/cartcreateddeployment.apps/cartservicecreatedserviceaccount/checkoutcreateddeployment.apps/checkoutservicecreatedserviceaccount/currencycreateddeployment.apps/currencyservicecreatedserviceaccount/emailcreateddeployment.apps/emailservicecreatedserviceaccount/frontendcreateddeployment.apps/frontendcreatedserviceaccount/loadgeneratorcreateddeployment.apps/loadgeneratorcreatedserviceaccount/paymentcreateddeployment.apps/paymentservicecreatedserviceaccount/product-catalogcreateddeployment.apps/productcatalogservicecreatedserviceaccount/recommendationcreateddeployment.apps/recommendationservicecreatedserviceaccount/rediscreateddeployment.apps/redis-cartcreatedserviceaccount/shippingcreateddeployment.apps/shippingservicecreated
- 然后创建 Service 服务:
kubectlapply-fkubernetes-manifests/services/
预期会输出如下结果:
service/adservicecreatedservice/cartservicecreatedservice/checkoutservicecreatedservice/currencyservicecreatedservice/emailservicecreatedservice/frontendcreatedservice/frontend-externalcreatedservice/paymentservicecreatedservice/productcatalogservicecreatedservice/recommendationservicecreatedservice/redis-cartcreatedservice/shippingservicecreated
这里我们 m 每个服务都创建了一个独立的命名空间,并将该项目部署到该命名空间中,需要注意目前我们并没有注入 Istio
的 sidecar
,所以该项目中的微服务并没有使用 Istio
。
- 部署完成后我们可以查看该项目的所有
Pod
:
$fornsinadcartcheckoutcurrencyemailfrontendloadgenerator\paymentproduct-catalogrecommendationshippingredis;dokubectlgetpods-n$nsdone;NAMEREADYSTATUSRESTARTSAGEadservice-599557d587-k78zz1/1Running08m14sNAMEREADYSTATUSRESTARTSAGEcartservice-d965d797d-x6zm81/1Running07m34sNAMEREADYSTATUSRESTARTSAGEcheckoutservice-558cb79cd9-f8dv51/1Running02m19sNAMEREADYSTATUSRESTARTSAGEcurrencyservice-7bccdbb75c-fhjjk1/1Running08m13sNAMEREADYSTATUSRESTARTSAGEemailservice-b77685c45-2l7p51/1Running08m13sNAMEREADYSTATUSRESTARTSAGEfrontend-8495d678c6-k2l451/1Running052sNAMEREADYSTATUSRESTARTSAGEloadgenerator-7dcc798c94-l7lll1/1Running08m13sNAMEREADYSTATUSRESTARTSAGEpaymentservice-5d488686d9-s7qz51/1Running02m19sNAMEREADYSTATUSRESTARTSAGEproductcatalogservice-784876db87-tpxwx1/1Running02m19sNAMEREADYSTATUSRESTARTSAGErecommendationservice-67ddb5f6dc-thgrd1/1Running08m13sNAMEREADYSTATUSRESTARTSAGEshippingservice-576794b87c-94fph1/1Running08m12sNAMEREADYSTATUSRESTARTSAGEredis-cart-69bcdbcc59-8vjc81/1Running08m13s
从前面的架构图中我们可以看到该项目对外暴露的服务是 frontend
这个微服务,上面我们部署的资源清单文件中就包括一个 frontend
的 LoadBalancer
类型的 Service
资源:
apiVersion:v1kind:Servicemetadata:name:frontend-externalnamespace:frontendspec:type:LoadBalancerselector:app:frontendports:- name:httpport:80targetPort:8080
如果你的集群支持 LoadBalancer
类型的 Service
,那么该 Service
就会自动创建一个 LoadBalancer
类型的负载均衡器,并将其绑定到该 Service
上,这样我们就可以通过负载均衡器的地址来访问该服务了,可以通过下面命令查看该服务的地址:
kubectlgetservicefrontend-external-nfrontend|awk'{print $4}'
由于我们这里的集群并不支持 LoadBalancer
类型的 Service
,所以该 Service
并没有创建负载均衡器,但是我们还可以继续通过 NodePort
的方式来访问该服务,我们可以通过下面命令查看该服务的 NodePort
:
$kubectlgetsvcfrontend-external-nfrontendNAMETYPECLUSTER-IPEXTERNAL-IPPORT(S) AGEfrontend-externalLoadBalancer10.103.160.160<pending>80:30877/TCP7m17s
这样我们就可以通过 http:apiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:frontendnamespace:frontendspec:ingressClassName:nginxrules:- host:ob.k8s.localhttp:paths:- backend:service:name:frontendport:name:webpath:/pathType:PrefixEOF
然后通过 http:paymentproduct-catalogrecommendationshippingredis;dokubectllabelnamespace$ns istio-injection=enabled--overwritedone;