【注意】最后更新于 July 22, 2021,文中内容可能已过时,请谨慎使用。
在Kubernetes中提供了Ingress用来接入集群外部的流量,将集群内部的Service暴露到集群外部。
而Istio提供了另一个配置模型Istio Gateway,使用Istio Gateway同样可以将服务暴露到服务器网格之外,它还允许我们将Istio的功能(诸如:监控和路由规则等)应用到进入集群的流量上。
确认Istio Ingress Gateway的入口IP和端口
使用default
或demo
profile部署的istio默认都安装了istio-ingressgateway
组件:
1
2
3
4
5
6
7
8
9
10
11
12
|
kubectl get all -n istio-system -l app=istio-ingressgateway
NAME READY STATUS RESTARTS AGE
pod/istio-ingressgateway-5d57955454-fv5np 1/1 Running 0 3d1h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/istio-ingressgateway LoadBalancer 10.106.130.216 <pending> 15021:31723/TCP,80:30709/TCP,443:31482/TCP,31400:32432/TCP,15443:31499/TCP 19d
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/istio-ingressgateway 1/1 1 1 19d
NAME DESIRED CURRENT READY AGE
replicaset.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了:
1
2
3
|
kubectl get svc istio-ingressgateway -n istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
istio-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:
1
2
3
4
5
6
|
netstat -ntlp | grep 192.168.96.50
tcp 0 0 192.168.96.50:15021 0.0.0.0:* LISTEN 3055/kube-proxy
tcp 0 0 192.168.96.50:80 0.0.0.0:* LISTEN 3055/kube-proxy
tcp 0 0 192.168.96.50:15443 0.0.0.0:* LISTEN 3055/kube-proxy
tcp 0 0 192.168.96.50:443 0.0.0.0:* LISTEN 3055/kube-proxy
tcp 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:
1
|
kubectl get gateway bookinfo-gateway -o yaml
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: bookinfo-gateway
namespace: default
spec:
selector:
istio: ingressgateway
servers:
- hosts:
- '*'
port:
name: http
number: 80
protocol: HTTP
|
在k8s的Ingress资源配置中除了配置对外暴露的端口、协议、域名等信息外还会有一些流量路由的配置(如基于不同path的);而Istio Gateway资源中只定义对外暴露的端口、协议、域名,对于路由信息需要使用Istio的虚拟服务VirtualService的路由规则来配置。
上面的bookinfo-gateway
配置了bookinfo应用以host为任意*
, 80端口http协议暴露到集群外部,那么一定还有对应的虚拟服务配置路由信息:
1
|
kubectl get virtualservice bookinfo -o yaml
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: bookinfo
namespace: default
spec:
gateways:
- bookinfo-gateway
hosts:
- '*'
http:
- match:
- uri:
exact: /productpage
- uri:
prefix: /static
- uri:
exact: /login
- uri:
exact: /logout
- uri:
prefix: /api/v1/products
route:
- destination:
host: productpage
port:
number: 9080
|
gateways
指定了此虚拟服务的路由规则是为哪些gateway的。
上面的配置使用http://192.168.96.50/productpage
即可访问bookinfo应用。
实际中更多使用域名而非ip+path的形式来区分不同的应用,下面配置域名访问bookinfo应用,修改bookinfo的gateway如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: bookinfo-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "bookinfo.example.com"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
- "bookinfo.example.com"
gateways:
- bookinfo-gateway
http:
- match:
- uri:
exact: /productpage
- uri:
prefix: /static
- uri:
exact: /login
- uri:
exact: /logout
- uri:
prefix: /api/v1/products
route:
- destination:
host: productpage
port:
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下创建:
1
|
kubectl create -n istio-system secret tls bookinfo-credential --key=bookinfo.example.com.key --cert=bookinfo.example.com.crt
|
注意secret的名称不能是以istio
或prometheus
开头,且不能包含token
字段。
修改bookinfo应用的Gateway:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: bookinfo-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- bookinfo.example.com
tls:
httpsRedirect: true
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: bookinfo-credential # must be the same as secret
hosts:
- bookinfo.example.com
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
- bookinfo.example.com
gateways:
- bookinfo-gateway
http:
- match:
- uri:
exact: /productpage
- uri:
prefix: /static
- uri:
exact: /login
- uri:
exact: /logout
- uri:
prefix: /api/v1/products
route:
- destination:
host: productpage
port:
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应用页面。

参考