$ oc create namespace <gateway_namespace>网关是一个独立的 Envoy 代理部署和一个相关的 Kubernetes 服务,在服务网格的边缘运行。您可以配置网关以对进入或离开网格的流量进行细粒度控制。在 Red Hat OpenShift Service Mesh 中,您可以使用网关注入安装网关。
网关注入依赖于与 sidecar 注入相同的机制,将 Envoy 代理注入到网关 Pod 中。要使用网关注入安装网关,您需要在 Istio 控制平面可见的命名空间中创建 Kubernetes `Deployment` 对象和相关的 Kubernetes `Service` 对象。创建 `Deployment` 对象时,对其进行标记和注释,以便 Istio 控制平面注入代理,并将代理配置为网关。安装网关后,您可以使用 Istio `Gateway` 和 `VirtualService` 资源配置它来控制入站和出站流量。
此过程说明如何使用网关注入安装网关。
| 您可以使用此过程创建入站或出站网关。 | 
您已安装 OpenShift Service Mesh Operator 3.0 或更高版本。
您已创建 Istio 控制平面。
您已创建 `IstioCNI` 资源。
创建一个将用于安装网关的命名空间。
$ oc create namespace <gateway_namespace>| 在不同的命名空间中安装网关和 Istio 控制平面。 您可以将网关安装在专用网关命名空间中。这种方法允许许多在不同命名空间中运行的应用程序共享网关。或者,您可以将网关安装在应用程序命名空间中。在这种方法中,网关充当该命名空间中应用程序的专用网关。 | 
创建一个名为 `secret-reader.yml` 的 YAML 文件,该文件定义网关部署的服务帐户、角色和角色绑定。这些设置使网关能够读取秘密,这是获取 TLS 证书所必需的。
apiVersion: v1
kind: ServiceAccount
metadata:
  name: secret-reader
  namespace: <gateway_namespace>
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: secret-reader
  namespace: <gateway_namespace>
rules:
  - apiGroups: [""]
    resources: ["secrets"]
    verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name:  secret-reader
  namespace: <gateway_namespace>
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: secret-reader
subjects:
  - kind: ServiceAccount
    name:  secret-reader通过运行以下命令应用 YAML 文件
$ oc apply -f secret-reader.yml创建一个名为 `gateway-deployment.yml` 的 YAML 文件,该文件定义网关的 Kubernetes `Deployment` 对象。
apiVersion: apps/v1
kind: Deployment
metadata:
  name: <gateway_name>
  namespace: <gateway_namespace>
spec:
  selector:
    matchLabels:
      istio: <gateway_name>
  template:
    metadata:
      annotations:
        inject.istio.io/templates: gateway (1)
      labels:
        istio: <gateway_name> (2)
        sidecar.istio.io/inject: "true" (3)
    spec:
      containers:
        - name: istio-proxy
          image: auto (4)
          securityContext:
            capabilities:
              drop:
              - ALL
            allowPrivilegeEscalation: false
            privileged: false
            readOnlyRootFilesystem: true
            runAsNonRoot: true
          ports:
          - containerPort: 15090
            protocol: TCP
            name: http-envoy-prom
          resources:
            limits:
              cpu: 2000m
              memory: 1024Mi
            requests:
              cpu: 100m
              memory: 128Mi
      securityContext:
        sysctls:
        - name: net.ipv4.ip_unprivileged_port_start
          value: "0"
      serviceAccountName: secret-reader (5)| 1 | 指示 Istio 控制平面使用网关注入模板而不是默认的 sidecar 模板。 | 
| 2 | 确保为网关部署设置唯一的标签。需要唯一的标签,以便 Istio `Gateway` 资源可以选择网关工作负载。 | 
| 3 | 通过将 `sidecar.istio.io/inject` 标签设置为 `true` 来启用网关注入。如果 Istio 资源的名称不是 `default`,则必须使用 `istio.io/rev: | 
| 4 | 将 image 字段设置为 `auto`,以便每次 pod 启动时图像都会自动更新。 | 
| 5 | 将 `serviceAccountName` 设置为先前创建的 `ServiceAccount` 的名称。 | 
通过运行以下命令应用 YAML 文件
$ oc apply -f gateway-deployment.yml通过运行以下命令验证网关 `Deployment` 的推出是否成功
$ oc rollout status deployment/<gateway_name> -n <gateway_namespace>您应该看到类似于以下内容的输出
Waiting for deployment "<gateway_name>" rollout to finish: 0 of 1 updated replicas are available...
deployment "<gateway_name>" successfully rolled out创建一个名为 `gateway-service.yml` 的 YAML 文件,其中包含网关的 Kubernetes `Service` 对象。
apiVersion: v1
kind: Service
metadata:
  name: <gateway_name>
  namespace: <gateway_namespace>
spec:
  type: ClusterIP (1)
  selector:
    istio: <gateway_name> (2)
  ports:
    - name: status-port
      port: 15021
      protocol: TCP
      targetPort: 15021
    - name: http2
      port: 80
      protocol: TCP
      targetPort: 80
    - name: https
      port: 443
      protocol: TCP
      targetPort: 443| 1 | 当您将 `spec.type` 设置为 `ClusterIP` 时,只能从集群内部访问网关 `Service` 对象。如果网关必须处理来自集群外部的入站流量,请将 `spec.type` 设置为 `LoadBalancer`。或者,您可以使用 OpenShift 路由。 | 
| 2 | 将 `selector` 设置为您之前创建的网关部署的 pod 模板中指定的唯一标签或标签集。 | 
通过运行以下命令应用 YAML 文件
$ oc apply -f gateway-service.yml运行以下命令,验证网关服务是否指向网关 Pod 的端点。
$ oc get endpoints <gateway_name> -n <gateway_namespace>您应该看到类似以下示例的输出。
NAME              ENDPOINTS                             AGE
<gateway_name>    10.131.0.181:8080,10.131.0.181:8443   1m可选:创建一个名为gateway-hpa.yml的 YAML 文件,该文件定义了网关的水平 Pod 自动伸缩器。以下示例将最小副本数设置为2,最大副本数设置为5,并在平均 CPU 利用率超过 CPU 资源限制的 80% 时向上扩展副本数。此限制在网关部署的 Pod 模板中指定。
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: <gateway_name>
  namespace: <gateway_namespace>
spec:
  minReplicas: 2
  maxReplicas: 5
  metrics:
  - resource:
      name: cpu
      target:
        averageUtilization: 80
        type: Utilization
    type: Resource
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: <gateway_name> (1)| 1 | 将 spec.scaleTargetRef.name设置为之前创建的网关部署的名称。 | 
可选:运行以下命令应用 YAML 文件。
$ oc apply -f gateway-hpa.yml可选:创建一个名为gateway-pdb.yml的 YAML 文件,该文件为网关定义了 Pod  disruption 预算。以下示例仅允许在驱逐后集群上至少保留 1 个健康网关 Pod 时才能驱逐网关 Pod。
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: <gateway_name>
  namespace: <gateway_namespace>
spec:
  minAvailable: 1
  selector:
    matchLabels:
      istio: <gateway_name> (1)| 1 | 将 spec.selector.matchLabels设置为之前创建的网关部署的 Pod 模板中指定的唯一标签或标签集。 | 
可选:运行以下命令应用 YAML 文件。
$ oc apply -f gateway-pdb.yml