Istio Ingress—控制进入网格的流量(把网格中的服务暴露出去)


Istio Ingress—控制进入网格的流量(把网格中的服务暴露出去)

Ingress 基本概念

Istio Ingress 它作为服务的访问入口,接收外部请求并转发到后端服务。

Istio Gateway 的功能与 Kubernetes Ingress 类似,负责进出集群的南北流量。Istio Gateway 描述了一个负载均衡器,用于承载进出服务网格边缘的连接。该规范描述了一组开放端口和这些端口所使用的协议,以及用于负载均衡的 SNI 配置等。

Istio Gateway 资源本身只能配置L4到L6的功能,例如暴露的端口、TLS 设置等;但 Gateway 可与 VirtualService 绑定,在VirtualService 中可以配置七层路由规则,例如按比例和版本的流量路由,故障注入,HTTP 重定向,HTTP 重写等所有Mesh内部支持的路由规则。

Istio 的 Ingress gateway 和 kubernetes Ingress 的区别

  • Kubernetes: 针对 L7 协议(资源受限),可定义基础路由规则
  • Istio: 针对 L4-6 协议,只定义接入点,把所有的路由规则全都交给 VirtualService 去管理,这样就可以复用 VirtualService 里面丰富的路由配置

创建 Ingress 网关示例

确定入口 IP 和端口

  • 设置入口端口:

    export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
    export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].nodePort}')
    export TCP_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="tcp")].nodePort}')
  • 设置入口 IP

    export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n istio-system -o jsonpath='{.items[0].status.hostIP}')
    

任务说明

我们会创建一个 Ingress 网关,并且引入一个新的服务 httpbin,同时把 httpbin 这个服务通过 Ingress 暴露给外部的请求可以访问。

演示

  • 部署 httpbin 服务

    # zhangquan @ MacBook-Pro-2 in ~/Downloads/devops/istio-1.5.1 [18:20:24] 
    $ kubectl apply -f samples/httpbin/httpbin.yaml
    serviceaccount/httpbin created
    service/httpbin created
    deployment.apps/httpbin created
    
    # 查看部署的 Pod
    $ kubectl get pod
    NAME                              READY   STATUS            RESTARTS   AGE
    ......
    httpbin-779c54bf49-wlxjk          0/2     PodInitializing   0          85s
    ......
  • 部署针对 httpbin 这个服务的 Ingress

    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1alpha3
    kind: Gateway
    metadata:
      name: httpbin-gateway
    spec:
      selector:
        istio: ingressgateway # use Istio default gateway implementation
      servers:
      - port:    # 暴露 http 的 80 端口作为访问点
          number: 80
          name: http
          protocol: HTTP
        hosts:
        - "httpbin.example.com"
    EOF
    
  • 给 Gateway 创建一个对应的 Virtual Service,让它来对 httpbin 这个服务做一个简单的路由

    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: httpbin
    spec:
      hosts:
      - "httpbin.example.com"  # 要跟 gateway 对应设置一个相同的 hosts
      gateways:
      - httpbin-gateway   # 绑定刚才创建的 gateway 名称
      http:
      - match:
        - uri:
            prefix: /status
        - uri:
            prefix: /delay
        route:
        - destination:
            port:
              number: 8000
            host: httpbin
    EOF
    

    您现在已经为 httpbin 服务创建了一个虚拟服务配置,其中包含两个允许路径 /status 和 /delay 的流量的路由规则。

    gateways 列表指定只允许通过您的 httpbin-gateway 的请求。 所有其他外部请求都将被 404 响应拒绝。

  • 查看系统中虚拟服务信息

    # zhangquan @ MacBook-Pro-2 in ~/Downloads/devops/istio-1.5.1 [18:32:45] C:130
    $ kubectl get vs 
    NAME           GATEWAYS             HOSTS                   AGE
    ......
    httpbin        [httpbin-gateway]    [httpbin.example.com]   4m4s
    ......

    可以看到我们已经创建了一个叫 httpbin 的虚拟服务,它对应的网关就是我们刚创建的叫 httpbin-gateway 网关,它绑定的 host 也是我们在网关中配置的 host

  • 使用 curl 访问 httpbin 服务

    首先我们访问第一个接口就是 status 接口,这个接口会根据你后面的参数,也就是 response code 来给你打印出相应的信息

    $ curl -s -I -HHost:httpbin.example.com "http://$INGRESS_HOST:$INGRESS_PORT/status/200"
    HTTP/1.1 200 OK
    server: istio-envoy
    date: Sun, 06 Nov 2022 10:50:40 GMT
    content-type: text/html; charset=utf-8
    access-control-allow-origin: *
    access-control-allow-credentials: true
    content-length: 0
    x-envoy-upstream-service-time: 3

    请注意,因为我们之前设置的 host 字段 “httpbin.example.com” 并不是真实存在的,所以我们需要通过 curl 里面的 -H 入参把这个域名设置进来以模拟它的请求。

    接口再来测试一下第一个 uri 是 delay,delay 这个接口会根据你后面的入参具体延迟多少秒,比如下面的请求会延迟2秒:

    $ curl -s -I -HHost:httpbin.example.com "http://$INGRESS_HOST:$INGRESS_PORT/delay/2"   
    HTTP/1.1 200 OK
    server: istio-envoy
    date: Sun, 06 Nov 2022 10:52:47 GMT
    content-type: application/json
    content-length: 728
    access-control-allow-origin: *
    access-control-allow-credentials: true
    x-envoy-upstream-service-time: 2015

    访问尚未明确公开的任何其他 URL。 您应该会看到 HTTP 404 错误:

    $ curl -s -I -HHost:httpbin.example.com "http://$INGRESS_HOST:$INGRESS_PORT/headers"
    HTTP/1.1 404 Not Found
    date: Sun, 06 Nov 2022 10:53:23 GMT
    server: istio-envoy
    transfer-encoding: chunked

    这说明我们可以使用 Ingress 来访问之前部署在网格内的 httpbin 这个服务了。

  • 配置分析

Cleanup

删除Gateway和VirtualService配置,关闭httpbin服务:

kubectl delete gateway httpbin-gateway
kubectl delete virtualservice httpbin
kubectl delete --ignore-not-found=true -f samples/httpbin/httpbin.yaml

参考


文章作者: 张权
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 张权 !
评论
  目录