通过 gateway 注入安装网关

本操作步骤说明如何通过 gateway 注入安装网关。

INFO

以下操作步骤适用于 ingress 和 egress gateway 部署。

前提条件

操作步骤

  1. 为网关创建一个 namespace:

    kubectl create namespace <gateway_namespace>
    NOTE

    请将网关与 Istio 控制平面安装在不同的 namespace 中。

    你可以将网关安装在专用的网关 namespace 中。 这种方式允许多个运行在不同 namespace 中的应用共享该网关。 另外,你也可以将网关安装在应用 namespace 中。 在这种方式下,该网关作为该 namespace 中应用的专用网关。

  2. 创建一个名为 secret-reader.yaml 的 YAML 文件,用于定义该网关部署的 service account、role 和 role binding。这些设置允许网关读取 secrets,这是获取 TLS 凭据所必需的。

    secret-reader.yaml
    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 文件:

    kubectl apply -f secret-reader.yaml
  4. 创建一个名为 gateway-deployment.yaml 的 YAML 文件,用于定义该网关的 Kubernetes Deployment 对象。

    gateway-deployment.yaml
    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
          labels:
            istio: <gateway_name>
            sidecar.istio.io/inject: "true"
        spec:
          containers:
            - name: istio-proxy
              image: auto
              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
          serviceAccountName: secret-reader
          # nodeSelector:  
          #   node-role.kubernetes.io/infra: ""
          # tolerations:  
          #   - effect: NoSchedule
          #     key: node-role.kubernetes.io/infra
          #     value: reserved
          #     operator: Equal
    1. 表示 Istio 控制平面使用 gateway 注入模板,而不是默认的 sidecar 模板。
    2. 确保为该网关部署设置唯一标签。 需要唯一标签,以便 Istio Gateway 资源可以选择网关工作负载。
    3. 通过将 sidecar.istio.io/inject 标签设置为 true 来启用 gateway 注入。 如果 Istio 资源的名称不是 default,则必须改用 istio.io/rev: <istio_revision> 标签,其中 revision 表示 Istio 资源的活动 revision。
    4. 将 image 字段设置为 auto,以便每次 Pod 启动时自动更新 image。
    5. serviceAccountName 设置为之前创建的 ServiceAccount 名称。
    6. (可选)取消注释以设置 node selector,将网关 Pod 调度到 Infra Nodes 上。
    7. (可选)取消注释以设置 toleration,使网关 Pod 可以调度到 Infra Nodes 上。
  5. 运行以下命令应用该 YAML 文件:

    kubectl apply -f gateway-deployment.yaml
  6. 运行以下命令,验证网关 Deployment 的 rollout 是否成功:

    kubectl 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.yaml 的 YAML 文件,其中包含该网关的 Kubernetes Service 对象。

    gateway-service.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: <gateway_name>
      namespace: <gateway_namespace>
    spec:
      type: ClusterIP
      selector:
        istio: <gateway_name>
      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 对象只能从集群内部访问。 如果网关需要处理来自集群外部的 ingress 流量,请将 spec.type 设置为 LoadBalancer
    2. selector 设置为你之前创建的网关部署的 Pod 模板中指定的唯一标签或标签集合。
  8. 运行以下命令应用该 YAML 文件:

    kubectl apply -f gateway-service.yaml
  9. 运行以下命令,验证网关 service 是否指向网关 Pod 的 endpoint:

    kubectl get endpoints <gateway_name> -n <gateway_namespace>

你应会看到类似以下示例的输出:

示例输出

NAME              ENDPOINTS                                             AGE
<gateway_name>    10.131.0.181:15021,10.131.0.181:80,10.131.0.181:443   1m
  1. 可选:创建一个名为 gateway-hpa.yaml 的 YAML 文件,用于定义该网关的水平 Pod 自动扩缩器。 以下示例将最小副本数设置为 2、最大副本数设置为 5,并在平均 CPU 利用率超过 CPU 资源限制的 80% 时增加副本数。 该限制在网关部署的 Pod 模板中指定。

    gateway-hpa.yaml
    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. spec.scaleTargetRef.name 设置为之前创建的网关部署名称。
  2. 可选:运行以下命令应用该 YAML 文件:

    kubectl apply -f gateway-hpa.yaml
  3. 可选:创建一个名为 gateway-pdb.yaml 的 YAML 文件,用于定义该网关的 Pod 中断预算。 以下示例仅允许在驱逐后集群中至少仍保留 1 个健康的网关 Pod 时,才驱逐网关 Pod。

    gateway-pdb.yaml
    apiVersion: policy/v1
    kind: PodDisruptionBudget
    metadata:
      name: <gateway_name>
      namespace: <gateway_namespace>
    spec:
      minAvailable: 1
      selector:
        matchLabels:
          istio: <gateway_name>
    1. spec.selector.matchLabels 设置为之前创建的网关部署的 Pod 模板中指定的唯一标签或标签集合。
  4. 可选:运行以下命令应用该 YAML 文件:

    kubectl apply -f gateway-pdb.yaml