Harbor 常用 CLI 命令详解
详解 Harbor 2.15.4 常用命令行操作:docker login/push/pull 镜像流转,以及 curl 调用 REST API(项目/仓库/制品、漏洞扫描、垃圾回收 GC、系统信息),每个命令给出完整命令、真实输出与参数说明
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(digestsha256:6c2a9711b0a9f...) - 工具:
docker(29.8.1)、curl、jq/python3(可选做 JSON 解析)
二、工具概览
| 工具 | 主要用途 |
|---|---|
docker login | HTTPS 认证登录 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 平台开发