内容简介:如果单纯使用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应用程序。现在我打赌你对像 VirtualService , DestinationRule 这样的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微服务网格演示源码》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 堆排序动画演示,Python代码演示,看不懂你砍我!
- GraphQL案例演示
- Kubernetes身份验证机制演示
- 中心极限定理的Matlab演示
- 中心极限定理的Matlab演示
- [Grid 网格布局教程]显式网格和隐式网格之间的区别
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
RESTful Web Services Cookbook
Subbu Allamaraju / Yahoo Press / 2010-3-11 / USD 39.99
While the REST design philosophy has captured the imagination of web and enterprise developers alike, using this approach to develop real web services is no picnic. This cookbook includes more than 10......一起来看看 《RESTful Web Services Cookbook》 这本书的介绍吧!