部署Harbor镜像仓库
采用Docker部署harbor服务,使用自签名证书访问,作为私有镜像仓库测试使用。
部署环境信息
- 操作系统:Ubuntu 22.04
- Docker版本:29.3.1
- Docker Compose 版本:v5.1.1
- Harbor版本:v2.15.0
- 主机IP:192.168.100.111
- 主机名:haproxy
- Harbor安装目录:/opt/harbor
参考
这里采用离线安装包进行安装Harbor。
一.准备安装目录
各版本软件包地址:https://github.com/goharbor/harbor/releases
1.下载离线安装包 harbor-offline-installer-v2.15.0.tgz
wget https://github.com/goharbor/harbor/releases/download/v2.15.0/harbor-offline-installer-v2.15.0.tgz2.解压
tar -xzvf harbor-offline-installer-v2.15.0.tgz3./opt/harbor作为harbor的安装目录
mv harbor /opt/二.准备证书
两种证书:
- 正规CA签名证书。
- 自签名证书。
这里使用自签名证书,本地测试使用,正规证书替换相关key和证书即可。
# https related config
https:
# The path of cert and key files for nginx
certificate: /your/certificate/path
private_key: /your/private/key/path配置ssl证书,生产环境,应该从证书办法机构(CA)获取证书,测试或者开发环境,可以自行生成CA证书。
1. 生成证书颁发机构证书
操作目录:/opt/harbor/ssl,自行创建
mkdir /opt/harbor/ssl1.1 生成CA证书私钥
openssl genrsa -out ca.key 40961.2 生成CA证书
请根据贵组织的具体情况调整选项中的值-subj。如果您使用完全限定域名 (FQDN) 连接 Harbor 主机,则必须将其指定为通用名称 ( CN) 属性。
openssl req -x509 -new -nodes -sha512 -days 3650 \
-subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=MyPersonal Root CA" \
-key ca.key \
-out ca.crt2. 生成服务器证书
证书通常包含一个.crt文件和一个.key文件,例如,yourdomain.com.crt和yourdomain.com.key。
2.1 生成私钥。
openssl genrsa -out yourdomain.com.key 40962.2 生成证书签名请求(CSR)。
请根据贵组织的具体情况调整选项中的值-subj。如果您使用完全限定域名 (FQDN) 连接 Harbor 主机,则必须将其指定为通用名称 (CN CN) 属性,并在密钥和 CSR 文件名中使用它。
openssl req -sha512 -new \
-subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=yourdomain.com" \
-key yourdomain.com.key \
-out yourdomain.com.csr2.3 生成 x509 v3 扩展文件。
无论您是使用完全限定域名 (FQDN) 还是 IP 地址连接到您的 Harbor 主机,都必须创建此文件,以便为您的 Harbor 主机生成符合主题备用名称 (SAN) 和 x509 v3 扩展要求的证书。请将条目替换DNS为您的域名。
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.com
DNS.2=yourdomain
# hostname
DNS.3=haproxy
# 如果使用IP访问,添加
IP.1=192.168.100.111
EOF2.4 使用该v3.ext文件为您的 Harbor 主机生成证书。
yourdomain.com将CSR 和 CRT 文件名中的“host”替换为 Harbor 主机名。
openssl x509 -req -sha512 -days 3650 \
-extfile v3.ext \
-CA ca.crt -CAkey ca.key -CAcreateserial \
-in yourdomain.com.csr \
-out yourdomain.com.crt三.准备配置文件
cd /opt/harbor
cp harbor.yml.tmpl harbor.ymlharbor.yml 配置修改项
1.修改hostname,这里暂时使用IP访问
# The IP address or hostname to access admin UI and registry service.
# DO NOT use localhost or 127.0.0.1, because Harbor needs to be accessed by external clients.
#hostname: reg.mydomain.com
#1.修改hostsname
hostname: 192.168.100.111
2.修改证书路径,指定ssl证书
# https related config
https:
# https port for harbor, default is 443
port: 443
# The path of cert and key files for nginx
# 2.修改证书路径
#certificate: /your/certificate/path
#private_key: /your/private/key/path
certificate: /opt/harbor/ssl/yourdomain.com.crt
private_key: /opt/harbor/ssl/yourdomain.com.key
# enable strong ssl ciphers (default: false)
# strong_ssl_ciphers: false四.安装
cd /opt/harbor
# 默认的 Harbor 安装不包含 Trivy 服务。运行以下命令
# sudo ./install.sh
# 要安装带有 Trivy 服务的 Harbor,请在运行以下命令时 install.sh 添加参数 --with-trivy:
# sudo ./install.sh --with-trivy
# 这里安装的带有trivy 服务的harbor。
sudo ./install.sh --with-trivy
# 后续修改配置,可以通过运行 prepare --with-trivy 进行更新,然后重启服务
# cd /opt/harbor
# prepare --with-trivy
# docker compose down
# docker compose up -d安装成功
✔ ----Harbor has been installed and started successfully.----1.配置harbor自启动
重启docker服务,harbor服务由于存在依赖harbor-log服务启动,而重启docker服务,恢复容器的时候并不会知道依赖关系,导致harbor服务存在异常,无法成功启动。
解决方法:
修改 /lib/systemd/system/docker.service 文件,添加启动后运行命令 /usr/bin/docker compose -f /opt/harbor/docker-compose.yml up -d ,正确启动harbor服务。
确保docker服务重启,服务器重启后,harbor服务自动恢复。
vim /lib/systemd/system/docker.service
添加
# 配置harbor正常启动
ExecStartPost=/bin/sleep 5
ExecStartPost=/usr/bin/docker compose -f /opt/harbor/docker-compose.yml up -d修改后的文件
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target nss-lookup.target docker.socket firewalld.service containerd.service time-set.target
Wants=network-online.target containerd.service
Requires=docker.socket
StartLimitBurst=3
StartLimitIntervalSec=60
[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
# 配置harbor正常启动
ExecStartPost=/bin/sleep 5
ExecStartPost=/usr/bin/docker compose -f /opt/harbor/docker-compose.yml up -d
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutStartSec=0
RestartSec=2
Restart=always
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNPROC=infinity
LimitCORE=infinity
# Comment TasksMax if your systemd version does not support it.
# Only systemd 226 and above support this option.
TasksMax=infinity
# set delegate yes so that systemd does not reset the cgroups of docker containers
Delegate=yes
# kill only the docker process, not all processes in the cgroup
KillMode=process
OOMScoreAdjust=-500
[Install]
WantedBy=multi-user.target修改service文件后,需要重新reload配置
sudo systemctl daemon-reload测试,正常
1.停止docker服务后再启动docker服务,等待5s,harbor正常
2.重启docker服务,等待5s,harbor正常启动
3.重启服务器,docker启动,等待5s,harbor正常启动
ExecStartPost=/bin/sleep 5 可以视情况,删除或者调整
2.验证浏览器访问Harbor服务
按照证书签名配置,以下地址都可以正常访问:
访问域名地址,需要先添加本地的hosts
- Windows:
C:\Windows\System32\drivers\etc\hosts - Linux:
/etc/hosts
192.168.100.111 yourdomain.com
192.168.100.111 yourdomain
192.168.100.111 haproxy将自签名CA证书导入计算机
因为是自签名证书,浏览器访问https地址会提示不安全,可以将ca证书(ca.crt)安装到电脑中,再进行访问就不会提示不安全了。
这里是通过Windows电脑访问,提供windows安装CA证书步骤。
1.将 ca.crt 文件下载到电脑本地
2.运行,安装证书,添加到受信任的根证书颁发机构
手动指定选择,受信任的根证书颁发机构,进行导入,确认即可
浏览器访问harbor的https地址,访问正常
登陆
用户:admin
密码:Harbor12345 (默认)
五.为Docker提供证书
为docker提供证书,以正常访问自签名证书的https地址。
1.配置Docker使用的证书
1.1 转换yourdomain.com.crt为yourdomain.com.certDocker 可以使用的格式。
Docker守护进程将.crt文件解释为CA证书,将.cert文件解释为客户端证书。
# x509 证书管理
# -inform PEM 指定输入格式,PEM是添加了页眉和页脚的DER编码的base64编码,DER 格式是证书的DER编码
# 没有指定 -outform ,默认输出 PEM
# 验证PEM格式证书,然后输出为PEM格式证书,yourdomain.com.crt 和 yourdomain.com.cert 一样。
# 直接cp 应该也可以,就是通过该openssl命令,可以验证证书
openssl x509 -inform PEM -in yourdomain.com.crt -out yourdomain.com.cert1.2 将服务器证书、密钥和 CA 文件复制到 Harbor 主机上的 Docker 证书文件夹中。您必须先创建相应的文件夹。
cp yourdomain.com.cert /etc/docker/certs.d/yourdomain.com/
cp yourdomain.com.key /etc/docker/certs.d/yourdomain.com/
cp ca.crt /etc/docker/certs.d/yourdomain.com/如果您将默认nginx端口 443 映射到其他端口,请创建文件夹/etc/docker/certs.d/yourdomain.com:port,或/etc/docker/certs.d/harbor_IP:port。
1.3 重启 Docker 引擎。
systemctl restart docker以下示例说明了使用自定义证书的配置。
/etc/docker/certs.d/
└── yourdomain.com:port
├── yourdomain.com.cert <-- Server certificate signed by CA
├── yourdomain.com.key <-- Server key signed by CA
└── ca.crt <-- Certificate authority that signed the registry certificate精简步骤
cd /opt/harbor/ssl
openssl x509 -inform PEM -in yourdomain.com.crt -out yourdomain.com.cert
mkdir -p /etc/docker/certs.d/yourdomain.com/
cp yourdomain.com.cert /etc/docker/certs.d/yourdomain.com/
cp yourdomain.com.key /etc/docker/certs.d/yourdomain.com/
cp ca.crt /etc/docker/certs.d/yourdomain.com/
sudo systemctl restart dockerdocker证书加载逻辑?
2.系统层面添加证书
将自签名ca证书添加到系统中。
sudo cp /etc/docker/certs.d/yourdomain.com/ca.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates
# 需要重启docker
sudo systemctl restart docker3.验证docker访问harbor
- 在运行 Docker 守护程序的机器上,检查该
/etc/docker/daemon.json文件以确保-insecure-registry未为https://yourdomain.com设置该选项。 使用 Docker 客户端登录 Harbor。
docker login yourdomain.com如果你已经将
nginx443 端口映射到其他端口,请在login命令中添加该端口。docker login yourdomain.com:port
手动添加hosts
192.168.100.111 yourdomain.com
192.168.100.111 yourdomain登陆Harbor
ubuntu@haproxy:~$ docker login yourdomain.com
Username: admin
Password:
WARNING! Your credentials are stored unencrypted in '/home/ubuntu/.docker/config.json'.
Configure a credential helper to remove this warning. See
https://docs.docker.com/go/credential-store/
Login Succeeded尝试push镜像
# 将一个镜像,打标签为私有地址镜像
docker tag goharbor/registry-photon:v2.15.0 yourdomain.com/library/registry-photon:v2.15.0
# 尝试push
docker push yourdomain.com/myproject/registry-photon:v2.15.0验证通过
六.问题记录
1.如何更新证书,更新harbor服务
修改配置文件 harbor.yml
# harbor.yml
certificate: /opt/harbor/ssl/yourdomain.com.crt
private_key: /opt/harbor/ssl/yourdomain.com.key更新harbor服务
# 更新,直接使用 ./prepare 会有问题,因为安装的时候是使用的 sudo ./install.sh --with-trivy
# 可以使用 ./prepare --with-trivy 更新配置,或者直接执行安装脚本,会自动更新,关闭和启动
sudo ./install.sh --with-trivy
# 使用prepare更新步骤
# ./prepare --with-trivy
# docker compose down
# docker compose up -d2.docker push 镜像提示证书不可信
之前按照官方文档,已经将证书添加到了 /etc/docker/cert.d/ 目录下,但是push镜像的时候,还是提示访问 /service/token 接口证书不可信。
最后是通过将自签名CA证书导入到系统层面才解决了。
测试过程
准备一个镜像
docker tag goharbor/registry-photon:v2.15.0 yourdomain.com/demo/registry-photon:v2.15.0注意:
这里是找了个镜像,重新打标签,进行的测试。
demo是在harbor创建的存储库项目。
1.如果没有/etc/docker/cert.d/yourdomain.com ,请求v2接口就会异常
ubuntu@haproxy:/etc/docker$ docker push yourdomain.com/demo/registry-photon:v2.15.0
The push refers to repository [yourdomain.com/demo/registry-photon]
6527a4b73f8b: Waiting
f1e70bedf10d: Waiting
ff7b01873518: Waiting
53f8c569b294: Waiting
2ecdc63655e9: Waiting
57e9fe9bcd93: Waiting
failed to do request: Head "https://yourdomain.com/v2/demo/registry-photon/blobs/sha256:ff7b01873518ca998eb8fb59b6878c1347d88407f5736b51b718a2f213d9f08b": tls: failed to verify certificate: x509: certificate signed by unknown authority2.配置cert.d后,请求v2接口正常,请求service/token异常
感觉请求token地址,没有使用cert.d 中的证书
ubuntu@haproxy:/etc/docker$ docker push yourdomain.com/demo/registry-photon:v2.15.0
The push refers to repository [yourdomain.com/demo/registry-photon]
ff7b01873518: Waiting
f1e70bedf10d: Waiting
2ecdc63655e9: Waiting
53f8c569b294: Waiting
57e9fe9bcd93: Waiting
6527a4b73f8b: Waiting
failed to authorize: failed to fetch oauth token: Post "https://yourdomain.com/service/token": tls: failed to verify certificate: x509: certificate signed by unknown authority3.将自签名CA证书添加到操作系统
sudo cp /etc/docker/certs.d/yourdomain.com/ca.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates
# 重启docker ,需要重启docker才可以,之前测试的时候没有重启,一直测试有问题
sudo systemctl restart dockerpush成功
ubuntu@haproxy:~$ docker push yourdomain.com/demo/registry-photon:v2.15.0
The push refers to repository [yourdomain.com/demo/registry-photon]
2ecdc63655e9: Layer already exists
53f8c569b294: Layer already exists
57e9fe9bcd93: Layer already exists
6527a4b73f8b: Layer already exists
f1e70bedf10d: Layer already exists
ff7b01873518: Layer already exists
v2.15.0: digest: sha256:5bedf0927b98ca34bf815bc6ee449114380f305d8a5396c0d8d1cecfd098aba6 size: 11633.通过http连接harbor,需要配置docker
注意: 个人没有使用http访问,这是官方操作步骤。详情参考:通过 HTTP 连接到 Harbor
如果您的 Harbor 安装使用 HTTP 而非 HTTPS,则必须将此选项添加--insecure-registry到客户端的 Docker 守护程序中。默认情况下,守护程序文件位于/etc/docker/daemon.json.
例如,将以下内容添加到您的daemon.json文件中:
{
"insecure-registries" : ["myregistrydomain.com:5000", "0.0.0.0"]
}更新 daemon.json 后,必须重启 Docker Engine 和 Harbor。
重启 Docker 引擎。
systemctl restart docker停止harbor
docker compose down -v重启harbor
docker compose up -d