在Kubernetes中提供了Ingress用来接入集群外部的流量,将集群内部的Service暴露到集群外部。 而Istio提供了另一个配置模型Istio Gateway,使用Istio Gateway同样可以将服务暴露到服务器网格之外,它还允许我们将Istio的功能(诸如:监控和路由规则等)应用到进入集群的流量上。 使用default或demo profile部署的istio默认都安装了istio-ingressgateway组件: 上面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了: 在每个k8s node上kube-proxy会监听各个service的port: 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应用。 前面我们可以从集群外部访问bookinfo应用,就是因为已经为bookinfo应用创建了Istio Gateway资源,对照k8s里的Ingress来理解的话: 下面看一下前面部署bookinfo应用时创建的Gateway: 在k8s的Ingress资源配置中除了配置对外暴露的端口、协议、域名等信息外还会有一些流量路由的配置(如基于不同path的);而Istio Gateway资源中只定义对外暴露的端口、协议、域名,对于路由信息需要使用Istio的虚拟服务VirtualService的路由规则来配置。 上面的bookinfo-gateway配置了bookinfo应用以host为任意*, 80端口http协议暴露到集群外部,那么一定还有对应的虚拟服务配置路由信息: gateways指定了此虚拟服务的路由规则是为哪些gateway的。 上面的配置使用http://192.168.96.50/productpage即可访问bookinfo应用。 实际中更多使用域名而非ip+path的形式来区分不同的应用,下面配置域名访问bookinfo应用,修改bookinfo的gateway如下: 按上面的配置完成对bookinfo gateway和路由规则的修改后,可以直接以地址http://bookinfo.example.com/productpage访问bookinfo应用。 下面为bookinfo应用的istio gateway开启https。创建bookinfo应用的Ingress Gateway所需的https证书的secret,注意是在istio-system的namespace下创建: 注意secret的名称不能是以istio或prometheus开头,且不能包含token字段。 修改bookinfo应用的Gateway: 上面的bookinfo gateway配置了请求域名bookinfo.example.comhttp的80端口到https的443端口的自动重定向跳转,tls.mode=SIMPLE配置的是单向TLS,证书使用tls.credentialName指定前面创建在istio-system命名空间下的secret。 应用上面的配置后,使用https://bookinfo.example.com/productpage地址就可以打开bookinfo应用页面。确认Istio Ingress Gateway的入口IP和端口
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
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
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
使用Istio Gateway接入集群外部流量
kubectl get gateway bookinfo-gateway -o yaml
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
kubectl get virtualservice bookinfo -o yaml
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
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
为Istio Gateway开启https
kubectl create -n istio-system secret tls bookinfo-credential --key=bookinfo.example.com.key --cert=bookinfo.example.com.crt
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
参考