控制 Ingress 流量
注意:此任务使用新的 v1alpha3 流量管理 API。旧的 API 已被弃用,将在下一个 Istio 版本中删除。如果您需要使用旧版本,请按照此处的文档操作。
在 Kubernetes 环境中,Kubernetes Ingress 资源 用于指定应在集群外部公开的服务。在 Istio 服务网格中,更好的方法(也适用于 Kubernetes 和其他环境)是使用不同的配置模型,即 Istio Gateway
。 Gateway
允许将 Istio 功能(例如,监控和路由规则)应用于进入集群的流量。
此任务描述如何配置 Istio 以使用 Istio 在服务网格外部公开服务 Gateway
。
前提条件
按照安装指南中的说明设置 Istio 。
确保您当前的目录是
istio
目录。启动 httpbin 样本,该样本将用作要在外部公开的目标服务。
如果您已启用自动注入 Sidecar,请执行
$ kubectl apply -f @samples/httpbin/httpbin.yaml@
否则就必须在部署 httpbin
应用程序之前手动注入 Sidecar:
$ kubectl apply -f <(istioctl kube-inject -f @samples/httpbin/httpbin.yaml@)
- 按照以下小节中的说明确定 Ingress 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 80:31380/TCP,443:31390/TCP,31400:31400/TCP 17h
如果 EXTERNAL-IP
设置了该值,则要求您的环境具有可用于 Ingress 网关的外部负载均衡器。如果 EXTERNAL-IP
值是 <none>
(或一直是 <pending>
),则说明可能您的环境不支持为 ingress 网关提供外部负载均衡器的功能。在这种情况下,您可以使用 Service 的 node port 方式访问网关。
使用外部负载均衡器时确定 IP 和端口
$ export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
$ export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http")].port}')
$ export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].port}')
确定使用 Node Port 时的 ingress IP 和端口
确定端口:
$ export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http")].nodePort}')
$ export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].nodePort}')
确定 ingress IP 的具体方法取决于集群提供商。
GKE:
$ export INGRESS_HOST=<workerNodeAddress>
您需要创建防火墙规则以允许 TCP 流量进入 ingress gateway 服务的端口。运行以下命令以允许 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 服务免费版本:
$ bx cs workers <cluster-name or id> $ export INGRESS_HOST=<public IP of one of the worker nodes>
Minikube:
$ export INGRESS_HOST=$(minikube ip)
其他环境(例如IBM Cloud Private等):
$ export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n istio-system -o 'jsonpath={.items[0].status.hostIP}')
使用 Istio 网关配置 Ingress
Ingress Gateway
描述了在网格边缘操作的负载平衡器,用于接收传入的 HTTP/TCP 连接。它配置暴露的端口,协议等,但与 Kubernetes Ingress Resources 不同,它不包括任何流量路由配置。流入流量的流量路由使用 Istio 路由规则进行配置,与内部服务请求完全相同。
让我们看看如何为 Gateway
在 HTTP 80 端口上配置流量。
创建一个 Istio
Gateway
:cat <<EOF | istioctl create -f - 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" EOF
为通过
Gateway
进入的流量配置路由:cat <<EOF | istioctl create -f - apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: httpbin spec: hosts: - "httpbin.example.com" gateways: - httpbin-gateway http: - match: - uri: prefix: /status - uri: prefix: /delay route: - destination: port: number: 8000 host: httpbin EOF
在这里,我们 为服务创建了一个虚拟服务配置
httpbin
,其中包含两条路由规则,允许路径/status
和 路径的流量/delay
。该网关列表指定,只有通过我们的要求
httpbin-gateway
是允许的。所有其他外部请求将被拒绝,并返回 404 响应。请注意,在此配置中,来自网格中其他服务的内部请求不受这些规则约束,而是简单地默认为循环路由。要将这些(或其他规则)应用于内部调用,我们可以将特殊值
mesh
添加到gateways
的列表中。使用 curl 访问 httpbin 服务:
$ curl -I -HHost:httpbin.example.com http://$INGRESS_HOST:$INGRESS_PORT/status/200 HTTP/1.1 200 OK server: envoy date: Mon, 29 Jan 2018 04:45:49 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: 48
请注意,这里使用该
-H
标志将Host
HTTP Header 设置为 “httpbin.example.com”。这以操作是必需的,因为上面的 IngressGateway
被配置为处理 “httpbin.example.com”,但在测试环境中没有该主机的 DNS 绑定,只是将请求发送到 Ingress IP。访问任何未明确公开的其他 URL,应该会看到一个 HTTP 404 错误:
$ curl -I -HHost:httpbin.example.com http://$INGRESS_HOST:$INGRESS_PORT/headers HTTP/1.1 404 Not Found date: Mon, 29 Jan 2018 04:45:49 GMT server: envoy content-length: 0
使用浏览器访问 Ingress 服务
在浏览器中输入 httpbin 服务的地址是不会生效的,这是因为因为我们没有办法让浏览器像 curl
一样装作访问 httpbin.example.com
。而在现实世界中,因为有正常配置的主机和 DNS 记录,这种做法就能够成功了——只要简单的在浏览器中访问由域名构成的 URL 即可,例如 https://httpbin.example.com/status/200
。
要解决此问题以进行简单的测试和演示,我们可以在 Gateway
和 VirutualService
配置中为主机使用通配符值 *
。例如,如果我们将 Ingress 配置更改为以下内容:
cat <<EOF | istioctl replace -f -
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: /headers
route:
- destination:
port:
number: 8000
host: httpbin
EOF
接下来就可以在浏览器的 URL 中使用 $INGRESS_HOST:$INGRESS_PORT
(也就是 192.168.99.100:31380
)进行访问,输入 http://192.168.99.100:31380/headers
网址之后,应该会显示浏览器发送的请求 Header。
理解原理
Gateway
配置资源允许外部流量进入 Istio 服务网,并使 Istio 的流量管理和策略功能可用于边缘服务。
在前面的步骤中,我们在 Istio 服务网格中创建了一个服务,并展示了如何将服务的 HTTP 端点暴露给外部流量。
清理
删除 Gateway
和 VirtualService
,并关闭 httpbin 服务:
$ istioctl delete gateway httpbin-gateway
$ istioctl delete virtualservice httpbin
$ kubectl delete --ignore-not-found=true -f @samples/httpbin/httpbin.yaml@
See also
配置 Istio 令其以 TLS 或双向 TLS 的方式在网格外公开服务。
Istio v1alpha3 路由 API 介绍,动机及其设计原则。
描述如何在AWS上使用网络负载均衡器配置 Istio Ingress。
介绍更安全,低风险的部署和发布到生产。
描述基于 Istio 的 Bookinfo 示例的简单场景。
描述基于 Istio Bookinfo 示例的简单场景。