SpringBoot、Kubernetes和Istio微服务网格演示源码

栏目: Java · 发布时间: 5年前

内容简介:如果单纯使用kubernetes的pod部署Spring微服务,K8s的负载平衡以及代理设置和你微服务应用之间不是非常的智能衔接,。无论如何,部署新的应用程序版本pod需要更加软化的方法。以下是典型的需求:所有这些问题都可以通过名为

如果单纯使用kubernetes的pod部署Spring微服务,K8s的负载平衡以及代理设置和你微服务应用之间不是非常的智能衔接,。无论如何,部署新的应用程序版本pod需要更加软化的方法。以下是典型的需求:

  • 智能调拨流量,在部署新的应用程序版本容器时,您经常需要以某种比例(即金丝雀 Canary测试) 分割新容器和当前生产之间的流量
  • 蓝绿部署,在部署新的应用程序版本pod时,假设您需要 蓝色/绿色部署
  • 在部署新的应用程序版本pod时,让我们说只有HTTP cookie识别的一些用户可以测试新版本

所有这些问题都可以通过名为 istio 的神奇 工具 来解决。

Istio安装

首先是在Istio安装之前,需要以至少4GB的内存启动 Minikube ,否则将无法启动 pilot ,阅读 stackoverflow讨论 ;第二个重要的是始终使用Istio Custom Resources Definitions开始安装:

$ kubectl apply -f <ISTIO_INSTALL_HOME> /install/kubernetes/helm/istio/templates/crds.yaml

这是安装后所需的输出:

kubernetes tomask79$ kubectl get pods -n istio-system
NAME                                      READY   STATUS      RESTARTS   AGE
grafana-59b8896965-6jcb8                  1/1     Running     4          7d
istio-citadel-856f994c58-jwdp2            1/1     Running     4          7d
istio-cleanup-secrets-glmrz               0/1     Completed   0          7d
istio-egressgateway-5649fcf57-5b885       1/1     Running     4          7d
istio-galley-7665f65c9c-89wsz             1/1     Running     13         7d
istio-grafana-post-install-z9v7z          0/1     Completed   0          7d
istio-ingressgateway-6755b9bbf6-qrvq8     1/1     Running     4          7d
istio-pilot-698959c67b-xpqnj              2/2     Running     11         7d
istio-policy-6fcb6d655f-8mkf4             2/2     Running     18         7d
istio-security-post-install-jn4sr         0/1     Completed   0          7d
istio-sidecar-injector-768c79f7bf-p8xqr   1/1     Running     4          7d
istio-telemetry-664d896cf5-zc8sr          2/2     Running     17         7d
istio-tracing-6b994895fd-wpc2c            1/1     Running     7          7d
prometheus-76b7745b64-hqnrq               1/1     Running     4          7d
servicegraph-5c4485945b-jql54             1/1     Running     12         7d

演示示例

在向您展示Istio流量管理魔术之前,我们将介绍第一个非常简单的Spring Boot MVC应用程序,我们将在两个版本中部署到kubernetes。

版本1:

@RestController
<b>public</b> <b>class</b> ControllerV1 {

    @GetMapping(path = <font>"/service"</font><font>)
    <b>public</b> String getResult() {
        <b>return</b> </font><font>"Hello I'm V1!"</font><font>;
    }
}
</font>

下面是这个版本的k8s的部署,标记mvc-service开始部分:

(mvc-1/istio/kubernetes-deploy/v1-deploy.yaml)

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: mvc-service
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: mvc-service
        version: v1
    spec:
      containers:
      - name: mvc-service
        image: service-v1:0.0.1-SNAPSHOT
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080

版本2:

@RestController
<b>public</b> <b>class</b> ControllerV2 {

    @GetMapping(path = <font>"/service"</font><font>)
    <b>public</b> String getResult() {
        <b>return</b> </font><font>"Hello i'm V2!"</font><font>;
    }
}
</font>

下面是这个版本的k8s的部署,标记mvc-service开始部分:

(mvc-2/istio/kubernetes-deploy/v2-deploy.yaml)

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: mvc-service-v2
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: mvc-service
        version: v2
    spec:
      containers:
      - name: mvc-service
        image: service-v2:0.0.1-SNAPSHOT
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080

我们在标有“mvc-service”字符串的pod中有两个版本的应用程序。因此kubernetes服务还应该使用标签'mvc-service'来定位pod后端:(mvc-1/istio/kubernetes-deploy/v1-deploy.yaml)

apiVersion: v1
kind: Service
metadata:
  name: mvc-service
  labels:
    app: mvc-service
spec:
  type: NodePort
  ports:
  - port: 8080
    name: http
  selector:
    app: mvc-service

使用Istio支持部署到Kubernetes

好的,我们已经准备好了kubernetes清单,但还没有部署任何东西!为了能够使用 Istio流量管理, 您需要向您的pod 注入 sidecar代理 。如果没有istio边车,你就不会形成 服务网格 。你有两个选择:

我选择了第一个选项并将边车sidecar设置注入到这样的清单中:

istioctl kube-inject -f v1-deploy.yaml >> v1-deploy-istio.yaml

对于第二个版本(文件夹mvc-2 / istio / kubernetes-deploy)同样这么做:

istioctl kube-inject -f v2-deploy.yaml >> v2-deploy-istio.yaml

现在部署生成的kubernetes清单注入istio-sidecar:

kubectl apply -f v1-deploy-istio.yaml

然后部署第二个版本:

kubectl apply -f v2-deploy-istio.yaml

这是部署后所需的输出:

kubectl get pods
NAME                              READY   STATUS    RESTARTS   AGE
mvc-service-76ffb4bc9f-sdrtn      2/2     Running   10         10d
mvc-service-v2-59ff7d6886-v87jt   2/2     Running   10         10d

每个POD都有两个容器,因为它运行app容器和istio代理边车容器。要查看为pod启动的边车代理,只需键入:

kubernetes - deploy  tomask79 $  kubectl  describe  pod  mvc - service - 76 ffb4bc9f - sdrtn

检查事件:

Events:
  Type    Reason          Age    From               Message
  ----    ------          ----   ----               -------
  Normal  SandboxChanged  8m41s  kubelet, minikube  Pod sandbox changed, it will be killed and re-created.
  Normal  Pulled          8m37s  kubelet, minikube  Container image <font>"docker.io/istio/proxy_init:1.0.5"</font><font> already present on machine
  Normal  Created         8m35s  kubelet, minikube  Created container
  Normal  Started         8m34s  kubelet, minikube  Started container
  Normal  Pulled          8m34s  kubelet, minikube  Container image </font><font>"service-v1:0.0.1-SNAPSHOT"</font><font> already present on machine
  Normal  Created         8m33s  kubelet, minikube  Created container
  Normal  Started         8m33s  kubelet, minikube  Started container
  Normal  Pulled          8m33s  kubelet, minikube  Container image </font><font>"docker.io/istio/proxyv2:1.0.5"</font><font> already present on machine
  Normal  Created         8m33s  kubelet, minikube  Created container
  Normal  Started         8m33s  kubelet, minikube  Started container
</font>

Istio形成服务网格

好的,部署了两个版本的Spring Boot MVC应用程序。现在我打赌你对像 VirtualServiceDestinationRule 这样的Istio对象感到困惑......什么时候使用它们,你还在Kubernetes服务吗?在 stackoverflow 有一个非常好的讨论,这对我来说非常有用。简而言之:

在我们的Spring MVC演示中,我们获得了名为mvc-service的kubernetes 服务。这将是DestinationRule 对象中的主机参数,因为这是提供目标服务的后端。现在我们的mvc-service提供了两个版本的Spring MVC应用程序v1和v2 ,它们将构成 服务网格 ,因此DestinationRule看起来像:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: mvc-service
spec:
  host: mvc-service
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2

在我们的演示中,通过kubectl部署它:

spring-kubernetes-istio tomask79$ kubectl apply -f istio-destionation-rule.yaml 

现在VirtualService进入游戏:

VirtualService定义了一组要在主机被寻址时应用的流量路由规则。每个路由规则定义特定协议的流量的匹配标准。如果流量匹配,则将其发送到注册表中定义的命名目标服务(或其子集 /版本)。

换句话说,您首先部署K8s部署和服务。然后,通过Istio DestionRule定义微服务的网络,然后通过VirtualService设置HTTP路由规则。

用Istio进行金丝雀测试

因此,假设我们的演示SpringMVC应用程序的第二个版本(在服务网格中,子集v2)不够稳定,无法处理满负载,因此我们只将20%的流量路由到它。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: service-gateway
spec:
  hosts:
  - <font>"*"</font><font>
  gateways:
  - service-gateway
  http:
  - match:
    - uri:
        exact: /service
    route:
    - destination:
        host: mvc-service
        subset: v1
      weight: 80
    - destination:
        host: mvc-service
        subset: v2
      weight: 20
</font>

这真的很容易。作为最后一步,我们需要公开服务网关,即 Istio-Ingress网关 ,它从服务网格外部获取流量并将其转发到该 网关

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: service-gateway
spec:
  selector:
    istio: ingressgateway # use istio <b>default</b> controller
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - <font>"*"</font><font>
</font>

在这个repo中提到的网关和虚拟服务都在istio-gateway.yaml文件中,所以让我们部署它:

spring-kubernetes-istio tomask79$ kubectl apply -f istio-gateway.yaml

好的,这是测试之前所需的输出,服务网格在前:

istioctl get destinationrules -o yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {<font>"apiVersion"</font><font>:</font><font>"networking.istio.io/v1alpha3"</font><font>,</font><font>"kind"</font><font>:</font><font>"DestinationRule"</font><font>,</font><font>"metadata"</font><font>:{</font><font>"annotations"</font><font>:{},</font><font>"name"</font><font>:</font><font>"mvc-service"</font><font>,</font><font>"namespace"</font><font>:</font><font>"default"</font><font>},</font><font>"spec"</font><font>:{</font><font>"host"</font><font>:</font><font>"mvc-service"</font><font>,</font><font>"subsets"</font><font>:[{</font><font>"labels"</font><font>:{</font><font>"version"</font><font>:</font><font>"v1"</font><font>},</font><font>"name"</font><font>:</font><font>"v1"</font><font>},{</font><font>"labels"</font><font>:{</font><font>"version"</font><font>:</font><font>"v2"</font><font>},</font><font>"name"</font><font>:</font><font>"v2"</font><font>}]}}
  creationTimestamp: <b>null</b>
  name: mvc-service
  namespace: <b>default</b>
  resourceVersion: </font><font>"5722"</font><font>
spec:
  host: mvc-service
  subsets:
  - labels:
      version: v1
    name: v1
  - labels:
      version: v2
    name: v2
---
</font>

然后是virtualservices:

istioctl get virtualservices -o <b>short</b>
VIRTUAL-SERVICE NAME   GATEWAYS          HOSTS         #HTTP     #TCP      NAMESPACE   AGE
mvc-service                              mvc-service       1        0      <b>default</b>     11d
service-gateway        service-gateway   *                 1        0      <b>default</b>     11d

金丝雀测试

我们需要获取istio-ingress网关和端口的IP地址。

kubectl get service istio-ingressgateway -n istio-system
NAME                   TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)                                                                                                                   AGE
istio-ingressgateway   LoadBalancer   10.111.15.19   <pending>     80:31380/TCP,443:31390/TCP,31400:31400/TCP,15011:32464/TCP,8060:30626/TCP,853:30365/TCP,15030:31121/TCP,15031:31359/TCP   13d

istio-ingress文档如是说:

如果设置了EXTERNAL-IP值,则您的环境具有可 用于入口网关的外部负载平衡器。如果EXTERNAL-IP值为<none>(或永久<pending>),则您的环境 不会为入口网关提供外部负载平衡器。在这种情况下,您可以 使用service s节点端口访问网关。

这意味着调用我们的金丝雀版本,我们将继续:

 minikube ip
192.168.99.110

现在终于调用了后台,请注意文档中指出的nodeport端口:

10个点击中:2个进入V2版本,8个点击进入V1。

tomask79:spring-kubernetes-istio tomask79$ curl http:<font><i>//192.168.99.110:31380/service</i></font><font>
Hello I'm V1!tomask79:spring-kubernetes-istio tomask79$ curl http:</font><font><i>//192.168.99.110:31380/service</i></font><font>
Hello I'm V1!tomask79:spring-kubernetes-istio tomask79$ curl http:</font><font><i>//192.168.99.110:31380/service</i></font><font>
Hello I'm V1!tomask79:spring-kubernetes-istio tomask79$ curl http:</font><font><i>//192.168.99.110:31380/service</i></font><font>
Hello i'm V2!tomask79:spring-kubernetes-istio tomask79$ curl http:</font><font><i>//192.168.99.110:31380/service</i></font><font>
Hello I'm V1!tomask79:spring-kubernetes-istio tomask79$ curl http:</font><font><i>//192.168.99.110:31380/service</i></font><font>
Hello I'm V1!tomask79:spring-kubernetes-istio tomask79$ curl http:</font><font><i>//192.168.99.110:31380/service</i></font><font>
Hello I'm V1!tomask79:spring-kubernetes-istio tomask79$ curl http:</font><font><i>//192.168.99.110:31380/service</i></font><font>
Hello I'm V1!tomask79:spring-kubernetes-istio tomask79$ curl http:</font><font><i>//192.168.99.110:31380/service</i></font><font>
Hello i'm V2!tomask79:spring-kubernetes-istio tomask79$ curl http:</font><font><i>//192.168.99.110:31380/service</i></font><font>
Hello I'm V1!tomask79:spring-kubernetes-istio tomask79$ 
</font>

使用Istio进行蓝/绿部署

现在让我们说我们的应用程序的V2版本足够稳定,我们可以将100%的流量路由到它。要使用Istio实现这一点,我们将更改VirtualService中的规则:

将istio-gateway.yaml文件中的VirtualService修改为:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: service-gateway
spec:
  hosts:
  - <font>"*"</font><font>
  gateways:
  - service-gateway
  http:
  - match:
    - uri:
        exact: /service
    route:
    - destination:
        host: mvc-service
        subset: v2
</font>

重新部署:

tomask79:spring-kubernetes-istio tomask79$ kubectl apply -f istio-gateway.yaml 
gateway.networking.istio.io/service-gateway unchanged
virtualservice.networking.istio.io/service-gateway configured

测试蓝/绿部署

现在V2版本应该成为我们的生产版本并处理100%的流量:

tomask79:spring-kubernetes-istio tomask79$ curl http:<font><i>//192.168.99.110:31380/service</i></font><font>
Hello i'm V2!tomask79:spring-kubernetes-istio tomask79$ curl http:</font><font><i>//192.168.99.110:31380/service</i></font><font>
Hello i'm V2!tomask79:spring-kubernetes-istio tomask79$ curl http:</font><font><i>//192.168.99.110:31380/service</i></font><font>
Hello i'm V2!tomask79:spring-kubernetes-istio tomask79$ curl http:</font><font><i>//192.168.99.110:31380/service</i></font><font>
Hello i'm V2!tomask79:spring-kubernetes-istio tomask79$ curl http:</font><font><i>//192.168.99.110:31380/service</i></font><font>
Hello i'm V2!tomask79:spring-kubernetes-istio tomask79$ curl http:</font><font><i>//192.168.99.110:31380/service</i></font><font>
Hello i'm V2!tomask79:spring-kubernetes-istio tomask79$ curl http:</font><font><i>//192.168.99.110:31380/service</i></font><font>
Hello i'm V2!tomask79:spring-kubernetes-istio tomask79$ curl http:</font><font><i>//192.168.99.110:31380/service</i></font><font>
Hello i'm V2!tomask79:spring-kubernetes-istio tomask79$ curl http:</font><font><i>//192.168.99.110:31380/service</i></font><font>
Hello i'm V2!tomask79:spring-kubernetes-istio tomask79$ curl http:</font><font><i>//192.168.99.110:31380/service</i></font><font>
Hello i'm V2!tomask79:spring-kubernetes-istio tomask79$ 
</font>

总结

Istio看起来对我来说是超级强大的工具。但它的学习曲线有点长。此外,他们还在配置模型之间进行了 重大更改 。无论如何,他们支持粘性会话甚至websockets。例如,对于我在EmbedIT中使用的系统,这是两个“必须拥有”的东西。像istio这样的另一个类似工具是 Linkerd 。你也可以看一下:)

本文源码


以上所述就是小编给大家介绍的《SpringBoot、Kubernetes和Istio微服务网格演示源码》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Essential ActionScript 3.0

Essential ActionScript 3.0

Colin Moock / Adobe Dev Library / June 22, 2007 / $34.64

ActionScript 3.0 is a huge upgrade to Flash's programming language. The enhancements to ActionScript's performance, feature set, ease of use, cleanliness, and sophistication are considerable. Essentia......一起来看看 《Essential ActionScript 3.0》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

随机密码生成器
随机密码生成器

多种字符组合密码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器