目录

采用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.tgz

2.解压

tar -xzvf harbor-offline-installer-v2.15.0.tgz

3./opt/harbor作为harbor的安装目录

mv harbor /opt/

二.准备证书

两种证书:

  1. 正规CA签名证书。
  2. 自签名证书。

这里使用自签名证书,本地测试使用,正规证书替换相关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/ssl

1.1 生成CA证书私钥

openssl genrsa -out ca.key 4096

1.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.crt

2. 生成服务器证书

证书通常包含一个.crt文件和一个.key文件,例如,yourdomain.com.crtyourdomain.com.key

2.1 生成私钥。

openssl genrsa -out yourdomain.com.key 4096

2.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.csr

2.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
EOF

2.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.yml

harbor.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.crtyourdomain.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.cert

1.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 docker

docker证书加载逻辑?

参考:使用证书验证存储库客户端。

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 docker

3.验证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 -d

2.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 authority

2.配置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 authority

3.将自签名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 docker

push成功

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: 1163

3.通过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 EngineHarbor

重启 Docker 引擎。

systemctl restart docker

停止harbor

docker compose down -v

重启harbor

docker compose up -d

标签: Harbor

添加新评论