使用网关注入安装网关时,您可以结合使用 Istio Gateway
和 VirtualService
资源来配置它以接收入站流量。Istio Gateway
资源描述了在网格边缘运行的负载均衡器,它接收传入或传出的 HTTP/TCP 连接。Gateway
规范描述了一组应公开的端口、要使用的协议类型以及负载均衡器的服务器名称指示 (SNI) 配置。VirtualServices
定义要应用于 Istio Gateway
的路由规则,类似于您可以使用 VirtualServices
为内部网格流量定义路由规则的方式。
在以下示例中,Istio Gateway
资源配置网关代理充当外部流量的入口点。此配置为主机bookinfo.com
公开端口 443 (HTTPS)。示例配置适用于具有istio: ingressgateway
标签的 Pod。tls
模式配置为SIMPLE
,它使用示例提供的证书和私钥终止传入的 HTTPS 流量。
示例配置
apiVersion: networking.istio.io/v1
kind: Gateway
metadata:
name: bookinfo-gateway
namespace: bookinfo
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: https-443
protocol: HTTPS
hosts:
- bookinfo.com
tls:
mode: SIMPLE
serverCertificate: /etc/certs/servercert.pem
privateKey: /etc/certs/privatekey.pem
以下VirtualService
绑定到前面示例配置中显示的 Istio Gateway
资源。该规范定义了将具有/reviews/
路径前缀的流量路由到bookinfo
命名空间中的 reviews 服务的规则。VirtualService
显式引用了前面显示的Gateway
资源。这确保路由规则仅应用于通过指定网关进入的流量。
示例配置
kind: VirtualService
metadata:
name: bookinfo-rule
namespace: bookinfo
spec:
hosts:
- bookinfo.com
gateways:
- bookinfo/bookinfo-gateway
http:
- match:
- uri:
prefix: /reviews/
route:
- destination:
port:
number: 9080
host: reviews.bookinfo.svc.cluster.local
使用 Istio Gateway 和 VirtualService 资源公开服务
此过程使用 Istio Gateway
和 VirtualService
资源来配置使用网关注入部署的网关。这些资源配置网关以将网格中的服务公开给网格外部的流量。然后,您可以通过将网关的Service
设置为类型LoadBalancer
来将网关公开给集群外部的流量。
步骤
-
运行以下命令创建名为httpbin
的命名空间
$ oc create namespace httpbin
-
启用命名空间中的 sidecar 注射。如果您使用的是InPlace
升级策略,请运行以下命令
$ oc label namespace httpbin istio-injection=enabled
|
如果您使用的是RevisionBased 升级策略,请运行以下命令
-
要查找您的<revision-name> ,请运行以下命令
$ oc get istiorevisions.sailoperator.io
示例输出
NAME TYPE READY STATUS IN USE VERSION AGE
default-v1-23-0 Local True Healthy True v1.23.0 3m33s
-
使用修订版名称标记命名空间以启用 sidecar 注射
$ oc label namespace httpbin istio.io/rev=default-v1-23-0
|
-
运行以下命令部署名为httpbin
的示例服务
$ oc apply -n httpbin -f https://raw.githubusercontent.com/openshift-service-mesh/istio/refs/heads/master/samples/httpbin/httpbin.yaml
-
创建一个名为httpbin-gw.yaml
的 YAML 文件,该文件定义 Istio Gateway
资源。此资源配置网关代理以公开主机httpbin.example.com
的端口 80 (HTTP)。
apiVersion: networking.istio.io/v1
kind: Gateway
metadata:
name: httpbin-gateway
namespace: httpbin
spec:
selector:
istio: <gateway_name> (1)
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- httpbin.example.com (2)
1 |
将selector 设置为网关代理Deployment 的 pod 模板中指定的唯一标签或标签集。默认情况下,Istio Gateway 资源配置将应用于所有命名空间中匹配的网关 Pod。 |
2 |
使用hosts 字段,指定客户端在尝试访问关联端口处的网格服务时可以使用的一组地址。 |
-
运行以下命令应用 YAML 文件
$ oc apply -f httpbin-gw.yaml
-
为VirtualService
创建一个名为httpbin-vs.yaml
的 YAML 文件。VirtualService
定义将流量从网关代理路由到httpbin
服务的规则。
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: httpbin
namespace: httpbin
spec:
hosts:
- httpbin.example.com (1)
gateways:
- httpbin-gateway (2)
http:
- match:
- uri:
prefix: /status
- uri:
prefix: /headers
route:
- destination: (3)
port:
number: 8000
host: httpbin
1 |
指定将应用VirtualService 的路由规则的主机。指定的主机必须由VirtualService 绑定的 Istio Gateway 资源公开。 |
2 |
通过将Gateway 名称添加到网关列表中,将VirtualService 绑定到上一步中创建的 Istio Gateway 资源。 |
3 |
通过定义包含 `httpbin` `Service` 的 `host` 和 `port` 的 `destination`,将匹配的流量路由到之前部署的 `httpbin` 服务。 |
-
运行以下命令应用 YAML 文件
$ oc apply -f httpbin-vs.yaml
-
出于验证目的,运行以下命令为 `curl` 客户端创建一个命名空间
$ oc create namespace curl
-
运行以下命令部署 `curl` 客户端
$ oc apply -n curl -f https://raw.githubusercontent.com/openshift-service-mesh/istio/refs/heads/master/samples/curl/curl.yaml
-
运行以下命令设置一个名为 `curl` pod 的 `CURL_POD` 变量
$ CURL_POD=$(oc get pods -n curl -l app=curl -o jsonpath='{.items[*].metadata.name}')
-
使用 `curl` 客户端,通过 Ingress 网关 `Service` 资源向 `httpbin` 应用的 `/headers` 端点发送请求。将请求的 `Host` 头设置为 `httpbin.example.com`,以匹配 Istio `Gateway` 和 `VirtualService` 资源指定的 host。运行以下 `curl` 命令发送请求
$ oc exec $CURL_POD -n curl -- \
curl -s -I \
-H Host:httpbin.example.com \
<gateway_name>.<gateway_namespace>.svc.cluster.local/headers
-
响应应该具有 `200 OK HTTP` 状态,表明请求成功。
示例输出
HTTP/1.1 200 OK
server: istio-envoy
...
-
运行以下命令向 `httpbin` `VirtualService` 中未定义相应 URI 前缀匹配的端点发送 curl 请求
$ oc exec $CURL_POD -n curl -- \
curl -s -I \
-H Host:httpbin.example.com \
<gateway_name>.<gateway_namespace>.svc.cluster.local/get
响应应返回 `404 Not Found` 状态。这是预期的,因为 `/get` 端点在 `httpbin` `VirtualService` 资源中没有匹配的 URI 前缀。
示例输出
HTTP/1.1 404 Not Found
server: istio-envoy
...
-
将 `Service` 类型设置为 `LoadBalancer`,将网关代理暴露给集群外部的流量
$ oc patch service <gateway_name> -n <gateway_namespace> -p '{"spec": {"type": "LoadBalancer"}}'
|
也可以使用 OpenShift Routes 将网关暴露给集群外部的流量。更多信息,请参见“使用 OpenShift Routes 将网关暴露给集群外部的流量”。
|
-
使用网关 `Service` 资源的外部主机名或 IP 地址验证是否可以从集群外部访问 `httpbin` 服务。确保已为集群运行的环境适当地设置 `INGRESS_HOST` 变量。
-
如果集群在 AWS 上运行,则运行以下命令设置 `INGRESS_HOST` 变量
$ INGRESS_HOST=$(oc get service <gateway_name> -n <gateway_namespace> -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
-
如果集群在 GCP 或 Azure 上运行,则运行以下命令设置 `INGRESS_HOST` 变量
$ INGRESS_HOST=$(oc get service <gateway_name> -n <gateway_namespace> -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
-
使用网关的主机运行以下命令,向 `httpbin` 服务发送 `curl` 请求
$ curl -s -I -H Host:httpbin.example.com http://$INGRESS_HOST/headers
-
验证响应是否具有 `HTTP/1.1 200 OK` 状态,这表示请求成功。