ModelArts 自定义镜像部署避坑指南:8080 端口、/home/mind/model 与 ma-user

举报
yd_254048033 发表于 2026/10/26 17:44:48 2026/10/26
【摘要】 自定义镜像部署 ModelArts 在线服务的实战记录:ma-user 用户、8080 端口、/home/mind/model 三条硬约束,加上架构不一致、健康检查、路径写死等五个高频坑的排查思路。

写在前面

用 ModelArts 的预置引擎部署模型,基本是点几下的事;一旦换成自定义镜像,第一次部署大概率会卡在"服务一直部署中"或者"调用返回 502"。这篇把自己踩过的几个坑按顺序整理一遍,给同样在折腾自定义镜像的同学省点时间。

一、先搞清楚平台对镜像的三条硬约束

自定义镜像不是"能跑就行",ModelArts 对镜像有明确规范,这三条不满足必然失败:

1. 必须内置 ma-user 用户,uid=1000、gid=100

平台会以 uid=1000 的身份启动容器,镜像里没有这个用户,容器起来就挂。Dockerfile 里加这两行:

RUN groupadd -g 100 ma-group && \
    useradd -d /home/ma-user -m -u 1000 -g 100 -s /bin/bash ma-user
USER 1000

2. 推理服务必须监听 8080 端口

平台只把容器 8080 端口的服务注册到 API 网关,写 app.run(port=5000) 之类的一律访问不到。协议按镜像实际情况填,HTTP/HTTPS 都支持。

3. 模型包目录名必须叫 model,落到容器里是 /home/mind/model

OBS 上的模型目录下载到容器后固定挂载在 /home/mind/model,且文件 owner 会被统一改成 ma-user。所以推理脚本里读模型要用这个绝对路径或者相对脚本自身的路径,千万别写死本地的 ./weights——本地跑得好好的,上云就找不到文件。

顺便提一个容易忽略的点:代码里不要对 /home/mind/model 做写操作,该目录在线上是可写的但权限收紧过,只读推理才是稳妥做法。

二、懒人版最小流程

  1. 本地按上面三条改好镜像,推到 SWR;
  2. 本地先验证一遍,避免上云才发现问题:
docker run --user 1000:100 -p 8080:8080 -v $(pwd)/model:/home/mind/model custom_engine:v1
curl http://127.0.0.1:8080/health
  1. OBS 里建一个目录(名字就叫 model),把权重、推理脚本、配置文件传上去;
  2. ModelArts 控制台 → 模型管理 → 创建模型:元模型来源选"从对象存储服务(OBS)中选择",AI 引擎选 Custom,再选 SWR 镜像;
  3. 模型状态"正常"后 → 部署 → 在线服务,选实例规格,等状态变"运行中"。

注意第一步本地验证只能验证个大概:-v 挂载进去的目录是 root 权限,和线上 ma-user 的权限模型不完全一致,所以权限相关的问题还得靠线上日志判断。

三、调用环节

服务跑起来之后,服务详情页会给一个 API 接口地址(形如 https://xxx/v1/infers/{service_id},以控制台实际展示为准)。请求头里要带 IAM token:

import requests

def get_token(user, password, domain, project_id, region="cn-north-4"):
    body = {
        "auth": {
            "identity": {
                "methods": ["password"],
                "password": {"user": {"name": user, "password": password, "domain": {"name": domain}}}
            },
            "scope": {"project": {"id": project_id}}
        }
    }
    r = requests.post(f"https://iam.{region}.myhuaweicloud.com/v3/auth/tokens",
                      json=body, verify=False)
    return r.headers["X-Subject-Token"]

token = get_token("你的用户名", "你的密码", "你的账号名", "项目ID")
resp = requests.post(SERVICE_URL,
                     headers={"X-Auth-Token": token, "Content-Type": "application/json"},
                     json={"data": "your input"})
print(resp.status_code, resp.text)

token 有效期 24 小时,长期跑的服务记得做缓存或提前刷新,别每次请求都去换。

四、最常踩的五个坑

现象 常见原因 处理
服务一直"部署中",最后失败 镜像架构和资源池不一致(x86 拉 AMD64、ARM 拉了 x86) docker build --platform linux/amd64 重新构建
服务"运行中"但调用 502 服务没监听 8080,或监听在 127.0.0.1 上 绑 0.0.0.0:8080
容器启动即退出 没有 ma-user / 启动命令在前台没挂住 加 USER 1000,CMD 用前台进程
推理报"找不到模型文件" 路径写死成本地相对路径 统一用 /home/mind/model
健康检查一直不通过 没实现 /health,或返回码不是 200 加一个直接 return 200 的 /health

排查顺序建议:先看服务详情页的事件,再看日志。事件里通常会直接写"镜像拉取失败""健康检查超时",比翻日志快得多。

五、两件小事

  • 用完记得停。在线服务按实例时长计费,调试阶段建议实例数 1、用完就停,别留一堆"运行中"的实例过夜。
  • 别把 AK/SK 写进镜像。镜像推到 SWR 是可被拉取的,凭据一律走环境变量或委托(Agency)授权。

自定义镜像这条路前期确实比预置引擎麻烦,但把上面三条规范和五个坑过一遍,后面基本就是改模型换镜像的重复劳动了。祝部署顺利。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。