×

网关是一个独立的 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` 资源。

步骤
  1. 创建一个将用于安装网关的命名空间。

    $ oc create namespace <gateway_namespace>

    在不同的命名空间中安装网关和 Istio 控制平面。

    您可以将网关安装在专用网关命名空间中。这种方法允许许多在不同命名空间中运行的应用程序共享网关。或者,您可以将网关安装在应用程序命名空间中。在这种方法中,网关充当该命名空间中应用程序的专用网关。

  2. 创建一个名为 `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
  3. 通过运行以下命令应用 YAML 文件

    $ oc apply -f secret-reader.yml
  4. 创建一个名为 `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: ` 标签,其中修订版代表 Istio 资源的活动修订版。
    4 将 image 字段设置为 `auto`,以便每次 pod 启动时图像都会自动更新。
    5 将 `serviceAccountName` 设置为先前创建的 `ServiceAccount` 的名称。
  5. 通过运行以下命令应用 YAML 文件

    $ oc apply -f gateway-deployment.yml
  6. 通过运行以下命令验证网关 `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
  7. 创建一个名为 `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 模板中指定的唯一标签或标签集。
  8. 通过运行以下命令应用 YAML 文件

    $ oc apply -f gateway-service.yml
  9. 运行以下命令,验证网关服务是否指向网关 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
  10. 可选:创建一个名为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设置为之前创建的网关部署的名称。
  11. 可选:运行以下命令应用 YAML 文件。

    $ oc apply -f gateway-hpa.yml
  12. 可选:创建一个名为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 模板中指定的唯一标签或标签集。
  13. 可选:运行以下命令应用 YAML 文件。

    $ oc apply -f gateway-pdb.yml