您可以使用网关来管理网格的入站和出站流量,以指定您想要进入或离开网格的流量。网关配置应用于在网格边缘运行的独立 Envoy 代理,而不是与您的服务工作负载一起运行的 sidecar Envoy 代理。
与控制进入您系统的流量的其他机制(例如 Kubernetes Ingress API)不同,Red Hat OpenShift Service Mesh 网关使用流量路由的全部功能和灵活性。
Red Hat OpenShift Service Mesh 网关资源可以使用 4-6 层负载均衡属性(例如端口)来公开和配置 Red Hat OpenShift Service Mesh TLS 设置。无需在同一 API 资源中添加应用层流量路由 (L7),您可以将常规 Red Hat OpenShift Service Mesh 虚拟服务绑定到网关,并像管理服务网格中的任何其他数据平面流量一样管理网关流量。
网关主要用于管理入口流量,但您也可以配置出口网关。出口网关允许您为离开网格的流量配置专用出口节点。这使您可以限制哪些服务可以访问外部网络,从而为您的服务网格增加安全控制。您还可以使用网关配置纯内部代理。
网关示例
网关资源描述了在网格边缘运行的负载均衡器,接收传入或传出的 HTTP/TCP 连接。规范描述了一组应公开的端口、要使用的协议类型、负载均衡器的 SNI 配置等等。
以下示例显示了用于外部 HTTPS 入口流量的示例网关配置
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: ext-host-gwy
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 443
name: https
protocol: HTTPS
hosts:
- ext-host.example.com
tls:
mode: SIMPLE
serverCertificate: /tmp/tls.crt
privateKey: /tmp/tls.key
此网关配置允许来自 `ext-host.example.com` 的 HTTPS 流量通过 443 端口进入网格,但不指定任何流量路由。
要指定路由并使网关按预期工作,您还必须将网关绑定到虚拟服务。您可以使用虚拟服务的 gateways 字段来执行此操作,如下例所示
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: virtual-svc
spec:
hosts:
- ext-host.example.com
gateways:
- ext-host-gwy
启用网关注入
网关配置适用于在网格边缘运行的独立 Envoy 代理,而不是与您的服务工作负载一起运行的 sidecar Envoy 代理。因为网关是 Envoy 代理,所以您可以配置 Service Mesh 自动注入网关,类似于您可以注入 sidecar 的方式。
使用网关的自动注入,您可以独立于 `ServiceMeshControlPlane` 资源部署和管理网关,并使用您的用户应用程序管理网关。为网关部署使用自动注入可以让开发人员完全控制网关部署,同时简化操作。当有新的升级可用或配置已更改时,您可以重新启动网关 Pod 以更新它们。这样做使操作网关部署的体验与操作 sidecar 相同。
|
默认情况下,对于 `ServiceMeshControlPlane` 命名空间(例如 `istio-system` 命名空间)禁用注入。作为安全最佳实践,请在与控制平面不同的命名空间中部署网关。
|
部署自动网关注入
部署网关时,您必须通过向网关 `deployment` 对象添加注入标签或注释来选择加入注入。以下示例部署了一个网关。
步骤
-
为 Istio 入口网关设置一个唯一的标签。此设置是必需的,以确保网关可以选择工作负载。此示例使用 `ingressgateway` 作为网关的名称。
apiVersion: v1
kind: Service
metadata:
name: istio-ingressgateway
namespace: istio-ingress
spec:
type: ClusterIP
selector:
istio: ingressgateway
ports:
- name: http2
port: 80
targetPort: 8080
- name: https
port: 443
targetPort: 8443
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: istio-ingressgateway
namespace: istio-ingress
spec:
selector:
matchLabels:
istio: ingressgateway
template:
metadata:
annotations:
inject.istio.io/templates: gateway
labels:
istio: ingressgateway
sidecar.istio.io/inject: "true" (1)
spec:
containers:
- name: istio-proxy
image: auto (2)
1 |
通过将 `sidecar.istio.io/inject` 字段设置为 `"true"` 来启用网关注入。 |
2 |
将 `image` 字段设置为 `auto`,以便每次 Pod 启动时图像都会自动更新。 |
-
设置角色以允许读取 TLS 的凭据。
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: istio-ingressgateway-sds
namespace: istio-ingress
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: istio-ingressgateway-sds
namespace: istio-ingress
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: istio-ingressgateway-sds
subjects:
- kind: ServiceAccount
name: default
-
授予从集群外部访问新网关的权限,这在 `spec.security.manageNetworkPolicy` 设置为 `true` 时是必需的。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: gatewayingress
namespace: istio-ingress
spec:
podSelector:
matchLabels:
istio: ingressgateway
ingress:
- {}
policyTypes:
- Ingress
-
当入口流量增加时自动扩展 Pod。此示例将最小副本数设置为 `2`,最大副本数设置为 `5`。当利用率达到 80% 时,它还会创建一个新的副本。
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
labels:
istio: ingressgateway
release: istio
name: ingressgatewayhpa
namespace: istio-ingress
spec:
maxReplicas: 5
metrics:
- resource:
name: cpu
target:
averageUtilization: 80
type: Utilization
type: Resource
minReplicas: 2
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: istio-ingressgateway
-
指定必须在节点上运行的 Pod 的最小数量。此示例确保如果 Pod 在新节点上重新启动,则会运行一个副本。
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
labels:
istio: ingressgateway
release: istio
name: ingressgatewaypdb
namespace: istio-ingress
spec:
minAvailable: 1
selector:
matchLabels:
istio: ingressgateway
管理入口流量
在 Red Hat OpenShift Service Mesh 中,入口网关允许将监控、安全和路由规则应用于进入集群的流量。使用 Service Mesh 网关来公开服务网格外部的服务。
确定入口 IP 和端口
入口配置取决于您的环境是否支持外部负载均衡器。外部负载均衡器在集群的入口 IP 和端口中设置。要确定您的集群的 IP 和端口是否已配置为外部负载均衡器,请运行以下命令。在此示例中,`istio-system` 是 Service Mesh 控制平面项目的名称。
$ oc get svc istio-ingressgateway -n istio-system
该命令将返回命名空间中每个项目的 `NAME`、`TYPE`、`CLUSTER-IP`、`EXTERNAL-IP`、`PORT(S)` 和 `AGE`。
如果设置了 `EXTERNAL-IP` 值,则您的环境具有可用于入口网关的外部负载均衡器。
如果 `EXTERNAL-IP` 值为 `` 或永久为 ``,则您的环境不为入口网关提供外部负载均衡器。
使用负载均衡器确定入口端口
如果您的环境具有外部负载均衡器,请按照以下说明操作。
步骤
-
运行以下命令以设置入口 IP 和端口。此命令在您的终端中设置一个变量。
$ export INGRESS_HOST=$(oc -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
-
运行以下命令以设置入口端口。
$ export INGRESS_PORT=$(oc -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')
-
运行以下命令以设置安全入口端口。
$ export SECURE_INGRESS_PORT=$(oc -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].port}')
-
运行以下命令以设置 TCP 入口端口。
$ export TCP_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="tcp")].port}')
|
在某些环境中,负载均衡器可以使用主机名而不是 IP 地址公开。在这种情况下,入口网关的 `EXTERNAL-IP` 值不是 IP 地址。相反,它是一个主机名,之前的命令无法设置 `INGRESS_HOST` 环境变量。
在这种情况下,请使用以下命令更正 `INGRESS_HOST` 值
|
$ export INGRESS_HOST=$(oc -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
在没有负载均衡器的情况下确定入口端口
如果您的环境没有外部负载均衡器,请确定入口端口并改用节点端口。
步骤
-
设置入口端口。
$ export INGRESS_PORT=$(oc -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
-
运行以下命令以设置安全入口端口。
$ export SECURE_INGRESS_PORT=$(oc -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].nodePort}')
-
运行以下命令以设置 TCP 入口端口。
$ export TCP_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="tcp")].nodePort}')
配置入口网关
入口网关是在网格边缘运行的负载均衡器,接收传入的 HTTP/TCP 连接。它配置公开的端口和协议,但不包含任何流量路由配置。入口流量的流量路由与内部服务请求的流量路由方式相同,使用路由规则配置。
以下步骤演示如何创建一个网关并配置一个VirtualService
,以便将Bookinfo示例应用程序中的服务通过路径/productpage
和/login
暴露给外部流量。
步骤
-
创建一个网关来接收流量。
-
创建一个YAML文件,并将以下YAML复制到其中。
网关示例 gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: bookinfo-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
-
应用YAML文件。
$ oc apply -f gateway.yaml
-
创建一个VirtualService
对象来重写主机头。
-
创建一个YAML文件,并将以下YAML复制到其中。
虚拟服务示例
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
- "*"
gateways:
- bookinfo-gateway
http:
- match:
- uri:
exact: /productpage
- uri:
prefix: /static
- uri:
exact: /login
- uri:
exact: /logout
- uri:
prefix: /api/v1/products
route:
- destination:
host: productpage
port:
number: 9080
-
应用YAML文件。
-
测试网关和VirtualService是否已正确设置。
-
设置网关URL。
export GATEWAY_URL=$(oc -n istio-system get route istio-ingressgateway -o jsonpath='{.spec.host}')
-
设置端口号。在本例中,istio-system
是服务网格控制平面项目的名称。
export TARGET_PORT=$(oc -n istio-system get route istio-ingressgateway -o jsonpath='{.spec.port.targetPort}')
-
测试一个已明确暴露的页面。
curl -s -I "$GATEWAY_URL/productpage"