玖叶教程网

前端编程开发入门

istio 1.10学习笔记07: 使用Istio Gateway将外部流量接入到服务网格

在Kubernetes中提供了Ingress用来接入集群外部的流量,将集群内部的Service暴露到集群外部。 而Istio提供了另一个配置模型Istio Gateway,使用Istio Gateway同样可以将服务暴露到服务器网格之外,它还允许我们将Istio的功能(诸如:监控和路由规则等)应用到进入集群的流量上。

确认Istio Ingress Gateway的入口IP和端口

使用defaultdemo profile部署的istio默认都安装了istio-ingressgateway组件:

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了:

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:

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:

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

在k8s的Ingress资源配置中除了配置对外暴露的端口、协议、域名等信息外还会有一些流量路由的配置(如基于不同path的);而Istio Gateway资源中只定义对外暴露的端口、协议、域名,对于路由信息需要使用Istio的虚拟服务VirtualService的路由规则来配置。 上面的bookinfo-gateway配置了bookinfo应用以host为任意*, 80端口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

gateways指定了此虚拟服务的路由规则是为哪些gateway的。

上面的配置使用http://192.168.96.50/productpage即可访问bookinfo应用。

实际中更多使用域名而非ip+path的形式来区分不同的应用,下面配置域名访问bookinfo应用,修改bookinfo的gateway如下:

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下创建:

kubectl create -n istio-system secret tls bookinfo-credential --key=bookinfo.example.com.key --cert=bookinfo.example.com.crt

注意secret的名称不能是以istioprometheus开头,且不能包含token字段。

修改bookinfo应用的Gateway:

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应用页面。


参考

  • https://istio.io/latest/zh/docs/tasks/traffic-management/ingress/ingress-control/
  • https://istio.io/latest/zh/docs/tasks/traffic-management/ingress/secure-ingress/

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言