istio 1.10学习笔记07: 使用Istio Gateway将外部流量接入到服务网格
2021-07-22
在Kubernetes中提供了Ingress用来接入集群外部的流量,将集群内部的Service暴露到集群外部。 而Istio提供了另一个配置模型Istio Gateway,使用Istio Gateway同样可以将服务暴露到服务器网格之外,它还允许我们将Istio的功能(诸如:监控和路由规则等)应用到进入集群的流量上。
确认Istio Ingress Gateway的入口IP和端口 #
使用default
或demo
profile部署的istio默认都安装了istio-ingressgateway
组件:
1kubectl get all -n istio-system -l app=istio-ingressgateway
2NAME READY STATUS RESTARTS AGE
3pod/istio-ingressgateway-5d57955454-fv5np 1/1 Running 0 3d1h
4
5NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
6service/istio-ingressgateway LoadBalancer 10.106.130.216 <pending> 15021:31723/TCP,80:30709/TCP,443:31482/TCP,31400:32432/TCP,15443:31499/TCP 19d
7
8NAME READY UP-TO-DATE AVAILABLE AGE
9deployment.apps/istio-ingressgateway 1/1 1 1 19d
10
11NAME DESIRED CURRENT READY AGE
12replicaset.apps/istio-ingressgateway-5d57955454 1 1 1 19d
上面istio-ingressgateway
的Service的Type是LoadBalancer, 它的EXTERNAL-IP
处于pending
状态,
这是因为我们目前的环境并没有可用于Istio Ingress Gateway外部的负载均衡器,为了使得可以从外部访问,
通过修改istio-ingressgateway
这个Service的externalIps,因为当前Kubernetes集群的kube-proxy启用了ipvs,所以这个指定一个VIP 192.168.96.50作为externalIp。
此时再次查看istio-ingressgateway这个Service,EXTERNAL-IP
上已经变成我们设置的VIP了:
1kubectl get svc istio-ingressgateway -n istio-system
2NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
3istio-ingressgateway LoadBalancer 10.106.130.216 192.168.96.50 15021:31723/TCP,80:30709/TCP,443:31482/TCP,31400:32432/TCP,15443:31499/TCP
在每个k8s node上kube-proxy会监听各个service的port:
1netstat -ntlp | grep 192.168.96.50
2tcp 0 0 192.168.96.50:15021 0.0.0.0:* LISTEN 3055/kube-proxy
3tcp 0 0 192.168.96.50:80 0.0.0.0:* LISTEN 3055/kube-proxy
4tcp 0 0 192.168.96.50:15443 0.0.0.0:* LISTEN 3055/kube-proxy
5tcp 0 0 192.168.96.50:443 0.0.0.0:* LISTEN 3055/kube-proxy
6tcp 0 0 192.168.96.50:31400 0.0.0.0:* LISTEN 3055/kube-proxy
80和433将作为192.168.96.50这个VIP将集群外部流量接入的两个端口,分别对应http和https。
注意,这里使用k8s service的external ip则要求这个ip至少能够路由到集群中的一个或多个k8s节点,例如服务器是在openstack环境时,需要每个服务器的网络端口中配置添加一个可用地址对为external ip。
如果istio-ingressgateway这个Service的EXTERNAL-IP
值已设置,istio-ingressgateway组件就可以为Ingress Gateway提供服务。
如果EXTERNAL-IP
值为<none>
或持续显示<pending>
,则无法需要使用istio-ingressgateway这个Service的相关NodePort来访问Ingress Gateway提供服务,前面几节内容学习istio流量管理时就是使用NodePort来访问bookinfo应用。
使用Istio Gateway接入集群外部流量 #
前面我们可以从集群外部访问bookinfo应用,就是因为已经为bookinfo应用创建了Istio Gateway资源,对照k8s里的Ingress来理解的话:
- Istio
Gateway
: 相当于k8s里的Ingress, 需要为某个服务创建以把服务暴露到集群外部 istio-ingressgateway
组件相当于k8s里的ingress-controller
下面看一下前面部署bookinfo应用时创建的Gateway:
1kubectl get gateway bookinfo-gateway -o yaml
1apiVersion: networking.istio.io/v1beta1
2kind: Gateway
3metadata:
4 name: bookinfo-gateway
5 namespace: default
6spec:
7 selector:
8 istio: ingressgateway
9 servers:
10 - hosts:
11 - '*'
12 port:
13 name: http
14 number: 80
15 protocol: HTTP
在k8s的Ingress资源配置中除了配置对外暴露的端口、协议、域名等信息外还会有一些流量路由的配置(如基于不同path的);而Istio Gateway资源中只定义对外暴露的端口、协议、域名,对于路由信息需要使用Istio的虚拟服务VirtualService的路由规则来配置。
上面的bookinfo-gateway
配置了bookinfo应用以host为任意*
, 80端口http协议暴露到集群外部,那么一定还有对应的虚拟服务配置路由信息:
1kubectl get virtualservice bookinfo -o yaml
1apiVersion: networking.istio.io/v1beta1
2kind: VirtualService
3metadata:
4 name: bookinfo
5 namespace: default
6spec:
7 gateways:
8 - bookinfo-gateway
9 hosts:
10 - '*'
11 http:
12 - match:
13 - uri:
14 exact: /productpage
15 - uri:
16 prefix: /static
17 - uri:
18 exact: /login
19 - uri:
20 exact: /logout
21 - uri:
22 prefix: /api/v1/products
23 route:
24 - destination:
25 host: productpage
26 port:
27 number: 9080
gateways
指定了此虚拟服务的路由规则是为哪些gateway的。
上面的配置使用http://192.168.96.50/productpage
即可访问bookinfo应用。
实际中更多使用域名而非ip+path的形式来区分不同的应用,下面配置域名访问bookinfo应用,修改bookinfo的gateway如下:
1apiVersion: networking.istio.io/v1alpha3
2kind: Gateway
3metadata:
4 name: bookinfo-gateway
5spec:
6 selector:
7 istio: ingressgateway # use istio default controller
8 servers:
9 - port:
10 number: 80
11 name: http
12 protocol: HTTP
13 hosts:
14 - "bookinfo.example.com"
15---
16apiVersion: networking.istio.io/v1alpha3
17kind: VirtualService
18metadata:
19 name: bookinfo
20spec:
21 hosts:
22 - "bookinfo.example.com"
23 gateways:
24 - bookinfo-gateway
25 http:
26 - match:
27 - uri:
28 exact: /productpage
29 - uri:
30 prefix: /static
31 - uri:
32 exact: /login
33 - uri:
34 exact: /logout
35 - uri:
36 prefix: /api/v1/products
37 route:
38 - destination:
39 host: productpage
40 port:
41 number: 9080
按上面的配置完成对bookinfo gateway和路由规则的修改后,可以直接以地址http://bookinfo.example.com/productpage
访问bookinfo应用。
为Istio Gateway开启https #
下面为bookinfo应用的istio gateway开启https。创建bookinfo应用的Ingress Gateway所需的https证书的secret,注意是在istio-system的namespace下创建:
1kubectl create -n istio-system secret tls bookinfo-credential --key=bookinfo.example.com.key --cert=bookinfo.example.com.crt
注意secret的名称不能是以istio
或prometheus
开头,且不能包含token
字段。
修改bookinfo应用的Gateway:
1apiVersion: networking.istio.io/v1alpha3
2kind: Gateway
3metadata:
4 name: bookinfo-gateway
5spec:
6 selector:
7 istio: ingressgateway # use istio default controller
8 servers:
9 - port:
10 number: 80
11 name: http
12 protocol: HTTP
13 hosts:
14 - bookinfo.example.com
15 tls:
16 httpsRedirect: true
17 - port:
18 number: 443
19 name: https
20 protocol: HTTPS
21 tls:
22 mode: SIMPLE
23 credentialName: bookinfo-credential # must be the same as secret
24 hosts:
25 - bookinfo.example.com
26---
27apiVersion: networking.istio.io/v1alpha3
28kind: VirtualService
29metadata:
30 name: bookinfo
31spec:
32 hosts:
33 - bookinfo.example.com
34 gateways:
35 - bookinfo-gateway
36 http:
37 - match:
38 - uri:
39 exact: /productpage
40 - uri:
41 prefix: /static
42 - uri:
43 exact: /login
44 - uri:
45 exact: /logout
46 - uri:
47 prefix: /api/v1/products
48 route:
49 - destination:
50 host: productpage
51 port:
52 number: 9080
上面的bookinfo gateway配置了请求域名bookinfo.example.comhttp的80端口到https的443端口的自动重定向跳转,tls.mode=SIMPLE配置的是单向TLS,证书使用tls.credentialName指定前面创建在istio-system命名空间下的secret。
应用上面的配置后,使用https://bookinfo.example.com/productpage
地址就可以打开bookinfo应用页面。