ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Harbor离线安装与HTTPS配置:内网私有镜像仓库实战指南

Harbor离线安装与HTTPS配置:内网私有镜像仓库实战指南 简介这是一份Harbor v2.5.0-rc1的离线安装资源面向需要在内网或隔离环境部署容器镜像仓库的运维与开发人员解决因无法访问公共镜像源而导致的安装、部署困难。资源共6个文件以shell安装脚本、YAML配置模板、license许可文件及离线镜像压缩包等类型为主整体约623.92MB内置了Harbor服务镜像、安装入口脚本、公共处理脚本及配置准备工具用户只需按模板修改配置并执行脚本即可完成安装。该资源包已有254人学习下载适合具备一定容器基础、希望高效部署Harbor的工程技术人员。通过该离线包使用者可以快速搭建私有镜像仓库同时借助脚本和配置文件理解Harbor各组件的关系与参数含义为后续生产环境的定制与运维提供可靠参考。 Harbor 是我这几年用下来最顺手的私有镜像仓库没有之一。每次接手新环境第一件事就是把harbor-offline-installer-v2.5.0-rc1.tgz这个包推过去解压、改配置、跑install.sh基本就是这三板斧。虽然它名字里带 rc1但 v2.5.0 的候选版本在功能层面已经冻结拿来做预发环境甚至小规模生产完全够用。这篇博文我就从头到尾写一遍离线安装包的结构、Ubuntu 环境怎么准备、部署时的关键参数以及很多人躲不开的 http 改 https 的实操。照着做基本不会踩坑。1. 这个离线安装包里到底有什么很多人拿到 tgz 就开始解压实际上我建议先花十秒钟看看包的结构能省掉后面不少疑惑。用tar -tzf harbor-offline-installer-v2.5.0-rc1.tgz查看包内文件列表你会看到一个相对清爽的结构install.sh、prepare、harbor.yml.tmpl、common.sh、harbor.v2.5.0.tar.gz另外还有 license 和 readme 之类的说明文件。看到这里包的类型基本就明确了。Harbor 官方提供两种安装器online-installer 和 offline-installer。名字已经说明问题——online 的包很小脚本在安装时会去外部拉取所需 Docker 镜像服务器必须能连通外部镜像源而 offline 包把 goharbor 相关的所有镜像提前打进了harbor.v2.5.0.tar.gz安装时直接用docker load载入。这里的 offline 不是说机器完全不能联网而是指不依赖外部网络资源。这带来的直接好处是内网服务器没有外网访问权限时照样能完整部署一套 Harbor。我帮朋友公司搭环境时很多服务器都在隔离得很干净的网段里outbound 访问基本不存在online 安装器直接没法用这种离线包才是唯一正确打开方式。1.1 离线包设计的隐藏优势离线包还有一个很多人忽略的隐藏优势版本一致性。harbor.v2.5.0.tar.gz里面锁定了所有组件的镜像 tagcore、portal、registry、jobservice、trivy 这些镜像都是 v2.5.0-rc1 这一套不会因为你安装当天在线源更新了某个 tag 导致版本漂移。排障成本也随之降低。所有东西都在本地加载镜像失败就看磁盘和权限容器起不来就看配置和依赖干扰项比在线安装少得多。对于生产环境来说可重复、可预期远比装个最新版重要这也是我这些年越来越倾向离线包的原因。2. 部署前的环境准备任何安装类问题的根子九成在环境没准备好。Harbor 看起来就是一坨 docker compose但它对底层 Docker、存储空间、端口占用是有明确要求的。我吃过几次亏之后总结了一套固定检查项每台新机器先过一遍再动手。2.1 Ubuntu 版本与基础依赖Harbor v2.5.0 我当时跑得最多的是 Ubuntu 20.04 LTS18.04 也能跑22.04 也试过问题都不大。Ubuntu 版本反而不是主要矛盾真正容易出问题的是 Docker 版本太老。基础依赖我一般只装几个tar解压必需、curl排查用、openssl后面生成 https 证书必须。命令很简单sudo apt update sudo apt install -y tar curl opensslopenssl 这里多说一句Ubuntu 20.04 自带的 OpenSSL 1.1.1 足够用了生成证书、查看证书都方便。如果哪天遇到 openssl 命令参数行为诡异先确认不是系统里残留了太老的版本。2.2 Docker 和 Docker Compose 的安装与验证Docker 我建议直接用官方源装Ubuntu 下的安装方式已经非常成熟curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker.gpg echo deb [arch$(dpkg --print-architecture) signed-by/usr/share/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable | sudo tee /etc/apt/sources.list.d/docker.list sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin如果是在完全离线的环境里装 Docker那就需要提前把 docker-ce 相关的 deb 包整体拷贝进去用dpkg -i或apt install ./xxx.deb装。装完之后最重要的验证是 compose 插件可用docker version --format {{.Server.Version}} docker compose version没有docker compose命令时传统 standalone 的docker-compose也可以Harbor 的install.sh会自己判断。但不管用哪个版本都不能太老Compose v2 最好v1 的 1.29 也行。2.3 存储空间、端口和网络规划存储规划这一块我建议提前做别等装完再后悔。Docker 的数据目录/var/lib/docker和 Harbor 的数据目录默认/data都要预留足够空间。离线包里镜像 tar 大概 1GB 左右导入之后占用的实际磁盘空间会更可观建议 Docker 数据目录预留 20GB 以上Harbor 的data_volume预留 100GB 以上——镜像仓库这种东西后面数据涨幅是很快的。端口方面主要看 80 和 443。Harbor 默认对外入口就是这两个端口如果机器上已经跑了 nginx 或者其他 Web 服务要提前把端口错开不然install.sh起来后就会看到端口冲突的错误。我一般习惯先用ss -lntp看一眼监听情况再决定要不要调整 harbor.yml 里的端口配置。3. 在 Ubuntu 上直装 Harbor 的完整流程环境弄好之后安装本身其实很简单但每一步都有一个为什么。我按实操顺序把完整流程走一遍重点讲那些官方文档没说透的细节。3.1 校验、解压、生成配置文件拿到harbor-offline-installer-v2.5.0-rc1.tgz后的第一步我建议先做完整性校验。离线包在传输过程中损坏的概率不高但一旦损坏docker load到一半报错排查起来非常浪费时间。用 md5sum 或 sha256sum 都行md5sum harbor-offline-installer-v2.5.0-rc1.tgz校验值对上之后解压进入目录把模板复制成真正的配置tar -xzf harbor-offline-installer-v2.5.0-rc1.tgz cd harbor cp harbor.yml.tmpl harbor.ymlharbor.yml是 Harbor 唯一的配置入口install.sh和prepare都会以它为准所以值得多花几分钟逐项看清楚。后面改配置、改端口、改密码都是改这个文件。3.2 harbor.yml 关键参数解析我第一次部署时对这些参数没什么概念后来才发现有些坑是写死在默认值里的。现在我把关键参数整理成一张表方便对着改。参数作用我的建议hostname对外暴露的地址docker login 时要用它填能解析到本机的域名或内网 IPhttp.porthttp 监听端口默认 80被占用就改https.porthttps 监听端口启用 https 后建议用 443https.certificate / private_key服务端证书与私钥路径后面专门讲如何生成harbor_admin_password管理员初始密码一定要改别用默认的 Harbor12345database.password数据库 root 密码启动后改很麻烦第一次就设好data_volume持久化数据目录放到大分区或独立数据盘关于 hostname 有个容易踩的坑后续docker login的地址必须和 hostname 保持一致。如果你填的是本机 IP后面就用这个 IP 登录如果你填的是域名那证书和登录都要用域名。我第一次部署时图省事填了hostname: 127.0.0.1结果其他节点根本没法用这个仓库只能全部重新来一遍。3.3 执行 install.sh 安装基础安装直接跑sudo ./install.sh执行过程中 install.sh 会先调用docker load导入harbor.v2.5.0.tar.gz里的所有镜像然后运行prepare生成 nginx 配置和 docker-compose.yml最后docker compose up -d启动全部组件。如果想让漏洞扫描功能可用可以带上 Trivy 参数sudo ./install.sh --with-trivy如果你是从老版本比如 2.2、2.3升上来的注意 v2.5.0 开始官方安装脚本的可选组件已经变了Clair 和 ChartMuseum 在新版本里逐渐退出扫描器以 Trivy 为主。这种变化直接看install.sh --help的输出就行别拿老版本的肌肉记忆去加参数加了反而会报错。安装完成后验证服务状态docker compose ps curl -k http://127.0.0.1/api/v2.0/health返回 healthy 或者版本信息就说明服务正常。浏览器打开http://hostname输入管理员账号第一次登录系统会强制要求修改初始密码这个设计还是很好的。4. 从 http 改成 https绕不开的那几步如果只在局域网里自己用http 似乎也行。但一旦要接 Kubernetes 集群、要让其他开发机都来拉镜像或者面对内网安全审计http 就成了绕不开的坎。4.1 为什么我建议仓库直接上 https理由有很多我讲几个实际层面的。第一镜像仓库里存的是公司核心业务代码和运行配置明文传输等于把账本贴在门外面抓包工具一扫镜像内容、访问凭证全暴露了。第二Kubernetes 节点如果配置 http 镜像源每个节点都要设置 insecure-registries还要忍受跳过 TLS 校验带来的各种诡异问题统一改成 https所有节点只要信任同一个 CA客户端配置干净利落。第三很多安全基线扫描现在都把 TLS 作为硬性要求仓库开着 http 连验收都过不了。4.2 用 openssl 生成自签名 CA 与服务端证书生成证书的过程我拆成两层一个是根 CA一个是 Harbor 自己的服务端证书。正规做法是让内部 CA 体系签发但在实验室或小团队场景里自建 CA 然后签 Harbor 证书完全够用而且全程可控。第一步生成 CA 私钥和自签名根证书openssl genrsa -out ca.key 4096 openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 -subj /CNHarbor-CA -out ca.crt第二步生成 Harbor 服务端私钥openssl genrsa -out harbor.key 2048这一步是很多人翻车的地方。直接openssl req -new -x509生成的证书没有 SAN 字段Chrome 会拦截访问docker 和 containerd 也会报 x509 错误。所以签发证书必须带 subjectAltName。新建一个harbor-san.cnf内容类似[req] distinguished_name dn req_extensions ext [dn] CN harbor.example.com [ext] subjectAltName alt_names [alt_names] DNS.1 harbor.example.com DNS.2 localhost IP.1 192.168.1.10alt_names这一段务必覆盖所有实际访问入口。如果你有多个内网 IP或者计划用域名访问把 IP 和域名都列进去。然后用这个配置签发证书openssl req -new -key harbor.key -out harbor.csr -config harbor-san.cnf openssl x509 -req -in harbor.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 825 -sha256 -extfile harbor-san.cnf -extensions ext -out harbor.crt生成的harbor.crt和harbor.key就是后面 harbor.yml 里要引用的文件。证书有效期我习惯给 825 天约等于两年多既符合常见安全策略也不需要频繁续期。4.3 修改 harbor.yml 并安全重启服务把证书放到固定目录我习惯放在/data/certs下权限要收好sudo mkdir -p /data/certs sudo cp harbor.crt harbor.key ca.crt /data/certs/ sudo chown -R root:root /data/certs sudo chmod 640 /data/certs/*修改 harbor.ymlhostname: harbor.example.com http: port: 80 https: port: 443 certificate: /data/certs/harbor.crt private_key: /data/certs/harbor.key注意这里有个设计取舍。如果同时保留http.port和https.portHarbor 的 nginx 入口会同时监听 80 和 443两种方式都能访问。我建议尽早只暴露 https把 http 部分注释掉或者把 http.port 改成一个内网调试端口。否则业务方一直在走明文等你想关 http 时又要全局通知一遍反而更麻烦。接下来是很多人都会犯的错修改完 harbor.yml 后直接docker compose down docker compose up -d发现 https 根本不生效。原因是 Harbor 的 nginx 配置和 docker-compose.yml 都由prepare脚本在 install 阶段生成配置文件改了不重新跑 preparenginx 根本不会加载新证书。最稳妥的做法是直接再跑一次 install.shcd ~/harbor sudo ./install.sh --with-trivyinstall.sh 会检测到本地镜像已存在docker load很快就能跳过prepare 在启动前重新生成整套配置整个流程非常安全。启动完成后浏览器访问https://harbor.example.com验证证书是否生效。4.4 客户端如何信任这个 CA服务端配好了客户端如果不信任 CAdocker login依然报错。这里要区分两种情况。docker 客户端Debian/Ubuntu需要在/etc/docker/certs.d/下建立以 hostname 命名的目录并把 ca.crt 放进去sudo mkdir -p /etc/docker/certs.d/harbor.example.com sudo cp /data/certs/ca.crt /etc/docker/certs.d/harbor.example.com/ sudo systemctl restart docker docker login harbor.example.comcontainerd 作为 Kubernetes 节点的运行时则是在/etc/containerd/certs.d/或 config.toml 里配置 ca_file。以 containerd 为例[plugins.io.containerd.grpc.v1.cri.registry] [plugins.io.containerd.grpc.v1.cri.registry.configs] [plugins.io.containerd.grpc.v1.cri.registry.configs.harbor.example.com] [plugins.io.containerd.grpc.v1.cri.registry.configs.harbor.example.com.tls] ca_file /etc/containerd/certs.d/harbor.example.com/ca.crt把 ca.crt 放到对应位置重启 containerdkubelet 就能正常从 Harbor 拉取镜像了。这里有个常见的误区有人把 ca.crt 丢到系统级的/etc/ssl/certs重启 docker 后还是失败。因为 docker 守护进程默认不读系统 CA 证书库它认的是/etc/docker/certs.d/这套独立的逻辑必须按 docker 自己的规则来。5. 部署和改造过程中遇到的几个典型问题整个流程走下来总会遇到几个经典问题。我把高频的和几个特有场景整理成速查表现象常见原因解决思路install.sh 阶段 docker load 失败/var/lib/docker所在分区满了用 df -h 确认空间清理镜像或扩容80/443 端口启动失败端口被已有服务占用ss -lntp 排查改端口或停冲突服务docker login 报 x509 证书错误ca.crt 未正确配置或证书缺 IP SAN放对 certs.d 路径重新签带 SAN 的证书页面显示 502postgres/redis 初始化较慢等待启动完成用 docker compose logs 观察修改配置后不生效没有重新执行 prepare重跑 install.sh或显式执行 prepare忘记管理员密码密码修改后未及时记录进 PostgreSQL 重置或从备份恢复展开讲两个真实案例。第一个是磁盘空间问题。有次在一个内网环境部署install.sh 停在 loading image 阶段很长时间最后直接报 no space left on device。排查了很久才发现/var/lib/docker挂在根分区上根分区只剩不到 2GB而离线包里的镜像加起来有好几个 GB。解决方法是把 docker 的 style="width:16px;margin-left:4px;vertical-align:text-bottom;cursor:text;" />
返回列表