Istio流量管理之Ingress Gateway

Istio Ingress Gateway是允许外部流量进入Istio服务网格的边缘服务。其比Kubernetes Ingress更具扩展性。且使用Istio Ingress Gateway,使得Istio对于入口流量同样具有策略控制能力及可观察性。

本文将使用Istio安装目录自带的httpbin样例来演示如何配置Gateway来实现外部访问。关于Istio安装等环境准备,请参阅“Istio安装使用”。

1 httpbin样例部署

进入Istio安装目录,应用自带的httpbin部署文件,将其部署到istio-demo namespace。

$ cd /usr/local/istio-1.8.1
$ kubectl apply -n istio-demo -f samples/httpbin/httpbin.yaml

2 httpbin配置Gateway

为httpbin创建Gateway。

$ kubectl apply -n istio-demo -f - <<EOF
heredoc> apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: httpbin-gateway
spec:
  selector:
    istio: ingressgateway # use Istio default gateway implementation
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "httpbin.example.com"
heredoc> EOF

为httpbin配置Virtual Service。

$ kubectl apply -n istio-demo -f - <<EOF
heredoc> apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: httpbin
spec:
  hosts:
  - "httpbin.example.com"
  gateways:
  - httpbin-gateway
  http:
  - match:
    - uri:
        prefix: /status
    route:
    - destination:
        port:
          number: 8000
        host: httpbin
heredoc> EOF

上述命令为httpbin配置Gateway与VirtualService,将其暴露给集群外部访问。且指定访问httpbin的Host须为httpbin.example.com,且只可访问前缀为/status的REST资源。同时我们可以看到,Istio Gateway与Kubernetes Ingress不同的是,无须在Gateway部署文件配置路由,而将路由配置移到了VirtualService。

下面通过查询用于外部访问的INGRESS_HOST与INGRESS_PORT来测试我们的配置。

3 httpbin外部访问

查询用于外部访问的INGRESS_HOST与INGRESS_PORT。

$ kubectl get svc istio-ingressgateway -n istio-system

NAME                   TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)
istio-ingressgateway   LoadBalancer   10.102.158.234   localhost     ...80:30841/TCP...

本文使用的是Docker Desktop自带的Kubernetes,可以看到INGRESS_HOST即为localhost,INGRESS_PORT为80。

亦可以使用如下命令查看INGRESS_HOST与INGRESS_PORT,得到同样的结果。

$ kubectl get svc istio-ingressgateway -n istio-system -o jsonpath='{.status.loadBalancer.ingress[0].hostname}'
$ kubectl get svc istio-ingressgateway -n istio-system -o jsonpath='{.spec.ports[?(@.name=="http2")].port}'

下面,分别尝试通过curl命令及浏览器来访问httpbin的status接口。

curl命令访问

通过如下命令访问httpbin的status接口时,发现报404错误。

$ curl -s -I http://localhost/status/200

HTTP/1.1 404 Not Found
date: Fri, 01 Jan 2021 08:27:57 GMT
server: istio-envoy
transfer-encoding: chunked

原因是我们在第2步的Gateway中指定访问Host必须为httpbin.example.com,加上Header后重新访问,发现状态码为200,访问成功。

$ curl -s -I -H "Host: httpbin.example.com" http://localhost/status/200
HTTP/1.1 200 OK
server: istio-envoy
date: Fri, 01 Jan 2021 08:28:02 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: 20

Web浏览器访问

使用浏览器直接打开http://localhost/status/200时,发现同样报404错误。因我们仅是在做测试,未真正配置域名解析,所以尝试将Gateway与VirtualService中hosts由httpbin.example.com改为通配符*来实现访问。

$ kubectl apply -n istio-demo -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: httpbin-gateway
spec:
  selector:
    istio: ingressgateway # use Istio default gateway implementation
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: httpbin
spec:
  hosts:
  - "*"
  gateways:
  - httpbin-gateway
  http:
  - match:
    - uri:
        prefix: /status
    route:
    - destination:
        port:
          number: 8000
        host: httpbin

这样,再次访问http://localhost/status/200时,发现返回200状态码。

4 环境清理

测试完成,使用如下命令清除httpbin的Gateway及VirtualService配置。

$ kubectl delete gateway httpbin-gateway -n istio-demo
$ kubectl delete virtualservice httpbin -n istio-demo

卸载httpbin。

$ cd /usr/local/istio-1.8.1
$ kubectl delete -n istio-demo -f samples/httpbin/httpbin.yaml

总结本文,首先介绍了使用Istio Gateway可以实现外部流量进入服务网格,然后为httpbin样例配置了Gateway并做了外部访问演示。

参考资料

[1] Istio Ingress Gateways

[2] Istio Traffic Management

若我的文章对您有帮助,欢迎小额打赏,以支持我更好的写作,Thanks!
微信 支付宝