# ingress

除了对Kubernetes Ingress的支持之外,Istio还提供了另一种配置模型Istio Gateway。Gateway与相比Ingress,A提供了更广泛的自定义和灵活性,并允许将Istio功能(例如监视和路由规则)应用于进入集群的流量。

此任务描述如何配置Istio以使用Istio在服务网格外部公开服务Gateway。

在你开始之前 按照安装指南中的说明安装Istio 。

确保当前目录是该istio目录。

启动httpbin示例。

如果启用了自动边车注入,请部署httpbin服务:

$ kubectl apply -f samples/httpbin/httpbin.yaml

否则,您必须在部署httpbin应用程序之前手动注入sidecar :

$ kubectl apply -f <(istioctl kube-inject -f samples/httpbin/httpbin.yaml)

如以下小节所述,确定入口IP和端口。 确定入口IP和端口 执行以下命令以确定您的Kubernetes集群是否在支持外部负载均衡器的环境中运行:

$ kubectl get svc istio-ingressgateway -n istio-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE istio-ingressgateway LoadBalancer 172.21.109.129 130.211.10.121 ... 17h

如果EXTERNAL-IP设置了该值,则您的环境具有可用于入口网关的外部负载均衡器。如果EXTERNAL-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取决于集群提供者:

GKE:

$ export INGRESS\_HOST=worker-node-address

您需要创建防火墙规则,以允许TCP流量进入Ingressgateway服务的端口。运行以下命令以允许HTTP端口和/或安全端口(HTTPS)的通信:

$ gcloud compute firewall-rules create allow-gateway-http --allow "tcp:$INGRESS\_PORT" $ gcloud compute firewall-rules create allow-gateway-https --allow "tcp:$SECURE\_INGRESS\_PORT"

IBM Cloud Kubernetes服务:

$ ibmcloud ks workers --cluster cluster-name-or-id $ export INGRESS\_HOST=public-IP-of-one-of-the-worker-nodes

迷你库:

$ export INGRESS\_HOST=$(minikube ip)

桌面版Docker:

$ export INGRESS\_HOST=127.0.0.1

其他环境:

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

使用Istio网关配置入口 入口网关描述了负载均衡器,该负载均衡器在网格的边缘运行,以接收传入的HTTP/TCP连接。它配置暴露的端口,协议等,但与Kubernetes Ingress资源不同,它不包含任何流量路由配置。相反,使用Istio路由规则配置入口流量的流量路由,其方式与内部服务请求的方式完全相同。

让我们看看如何Gateway在端口80上配置HTTP流量。

创建一个Istio Gateway:

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

    &#x20; number: 80

    &#x20; name: http

    &#x20; protocol: HTTP

    hosts:

    *   "httpbin.example.com"

        EOF

配置通过以下路径进入的流量的路由Gateway:

$ kubectl apply -f - <\<EOF apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: httpbin spec: hosts:

*   "httpbin.example.com"

    gateways:
*   httpbin-gateway

    http:
* match:
  *   uri:

      &#x20; prefix: /status
  *   uri:

      &#x20; prefix: /delay

      route:
  *   destination:

      &#x20; port:

      ```
      number: 8000
      ```

      &#x20; host: httpbin

      EOF

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

该网关列表指定,只有通过你的请求httpbin-gateway是允许的。所有其他外部请求将被404响应拒绝。

来自网格中其他服务的内部请求不受这些规则的约束,而是默认为轮询路由。要将这些规则也应用于内部调用,您可以将特殊值添加mesh到的列表中gateways。由于服务的内部主机名可能与外部主机名不同(例如httpbin.default.svc.cluster.local),因此您还需要将其添加到hosts列表中.有关更多详细信息,请参见 操作指南。 使用curl访问httpbin服务:

$ curl -s -I -HHost:httpbin.example.com "http://$INGRESS\_HOST:$INGRESS\_PORT/status/200" HTTP/1.1 200 OK server: istio-envoy ...

请注意,您可以使用该-H标志将Host HTTP标头设置为" httpbin.example.com"。这是必需的,因为您的入口Gateway配置为处理" httpbin.example.com",但是在测试环境中,该主机没有DNS绑定,只是将您的请求发送到入口IP。

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

$ curl -s -I -HHost:httpbin.example.com "http://$INGRESS\_HOST:$INGRESS\_PORT/headers" HTTP/1.1 404 Not Found ...

使用浏览器访问入口服务 httpbin在浏览器中输入服务URL无效,因为您不能像使用那样将Host标头传递给浏览器curl。在现实世界中,这不是问题,因为您可以正确配置请求的主机并且可以解析DNS。因此,您可以在URL中使用主机的域名,例如[https://httpbin.example.com/status/200。](https://httpbin.example.com/status/200%E3%80%82)

要通过简单的测试和演示解决此问题,请\*在Gateway 和VirtualService配置中为主机使用通配符值。例如,如果将入口配置更改为以下内容:

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

    &#x20; number: 80

    &#x20; name: http

    &#x20; protocol: HTTP

    hosts:

    * "\*"

apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: httpbin spec: hosts:

*   "\*"

    gateways:
*   httpbin-gateway

    http:
* match:
  *   uri:

      &#x20; prefix: /headers

      route:
  *   destination:

      &#x20; port:

      ```
      number: 8000
      ```

      &#x20; host: httpbin

      EOF

然后$INGRESS\_HOST:$INGRESS\_PORT,您可以在浏览器URL中使用。例如, http://$INGRESS\_HOST:$INGRESS\_PORT/headers将显示浏览器发送的所有标头。

了解发生了什么 在Gateway配置资源允许外部通讯进入Istio服务网,使Istio的流量管理和策略功能可用于边缘服务。

在前面的步骤中,您在服务网格内部创建了一个服务,并将该服务的HTTP端点暴露给外部流量。

故障排除 检查INGRESS\_HOST和INGRESS\_PORT环境变量的值。根据以下命令的输出,确保它们具有有效值:

$ kubectl get svc -n istio-system $ echo "INGRESS\_HOST=$INGRESS\_HOST, INGRESS\_PORT=$INGRESS\_PORT"

检查是否在同一端口上没有定义其他Istio入口网关:

$ kubectl get gateway --all-namespaces

检查是否在相同的IP和端口上没有定义Kubernetes Ingress资源:

$ kubectl get ingress --all-namespaces

如果您有一个外部负载均衡器,但不适用于您,请尝试 使用其节点端口访问网关。

清理 删除Gateway和VirtualService配置,然后关闭httpbin服务:

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