Harbor 介绍
Harbor 是由 VMware 开源的一款云原生制品仓库,Harbor 的核心功能是存储和管理 Artifact。Harbor 允许用户用命令行工具对容器镜像及其他 Artifact 进行推送和拉取,并提供了图形管理界面帮助用户查看和管理这些 Artifact。 在 Harbor 2.0 版本中,除容器镜像外,Harbor 对符合 OCI 规范的 Helm Chart、CNAB、OPA Bundle 等都提供了更多的支持。
Harbor 整体架构
如上图所示是 Harbor 2.0 的架构图,从上到下可分为代理层、功能层和数据层。
- 代理层:代理层实质上是一个 Nginx 反向代理,负责接收不同类型的客户端请求,包括浏览器、用户脚本、Docker 等,并根据请求类型和 URI 转发给不同的后端服务进行处理。
- 功能层:
- Portal:是一个基于 Argular 的前端应用,提供 Harbor 用户访问的界面。
- Core:是 Harbor 中的核心组件,封装了 Harbor 绝大部分的业务逻辑。
- JobService:异步任务组件,负责 Harbor 中很多比较耗时的功能,比如 Artifact 复制、扫描、垃圾回收等。
- Docker Distribution:Harbor 通过 Distribution 实现 Artifact 的读写和存取等功能。
- RegistryCtl:Docker Distribution 的控制组件。
- Notary(可选):基于 TUF 提供镜像签名管理的功能。
- 扫描工具(可选):镜像的漏洞检测工具。
- ChartMuseum(可选):提供 API 管理非 OCI 规范的 Helm Chart,随着兼容 OCI 规范的 Helm Chart 在社区上被更广泛地接受,Helm Chart 能以 Artifact 的形式在 Harbor 中存储和管理,不再依赖 ChartMuseum,因此 Harbor 可能会在后续版本中移除对 ChartMuseum 的支持。
- 数据层:
- Redis:主要作为缓存服务存储一些生命周期较短的数据,同时对于 JobService 还提供了类似队列的功能。
- PostgreSQL:存储 Harbor 的应用数据,比如项目信息、用户与项目的关系、管理策略、配置信息、Artifact 的元数据等等。
- Artifact 存储:存储 Artifact 本身的内容,也就是每次推送镜像、Helm Chart 或其他 Artifact 时,数据最终存储的地方。默认情况下,Harbor 会把 Artifact 写入本地文件系统中。用户也可以修改配置,将 Artifact 存储在外部存储中,例如亚马逊的对象存储 S3、谷歌云存储 GCS、阿里云的对象存储 OSS 等等。
Docker Compose 部署 Harbor
前提要求
硬件要求:
软件要求:
下载安装包
wget https://github.com/goharbor/harbor/releases/download/v2.3.1/harbor-offline-installer-v2.3.1.tgz
tar -xzvf harbor-offline-installer-v2.3.1.tgz
cd harbor
修改配置文件
拷贝模板文件为 harbor.yml。
cp harbor.yml.tmpl harbor.yml
编辑 harbor.yml 配置文件,hostname 是 harbor 对外暴露的访问地址,HTTP 服务对外暴露 8888 端口。这里暂时先不配置 HTTPS,将 HTTPS 相关内容注释。
部署 Harbor
修改完配置文件后,只需要执行 install.sh 脚本即可安装 Harbor。
./install.sh
查看 Harbor 组件运行状况:
> docker-compose ps
Name Command State Ports
------------------------------------------------------------------------------------------------------------
harbor-core /harbor/entrypoint.sh Up (healthy)
harbor-db /docker-entrypoint.sh 96 13 Up (healthy)
harbor-jobservice /harbor/entrypoint.sh Up (healthy)
harbor-log /bin/sh -c /usr/local/bin/ ... Up (healthy) 127.0.0.1:1514->10514/tcp
harbor-portal nginx -g daemon off; Up (healthy)
nginx nginx -g daemon off; Up (healthy) 0.0.0.0:8888->8080/tcp,:::8888->8080/tcp
redis redis-server /etc/redis.conf Up (healthy)
registry /home/harbor/entrypoint.sh Up (healthy)
registryctl /home/harbor/start.sh Up (healthy)
登录页面
浏 览器输入 http://11.8.36.21:8888 访问 Harbor 页面,用户名和密码为 harbor.yml 配置文件中默认设置的 admin,Harbor12345。
推送镜像
从公网拉取一个 nginx:1.19 版本的镜像:
> docker pull nginx:1.19
1.19: Pulling from library/nginx
69692152171a: Already exists
49f7d34d62c1: Pull complete
5f97dc5d71ab: Pull complete
cfcd0711b93a: Pull complete
be6172d7651b: Pull complete
de9813870342: Pull complete
Digest: sha256:df13abe416e37eb3db4722840dd479b00ba193ac6606e7902331dcea50f4f1f2
Status: Downloaded newer image for nginx:1.19
编辑 /etc/docker/daemon.json,设置允许访问的 HTTP 仓库地址。
{
"insecure-registries":["11.8.36.21:8888"]
}
修改镜像 tag:
docker tag nginx:1.19 11.8.36.21:8888/library/nginx:1.19
登录 Harbor:
> docker login 11.8.36.21:8888
Username: admin
Password:
Login Succeeded
推送镜像到 Harbor:
> docker push 11.8.36.21:8888/library/nginx:1.19
The push refers to a repository [11.8.36.21:8888/library/nginx]
f0f30197ccf9: Pushed
eeb14ff930d4: Pushed
c9732df61184: Pushed
4b8db2d7f35a: Pushed
431f409d4c5a: Pushed
02c055ef67f5: Pushed
1.19: digest: sha256:eba373a0620f68ffdc3f217041ad25ef084475b8feb35b992574cd83698e9e3c size: 1570
查看推送的镜像:
HTTPS 配置(可选)
在生产环境中建议配置 HTTPS,可以使用由受信任的第三方 CA 签名的证书,也可以使用自签名证书。如果想要启用 Content Trust with Notary 来正确签名所有图像,则必须使用 HTTPS。
创建目录
首先创建目录存放生成的证书。
mkdir /root/cert
cd /root/cert/
生成 CA 证书
本次实验中我们使用自签名证书。生产环境中应使用受信任的第三方 CA 签名的证书。
生成 CA 证书私钥
openssl genrsa -out ca.key 4096
生成 CA 证书
-subj 表示证书的组织。CN 后面的值改成 harbor 的 IP 地址或者域名。
openssl req -x509 -new -nodes -sha512 -days 3650 \
-subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=11.8.36.21" \
-key ca.key \
-out ca.crt
生成 Server 证书
生成 Harbor 使用的证书和私钥。
生成 Server 私钥
openssl genrsa -out server.key 4096
生成 Server 证书签名请求(CSR)
生成 Harbor 的证书签名请 求,使用上面生成的 CA 证书来给 Server 签发证书。
openssl req -sha512 -new \
-subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=11.8.36.21" \
-key server.key \
-out server.csr
生成 x509 v3 扩展文件
通过 docker 或者 ctr 等工具拉取 HTTPS 的镜像时,要求 HTTPS 的证书包含 SAN 扩展。
SAN(Subject Alternative Name) 是 SSL 标准 x509 中定义的一个扩展。使用了 SAN 字段的 SSL 证书,可以扩展此证书支持的域名,使得一个证书可以支持多个不同域名的解析。例如下图中 Google 的这张证书的主题备用名称(SAN)中列了一大串的域名,因此这张证书能够被多个域名所使用。对于 Google 这种域名数量较多的公司来说,使用这种类型的证书能够极大的简化网站证书的管理。
使用以下命令生成 x509 v3 扩展文件:
cat > v3.ext <<-EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = IP:11.8.36.21
EOF
如果是域名访问通过下面方式生成 x509 v3 扩展文件:
cat > v3.ext <<-EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1=yourdomain.harbor.com
EO
使用 CA 证书签发 Server 证书
openssl x509 -req -sha512 -days 3650 \
-extfile v3.ext \
-CA ca.crt -CAkey ca.key -CAcreateserial \
-in server.csr \
-out server.crt
查看当前目录生成的文件:
root@ydt-net-portainer:/root/cert #ll
total 32
-rw-r--r-- 1 root root 2025 Aug 6 20:44 ca.crt
-rw-r--r-- 1 root root 3243 Aug 6 20:40 ca.key
-rw-r--r-- 1 root root 17 Aug 6 21:03 ca.srl
-rw-r--r-- 1 root root 2045 Aug 6 21:03 server.crt
-rw-r--r-- 1 root root 1704 Aug 6 20:47 server.csr
-rw-r--r-- 1 root root 3247 Aug 6 20:45 server.key
-rw-r--r-- 1 root root 202 Aug 6 21:00 v3.ext
为 Harbor 和 Docker 配置证书
将 server 证书和密钥复制到 Harbor 主机上的 /data/cert 目录中
mkdir -p /data/cert
cp server.crt /data/cert/
cp server.key /data/cert/
转换 server.crt 为 server.cert
Docker 守护程序会认为 .crt 文件是 CA 证书,因此需要将 server 证书转换为 server.cert 文件。其实改下后缀就可以了,证书里面的内容是一样的。
openssl x509 -inform PEM -in server.crt -out server.cert