Harbor 常用 CLI 命令详解

详解 Harbor 2.15.4 常用命令行操作:docker login/push/pull 镜像流转,以及 curl 调用 REST API(项目/仓库/制品、漏洞扫描、垃圾回收 GC、系统信息),每个命令给出完整命令、真实输出与参数说明

HarborHarborDevOps制品管理2026/10/10

Harbor 常用 CLI 命令详解

目标:详解 Harbor 2.15.4 的常用命令行操作——docker login / docker push / docker pull 等镜像流转,以及用 curl 调用 Harbor REST API v2.0 管理项目、仓库、制品、漏洞扫描、垃圾回收(GC)与系统信息。每个命令给出完整命令、真实输出与参数说明。本文已在 Ubuntu 22.04 真实环境实测通过。

一、环境信息

  • 操作系统:Ubuntu 22.04.5 LTS
  • 系统架构:x86_64
  • Harbor 服务器:2.15.4(HTTPS https://172.17.0.63,自签证书)
  • 数据目录:/opt/data/harbor
  • 管理账号:admin / 密码 q1w2e3r4
  • 服务器地址:172.17.0.63(示例内网 IP,请替换为你的实际地址)
  • 测试项目:library(系统内置公开项目)、myapp(私有项目,由 REST 创建)
  • 测试制品:alpine:3.20 / alpine:2.0(digest sha256:6c2a9711b0a9f...)
  • 工具:docker(29.8.1)、curl、jq/python3(可选做 JSON 解析)

二、工具概览

工具主要用途
docker loginHTTPS 认证登录 Harbor
docker push / docker pull向 Harbor 推送 / 拉取制品
docker logout登出 Harbor
curl + Harbor REST API /api/v2.0/*项目、仓库、制品、扫描、GC、系统信息等管理

💡 说明:Harbor 无独立 CLI 客户端,日常命令行操作 = Docker CLI(镜像流转)+ curl 调用 REST API(管理)。全部走 HTTPS,自签证书时 curl 需加 -k、docker login 需提前信任证书(见《Ubuntu 22.04 安装 Harbor 指南》8.4)。

三、前置条件

  • 已部署 Harbor 2.15.4 且服务正常(/api/v2.0/ping 返回 Pong)
  • Docker 客户端已配置信任 Harbor 的 HTTPS(导入 ca.crt,或将地址加入 insecure-registries)
  • 本地已有待推送的镜像(如 alpine:3.20)
  • 具备管理账号 admin/q1w2e3r4 或机器人凭据

四、docker CLI 镜像流转

4.1 登录(docker login)

docker login 172.17.0.63 -u admin -p q1w2e3r4

实测输出:

WARNING! Using --password via the CLI is insecure. Use --password-stdin.

WARNING! Your credentials are stored unencrypted in '/root/.docker/config.json'.
Configure a credential helper to remove this warning. See
https://docs.docker.com/go/credential-store/

Login Succeeded

💡 说明:Login Succeeded 表示 HTTPS 认证通过。安全起见生产建议用 --password-stdin 避免口令落到 shell 历史,并优先使用机器人账户凭据(见《Harbor 配置参数详解》5.9):

echo q1w2e3r4 | docker login 172.17.0.63 -u admin --password-stdin

4.2 推送镜像(docker push)

docker tag alpine:3.20 172.17.0.63/library/alpine:3.20
docker push 172.17.0.63/library/alpine:3.20

实测输出:

The push refers to repository [172.17.0.63/library/alpine]
08bc4e534116: Preparing
08bc4e534116: Pushed
3.20: digest: sha256:6c2a9711b0a9f32b0239d9222eb1072309cf46c6431d319ae249186d811a987c size: 527

💡 说明:tag 的格式为 <Harbor服务地址>/<项目名>/<镜像名>:<标签>。往私有项目(如 myapp)推送时,重复层会显示 Mounted from library/alpine(实测):

docker tag alpine:3.20 172.17.0.63/myapp/alpine:2.0
docker push 172.17.0.63/myapp/alpine:2.0

实测输出:

The push refers to repository [172.17.0.63/myapp/alpine]
08bc4e534116: Preparing
08bc4e534116: Mounted from library/alpine
2.0: digest: sha256:6c2a9711b0a9f32b0239d9222eb1072309cf46c6431d319ae249186d811a987c size: 527

4.3 拉取镜像(docker pull)

先删除本地镜像再拉取,验证真正从 Harbor 下载:

docker rmi 172.17.0.63/library/alpine:3.20
docker pull 172.17.0.63/library/alpine:3.20

实测输出:

3.20: Pulling from library/alpine
Digest: sha256:6c2a9711b0a9f32b0239d9222eb1072309cf46c6431d319ae249186d811a987c
Status: Downloaded newer image for 172.17.0.63/library/alpine:3.20
172.17.0.63/library/alpine:3.20

💡 说明:Status: Downloaded newer image 与末尾返回镜像全名,表示拉取成功且 digest 与推送时一致,说明制品在 Harbor 中完整存取。

4.4 查看登录状态与环境信息

docker login --help | head -20        # 查看 login 所有参数

4.5 登出(docker logout)

docker logout 172.17.0.63

预期输出:

Removing login credentials for 172.17.0.63

💡 说明:docker logout 仅删除本地保存的凭据,不影响 Harbor 服务。


五、REST API(curl)——系统与项目

所有接口前缀 https://172.17.0.63/api/v2.0,如下 B 变量即该前缀(自签加 -k):

B="https://172.17.0.63/api/v2.0"

5.1 健康与版本

curl -sk "$B/ping"; echo
curl -sk -u admin:q1w2e3r4 "$B/health"

实测输出:

Pong
{"components":[{"name":"core","status":"healthy"},{"name":"database","status":"healthy"},{"name":"jobservice","status":"healthy"},{"name":"portal","status":"healthy"},{"name":"redis","status":"healthy"},{"name":"registry","status":"healthy"},{"name":"registryctl","status":"healthy"}],"status":"healthy"}

5.2 系统信息(systeminfo)

curl -sk "$B/systeminfo"

实测输出:

{"auth_mode":"db_auth","banner_message":"","oidc_provider_name":"","primary_auth_mode":false,"self_registration":false}

💡 说明:auth_mode: db_auth(本地数据库认证)、self_registration: false 等处理信息,可用于判断认证与注册配置。

5.3 当前用户身份

curl -sk -u admin:q1w2e3r4 "$B/users/current"

实测输出:

{"username":"admin","sysadmin_flag":true}

💡 说明:sysadmin_flag:true 确认当前为系统管理员。

5.4 创建项目(POST /projects)

curl -sk -u admin:q1w2e3r4 -X POST "$B/projects" \
  -H "Content-Type: application/json" \
  -d '{"project_name":"myapp","metadata":{"public":"false"},"storage_limit":-1}' \
  -o /dev/null -w "create project HTTP %{http_code}\n"

实测输出:

create project HTTP 201

💡 说明:201 表示创建成功。参数 project_name 必填;metadata.public 控制公开/私有;storage_limit 为满额上限(-1 不限,单位字节)。

5.5 列出项目(GET /projects)

curl -sk -u admin:q1w2e3r4 "$B/projects?page_size=10"

实测输出(节选,格式化后):

[
  {
    "name": "library",
    "project_id": 1,
    "repo_count": 1,
    "metadata": {"public": "true"},
    "owner_name": "admin"
  },
  {
    "name": "myapp",
    "project_id": 2,
    "repo_count": 1,
    "metadata": {"public": "false"},
    "owner_name": "admin"
  }
]

💡 说明:myapp 为私有项目(public:false)、library 为系统内置公开项目(public:true)。可用 ?name=myapp 精确过滤单项目。


六、REST API(curl)——仓库与制品

6.1 列出项目仓库(GET /projects/{name}/repositories)

curl -sk -u admin:q1w2e3r4 "$B/projects/myapp/repositories"

实测输出:

[
  {
    "artifact_count": 1,
    "creation_time": "2026-10-10T01:03:01.449Z",
    "id": 2,
    "name": "myapp/alpine",
    "project_id": 2,
    "pull_count": 0,
    "update_time": "2026-10-10T01:03:01.436Z"
  }
]

💡 说明:name: myapp/alpine(含项目前缀)、artifact_count 制品数、pull_count 拉取次数,可据此观察制品热度。

6.2 列出仓库内制品(GET .../artifacts)

curl -sk -u admin:q1w2e3r4 "$B/projects/myapp/repositories/alpine/artifacts"

实测输出(关键字段):

[
  {
    "artifact_type": "application/vnd.docker.container.image.v1+json",
    "digest": "sha256:6c2a9711b0a9f32b0239d9222eb1072309cf46c6431d319ae249186d811a987c",
    "extra_attrs": {
      "architecture": "amd64",
      "os": "linux",
      "created": "2026-04-16T23:53:26.803599608Z"
    },
    "id": 2,
    "project_id": 2,
    "repository_name": "myapp/alpine",
    "size": 3631460,
    "tags": [
      {
        "artifactId": 2,
        "id": 2,
        "immutable": false,
        "name": "2.0",
        "push_time": "2026-10-10T01:03:01.500Z"
      }
    ],
    "type": "IMAGE"
  }
]

💡 说明:digest 为不可变内容地址、tags[].name 即标签 2.0、size 为制品大小(字节,实测 3.6 MB)。加 ?with_tag=true&with_label=true 可带出更多附加信息。

6.3 删除仓库 / 制品

# 删除某仓库内的某个制品(将产物下线,谨慎)
curl -sk -u admin:q1w2e3r4 -X DELETE \
  "$B/projects/myapp/repositories/alpine/artifacts/2.0"

⚠️ 注意:DELETE 属破坏性操作,脚本中务必二次确认。正式清理常结合"垃圾回收(GC)"释放已删除制品的存储。


七、REST API(curl)——漏洞扫描与垃圾回收

7.1 触发漏洞扫描

curl -sk -u admin:q1w2e3r4 -X POST \
  "$B/projects/myapp/repositories/alpine/artifacts/2.0/scan" \
  -o /dev/null -w "scan HTTP %{http_code}\n"

实测输出:

scan HTTP 412

⚠️ 排障(实测):返回 412 Precondition Failed 是因为本次部署未启用 Trivy 扫描服务(安装时未加 --with-trivy)。启用后该请求返回 202,随后可用

curl -sk -u admin:q1w2e3r4 -H "X-Accept-Vulnerabilities: application/vnd.security.vulnerability.report; version=1.1" \
  "$B/projects/myapp/repositories/alpine/artifacts/2.0"

读取包含 scan_overview 的漏洞报告(含 severity、summary、CVE 列表)。需启用扫描时以 ./install.sh --with-trivy 重新部署。

7.2 垃圾回收(GC)—— 设置定时调度

curl -sk -u admin:q1w2e3r4 -X POST "$B/system/gc/schedule" \
  -H "Content-Type: application/json" \
  -d '{"schedule":{"type":"Custom","cron":"0 0 2 * * *"},"parameters":{"delete_untagged":false,"dry_run":false}}' \
  -o /dev/null -w "GC schedule HTTP %{http_code}\n"

实测输出:

GC schedule HTTP 201

查询当前 GC 调度(实测):

curl -sk -u admin:q1w2e3r4 "$B/system/gc/schedule"

实测输出:

{"creation_time":"2026-10-10T00:46:01.369Z","id":3,"job_kind":"0 0 2 * * *","job_parameters":"{\"delete_tag\":false,\"delete_untagged\":false,\"workers\":0}","job_status":"Running","schedule":{"cron":"0 0 2 * * *","next_scheduled_time":"2026-10-10T02:00:00.000Z","type":"Custom"},"update_time":"2026-10-10T00:46:01.369Z"}

💡 说明:type: Custom + cron: 0 0 2 * * * 表示每天 02:00 自动 GC。parameters.delete_untagged 控制是否同时清理未打标签制品。GC 可回收被删除制品仍占用的存储,建议生产定期执行(默认巡检可关闭触发)。

⚠️ 排障(实测):即时触发 GC 用 POST /system/gc(body 带 Manual 调度)在 v2.0 中实际返回 405 METHOD_NOT_ALLOWED —— 该接口仅允许 GET,应立即改为创建/查询调度(/system/gc/schedule),如 7.2。不要直接以 POST 打 /system/gc。


八、汇总:常用命令速查

B="https://172.17.0.63/api/v2.0"
AUTH="-u admin:q1w2e3r4"

# 镜像流转
docker login 172.17.0.63 -u admin -p q1w2e3r4
docker tag alpine:3.20 172.17.0.63/library/alpine:3.20
docker push     172.17.0.63/library/alpine:3.20
docker pull     172.17.0.63/library/alpine:3.20
docker logout   172.17.0.63

# 系统信息
curl -sk $AUTH "$B/ping"
curl -sk "$B/systeminfo"
curl -sk $AUTH "$B/health"
curl -sk $AUTH "$B/users/current"

# 项目
curl -sk $AUTH -X POST "$B/projects" -H "Content-Type: application/json" \
  -d '{"project_name":"myapp","metadata":{"public":"false"},"storage_limit":-1}'
curl -sk $AUTH "$B/projects?name=myapp&page_size=10"

# 仓库 / 制品
curl -sk $AUTH "$B/projects/myapp/repositories"
curl -sk $AUTH "$B/projects/myapp/repositories/alpine/artifacts"
curl -sk $AUTH -X DELETE "$B/projects/myapp/repositories/alpine/artifacts/2.0"

# 扫描 / GC
curl -sk $AUTH -X POST "$B/projects/myapp/repositories/alpine/artifacts/2.0/scan"
curl -sk $AUTH "$B/system/gc/schedule"

💡 说明:以上 AUTH、B 均为真实取值的示例变量;生产建议把认证信息改为机器人凭据(robot$project+name)或 API token,避免明文口令散落 shell 历史。


九、注意事项

  • 认证安全:演示用 admin/q1w2e3r4;生产用机器人账户(robot$<项目>+<名>)或 API token,最小权限 + 定期轮换(见《Harbor 配置参数详解》5.9)。
  • 自签 HTTPS:curl 加 -k;docker login 需把 ca.crt 导入客户端 Docker 或加入 insecure-registries。
  • 破坏性命令谨慎:DELETE 制品、删除项目等不可逆,脚本中需校验。
  • 扫描需 Trivy:未启用 Trivy 时扫描返回 412,需 --with-trivy 部署。
  • GC 即时触发注意:用 /system/gc/schedule 而非 POST /system/gc(后者 405)。

十、常见问题

10.1 问题 1:docker login 报 certificate signed by unknown authority

原因: 客户端 Docker 未信任 Harbor 的自签证书。

解决: 将 ca.crt 放置到 /etc/docker/certs.d/172.17.0.63/ca.crt 后重启 Docker;或把地址加进 daemon 的 insecure-registries(仅限受信内网)。

10.2 问题 2:扫描返回 412 Precondition Failed

原因: 部署未启用 Trivy。

解决: 用 ./install.sh --with-trivy 重新部署;或先离线安装 trivy-db。

10.3 问题 3:POST /system/gc 返回 405

原因: v2.0 该接口不接受 POST 即时触发。

解决: 改用创建/查询 GC 调度(/system/gc/schedule,见 7.2)。

10.4 问题 4:删除制品后磁盘空间未释放

原因: 删除只会移除元数据引用,底层层文件要等 GC 回收。

解决: 配置或触发 GC 任务(/system/gc/schedule)。

10.5 问题 5:推送到私有项目提示 unauthorized

原因: 登录账号对该项目无推送权限,或未登录。

解决: 确认已 docker login;给该账号/机器人授予对应项目的 push 权限。


十一、参考链接


本文档由 www.quzuo.net 平台开发