第八章

镜像仓库与镜像安全

第七层 · Registry/Harbor 镜像从哪来,靠不靠谱

一、镜像不能只存在自己电脑上

小陈构建好了直播模块的镜像,正要部署到生产服务器,发现一个问题:

"师傅,生产服务器上没有我构建的镜像啊……难道我要把镜像文件拷过去?"

"对,这就是镜像仓库(Registry)存在的意义。"老周说,"镜像仓库 = 镜像的'中央仓库'——开发机构建好镜像,推送到仓库;生产服务器从仓库拉取。镜像有了一个'官方来源',部署才有了标准流程。"

镜像仓库 Registry:
  ┌──────────┐   push(推)   ┌──────────┐   pull(拉)  ┌──────────┐
  │ 开发机    │ ────────────▶ │  仓库     │ ────────────▶ │ 生产服务器 │
  │ (构建镜像) │              │ Registry │              │ (部署)     │
  └──────────┘               └──────────┘              └──────────┘

  作用:
  ① 集中存放:所有镜像统一管理,不散落在各机器
  ② 版本管理:同一镜像多个 tag(v1/v2/latest)
  ③ 权限控制:谁能推、谁能拉,可以精细管理
  ④ 安全扫描:扫描镜像漏洞(下面讲)

二、公共仓库 vs 私有仓库

"镜像仓库分两种:公共的和私有的。"老周说:

公共仓库:
  Docker Hub(官方,最常用)
  - 拉公共镜像(nginx、mysql、python...)从这里
  - 也可以把自己的镜像公开分享
  - 问题:公共的,企业敏感镜像不能放这

私有仓库:
  自建的、只有自己人能访问
  - Docker Registry(官方轻量版)
  - Harbor(企业级,功能全:权限/扫描/复制,最常用)
  - 云厂商的容器镜像服务(阿里云 ACR 等)

云间书店方案:
  公共镜像(mysql/nginx/python)→ 从 Docker Hub 拉
  业务镜像(yunjian/web、yunjian/api)→ 推到私有 Harbor

"公共的拉基础,私有的存业务——这是镜像仓库的标准用法。"


三、搭建私有仓库:Harbor

老周带小陈部署 Harbor(企业级私有仓库):

# 方式一:docker run 起一个轻量私有仓库(开发测试用)
docker run -d -p 5000:5000 --name registry registry:2

# 方式二:企业级 Harbor(生产推荐,功能全)
# 下载安装包后
./install.sh    # 安装 Harbor(自带 UI、权限、扫描)

# 使用流程
# 1. 登录私有仓库
docker login harbor.yunjian.com

# 2. 给镜像打上仓库地址的标签
docker tag yunjian/web:v1 harbor.yunjian.com/library/web:v1

# 3. 推送
docker push harbor.yunjian.com/library/web:v1

# 4. 生产服务器拉取
docker pull harbor.yunjian.com/library/web:v1

"注意镜像名的格式:仓库地址/项目/镜像名:版本 生产上镜像名带上仓库地址,pull 的时候才知道从哪拉。"


四、镜像安全:别让"供应链"变成"漏洞链"

"镜像从仓库来,那仓库里的镜像安全吗?"老周话锋一转,严肃起来,"2021 年有一个真实的供应链攻击案例:有攻击者往 Docker Hub 上上传了伪装成热门工具的恶意镜像,下载量超过 100 万次——开发者拉下来一跑,服务器就被种了后门。 这就是镜像供应链攻击。"

镜像安全三大威胁:
  ① 恶意镜像:伪装成热门工具,内藏后门/挖矿程序
     → 只从官方/可信源拉取,不拉来路不明的镜像
  ② 漏洞镜像:基础镜像或依赖有已知漏洞(如 Log4j)
     → 定期扫描(trivy/Clair/Harbor 自带扫描)
  ③ 篡改镜像:镜像被中间人篡改(推拉过程中被替换)
     → 用内容信任(Docker Content Trust)签名验证
# 用 trivy 扫描镜像漏洞
trivy image harbor.yunjian.com/library/web:v1
# 输出:发现 3 个高危漏洞 → 升级基础镜像修复

# 只拉可信来源(安全习惯)
docker pull nginx:1.25        # 官方库
docker pull hub.example.com/... # 自建可信仓库
# ❌ 不要从陌生人的仓库拉不明镜像!

"镜像安全的核心是'来源可信':从哪里拉、有没有签名、有没有漏洞——生产环境的镜像,必须是受控的。 这就是为什么企业都要自建 Harbor + 扫描,而不是随便从公共仓库拉业务镜像。"


五、镜像版本管理:tag 的艺术

"最后讲镜像的版本管理。tag 起得不好,部署就是灾难。"老周说:

坏的 tag 习惯:
  ❌ latest:永远指向最新,但"最新"是什么?没法回滚!
  ❌ v1:太模糊,v1 改了几十次,哪个是哪个?
  ❌ 不带 tag:默认 latest,同上

好的 tag 习惯:
  ✅ 语义化版本:v1.2.3(主版本.次版本.补丁)
  ✅ 带构建号:v1.2.3-build20260909(精确到这次构建)
  ✅ 加环境:web-prod-v1.2.3(明确环境)

云间书店的 tag 规范:
  yunjian/api:1.2.3              # 正式版本
  yunjian/api:1.2.3-rc1          # 候选版本(预发布)
  yunjian/api:latest             # 仅指向最新稳定版(方便测试)
  # 部署永远用具体版本号,方便回滚!

"生产部署必须用具体版本号,绝不裸用 latest。 这样回滚就是一句 docker pull 旧版本号 的事。"


六、章末:老周的第七层总结

第七层:镜像仓库与安全
├── 仓库 Registry:镜像中央仓库(push/pull)
├── 公共 vs 私有:公共拉基础,私有存业务(Harbor)
├── 镜像名格式:仓库地址/项目/镜像名:版本
├── 镜像安全:来源可信 + 漏洞扫描(trivy)+ 内容信任
└── tag 规范:语义化版本,生产不用 latest(可回滚)

"小陈,镜像管理好了,部署也能一键完成了。但你现在部署的目标,还是'一台服务器'。如果云间书店要开 5 家分店、要搞双十一秒杀、流量翻 100 倍——一台服务器顶得住吗?"

"顶不住……那得上很多台服务器?"

"对,而且容器要在多台机器之间'自动调度':哪台闲跑哪台、挂了自动重启、流量大了自动扩容。这就是编排的终极形态——Kubernetes。 下一章,云间书店的容器要'上 K8s'了。"

✌ 语言