基于Kubernetes微服务Istio案例源码

19-01-17 banq
                   

该演示使用Kubernetes作为Docker环境。Kubernetes还支持服务发现和负载平衡。Apache httpd作为反向代理将呼叫路由到服务。

此外,演示还使用Istio进行监视,跟踪,故障注入和断路等功能。

该项目在Docker容器中创建了一个完整的微服务演示系统。这些服务使用Spring Boot和Spring Cloud在Java中实现。

它使用三个微服务:

微服务有一个Java主应用程序,src/test/java可以单独运行它们。microservice-demo-shipping和microservice-demo-invoicing都使用stub来为测试提供其他订单服务。

复制订单数据 - 包括客户数据和项目。因此,如果订单系统中的客户或项目发生变化,则不会影响现有发货和发票。如果价格的变化也会改变现有的发票,那就太奇怪了。此外,只有装运和发票所需的信息才会复制到其他系统。

轮询Atom订阅源的工作每30秒运行一次。

安装

  • 安装 minikube。Minikube是虚拟机中的Kubernetes环境,易于使用和安装。它不是用于生产,而是用于测试Kubernetes或开发人员环境。
  • 使用创建Minikube实例minikube start --cpus=2 --memory=6000。这将把Kubernetes VM的内存设置为6.000 MB - 对于大多数实验来说应该足够了。您可能需要根据本地计算机调整CPU数量。

[~/microservice-istio]minikube start --memory=6000
Starting local Kubernetes v1.12.4 cluster...
Starting VM...
Getting VM IP address...
Moving files into cluster...
Setting up certs...
Connecting to cluster...
Setting up kubeconfig...
Starting cluster components...
Kubectl is now configured to use the cluster.

  • 安装 kubectl。这是Kubernetes的命令行界面。
  • 安装istio

构建Docker镜像

  • 该示例在Java中实现。有关如何下载Java的信息,请参阅https://www.java.com/en/download/help/download_options.xml。需要编译示例,因此您需要安装JDK(Java Development Kit)。JRE(Java运行时环境)是不够的。安装完毕后,你应该能够执行 java,并javac在命令行上。
  • 该示例在Docker容器中运行。您需要安装Docker Community Edition,请参阅https://www.docker.com/community-edition/ 。您应该能够docker在安装后运行。

切换到目录microservice-isitio-demo并运行./mvnw clean package或mvnw.cmd clean package(Windows)。这需要一段时间:

[~/microservice-istio/microservice-istio]./mvnw clean package
....
<p>[INFO] 
<p>[INFO] --- maven-jar-plugin:2.6:jar (default-jar) @ microservice-istio-order ---
<p>[INFO] Building jar: /Users/wolff/microservice-istio/microservice-istio/microservice-istio-order/target/microservice-istio-order-0.0.1-SNAPSHOT.jar
<p>[INFO] 
<p>[INFO] --- spring-boot-maven-plugin:1.4.5.RELEASE:repackage (default) @ microservice-istio-order ---
<p>[INFO] ------------------------------------------------------------------------
<p>[INFO] Reactor Summary:
<p>[INFO] 
<p>[INFO] microservice-istio ....................... SUCCESS [  0.986 s]
<p>[INFO] microservice-istio-invoicing .............. SUCCESS [ 16.953 s]
<p>[INFO] microservice-istio-shipping ............... SUCCESS [ 18.016 s]
<p>[INFO] microservice-istio-order ................. SUCCESS [ 18.512 s]
<p>[INFO] ------------------------------------------------------------------------
<p>[INFO] BUILD SUCCESS
<p>[INFO] ------------------------------------------------------------------------
<p>[INFO] Total time: 57.633 s
<p>[INFO] Finished at: 2017-09-08T09:36:32+02:00
<p>[INFO] Final Memory: 56M/420M
<p>[INFO] ------------------------------------------------------------------------

如果这不起作用:

  • 确保settings.xml主目录.m2中的目录中不包含特定Maven存储库的配置。如有疑问:删除文件。
  • 测试使用本地计算机上的一些端口。确保没有服务器在后台运行。
  • 跳过测试:./mvnw clean package -Dmaven.test.skip=true或 mvnw.cmd clean package -Dmaven.test.skip=true(Windows)。
  • 在极少数情况下,可能无法正确下载依赖项。在这种情况下:删除主目录repository中目录.m2 中的目录。请注意,这意味着将再次下载所有依赖项。

现在已经编译了Java代码。下一步是创建Docker镜像:

  • 配置Docker以便它使用Kubernetes集群来安装Docker镜像:minikube.exe docker-env告诉您如何执行此操作。
  • 之后,如果您这样做,您应该看到Kubernetes的Docker图像docker images:

[~/microservice-istio/microservice-istio]docker images
REPOSITORY                                TAG                 IMAGE ID            CREATED             SIZE
k8s.gcr.io/kubernetes-dashboard-amd64     v1.10.1             f9aed6605b81        3 weeks ago         122MB
k8s.gcr.io/kube-proxy                     v1.12.4             6d393e89739f        3 weeks ago         96.5MB
k8s.gcr.io/kube-apiserver                 v1.12.4             c04b373449d3        3 weeks ago         194MB
k8s.gcr.io/kube-controller-manager        v1.12.4             51b2a8e5ff78        3 weeks ago         164MB
k8s.gcr.io/kube-scheduler                 v1.12.4             c1b5e63c0b56        3 weeks ago         58.4MB
istio/sidecar_injector                    1.0.5               091fd902183a        4 weeks ago         52.9MB
istio/servicegraph                        1.0.5               cef5bb589599        4 weeks ago         16.5MB
istio/proxyv2                             1.0.5               e393f805ceac        4 weeks ago         380MB
istio/pilot                               1.0.5               68f5cc3a87ff        4 weeks ago         313MB
istio/mixer                               1.0.5               582d5c76010e        4 weeks ago         70MB
istio/galley                              1.0.5               e35efbcb45ed        4 weeks ago         73.1MB
istio/citadel                             1.0.5               3e6285f52cd0        4 weeks ago         56.1MB
k8s.gcr.io/etcd                           3.2.24              3cab8e1b9802        3 months ago        220MB
k8s.gcr.io/coredns                        1.2.2               367cdc8433a4        4 months ago        39.2MB
grafana/grafana                           5.2.3               17a5ba3b1216        4 months ago        245MB
prom/prometheus                           v2.3.1              b82ef1f3aa07        6 months ago        119MB
jaegertracing/all-in-one                  1.5                 93f16463fee4        7 months ago        48.4MB
k8s.gcr.io/kube-addon-manager             v8.6                9c16409588eb        10 months ago       78.4MB
k8s.gcr.io/pause                          3.1                 da86e6ba6ca1        12 months ago       742kB
gcr.io/k8s-minikube/storage-provisioner   v1.8.1              4689081edb10        14 months ago       80.8MB
quay.io/coreos/hyperkube                  v1.7.6_coreos.0     2faf6f7a322f        15 months ago       699MB

  • docker-build.sh在目录中 运行microservice-istio。它构建镜像并将其上载到Kubernetes集群中。

./docker-build.sh 
...
Successfully tagged microservice-istio-invoicing:latest
Sending build context to Docker daemon  47.88MB
Step 1/4 : FROM openjdk:10.0.2-jre-slim
 ---> 4bd06752ac4a
Step 2/4 : COPY target/microservice-istio-order-0.0.1-SNAPSHOT.jar .
 ---> 31d666e6ecab
Step 3/4 : CMD /usr/bin/java -Xmx400m -Xms400m -jar microservice-istio-order-0.0.1-SNAPSHOT.jar
 ---> Running in 6a3aafef3449
Removing intermediate container 6a3aafef3449
 ---> a83eb4e8a9fe
Step 4/4 : EXPOSE 8080
 ---> Running in 5054a949c575
Removing intermediate container 5054a949c575
 ---> b60004d121e5
Successfully built b60004d121e5
Successfully tagged microservice-istio-order:latest

  • 镜像现在应该在Kubernets集群中可用:

docker images
REPOSITORY                                TAG                 IMAGE ID            CREATED              SIZE
microservice-istio-order             latest              b60004d121e5        About a minute ago   342MB
microservice-istio-invoicing          latest              287e662e8111        About a minute ago   342MB
microservice-istio-shipping           latest              3af9dd80a8ee        About a minute ago   342MB
microservice-istio-apache            latest              eff5fd508880        About a minute ago   240MB
microservice-istio-postgres          latest              deadbeef8880        About a minute ago   42MB

运行容器

  • 确保在启动pod时自动注入Istio容器: kubectl label namespace default istio-injection=enabled
  • 部署使用微服务基础设施kubectl: microservice-kubernetes-demo:

kubectl apply -f infrastructure.yaml
deployment.apps/apache created
deployment.apps/postgres created
service/apache created
service/postgres created
gateway.networking.istio.io/microservice-gateway created
virtualservice.networking.istio.io/apache created

  • 使用kubectl以下方式部署微服务:

kubectl apply -f microservices.yaml
deployment.apps/invoicing created
deployment.apps/shipping created
deployment.apps/order created
service/invoicing created
service/shipping created
service/order created
virtualservice.networking.istio.io/shipping created
virtualservice.networking.istio.io/invoicing created
virtualservice.networking.istio.io/order created

这部署了镜像。它创建了Pods。Pod可能包含一个或多个Docker容器。在这种情况下,每个Pod只包含一个Docker容器。

注意:Postgres安装非常有限,即无法确保数据在重新启动或群集中发生更改时仍然存在。但是,对于演示,这应该足够了,它简化了设置。

还创建了服务。服务具有群集范围内唯一的IP地址和DNS条目。服务可以使用许多Pod来进行负载平衡。要实际查看服务:

  • 运行kubectl get services以查看所有服务:

kubectl get services
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
apache       NodePort    10.110.196.4     <none>        80:31475/TCP     4m13s
catalog      NodePort    10.96.45.251     <none>        8080:32300/TCP   4m13s
customer     NodePort    10.101.227.211   <none>        8080:31621/TCP   4m13s
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP          152m
order        NodePort    10.109.230.95    <none>        8080:32182/TCP   4m13s

  • 运行kubectl describe services更多详细信息。这也适用于pods(kubectl describe pods)和deployments(kubectl describe deployments)。

kubectl describe service order
Name:                     order
Namespace:                default
Labels:                   run=order
                          visualize=true
Annotations:              kubectl.kubernetes.io/last-applied-configuration:
                            {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"creationTimestamp":null,"labels":{"run":"order","visualize":"true"},"nam...
Selector:                 run=order,serving=true
Type:                     NodePort
IP:                       10.109.230.95
Port:                     http  8080/TCP
TargetPort:               8080/TCP
NodePort:                 http  32182/TCP
Endpoints:                172.17.0.20:8080
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>kubectl describe services

  • 您还可以获取pod的列表:

kubectl get pods
NAME                        READY   STATUS    RESTARTS   AGE
apache-64f9b9545d-f5t6c     2/2     Running   0          5m12s
catalog-668455c696-5qf6q    2/2     Running   0          5m12s
customer-7bd99568cd-brsnk   2/2     Running   0          5m12s
order-67d6c6f756-5l2jb      2/2     Running   0          5m12s

  • ...你可以看到一个pod的日志:

$ kubectl logs catalog-668455c696-5qf6q catalog
2019-01-07 15:14:00.932  INFO [-,,,] 7 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@5c6648b0: startup date [Mon Jan 07 15:14:00 UTC 2019]; root of context hierarchy
2019-01-07 15:14:02.440  INFO [-,,,] 7 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'configurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$c87046ec] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.0.6.RELEASE)

2019-01-07 15:14:03.480  INFO [catalog,,,] 7 --- [           main] c.e.microservice.catalog.CatalogApp      : No active profile set, falling back to default profiles: default
2019-01-07 15:14:03.535  INFO [catalog,,,] 7 --- [           main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@57c03d88: startup date [Mon Jan 07 15:14:03 UTC 2019]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@5c6648b0
...
2019-01-07 15:14:50.636  INFO [catalog,,,] 7 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Located MBean 'dataSource': registering with JMX server as MBean [com.zaxxer.hikari:name=dataSource,type=HikariDataSource]
2019-01-07 15:14:50.923  INFO [catalog,,,] 7 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2019-01-07 15:14:50.981  INFO [catalog,,,] 7 --- [           main] c.e.microservice.catalog.CatalogApp      : Started CatalogApp in 55.296 seconds (JVM running for 57.545)

  • 您还可以在pod中运行命令:

kubectl exec catalog-668455c696-5qf6q /bin/ls
Defaulting container name to catalog.
Use 'kubectl describe pod/catalog-668455c696-5qf6q -n default' to see all of the containers in this pod.
bin
boot
dev
docker-java-home
etc
home
lib
lib32
lib64
libx32
media
microservice-istio-shipping-0.0.1-SNAPSHOT.jar
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var

  • 你甚至可以在一个pod中打开一个shell:

kubectl exec catalog-668455c696-5qf6q -it /bin/sh
Defaulting container name to catalog.
Use 'kubectl describe pod/catalog-668455c696-5qf6q -n default' to see all of the containers in this pod.
# ls
bin   docker-java-home  lib    libx32                                              mnt   root  srv  usr
boot  etc               lib32  media                                               opt   run   sys  var
dev   home              lib64  microservice-istio-shipping-0.0.1-SNAPSHOT.jar  proc  sbin  tmp
# 

使用演示

该演示可通过Ingress访问,该访问提供对所有服务的访问。

  • 确保Ingress gatway工作:

 kubectl get gateway
NAME                   AGE
microservice-gateway   30m

  • 首先找出Ingress的端口kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}'。在这种情况下,它是31380:

kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}'
31380

  • 然后找出Minikube VM的IP地址minikube ip,在这种情况下 192.168.99.104:

minikube ip -p istio2
192.168.99.104

  • 您还可以运行ingress-url.sh包含这两个命令的内容。
  • 所以Ingress可以访问http://192.168.99.104:31380/。如果您打开该URL,则会显示由apache服务提供的静态HTML页面。此页面包含指向所有其他服务的链接。

Prometheus

Istio配有 Prometheus配置。它从服务的代理收集指标。这是监测的基础。

输入kubectl -n istio-system port-forward deployment/prometheus 9090:9090以创建Prometheus服务的代理。

您可以访问http:// localhost:9090 /然后访问Prometheus 。

您也可以使用shell脚本monitoring-prometheus.sh。

Grafana

Prometheus只有非常有限的仪表板。因此Istio带有一个安装Grafana提供更好的图表和仪表板。

输入kubectl -n istio-system port-forward deployment/grafana 3000:3000以创建Grafana服务的代理。您可以在http:// localhost:3000 /然后访问该服务。有很多预定义的仪表板。

您也可以使用shell脚本monitoring-grafana.sh。

追踪​​​​​​​

Jaeger是一个跟踪微服务之间呼叫的系统。Istio提供Jaeger的安装。如果您运行,kubectl -n istio-system port-forward deployment/istio-tracing 16686:16686您可以访问http:// localhost:16686 /

您也可以使用shell脚本tracing.sh。

记录​​​​​​​

Istio还支持日志记录。但是,Istio的日志仅包含有关HTTP请求的信息。这很有价值,但通常不足以理解微服务中的问题。因此,微服务需要记录一些信息。为了支持大量微服务并确保重启等不会影响系统,日志必须存储在集中式系统中。

该演示使用 Elasticsearch存储日志。微服务将其日志直接写入Elasticsearchs。Kibana用于显示和分析日志。

要使用日志基础结构,必须先启动它kubectl apply -f logging.yaml。

kubectl -n logging port-forward deployment/kibana 5601:5601 启动Kibana的代理,以便在http:// localhost:5601 /上访问它。你也可以使用kibana.sh。

如果在没有Elasticsearch服务器的情况下启动微服务,则在启动后它们不会再尝试访问它。因此,您可能需要通过执行kubectl delete -f microservices.yaml和重新启动所有微服务kubectl apply -f microservices.yaml。

可以删除日志记录基础结构kubectl delete -f logging.yaml。

故障注入

Instio提供了向系统添加故障方案的功能。fault-injection.yaml向订单服务的REST请求添加30秒的延迟。您可以将其添加到系统中kubectl apply -f fault-injection.yaml。如果您现在让系统从订单微服务轮询新信息,这需要相当长的时间,最后以错误结束。

这对于模拟系统中的错误很有用。

要再次移除故障注入,只需使用kubectl delete -f fault-injection.yaml。

断路器

Istio提供断路器。如果系统太慢或产生错误,仍然将所有请求发送到系统没有多大意义。因此,如果等待处理一定数量的请求,则Istio可以具有接收流量并触发断路器的规则。

使用kubectl apply -f cicuit-breaker.yaml激活规则和限制并发请求的数量这么多,很容易使系统过载。然后在系统上加载一些负载。有一个非常简单的shell脚本使用cURL生成一些负载,所以开始 ./load.sh "-X POST http://192.168.99.110:31380/invoicing/poll" &几次就足够了。您将在输出中看到一些HTTP 500。如果你做了额外的curl -X POST http://192.168.99.110:31380/invoicing/poll,其中相当一部分也会产生500. ingress-url.sh用来计算URL。

使用kubectl apply -f cicuit-breaker.yaml删除的规则。

请注意,您还可以设置超时,以便系统不会等待太长时间来处理请求,请参阅 https://istio.io/docs/tasks/traffic-management/request-timeouts/

清理

  • 要删除所有运行的服务和部署kubectl delete -f microservices.yaml:

kubectl  delete -f microservices.yaml
deployment.apps "catalog" deleted
deployment.apps "customer" deleted
deployment.apps "order" deleted
service "catalog" deleted
service "customer" deleted
service "order" deleted
virtualservice.networking.istio.io "customer" deleted
virtualservice.networking.istio.io "catalog" deleted
virtualservice.networking.istio.io "order" deleted

  • 然后删除基础结构 - 运行kubectl delete -f infrastructure.yaml:

kubectl  delete -f infrastructure.yaml
deployment.apps "apache" deleted
service "apache" deleted
gateway.networking.istio.io "microservice-gateway" deleted
virtualservice.networking.istio.io "apache" deleted

用Helm安装

微服务的Kubernetes配置非常相似。因此,使用模板并对其进行参数化是有意义的。Helm是一种创建此类模板并使用它们来部署Kubernetes系统的工具。这些模板称为Helm Charts。

  • 安装Helm,请参阅 https://github.com/helm/helm/blob/master/docs/install.md
  • 要在Kubernetes集群上实际使用Helm,您需要运行 helm init。
  • 确保部署基础结构kubectl apply -f infrastructure.yaml,参见上文。
  • 要安装微服务的一个order,shipping和 invoicing你只需要运行helm install --set name=order ../spring-boot-microservice/。../spring-boot-microservice是包含头盔图的目录。
  • 该文件spring-boot-microservice/values.yaml包含name可以为安装更改的其他值。
  • helm install --dry-run --set name=order ../spring-boot-microservice/。../spring-boot-microservice做一个干运行,即没有实际改变。
  • 您还可以使用install-helm.sh包含所有必需helm命令的shell scritp 来运行所有三个微服务:

./install-helm.sh
NAME:   wobbling-billygoat
LAST DEPLOYED: Wed Jan 16 10:07:50 2019
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/Pod(related)
NAME                    READY  STATUS   RESTARTS  AGE
order-79cd6c8844-vhcqj  0/2    Pending  0         0s

==> v1/Service
NAME   TYPE      CLUSTER-IP      EXTERNAL-IP  PORT(S)         AGE
order  NodePort  10.109.102.171  <none>       8080:31666/TCP  0s

==> v1beta1/Deployment
NAME   DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE
order  1        1        1           0          0s
...

  • 结果是使用不同参数多次安装Helm Chart。调用控制台输出中的那个 wobbling-billygoat。该名称是自动生成的。

清理Helm 安装

  • 首先,您需要确定Helm Chart安装的名称:

helm list
NAME            REVISION        UPDATED                         STATUS          CHART                           APP VERSION                                          NAMESPACE
flabby-abalone  1               Wed Jan 16 08:21:50 2019        DEPLOYED        spring-boot-microservice-0.1.0  1.0                                                  default
insipid-puma    1               Wed Jan 16 08:21:57 2019        DEPLOYED        spring-boot-microservice-0.1.0  1.0                                                  default
lame-skunk      1               Wed Jan 16 08:21:40 2019        DEPLOYED        spring-boot-microservice-0.1.0  1.0                                                  default

  • 然后你可以按名称删除:

[~/microservice-istio/microservice-istio-demo] helm delete flabby-abalone
release "flabby-abalone" deleted
<p>[~/microservice-istio/microservice-istio-demo] helm delete insipid-puma
,release "insipid-puma" deleted
<p>[~/microservice-istio/microservice-istio-demo] helm delete lame-skunk
release "lame-skunk" deleted

  • 您也可以删除基础架构kubectl delete -f infrastructure.yaml。

​​​​​​​点击标题见案例源码!