本文记录istio搭建入口网关以及流量路由管控的场景。
一、应用准备
本文创建一个sprinboot应用做为docker镜像用于后面的验证。该springboot应用只提供了一个接口,分两个版本。
v1 版本:
@RestController
@RequestMapping("/test")
public class TestEndpoint {
private RestTemplate restTemplate;
@GetMapping("/get")
public String get(@RequestParam("a") String a) {
return "V test get and the parameter a is : " + a;
}
}
latest 版本:
@RestController
@RequestMapping("/test")
public class TestEndpoint {
private RestTemplate restTemplate;
@GetMapping("/get")
public String get(@RequestParam("a") String a) {
return "latest test get and the parameter a is : " + a;
}
}
打包成镜像,具体方法参考:Java应用打包成Docker镜像
二、应用部署
-
创建namespace
kubectl create ns istio-demos
添加istio-injection
kubectl label namespaces istio-demos istio-injection=enabled
查看标签是否添加成功
kubectl describe ns istio-demos
如果要删除标签的话,执行下面命令: kubectl label namespaces istio-demos istio-injection-
-
创建service account
demo-sa.yaml内容如下:apiVersion: v1 kind: ServiceAccount metadata: name: istio-demo
执行命令创建service account
kubectl apply -f demo-sa.yaml -n istio-demos
- 部署springboot pod
demo-a-vault.yaml
apiVersion: v1 kind: Service metadata: name: istio-springboot-demo-a labels: app: istio-springboot-demo-a service: istio-springboot-demo-a spec: ports: - name: http port: 8080 targetPort: 8080 selector: app: istio-springboot-demo-a --- apiVersion: apps/v1 kind: Deployment metadata: name: istio-springboot-demo-a-v1 spec: replicas: 1 selector: matchLabels: app: istio-springboot-demo-a version: v1 template: metadata: labels: app: istio-springboot-demo-a version: v1 spec: serviceAccountName: istio-demo containers: - image: demo-istio-springboot-demo-a:1.0-SNAPSHOT imagePullPolicy: IfNotPresent name: istio-springboot-demo-a ports: - containerPort: 8080 --- apiVersion: apps/v1 kind: Deployment metadata: name: istio-springboot-demo-a-latest spec: replicas: 1 selector: matchLabels: app: istio-springboot-demo-a version: latest template: metadata: labels: app: istio-springboot-demo-a version: latest spec: serviceAccountName: istio-demo containers: - image: demo-istio-springboot-demo-a:latest imagePullPolicy: IfNotPresent name: istio-springboot-demo-a ports: - containerPort: 8080
执行kubectl 命令创建service, Deployment
kubectl apply -f demo-a-vault.yaml -n istio-demos
- 部署springboot pod
三、外部访问应用
-
创建Gateway和VirtualService
demo-a-gateway.yamlapiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: istio-springboot-demo-a-gateway spec: selector: istio: ingressgateway servers: - port: number: 80 name: http protocol: HTTP hosts: - "*" --- apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: istio-springboot-demo-a spec: hosts: - "*" gateways: - istio-springboot-demo-a-gateway http: - route: - destination: host: istio-springboot-demo-a port: number: 8080
执行kubectl 命令:
kubectl apply -f demo-a-gateway.yaml -n istio-demos
-
查看标签为istio: ingressgateway 的service的EXTERNAL-IP
通过如下命令查看serivce信息:kubectl get service -n istio-system
输出结果如下:
% kubectl get service -n istio-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE grafana ClusterIP 10.109.66.208 <none> 3000/TCP 5d8h istio-egressgateway ClusterIP 10.106.23.204 <none> 80/TCP,443/TCP 5d9h istio-ingressgateway LoadBalancer 10.104.206.232 localhost 15021:30447/TCP,80:32629/TCP,443:32284/TCP 5d9h istiod ClusterIP 10.104.111.126 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP 5d10h jaeger-collector ClusterIP 10.97.49.134 <none> 14268/TCP,14250/TCP,9411/TCP 5d8h kiali ClusterIP 10.105.33.122 <none> 20001/TCP,9090/TCP 5d9h prometheus ClusterIP 10.96.74.154 <none> 9090/TCP 5d8h tracing ClusterIP 10.98.198.75 <none> 80/TCP,16685/TCP 5d8h zipkin ClusterIP 10.106.169.170 <none> 9411/TCP 5d8h
瞅着istio-ingressgateway最有可能,查看一下这个Service信息:
kubectl describe service istio-ingressgateway -n istio-systems
输出结果如下:
3.在/etc/hosts 中添加域名
Service istio-ingressgateway的EXTERNAL-IP是locahost, 可以在/etc/hosts中添加一个域名指向这个127.0.0.1,如下:
-
浏览器访问应用接口
通过域名访问: http://demoa.istiodemos.com/test/get?a=a35
此时会随机路由到v1版本和latest版本
四、路由管理
要实现更精细的路由管理就需要添加DestinationRule,以及对VirtualService做些许调整。
先将之前实验使用到的Gateway和VirtualService删除:
kubectl delete -f demo-a-gateway.yaml -n istio-demos
创建带路由规则的gateway
现在调整路由规则:
querystring a 匹配上正则时,路由到v1版本,否则都路由到latest版本
v1版本的querystring a正则规则:av\d+$
demo-a-route-gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: istio-springboot-demo-a-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: istio-springboot-demo-a-dr
spec:
host: istio-springboot-demo-a
trafficPolicy:
loadBalancer:
simple: LEAST_CONN
subsets:
- name: v1
labels:
version: v1
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
- name: latest
labels:
version: latest
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: istio-springboot-demo-a-vs
spec:
hosts:
- "*"
gateways:
- istio-springboot-demo-a-gateway
http:
- match:
- queryParams:
a:
# exact: ad
regex: av\d+$
route:
- destination:
host: istio-springboot-demo-a
subset: v1
- route:
- destination:
host: istio-springboot-demo-a
subset: latest
执行kubectl 命令:
kubectl apply -f demo-a-route-gateway.yaml -n istio-demos
访问应用接口
实验:
1、http://demoa.istiodemos.com/test/get?a=av35 路由到v1版本
2、http://demoa.istiodemos.com/test/get?a=adfdsf 路由到latest版本