Istio 入口

Seldon Core 可关联 istio 使用。Istio 提供了一个 入口网关,Seldon Core 可以将新的部署自动关联到该网关。下面描述了使用 istio 的步骤。

安装 Seldon Core Operator

请确保通过 Helm 安装 seldon-core operator 时开启 istio 支持。例如:

helm install seldon-core seldon-core-operator --set istio.enabled=true --repo https://storage.googleapis.com/seldon-charts --set usageMetrics.enabled=true

你需要将 istio 网关安装在 istio-system 命名空间。默认情况,我们假设网关叫 seldon-gateway。比如可通过以下 yaml 创建:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: seldon-gateway
  namespace: istio-system
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"

如果向创建 SSL 网关,请创建签名证书或者一个存在的签名证书(比如:fullchain.pem),key (privkey.pem)然后运行以下命令获取 SSL 网关。假设我们没有使用 cert-manager,然后我们自己进行签名证书创建:

openssl req -nodes -x509 -newkey rsa:4096 -keyout privkey.pem -out fullchain.pem -days 365 -subj "/C=GB/ST=GreaterLondon/L=London/O=SeldonSerra/OU=MLOps/CN=localhost"

导入 key 和证书到 istio-system 命名空间。

kubectl create -n istio-system secret tls seldon-ssl-cert --key=privkey.pem --cert=fullchain.pem

使用 YAML 文件创建 SSL Istio 网关。

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: seldon-gateway
  namespace: istio-system
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - hosts:
    - '*'
    port:
      name: https
      number: 443
      protocol: HTTPS
    tls:
      credentialName: seldon-ssl-cert
      mode: SIMPLE

如果有使用自己的网关,可在安装 seldon operator 时提供名称。比如你的网关名时 mygateway ,可通过以下命令安装 operator:

helm install seldon-core seldon-core-operator --set istio.enabled=true --set istio.gateway=mygateway --repo https://storage.googleapis.com/seldon-charts --set usageMetrics.enabled=true

你可以为每个 Seldon Deploy 通过使用 seldon.io/istio-gateway 配置不同的网关。

Istio 配置注释参考

Annotation

默认

描述

seldon.io/istio-gateway:<gateway name>

istio-system/seldon-gateway

用此网关的部署。如果未提供应用名称空间,将指向 Seldon Delpoyment 的命名空间。

seldon.io/istio-retries

None

istio 尝试次数

seldon.io/istio-retries-timeout

None

如果设置了 istio retries,每次请求多长事件超时

seldon.io/istio-host

*

istio 虚拟服务的 Host

所有注解均可放在 spec.annotationsmetadata.annotations。将优先使用放在 spec.annotations 的配置。

流量路由

Istio 具备细化分配流量到部署中的能力。这将允许:

  • canary 更新

  • green-blue 发布

  • A/B 测试

  • 影子部署

更多信息请查看 示例,其中包括 canary 更新

配置身份验证/授权

要强制客户端对 seldon 模型发布的访问进行验证/授权,可配置 Istio 的 RequestAuthenticationAuthorizationPolicy。 这将根据你的策略设计接受或拒绝对模型的请求。 更多信息请查看这里

你可以设置指向特定命名空间的所有模型的策略,但必须使用 istio sidecar 代理, 并确保 seldon operator 按如下配置:

istio:
  enabled: true
  tlsMode: STRICT

如果设置了 AuthorizationPolicy,将破坏 Prometheus 指标抓取, 两种可能的选项可以解决此问题:

  • AuthorizationPolicy 中指定允许 GET 请求

示例:

- to:
  - operation:
      methods: ["GET"]
      paths: ["/prometheus"]
      ports: ["6000", "8000", "6001"]
  • 也可在 Istio Operator 配置中 排除端口: .. code-block:: yaml

    proxy:

    autoInject: enabled clusterDomain: cluster.local componentLogLevel: misc:error enableCoreDump: false excludeInboundPorts: “” excludeOutboundPorts: “15021”

问题解决

如果看到类似 Failed to generate bootstrap config: mkdir ./etc/istio/proxy: permission denied 问题,它可能时因为你的 istio 版本 <= 1.6。 Istio 代理 sidecar 默认以 root 运行(在版本 >= 1.7,默认时非 root)。 可通过在 helm chart 中修改 defaultUserID=0 修复,或者添加 securityContext 到 istio 的 sidecar 代理。

securityContext:
  runAsUser: 0

使用 Istio 服务网格

Istio 也可以直接用于集群内部的导流,而不是将其作为入口(导流集群外部流量)。

为此,虚拟服务 Seldon 会创建附加到名为 mesh 的「特殊」网关。这会将路由规则应用于网格内的流量,而无需通过网关进行路由。

由于 Istio 的限制(从 v1.11.3 开始),本地网格中的虚拟服务只能应用于一个主机。(在此处查看他们的文档)。因此,每个 Graph 都需要一个唯一的服务,这可以通过在主预测器中设置 seldon.io/svc-name 注解。

这是一个 SeldonDeployment 示例,它将利用内部网状网络在两个预测器之间分配流量,第一个预测器为 75%,第二个预测器为 25%:

apiVersion: machinelearning.seldon.io/v1
kind: SeldonDeployment
metadata:
  labels:
    app: seldon
  name: canary-example-1
  namespace: my-ns
spec:
  annotations:
    seldon.io/istio-gateway: mesh # NOTE
    seldon.io/istio-host: canary-example-1 # NOTE
  name: canary-example-1
  predictors:
  - annotations:
      seldon.io/svc-name: canary-example-1   # NOTE
    componentSpecs:
    - spec:
        containers:
        - image: seldonio/mock_classifier:1.11.0
          imagePullPolicy: IfNotPresent
          name: classifier
          securityContext:
            readOnlyRootFilesystem: false
        terminationGracePeriodSeconds: 1
    graph:
      endpoint:
        type: REST
      name: classifier
      type: MODEL
    labels:
      sidecar.istio.io/inject: "true"
    name: main
    replicas: 1
    traffic: 75
  - componentSpecs:
    - spec:
        containers:
        - image: seldonio/mock_classifier:1.11.0
          imagePullPolicy: IfNotPresent
          name: classifier
        terminationGracePeriodSeconds: 1
    graph:
      endpoint:
        type: REST
      name: classifier
      type: MODEL
    labels:
      sidecar.istio.io/inject: "true"
    name: canary
    replicas: 1
    traffic: 25

需要指出的几个关键点:

  1. 为主要的 (第一个) 预测器创建名为 canary-example-1 的唯一服务。此服务不能与命名空间中的任何其他服务发生冲突。该服务可以_不是_通过 SeldonDeployment 创建的服务,但也必须匹配必要的 Istio 路由规则。

  2. 以上服务参考 spec 注解的 host 如下: seldon.io/istio-host: canary-example-1。浙江会设置 host 到 Istio Virutal Service 来创建新的服务。

  3. 网关指定为 seldon.io/istio-gateway: mesh 以在 Istio Mesh 利用这个路由。注意:为了调用所有服务,并进行适当的路由,客户端_必须_同样_处在_网格中。这是通过将 Istio Sidecar 注入客户端的 pod 来实现的。

从集群内部和网格内部的 pod 内部,可以进行如下调用,并在两个预测器之间拆分流量:

curl -X POST -H 'Content-Type: application/json' \
  -d '{"data": { "names": ["a", "b"], "ndarray": [[1,2]]}}' \
  http://mysvcname:8000/seldon/batest/canary-example-1/api/v1.0/predictions