这是本节的多页打印视图。 点击此处打印.

返回本页常规视图.

habor镜像仓库

镜像仓库 habor 的安装和配置

1 - habor介绍

镜像仓库 habor 的介绍

介绍

自我介绍,摘录自 https://goharbor.io/

Harbor is an open source registry that secures artifacts with policies and role-based access control, ensures images are scanned and free from vulnerabilities, and signs images as trusted. Harbor, a CNCF Graduated project, delivers compliance, performance, and interoperability to help you consistently and securely manage artifacts across cloud native compute platforms like Kubernetes and Docker.

Harbor 是一个开源注册表,它使用策略和基于角色的访问控制来保护工件,确保图像经过扫描且没有漏洞,并将图像签名为可信的。Harbor 是 CNCF 毕业项目,它提供合规性、性能和互操作性,帮助您跨 Kubernetes 和 Docker 等云原生计算平台持续安全地管理工件。

habor 的愿景是:

Our mission is to be the trusted cloud native repository for Kubernetes

我们的使命是成为 Kubernetes 的信任云原生仓库

信息

官网:https://goharbor.io/

中文网站: https://harbor.k8s.ac.cn/

2 - habor安装

镜像仓库 habor 的安装

准备工作

docker的安装

需要先安装好 docker 和 docker-compose。

安装

离线安装

https://github.com/goharbor/harbor/releases

下载 offline 安装文件如:

sudo mkdir -p /mnt/data/services/
cd /mnt/data/services/

sudo wget https://github.com/goharbor/harbor/releases/download/v2.14.0/harbor-offline-installer-v2.14.0.tgz

解压安装文件:

sudo tar -xvf harbor-offline-installer-v2.14.0.tgz

复制并修改配置文件:

cd harbor
sudo cp harbor.yml.tmpl harbor.yml

修改 hostname,port 和 harbor_admin_password 等参数:

hostname: 192.168.3.193
http:
  port: 5000

备注: 不要修改这里的默认密码, 遇到过修改密码之后无法登录的问题. 见下面的说明.

另外,因为是开发环境,所以可以忽略https。因此修改 harbor.yml 文件,将 https 的配置注释掉:

# https related config
#https:
  # https port for harbor, default is 443
  #port: 443
  # The path of cert and key files for nginx
  #certificate: /your/certificate/path
  #private_key: /your/private/key/path
  # enable strong ssl ciphers (default: false)
  # strong_ssl_ciphers: false

执行安装命令:

sudo ./install.sh

输出为:

[Step 0]: checking if docker is installed ...

Note: docker version: 28.5.1

[Step 1]: checking docker-compose is installed ...

Note: Docker Compose version v2.40.2

[Step 2]: loading Harbor images ...
Loaded image: goharbor/harbor-db:v2.14.0
Loaded image: goharbor/harbor-log:v2.14.0
Loaded image: goharbor/trivy-adapter-photon:v2.14.0
Loaded image: goharbor/redis-photon:v2.14.0
Loaded image: goharbor/nginx-photon:v2.14.0
Loaded image: goharbor/registry-photon:v2.14.0
Loaded image: goharbor/prepare:v2.14.0
Loaded image: goharbor/harbor-portal:v2.14.0
Loaded image: goharbor/harbor-core:v2.14.0
Loaded image: goharbor/harbor-jobservice:v2.14.0
Loaded image: goharbor/harbor-registryctl:v2.14.0
Loaded image: goharbor/harbor-exporter:v2.14.0

[Step 3]: preparing environment ...

[Step 4]: preparing harbor configs ...
prepare base dir is set to /mnt/data/services/harbor
WARNING:root:WARNING: HTTP protocol is insecure. Harbor will deprecate http protocol in the future. Please make sure to upgrade to https
Generated configuration file: /config/portal/nginx.conf
Generated configuration file: /config/log/logrotate.conf
Generated configuration file: /config/log/rsyslog_docker.conf
Generated configuration file: /config/nginx/nginx.conf
Generated configuration file: /config/core/env
Generated configuration file: /config/core/app.conf
Generated configuration file: /config/registry/config.yml
Generated configuration file: /config/registryctl/env
Generated configuration file: /config/registryctl/config.yml
Generated configuration file: /config/db/env
Generated configuration file: /config/jobservice/env
Generated configuration file: /config/jobservice/config.yml
copy /data/secret/tls/harbor_internal_ca.crt to shared trust ca dir as name harbor_internal_ca.crt ...
ca file /hostfs/data/secret/tls/harbor_internal_ca.crt is not exist
copy  to shared trust ca dir as name storage_ca_bundle.crt ...
copy None to shared trust ca dir as name redis_tls_ca.crt ...
Generated and saved secret to file: /data/secret/keys/secretkey
Successfully called func: create_root_cert
Generated configuration file: /compose_location/docker-compose.yml
Clean up the input dir


Note: stopping existing Harbor instance ...


[Step 5]: starting Harbor ...
[+] Running 10/10
 ✔ Network harbor_harbor        Created                                    0.0s
 ✔ Container harbor-log         Started                                    0.1s
 ✔ Container harbor-db          Started                                    0.2s
 ✔ Container registryctl        Started                                    0.2s
 ✔ Container redis              Started                                    0.2s
 ✔ Container harbor-portal      Started                                    0.2s
 ✔ Container registry           Started                                    0.2s
 ✔ Container harbor-core        Started                                    0.3s
 ✔ Container harbor-jobservice  Started                                    0.4s
 ✔ Container nginx              Started                                    0.4s
✔ ----Harbor has been installed and started successfully.----

安装完成后就可以用浏览器访问了:

http://192.168.3.193:5000/

用户名:admin,默认密码:Harbor12345

登录之后记得修改管理员密码.

登录密码错误的处理

遇到一个很奇怪的问题, 我在安装时修改了默认密码, 但安装完成后用修改的密码却无法登录, 修改前的默认密码 Harbor12345 也无法登录.

可以通过下面的方式查看到实际生效的密码:

  1. 查看 habor-core 容器的信息

    $ docker ps  
     CONTAINER ID   IMAGE                                 COMMAND                  CREATED          STATUS                    PORTS                       NAMES
     6a46f331f769   goharbor/harbor-core:v2.14.0          "/harbor/entrypoint.…"   23 minutes ago   Up 23 minutes (healthy)                               harbor-core
    
  2. 登录到 habor-core 的容器

    docker exec -it 6a46f331f769 bash
    

    然后查看环境变量 HARBOR_ADMIN_PASSWORD:

    $ env | grep HARBOR
    HARBOR_ADMIN_PASSWORD=xxxx
    

但很奇怪我在这里看到的密码和我设置的是一样的, 但依然无法登录. 这个问题有点莫名其妙.

不得已, 只好重新开始设置, timeshift 恢复之后再次安装居然还是同样错误, 更加无语. 最后把 devserver 的虚拟机删除, 从 basic 模板重新开始, 然后安装 harbor 时不修改默认密码, 等安装成功之后用默认密码登录, 然后再通过页面修改 admin 的密码.

开机自动启动

上面的方法只能临时启动 habor,方便起见还是应该设置为开机自动启动。

在 debian12/13 上,采用 systemd 的方式实现 habor 的开机自动启动:

sudo vi /usr/lib/systemd/system/harbor.service

内容为:

[Unit]
Description=Harbor
After=docker.service systemd-networkd.service systemd-resolved.service
Requires=docker.service
Documentation=http://github.com/vmware/harbor

[Service]
Type=simple
Restart=on-failure
RestartSec=5
ExecStart=/usr/local/bin/docker-compose -f /mnt/data/services/harbor/docker-compose.yml up
ExecStop=/usr/local/bin/docker-compose -f /mnt/data/services/harbor/docker-compose.yml down

[Install]
WantedBy=multi-user.target

保存后,执行命令:

sudo chmod +x /usr/lib/systemd/system/harbor.service
sudo systemctl enable harbor
sudo systemctl start harbor

3 - Harbor 托管仓库

使用 Harbor 托管仓库(hosted)

容许使用 http

habor 安装时默认建立了一个 library 的公共仓库,可以用来存储公共镜像。

因为我们没有开启 https,因此使用前要先修改配置文件:

sudo vi /etc/docker/daemon.json

添加如下内容:

{
  "registry-mirrors": ["xxxx"],
  "insecure-registries": ["192.168.3.193:5000"]
}

执行如下命令重启 docker 服务:

sudo systemctl daemon-reload
sudo systemctl restart docker

公共仓库

制作镜像

以 hello-world 镜像为例,执行:

docker run hello-world:latest

查看 hello-world 的镜像:

docker images

输入如下:

REPOSITORY                               TAG       IMAGE ID       CREATED       SIZE
hello-world                              latest    74cc54e27dc4   6 weeks ago   10.1kB

执行如下命令重新命名镜像名称

docker tag 1b44b5a3e06a 192.168.3.193:5000/library/hello-world:latest

推送镜像到仓库

登录到 habor 仓库:

docker login  -u admin -p xxxx http://192.168.3.193:5000

推送镜像到仓库:

docker push 192.168.3.193:5000/library/hello-world:latest

输出为:

The push refers to repository [192.168.3.193:5000/library/hello-world]
53d204b3dc5d: Pushed 
latest: digest: sha256:19459a6bbefb63f83f137f08c1df645f8846e2cd1f44fe209294ebc505e6495e size: 524

此时去 habor 页面查看,就可以看到推送上去的 hello-world 镜像了。

拉取镜像

拉取镜像的方式:

docker pull 192.168.3.193:5000/library/hello-world:latest

也可以直接用 docker run 拉取镜像:

docker run 192.168.3.193:5000/library/hello-world:latest

查看此时本地已有的 hello-world 镜像:

$ docker images

REPOSITORY                               TAG       IMAGE ID       CREATED        SIZE
192.168.3.193:5000/library/hello-world   latest    1b44b5a3e06a   3 months ago   10.1kB
hello-world                              latest    1b44b5a3e06a   3 months ago   10.1kB

能看到来自默认仓库的 hello-world 镜像,以及从本地 192.168.3.193:5000 仓库拉取的 hello-world 镜像。

4 - Harbor 代理仓库

使用 habor 作为代理仓库

新建仓库

“系统管理” -》 “仓库管理” 下,点"新建目标",

新建项目

新建项目,指向刚才新建的仓库:

使用代理仓库

使用新建的代理仓库 pull 镜像:

$ docker pull 192.168.3.193:5000/dockerhub/library/hello-world:latest

从日志可以看到,镜像是从代理仓库拉取的:

latest: Pulling from dockerhub/library/hello-world
Digest: sha256:56433a6be3fda188089fb548eae3d91df3ed0d6589f7c2656121b911198df065
Status: Downloaded newer image for 192.168.3.193:5000/dockerhub/library/hello-world:latest
192.168.3.193:5000/dockerhub/library/hello-world:latest

或者直接用 docker run 命令执行:

docker run 192.168.3.193:5000/dockerhub/library/hello-world:latest

5 - Harbor 透明代理

使用 habor 作为镜像仓库的透明代理

代理的问题

habor 代理仓库后,可以实现镜像下载的加速,但是使用上,镜像的名字需要指定完整的仓库地址。

docker run 192.168.3.193:5000/dockerhub/library/hello-world:latest

而不是我们不引入 habor 代理之前的简单方式:

docker run hello-world:latest

因此,普通的 habor 代理仓库在使用时,需要修改所有容器的部署文件,将镜像名称修改为带代理仓库前缀的镜像地址。

这会造成很大的麻烦。

透明代理

经过研究,我找到了 habor 做透明代理的方式,可以实现通过使用 habor 作为镜像代理来加快下载,又不需要修改镜像地址。

思路就是结合使用 habor 的镜像代理和 docker 的镜像加速。前面我们是这样设置 docker 的镜像加速地址的:

{
  "registry-mirrors": ["https://registry.docker-cn.com"]
}

通过这个方式可以将镜像代理到 registry-mirrors 所指向的镜像仓库,它不需要修改镜像地址,也就是我们期望得到所谓的"透明代理"。仿照这个做法,如果我们将 registry-mirrors 设置为 habor 的仓库地址,是不是就可以同样透明使用 habor 作为镜像加速地址?然后,我们再把 habor 默认的 library 项目修改为 docker hub 代理仓库,就可以实现 docker hub 的带本地缓存加速的透明代理。

具体操作步骤如下:

  1. 在 “仓库管理” 中新建 dockerhub 的仓库

  2. 删除 habor 安装时自带的 library 项目。

    注意: 删除之前要先把项目中已经保存的镜像删除,否则无法删除该项目。

    注意2: library 项目的配置中,有"镜像代理"选项,提示: 开启此项,以使得该项目成为目标仓库的镜像代理.仅支持 DockerHub, Docker Registry, Harbor, Aws ECR, Azure ACR, Alibaba Cloud ACR, Quay, Google GCR, JFrog Artifactory, 和 Github GHCR 类型的仓库。但需要先把当前项目中的镜像删除,否则灰色无法开启。

  3. 重新建立名为 library 的项目,将其设置为镜像代理,指向刚才新建的 dockerhub 仓库。

  4. 修改 docker 的配置文件,添加代理仓库地址。

    vi /etc/docker/daemon.json
    

    内容修改如下:

    {
      "registry-mirrors": ["http://192.168.3.193:5000/"],
      "insecure-registries": ["192.168.3.193:5000"]
    }
    
  5. 重启 docker 服务。

    sudo systemctl daemon-reload
    sudo systemctl restart docker
    
  6. 使用透明代理仓库下载镜像。

    docker pull hello-world:latest
    

    从日志上看镜像似乎是 docker.io 仓库拉取的:

    latest: Pulling from library/nginx
    Digest: sha256:9d6b58feebd2dbd3c56ab5853333d627cc6e281011cfd6050fa4bcf2072c9496
    Status: Image is up to date for nginx:latest
    docker.io/library/nginx:latest
    

    但是从 habor 的 library 代理仓库可以看到,之前为空的镜像仓库现在已经有了镜像,而且多 pull 几次(需要先清理本地镜像),下载数会相应增加:

    备注1:清理本地镜像,可以使用 docker rmi -f $(docker images -q) 命令。

    备注2:library 镜像仓库中的镜像数据,会延迟一点时间(分钟级别)才会显示出来,导致我开始还以为代理失败了。耐心等几分钟就能看到了。

遗留问题

如上图所示,library 镜像仓库中的镜像名称,会额外的带上 library/library/ 前缀。

这是因为默认的 registry/project 就是 library/library/

6 - Harbor 常用代理

创建常用的代理仓库以备日常使用

k8s 代理仓库

为了加速 k8s 的安装和使用,创建 k8s 代理仓库。

再创建一个 project,名为 k8s-proxy,设置为镜像代理,指向上面创建的 k8s 的代理仓库:

之后就可以这样拉取镜像:

docker pull 192.168.3.91:5000/k8s-proxy/kube-apiserver:v1.33.0
docker pull 192.168.3.91:5000/k8s-proxy/coredns/coredns:v1.12.0

这是安装 k8s v1.33 版本后的镜像情况: