通过 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