通过 gateway injection 安装 gateway

本操作步骤介绍如何使用 gateway injection 安装 gateway。

INFO

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

前提条件

操作步骤

  1. 为 gateway 创建 namespace:

    kubectl create namespace <gateway_namespace>
    NOTE

    请将 gateway 和 Istio 控制平面安装在不同的 namespace 中。

    您可以在专用的 gateway namespace 中安装 gateway。 这样可以让不同 namespace 中运行的多个原生应用共享该 gateway。 或者,您也可以在原生应用 namespace 中安装 gateway。 在这种方式中,gateway 将作为该 namespace 中原生应用的专用 gateway。

  2. 创建名为 secret-reader.yaml 的 YAML 文件,为 gateway 部署定义 service account、role 和 role binding。这些设置使 gateway 能够读取 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 文件,为 gateway 定义 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
                seccompProfile:
                  type: RuntimeDefault
              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 injection 模板,而不是默认的 sidecar 模板。
    2. 确保为 gateway 部署设置唯一的 label。 必须使用唯一 label,以便 Istio Gateway 资源能够选择 gateway 工作负载。
    3. sidecar.istio.io/inject label 设置为 true,启用 gateway injection。 如果 Istio 资源的名称不是 default,则必须改用 istio.io/rev: <istio_revision> label,其中 revision 表示 Istio 资源的活动 revision。
    4. 将 image 字段设置为 auto,以便每次 pod 启动时自动更新 image。
    5. 添加 RuntimeDefault seccomp profile,使 gateway pod 满足 Restricted Pod Security Admission profile。 gateway injection 模板不会从 Istio 资源读取 spec.values.global.proxy.seccompProfile,因此必须在 gateway 部署本身上设置该 profile。 如果 gateway namespace 未强制执行 Restricted profile,请删除此字段。
    6. serviceAccountName 设置为之前创建的 ServiceAccount 的名称。
    7. (可选)取消注释,以设置将 gateway pod 调度到 Infra Nodes 的 node selector。
    8. (可选)取消注释,以设置允许将 gateway pod 调度到 Infra Nodes 的 toleration。
  5. 运行以下命令应用 YAML 文件:

    kubectl apply -f gateway-deployment.yaml
  6. 运行以下命令,验证 gateway 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 文件,其中包含 gateway 的 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 时,gateway Service 对象只能从集群内部访问。 如果 gateway 必须处理来自集群外部的 ingress 流量,请将 spec.type 设置为 LoadBalancer
    2. selector 设置为之前创建的 gateway 部署 pod 模板中指定的唯一 label 或 label 集合。
  8. 运行以下命令应用 YAML 文件:

    kubectl apply -f gateway-service.yaml
  9. 运行以下命令,验证 gateway service 是否以 gateway 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 文件,为 gateway 定义 horizontal pod autoscaler。 以下示例将最小副本数设置为 2,最大副本数设置为 5,并在平均 CPU 利用率超过 CPU 资源限制的 80% 时扩展副本数。 此限制在 gateway 部署的 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 设置为之前创建的 gateway 部署的名称。
  2. 可选:运行以下命令应用 YAML 文件:

    kubectl apply -f gateway-hpa.yaml
  3. 可选:创建名为 gateway-pdb.yaml 的 YAML 文件,为 gateway 定义 pod disruption budget。 以下示例规定,只有在驱逐后集群中至少保留 1 个健康的 gateway pod 时,才允许驱逐 gateway 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 设置为之前创建的 gateway 部署 pod 模板中指定的唯一 label 或 label 集合。
  4. 可选:运行以下命令应用 YAML 文件:

    kubectl apply -f gateway-pdb.yaml