Después de entrenar un modelo, lo habitual es desplegarlo como un servicio de inference. Las cargas de trabajo de inference presentan patrones de tráfico variables, por lo que un pool fijo de nodos ECS no puede manejar picos repentinos de manera eficiente sin sobreaprovisionar recursos. Al programar los pods de inference en Elastic Container Instance (ECI), Container Service for Kubernetes (ACK) escala la capacidad bajo demanda y elimina la necesidad de gestionar nodos.
Este tema describe cómo desplegar un modelo BERT como un servicio de inference de TensorFlow Serving en ECI. También explica cómo configurar Horizontal Pod Autoscaler (HPA) para escalar según las consultas por segundo (QPS) y exponer el servicio a través de Internet.
Cómo funciona
A continuación se muestran los componentes que trabajan en conjunto para ofrecer inference elástica:
Client → Ingress (Internet-facing) → TF Serving pods (on ECI)
↑
HPA (scale-out/in)
↑
Metrics Adapter ← SLS (nginx-ingress QPS)
Cargue el modelo entrenado en un bucket de Object Storage Service (OSS).
Monte el bucket de OSS en el clúster mediante un volumen persistente (PV) y una solicitud de volumen persistente (PVC).
Despliegue el servicio de inference con
arenae incluya anotaciones que dirijan los nuevos pods a ECI.Configure HPA con una métrica externa proveniente de Simple Log Service (SLS) para activar el escalado horizontal cuando el QPS supere un umbral.
Cree un Ingress accesible desde Internet para que los clientes externos accedan al servicio.
Ejecute una prueba de estrés para comprobar que HPA escala los pods hacia afuera y hacia adentro según el QPS.
Requisitos previos
Antes de empezar, asegúrese de contar con lo siguiente:
Un modelo entrenado y listo para su despliegue. Este tema utiliza un modelo BERT entrenado con TensorFlow 1.15.
Los siguientes componentes instalados en su clúster de ACK: ack-virtual-node, ack-alibaba-cloud-metrics-adapter y arena. Para consultar las instrucciones de instalación, consulte Manage components. Para obtener información sobre ack-virtual-node, consulte Connection overview.
Paso 1: Cargar el modelo en OSS
Cargue los archivos del modelo entrenado en un bucket de OSS. Para consultar las instrucciones, consulte Upload objects.
Paso 2: Montar el modelo mediante un PV y un PVC
Cree un PV que apunte a su bucket de OSS y un PVC que monte el pod de inference.
-
Cree un archivo llamado
pvc.yamlcon el siguiente contenido:apiVersion: v1 kind: PersistentVolume metadata: name: model-csi-pv spec: capacity: storage: 5Gi accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain csi: driver: ossplugin.csi.alibabacloud.com volumeHandle: model-csi-pv # Must match the PV name above volumeAttributes: bucket: "<your-bucket-name>" url: "<your-oss-url>" akId: "<your-access-key-id>" akSecret: "<your-access-key-secret>" otherOpts: "-o max_stat_cache_size=0 -o allow_other" --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: model-pvc spec: accessModes: - ReadWriteMany volumeName: model-csi-pv storageClassName: "" resources: requests: storage: 5GiReemplace los marcadores de posición:
Marcador de posición
Descripción
<your-bucket-name>Nombre del bucket de OSS. Los nombres de los buckets son únicos a nivel global. Consulte Bucket naming conventions.
<your-oss-url>URL que se usa para acceder a los objetos del bucket. Consulte Obtain the URL of a single object or the URLs of multiple objects.
<your-access-key-id>AccessKey ID para acceder a OSS. Utilice un usuario de Resource Access Management (RAM) con permisos de mínimo privilegio. Consulte Create an AccessKey pair.
<your-access-key-secret>Secreto del accesskey correspondiente al AccessKey ID anterior.
El campo
otherOptsacepta opciones de montaje personalizadas para ossfs:-o max_stat_cache_size=0: deshabilita la caché de metadatos para que el pod siempre lea los metadatos más recientes de los objetos directamente desde OSS.-o allow_other: permite que los procesos ejecutados por otros usuarios dentro del pod accedan al bucket montado.
Para conocer más opciones de montaje, consulte Custom parameters supported by ossfs.
-
Aplique el manifiesto:
kubectl apply -f pvc.yaml
Paso 3: Desplegar el servicio de inference
Utilice arena para desplegar un servicio de inference de TensorFlow Serving. Las banderas --annotation determinan si los pods se ubican en nodos ECS o en ECI.
-
Ejecute el siguiente comando:
arena serve tensorflow \ --namespace=default \ --name=bert-tfserving \ --model-name=chnsenticorp \ --gpus=1 \ --image=tensorflow/serving:1.15.0-gpu \ --data=model-pvc:/data \ --model-path=/data/models/tensorflow/chnsenticorp \ --version-policy=specific:1623831335 \ --annotation=alibabacloud.com/burst-resource=eci_only \ --annotation=k8s.aliyun.com/eci-use-specs=ecs.gn6i-c4g1.xlargeLas dos anotaciones controlan la programación en ECI:
Anotación
Descripción
alibabacloud.com/burst-resourceControla dónde se programan los pods. Déjela en blanco para usar solo ECS (valor predeterminado). Establézcala en
ecipara usar ECI cuando la capacidad de ECS sea insuficiente. Establézcala eneci_onlypara usar ECI de forma exclusiva.k8s.aliyun.com/eci-use-specsEspecifica el tipo de instancia de ECI acelerada por GPU. Es obligatorio cuando se usan recursos de GPU en ECI.
-
Compruebe que el servicio se esté ejecutando:
arena serve listResultado esperado:
NAME TYPE VERSION DESIRED AVAILABLE ADDRESS PORTS GPU bert-tfserving Tensorflow 202207181536 1 1 172.16.52.170 GRPC:8500,RESTFUL:8501 1 -
Confirme que el pod se ejecute en ECI:
kubectl get pods -o wideResultado esperado:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES bert-tfserving-202207181536-tensorflow-serving-547797c546-djh58 1/1 Running 0 114s 192.168.0.246 virtual-kubelet-cn-beijing-h <none> <none>El valor
NODEigual avirtual-kubelet-cn-beijing-hconfirma que el pod se ejecuta en una instancia de ECI y no en un nodo ECS.
Paso 4: Configurar HPA para escalar según el QPS
HPA ajusta automáticamente la cantidad de pods de inference con base en la métrica sls_ingress_qps de SLS. El escalado horizontal se activa cuando el QPS supera el valor de averageValue, mientras que la reducción ocurre cuando el QPS cae por debajo de dicho valor.
-
Consulte los nombres del Deployment y del Service creados por
arena:kubectl get deploymentResultado esperado:
NAME READY UP-TO-DATE AVAILABLE AGE bert-tfserving-202207181536-tensorflow-serving 1/1 1 1 2m18skubectl get serviceResultado esperado:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE bert-tfserving-202207181536-tensorflow-serving ClusterIP 172.16.52.170 <none> 8500/TCP,8501/TCP 2m45s -
Cree un archivo llamado
bert-tfserving-eci-hpa.yamlcon el siguiente contenido:Parámetro
Descripción
scaleTargetRefEl Deployment que se va a escalar, es decir, el Deployment del servicio de inference creado en el paso 3.
minReplicasNúmero mínimo de pods.
maxReplicasNúmero máximo de pods.
sls.projectNombre del proyecto de SLS de su clúster, con el formato
k8s-log-{cluster id}. Reemplace{cluster id}con el identificador real de su clúster.sls.logstoreNombre del logstore de SLS. El valor predeterminado es
nginx-ingress.sls.ingress.routeIdentifica la ruta de Ingress que se va a monitorear, con el formato
{namespace}-{service name}-{service port}.averageValueUmbral de QPS por pod que activa el escalado horizontal. En este ejemplo se establece en
10.apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: bert-tfserving-eci-hpa namespace: default spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: bert-tfserving-202207181536-tensorflow-serving minReplicas: 1 maxReplicas: 10 metrics: - type: External external: metric: name: sls_ingress_qps selector: matchLabels: sls.project: "k8s-log-{cluster id}" sls.logstore: "nginx-ingress" sls.ingress.route: "default-bert-tfserving-202207181536-tensorflow-serving-8501" target: type: AverageValue averageValue: "10"Parámetros clave:
-
Aplique el manifiesto de HPA:
kubectl apply -f bert-tfserving-eci-hpa.yaml -
Compruebe que HPA esté activo:
kubectl get hpaResultado esperado:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE bert-tfserving-eci-hpa Deployment/bert-tfserving-202207181536-tensorflow-serving 0/10 (avg) 1 10 1 116s
Paso 5: Exponer el servicio a través de Internet
De forma predeterminada, arena serve tensorflow asigna únicamente una dirección IP de clúster al servicio. Para aceptar tráfico externo, cree un Ingress accesible desde Internet.
Inicie sesión en la consola de ACK y haga clic en Clusters en el panel de navegación izquierdo.
Haga clic en el nombre del clúster de destino. En el panel de navegación izquierdo, elija Network > Ingresses.
-
Seleccione el espacio de nombres donde reside el servicio de inference en la lista desplegable Namespace y luego haga clic en Create Ingress. Configure los siguientes parámetros. Para obtener más detalles, consulte Create an NGINX Ingress.
Parámetro
Valor de ejemplo
Name
bert-tfservingDomain name
test.example.com(utilice su propio dominio)Path
/Rule
ImplementationSpecific(predeterminado)Service name
bert-tfserving-202207181536-tensorflow-servingPort
8501 En la página Ingresses, busque el Ingress que creó y anote su dirección en la columna Rules.
Paso 6: Comprobar el escalado elástico con una prueba de estrés
Utilice la dirección de Ingress obtenida en el paso 5 para enviar carga al servicio de inference.
Cuando el QPS supera el valor de
averageValue(10 en este ejemplo), HPA activa el escalado horizontal y los nuevos pods se programan en ECI. La cantidad total de pods se mantiene dentro del límite demaxReplicas(10).Cuando el QPS cae por debajo de
averageValue, HPA activa la reducción de pods.