你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
排查 Azure 机器学习扩展问题
在本文中,你将了解如何排查在 AKS 或已启用 Arc 的 Kubernetes 中部署 Azure 机器学习扩展时可能遇到的常见问题。
Azure 机器学习扩展作为 helm 图表发布,由 Helm V3 安装。 Azure 机器学习扩展的所有组件安装在 azureml
命名空间中。 可使用以下命令来检查扩展状态。
# get the extension status
az k8s-extension show --name <extension-name>
# check status of all pods of Azure Machine Learning extension
kubectl get pod -n azureml
# get events of the extension
kubectl get events -n azureml --sort-by='.lastTimestamp'
此错误表示你指定的扩展名称已存在。 如果该名称已由 Azure 机器学习扩展使用,需要等待大约一小时,然后重试。 如果该名称已由其他 helm 图表使用,则你需要使用另一个名称。 运行 helm list -Aa
以列出群集中的所有 helm 图表。
需要等待大约一小时,让未知操作完成后重试。
如果某个卸载操作未完成,而此时触发了另一个安装操作,则会发生此错误。 可以运行 az k8s-extension show
命令来检查扩展的预配状态,并确保在执行其他操作之前已卸载扩展。
如果指定了错误的扩展版本,则会发生此错误。 需要确保指定的版本存在。 如果你要使用最新版本,则无需指定 --version
。
此错误表示现有群集资源与 Azure 机器学习扩展之间有冲突。 完整的错误消息可能类似于以下文本:
CustomResourceDefinition "jobs.batch.volcano.sh" in namespace "" exists and cannot be imported into the current release: invalid ownership metadata; label validation error: missing key "app.kubernetes.io/managed-by": must be set to "Helm"; annotation validation error: missing key "meta.helm.sh/release-name": must be set to "amlarc-extension"; annotation validation error: missing key "meta.helm.sh/release-namespace": must be set to "azureml"
使用以下步骤来缓解此问题。
检查有问题的资源由谁拥有,以及是否可以删除或修改该资源。
如果资源仅由 Azure 机器学习扩展使用并且可删除,则你可以手动添加标签来缓解问题。 以前面的错误消息为例,你可以运行如下所示的命令:
kubectl label crd jobs.batch.volcano.sh "app.kubernetes.io/managed-by=Helm" kubectl annotate crd jobs.batch.volcano.sh "meta.helm.sh/release-namespace=azureml" "meta.helm.sh/release-name=<extension-name>"
通过为资源设置标签和注释,指明 helm 正在管理由 Azure 机器学习扩展拥有的资源。
如果该资源还由群集中的其他组件使用并且无法修改。 请参阅部署 Azure 机器学习扩展,查看是否存在用于禁用冲突资源的配置设置。
如果安装失败但未出现上述任何错误消息,你可以使用内置的运行状况检查作业来对扩展进行全面检查。 Azure 机器学习扩展包含HealthCheck
作业,用于在尝试安装、更新或删除扩展时预先检查群集的就绪状态。 HealthCheck 作业会输出报告,该报告保存在azureml
命名空间中名为arcml-healthcheck
的配置映射内。 HealthCheck 的错误代码中列出了报告的错误代码和可能的解决方法。
运行以下命令以获取 HealthCheck 报告:
kubectl describe configmap -n azureml arcml-healthcheck
每当你安装、更新或删除扩展时,都会触发运行状况检查。 运行状况检查报告的结构包括 pre-install
、pre-rollback
、pre-upgrade
和 pre-delete
这几个部分。
- 如果扩展安装失败,你应该查看
pre-install
和pre-delete
。 - 如果扩展更新失败,你应该查看
pre-upgrade
和pre-rollback
。 - 如果扩展删除失败,你应该查看
pre-delete
。
当你请求支持时,我们建议运行以下命令并将 healthcheck.logs
文件发送给我们,因为它可以方便我们找出问题。
kubectl logs healthcheck -n azureml
下表显示了如何对 HealthCheck 报告返回的错误代码进行故障排除。
错误代码 | 错误消息 | 说明 |
---|---|---|
E40001 | LOAD_BALANCER_NOT_SUPPORT | 群集中不支持负载均衡器。 需要在群集中配置负载均衡器,或考虑将inferenceRouterServiceType 设置为nodePort 或clusterIP 。 |
E40002 | INSUFFICIENT_NODE | 已启用 inferenceRouterHA ,它要求群集中至少有三个节点。 如果节点少于三个,请禁用 HA。 |
E40003 | INTERNAL_LOAD_BALANCER_NOT_SUPPORT | 目前,只有 AKS 支持内部负载均衡器,而我们仅支持 azure 类型。 如果你没有 AKS 群集,请不要设置 internalLoadBalancerProvider 。 |
E40007 | INVALID_SSL_SETTING | SSL 密钥或证书无效。 CNAME 应与证书兼容。 |
E45002 | PROMETHEUS_CONFLICT | 安装的 Prometheus Operator 与现有的 Prometheus Operator 冲突。 有关详细信息,请参阅 Prometheus 运算符 |
E45003 | BAD_NETWORK_CONNECTIVITY | 需要满足网络要求。 |
E45004 | AZUREML_FE_ROLE_CONFLICT | 旧版 AKS 中不支持 Azure 机器学习扩展。 若要安装 Azure 机器学习扩展,需要删除旧版 azureml-fe 组件。 |
E45005 | AZUREML_FE_DEPLOYMENT_CONFLICT | 旧版 AKS 中不支持 Azure 机器学习扩展。 若要安装 Azure 机器学习扩展,需要运行此窗体下面的命令来删除旧 azureml-fe 组件,详细信息请参考此处。 |
用于删除 AKS 群集中的旧 azureml-fe 组件的命令:
kubectl delete sa azureml-fe
kubectl delete clusterrole azureml-fe-role
kubectl delete clusterrolebinding azureml-fe-binding
kubectl delete svc azureml-fe
kubectl delete svc azureml-fe-int-http
kubectl delete deploy azureml-fe
kubectl delete secret azuremlfessl
kubectl delete cm azuremlfeconfig
Azure 机器学习扩展使用了一些开源组件,包括 Prometheus Operator、Volcano Scheduler 和 DCGM Exporter。 如果 Kubernetes 群集中已安装了上述某些组件,你可以阅读以下部分,以将现有组件与 Azure 机器学习扩展集成。
Prometheus Operator 是一个开源框架,可帮助在 Kubernetes 中构建指标监视系统。 Azure 机器学习扩展也利用 Prometheus Operator 来帮助监视作业的资源利用率。
如果群集具有由其他服务安装的 Prometheus Operator,可以指定installPromOp=false
以在 Azure 机器学习扩展中禁用 Prometheus Operator,从而避免两个 Prometheus Operator 之间发生冲突。
在这种情况下,现有的 Prometheus Operator 管理所有 Prometheus 实例。 为确保 Prometheus 正常工作,在 Azure 机器学习扩展中禁用 Prometheus Operator 时需要注意以下事项。
- 检查 azureml 命名空间中的 Prometheus 是否由 Prometheus Operator 管理。 在某些方案中,Prometheus Operator 设置为仅监视某些特定的命名空间。 如果是这样,请确保 azureml 命名空间已列入允许列表。 有关详细信息,请参阅命令标志。
- 检查 Prometheus Operator 中是否启用了 kubelet-service。 kubelet-service 包含 kubelet 的所有终结点。 有关详细信息,请参阅命令标志。 另外需要确保 kubelet-service 具有标签
k8s-app=kubelet
。 - 为 kubelet-service 创建 ServiceMonitor。 使用替换的变量运行以下命令:
cat << EOF | kubectl apply -f - apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: prom-kubelet namespace: azureml labels: release: "<extension-name>" # Please replace to your Azure Machine Learning extension name spec: endpoints: - port: https-metrics scheme: https path: /metrics/cadvisor honorLabels: true tlsConfig: caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt insecureSkipVerify: true bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token relabelings: - sourceLabels: - __metrics_path__ targetLabel: metrics_path jobLabel: k8s-app namespaceSelector: matchNames: - "<namespace-of-your-kubelet-service>" # Please change this to the same namespace of your kubelet-service selector: matchLabels: k8s-app: kubelet # Please make sure your kubelet-service has a label named k8s-app and it's value is kubelet EOF
Dcgm-exporter 是 NVIDIA 建议用于收集 GPU 指标的官方工具。 我们已将其集成到 Azure 机器学习扩展中。 但是,dcgm-exporter 默认未启用,因此不会收集 GPU 指标。 可将 installDcgmExporter
标志指定为 true
来启用它。 由于它是 NVIDIA 的官方工具,因此你可能已将它安装在 GPU 群集中。 如果是这样,可以将installDcgmExporter
设置为false
,并按照步骤将 dcgm-exporter 集成到 Azure 机器学习扩展中。 需要注意的另一个事项是,dcgm-exporter 允许用户配置要公开的指标。 对于 Azure 机器学习扩展,请确保公开DCGM_FI_DEV_GPU_UTIL
、DCGM_FI_DEV_FB_FREE
和DCGM_FI_DEV_FB_USED
指标。
确保已成功安装 Aureml 扩展和 dcgm-exporter。 可以通过 Dcgm-exporter helm 图表或 Gpu-operator helm 图表安装 dcgm-exporter
检查是否存在 dcgm-exporter 的服务。 如果不存在或者你不知道如何检查,请运行以下命令创建一个服务。
cat << EOF | kubectl apply -f - apiVersion: v1 kind: Service metadata: name: dcgm-exporter-service namespace: "<namespace-of-your-dcgm-exporter>" # Please change this to the same namespace of your dcgm-exporter labels: app.kubernetes.io/name: dcgm-exporter app.kubernetes.io/instance: "<extension-name>" # Please replace to your Azure Machine Learning extension name app.kubernetes.io/component: "dcgm-exporter" annotations: prometheus.io/scrape: 'true' spec: type: "ClusterIP" ports: - name: "metrics" port: 9400 # Please replace to the correct port of your dcgm-exporter. It's 9400 by default targetPort: 9400 # Please replace to the correct port of your dcgm-exporter. It's 9400 by default protocol: TCP selector: app.kubernetes.io/name: dcgm-exporter # Those two labels are used to select dcgm-exporter pods. You can change them according to the actual label on the service app.kubernetes.io/instance: "<dcgm-exporter-helm-chart-name>" # Please replace to the helm chart name of dcgm-exporter EOF
检查上一步骤中的服务是否已正确设置
kubectl -n <namespace-of-your-dcgm-exporter> port-forward service/dcgm-exporter-service 9400:9400 # run this command in a separate terminal. You will get a lot of dcgm metrics with this command. curl http://127.0.0.1:9400/metrics
设置 ServiceMonitor 以将 dcgm-exporter 服务公开给 Azure 机器学习扩展。 运行以下命令,它会在几分钟后生效。
cat << EOF | kubectl apply -f - apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: dcgm-exporter-monitor namespace: azureml labels: app.kubernetes.io/name: dcgm-exporter release: "<extension-name>" # Please replace to your Azure Machine Learning extension name app.kubernetes.io/component: "dcgm-exporter" spec: selector: matchLabels: app.kubernetes.io/name: dcgm-exporter app.kubernetes.io/instance: "<extension-name>" # Please replace to your Azure Machine Learning extension name app.kubernetes.io/component: "dcgm-exporter" namespaceSelector: matchNames: - "<namespace-of-your-dcgm-exporter>" # Please change this to the same namespace of your dcgm-exporter endpoints: - port: "metrics" path: "/metrics" EOF
如果群集中已经安装 volcano 套件,则你可以设置 installVolcano=false
,这样,扩展就不会安装 Volcano Scheduler。 需要使用 Volcano Scheduler 和 Volcano Controller 来训练作业提交和安排计划。
Azure 机器学习扩展使用的 Volcano Scheduler 配置是:
volcano-scheduler.conf: |
actions: "enqueue, allocate, backfill"
tiers:
- plugins:
- name: task-topology
- name: priority
- name: gang
- name: conformance
- plugins:
- name: overcommit
- name: drf
- name: predicates
- name: proportion
- name: nodeorder
- name: binpack
需要使用此相同的配置设置,并且如果Volcano 版本低于 1.6,需要在 Volcano Admission 中禁用job/validate
Webhook,使 Azure 机器学习训练工作负载能够正常执行。
正如此主题中所讨论的,gang 插件无法很好地与群集自动缩放程序 (CA) 以及 AKS 中的节点自动缩放程序配合使用。
如果通过设置installVolcano=true
使用 Azure 机器学习扩展附带的 Volcano,则默认情况下,该扩展会具有计划程序配置,用于配置gang插件以防止作业死锁。 因此,通过扩展安装的 Volcano 将不支持 AKS 群集中的群集自动缩放器 (CA)。
对于这种情况,如果希望 AKS 群集自动缩放程序能够正常工作,则可以通过更新扩展来配置此volcanoScheduler.schedulerConfigMap
参数,并为其指定无 gangVolcano Scheduler 的自定义配置,例如:
volcano-scheduler.conf: |
actions: "enqueue, allocate, backfill"
tiers:
- plugins:
- name: sla
arguments:
sla-waiting-time: 1m
- plugins:
- name: conformance
- plugins:
- name: drf
- name: predicates
- name: proportion
- name: nodeorder
- name: binpack
要在 AKS 群集中使用此配置,需要执行以下步骤:
- 在
azureml
命名空间中使用上述配置创建 configmap 文件。 此命名空间通常将在你安装 Azure 机器学习扩展时创建。 - 在扩展配置中设置
volcanoScheduler.schedulerConfigMap=<configmap name>
以应用此配置映射。 在安装扩展时,需要通过配置amloperator.skipResourceValidation=true
来跳过资源验证。 例如:az k8s-extension update --name <extension-name> --config volcanoScheduler.schedulerConfigMap=<configmap name> amloperator.skipResourceValidation=true --cluster-type managedClusters --cluster-name <your-AKS-cluster-name> --resource-group <your-RG-name>
备注
由于删除了 gang 插件,因此 Volcano 计划作业时可能会发生死锁。
- 为避免这种情况,可以在作业中使用相同的实例类型。
使用 Azure 机器学习扩展提供的默认配置以外的调度程序配置可能不完全受支持。 请谨慎操作。
请注意,如果 Volcano 版本低于 1.6,则需要在 Volcano Admission 中禁用 job/validate
Webhook。
默认情况下,Azure 机器学习扩展安装附带入口 nginx 控制器类(作为k8s.io/ingress-nginx
)。 如果群集中已有入口 nginx 控制器,需要使用不同的控制器类以避免安装失败。
可以使用两个选项:
- 将现有的控制器类更改为
k8s.io/ingress-nginx
以外的其他类。 - 按照以下示例,使用不同于你的自定义控制器类创建或更新 Azure 机器学习扩展。
例如,要使用自定义控制器类创建扩展:
az ml extension create --config nginxIngress.controller="k8s.io/amlarc-ingress-nginx"
要使用自定义控制器类更新扩展:
az ml extension update --config nginxIngress.controller="k8s.io/amlarc-ingress-nginx"
症状
随 Azure 机器学习扩展一起安装的 nginx 入口控制器因内存不足 (OOM) 错误而发生故障,即使没有工作负载也是这样。 控制器日志不显示诊断问题的任何有用信息。
可能的原因
如果 nginx 入口控制器在具有许多 CPU 的节点上运行,则可能会出现此问题。 默认情况下,nginx 入口控制器会根据 CPU 数生成工作进程,这可能会消耗较多资源,并导致具有较多 CPU 的节点上出现 OOM 错误。 这是 GitHub 上报告的已知问题
解决方案
若要解决此问题,您可以:
- 通过使用参数
nginxIngress.controllerConfig.worker-processes=8
安装扩展,调整工作进程数。 - 使用参数
nginxIngress.resources.controller.limits.memory=<new limit>
提高内存上限。
确保根据特定的节点规格和工作负载要求调整这两个参数,以有效地优化工作负载。