千家信息网

Docker 私有Registry

发表于:2025-12-02 作者:千家信息网编辑
千家信息网最后更新 2025年12月02日,Registry用于保存docker镜像,包括镜像的层次结构和元数据。用户可以自建Registry,也可使用官方的Docker Hub。Docker Registry 分类:Sponsor Regis
千家信息网最后更新 2025年12月02日Docker 私有Registry

Registry用于保存docker镜像,包括镜像的层次结构和元数据。用户可以自建Registry,也可使用官方的Docker Hub。

Docker Registry 分类:

  • Sponsor Registry: 第三方的registry,供客户和Docker社区使用
  • Mirror Registry: 第三方的registryy,只让客户使用
  • Vendor Registry: 由发布Docker镜像的供应商提供的registry
  • Private Registry: 通过设有防火墙和额外的安全层的私有实体提供的registry

私有Registry

使用前先要将服务部署到服务器上。

YUM安装

可以通过yum安装:

yum install docker-registryyum install docker-distribution

上面两个命令都会安装docker-distribution只要执行一个就好了。

软件包的信息:

[root@Docker ~]# yum info docker-distribution已加载插件:fastestmirrorLoading mirror speeds from cached hostfile * base: mirrors.aliyun.com * extras: mirrors.aliyun.com * updates: mirrors.aliyun.com可安装的软件包名称    :docker-distribution架构    :x86_64版本    :2.6.2发布    :2.git48294d9.el7大小    :3.5 M源    :extras/7/x86_64简介    : Docker toolset to pack, ship, store, and deliver content网址    :https://github.com/docker/distribution协议    : ASL 2.0描述    : Docker toolset to pack, ship, store, and deliver content[root@Docker ~]# 

这个就不装了,因为还可以将服务安装在容器中运行。

容器安装

docker官方也提供了容器,基于容器提供Registry服务。

下载镜像:

[root@Docker ~]# docker image pull registryUsing default tag: latestlatest: Pulling from library/registryc87736221ed0: Pull complete 1cc8e0bb44df: Pull complete 54d33bcb37f5: Pull complete e8afc091c171: Pull complete b4541f6d3db6: Pull complete Digest: sha256:8004747f1e8cd820a148fb7499d71a76d45ff66bac6a29129bfdbfdc0154d146Status: Downloaded newer image for registry:latest[root@Docker ~]# 

启动容器:

docker run -d -p 5000:5000 --restart always --name registry registry

配置文件
查看registry的配置文件:

[root@Docker ~]# docker container exec -it registry cat /etc/docker/registry/config.ymlversion: 0.1log:  fields:    service: registrystorage:  cache:    blobdescriptor: inmemory  filesystem:    rootdirectory: /var/lib/registryhttp:  addr: :5000  headers:    X-Content-Type-Options: [nosniff]health:  storagedriver:    enabled: true    interval: 10s    threshold: 3[root@Docker ~]# 

这里是默认的配置文件。配置文件是通过CMD命令指定的,默认的dockerfile的CMD指令如下:

CMD ["/etc/docker/registry/config.yml"]

镜像存放的位置
镜像Dockerfile中有一条VOLUME指令,这个路径就是容器是存放镜像的路径:

VOLUME ["/var/lib/registry"]

启动镜像时,可以使用-v参数,指定宿主机的目录。

上传镜像

上传镜像前,先要给镜像打标:

[root@Docker ~]# docker push busybox loclhost:5000/busybox

这里要准备将本地的busybox推送到服务器loclhost:5000。这里省略了仓库的用户名,没有用户名就是一个顶层仓库。

推送:

[root@Docker ~]# docker push localhost:5000/busyboxThe push refers to repository [localhost:5000/busybox]0d315111b484: Pushed latest: digest: sha256:895ab622e92e18d6b461d671081757af7dbaa3b00e3e28e12505af7817f73649 size: 527[root@Docker ~]# 

不往本机lo接口推,也就是服务器地址不使用localhost或127.0.0.1。而是向本机的网卡地址推。就像其他主机要向本机的registry推送一样了。然后会产生如下的错误:

[root@Docker ~]# docker push 192.168.24.170:5000/busyboxThe push refers to repository [192.168.24.170:5000/busybox]Get https://192.168.24.170:5000/v2/: http: server gave HTTP response to HTTPS client[root@Docker ~]# 

这里的问题是,docker默认是使用https协议工作的,而registry服务器的响应是http协议。解决的办法有两个。
第一个方法是修改registry来适应docker,registry服务器改为https协议
第二个方法是修改docker来使用registry,将registry服务器地址加入到docker的insecure-registries中去

配置insecure-registries
修改配置文件,然后重启加载后就可以推送上去了:

[root@Docker ~]# cat /etc/docker/daemon.json{    "registry-mirrors": ["http://hub-mirror.c.163.com", "https://docker.mirrors.ustc.edu.cn"],    "insecure-registries": ["192.168.24.170:5000"]}[root@Docker ~]# systemctl reload docker[root@Docker ~]# docker push 192.168.24.170:5000/busyboxThe push refers to repository [192.168.24.170:5000/busybox]0d315111b484: Layer already exists latest: digest: sha256:895ab622e92e18d6b461d671081757af7dbaa3b00e3e28e12505af7817f73649 size: 527[root@Docker ~]# 

下载镜像

指定Registry下载之前上传的镜像:

[root@Docker ~]# docker pull 192.168.24.170:5000/busyboxUsing default tag: latestlatest: Pulling from busyboxee153a04d683: Pull complete Digest: sha256:895ab622e92e18d6b461d671081757af7dbaa3b00e3e28e12505af7817f73649Status: Downloaded newer image for 192.168.24.170:5000/busybox:latest[root@Docker ~]# 

Harbor

Harbor是一个用于存储和分发Docker镜像的企业级Registry服务器。

Harbor特性

基于角色的访问控制:用户与Docker镜像仓库通过"项目"进行组织管理,一个用户可以对多个镜像仓库在同一命名空间(project)里有不同的权限。
镜像复制:镜像可以在多个Registry实例中复制(同步)。尤其适合于负载均衡,高可用,混合云和多云的场景。
图形化用户界面:用户可以通过浏览器来浏览,检索当前Docker镜像仓库,管理项目和命名空间。
AD/LDAP 支持:Harbor可以集成企业内部已有的AD/LDAP,用于鉴权认证管理。
审计管理:所有针对镜像仓库的操作都可以被记录追溯,用于审计管理。
国际化:已拥有英文、中文、德文、日文和俄文的本地化版本。更多的语言将会添加进来。
RESTful API:RESTful API 提供给管理员对于Harbor更多的操控, 使得与其它管理软件集成变得更容易。
部署简单:提供在线和离线两种安装工具, 也可以安装到vSphere平台(OVA方式)虚拟设备。

安装准备

github项目地址:
https://github.com/vmware/harbor
这是一个vmware的开源项目,实际会跳转到下面这个地址:
https://github.com/goharbor/harbor

下载 harbor
查看项目的README,Features的内容上面提过了,这里主要看Install & Run部分的内容。

首先是下载
Harbor release:
https://github.com/goharbor/harbor/releases

$ wget https://storage.googleapis.com/harbor-releases/release-1.8.0/harbor-offline-installer-v1.8.2-rc1.tgz

安装配置向导
Installation & Configuration Guide:
https://github.com/goharbor/harbor/blob/master/docs/installation_guide.md

硬件要求:

ResourceCapacityDescription
CPUminimal 2 CPU4 CPU is preferred
Memminimal 4GB8GB is preferred
Diskminimal 40GB160GB is preferred

软件要求:

SoftwareVersionDescription
Docker engineversion 17.06.0-ce+ or higherFor installation instructions, please refer to: docker engine doc
Docker Composeversion 1.18.0 or higherFor installation instructions, please refer to: docker compose doc
Openssllatest is preferredGenerate certificate and keys for Harbor

安装步骤:

  1. Download the installer;
  2. Configure harbor.yml;
  3. Run install.sh to install and start Harbor;

下载完之后,先解压:

[root@Harbor ~]# tar xvf harbor-offline-installer-v1.8.1.tar -C /optharbor/harbor.v1.8.1.tar.gzharbor/prepareharbor/LICENSEharbor/install.shharbor/harbor.yml[root@Harbor ~]# 

下载的文件在解压后就不需要了。解压后的文件在安装完成后也都是不需要的。所以下载到哪里,解压到哪里其实都不重要。建议可以解压到 /opt 或 /usr/local 这两个目录里。

安装包中的镜像
解压后的文件中,有一个文件harbor.v1.8.1.tar.gz。这个是被导出的docker镜像。还记得docker save命令吧,可以打包导出多个镜像并完成压缩:

$ docker save myimg/httpd:v1 myimg/httpd:v2 | gzip > myimage_latest.tar.gz

这个文件应该就是这么来的。之后的安装过程中,则是会把这个文件里的所有镜像做一次批量导入:

$ docker load -i myimage_latest.tar.gz

在安装时执行的install.sh脚本里有解压并导入镜像的语句:

if [ -f harbor*.tar.gz ]then        h3 "[Step $item]: loading Harbor images ..."; let item+=1        docker load -i ./harbor*.tar.gzfi

安装的依赖和过程
Harbor的安装,就是给当前的主机安装很多容器,并且把这些容器都启动起来。启动Harbor就是用docker-compose把这些容器的启动起来,而关闭harbor也是通过docker-compose来把容器一次关闭。之所以需要借助docker-compose,因为harbor是由很多容器协同过程的,容器之间又依赖关系,这些都需要docker-compose这个单机编排工具来协调。

所以安装harbor前,需要安装好docker-compose,才能实现本地的容器的编排。需要安装好docker,才能把本地的镜像启动起来。镜像就在下载解压的文件中。并且还需要启动docker,这样才能运行容器。
准备工作完成后,就是执行harbor准备的install.sh脚本,在本地加载好镜像,通过docker-compose把这些镜像依次启动起来,并且运行在本地的docker上。

修改harbor.yml配置文件,主机名一定看改掉,最好使用本机的域名,如果没有域名那么就用本机的IP地址。没改的话,会有如下的错误提示:

[root@Harbor harbor]# ./install.sh ➜ Please set hostname and other necessary attributes in harbor.yml first. DO NOT use localhost or 127.0.0.1 for hostname, because Harbor needs to be accessed by external clients.Please set --with-notary if needs enable Notary in Harbor, and set ui_url_protocol/ssl_cert/ssl_cert_key in harbor.yml bacause notary must run under https. Please set --with-clair if needs enable Clair in HarborPlease set --with-chartmuseum if needs enable Chartmuseum in Harbor[root@Harbor harbor]# 

检查发现没有安装docker:

[root@Harbor harbor]# ./install.sh [Step 0]: checking installation environment ...✖ Need to install docker(17.06.0+) first and run this script again.[root@Harbor harbor]# 

检查发现没有安装docker-compose:

[root@Harbor harbor]# ./install.sh [Step 0]: checking installation environment ...Note: docker version: 19.03.1✖ Need to install docker-compose(1.18.0+) by yourself first and run this script again.[root@Harbor harbor]# 

检查发现docker没有启动:

[root@Harbor harbor]# ./install.sh [Step 0]: checking installation environment ...Note: docker version: 19.03.1Note: docker-compose version: 1.18.0[Step 1]: loading Harbor images ...Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?[root@Harbor harbor]# 

Docker Compose

Docker的单机编排工具。官方文档:
https://docs.docker.com/compose/

为了简化harbor的安装和部署,所以harbor做成了在容器中运行的应用。但是harbor的运行还依赖很多其他的应用,所以需要编排几个容器来协同工作。所以harbor的部署和使用时需要借助Docker的单机编排工具Docker Compose。

安装docker-compose,位于epel源中:

yum install docker-compose

Compose模板文件
模板文件是使用Compose的核心,设计的指令关键字也有很多,默认的模板文件名称为docker-compose.yml,格式为YAML格式。
这个不是重点,能安装使用harbor就好了,不过还是简单了解一下。
要使用docker-compose就要写一个编排脚本,和dockerfile类似,也是有很多指令。定义要启动的每一个容器,指明依赖关系,这样被依赖的容器需要先启动。关闭容器的时候也要对称,先把没有被依赖的容器关闭掉。
顺便就来看下harbor的docker-compose.yml文件:

[root@Harbor harbor]# cat docker-compose.yml version: '2.3'  # docker-compose的版本services:  # 定义一个服务  log:  # 服务的名称,服务是通过容器来提供的,具体就是下面的设置    image: goharbor/harbor-log:v1.8.1  # 指定容器的镜像,也可以用build指令通过dockerfile创建    container_name: harbor-log  # 生成的容器的名称    restart: always  # 容器自动重启    dns_search: .    cap_drop:      - ALL    cap_add:      - CHOWN      - DAC_OVERRIDE      - SETGID      - SETUID    volumes:  # 定义卷      - /var/log/harbor/:/var/log/docker/:z      - ./common/config/log/:/etc/logrotate.d/:z    ports:      - 127.0.0.1:1514:10514    networks:  # 加入的网络      - harbor  registry:    image: goharbor/registry-photon:v2.7.1-patch-2819-v1.8.1    container_name: registry    restart: always    cap_drop:      - ALL    cap_add:      - CHOWN      - SETGID      - SETUID    volumes:      - /data/registry:/storage:z      - ./common/config/registry/:/etc/registry/:z      - type: bind        source: /data/secret/registry/root.crt        target: /etc/registry/root.crt    networks:      - harbor    dns_search: .    depends_on:  # 依赖的容器名称      - log    logging:      driver: "syslog"      options:          syslog-address: "tcp://127.0.0.1:1514"        tag: "registry"  registryctl:    image: goharbor/harbor-registryctl:v1.8.1    container_name: registryctl    env_file:      - ./common/config/registryctl/env    restart: always    cap_drop:      - ALL    cap_add:      - CHOWN      - SETGID      - SETUID    volumes:      - /data/registry:/storage:z      - ./common/config/registry/:/etc/registry/:z      - type: bind        source: ./common/config/registryctl/config.yml        target: /etc/registryctl/config.yml    networks:      - harbor    dns_search: .    depends_on:      - log    logging:      driver: "syslog"      options:          syslog-address: "tcp://127.0.0.1:1514"        tag: "registryctl"  postgresql:    image: goharbor/harbor-db:v1.8.1    container_name: harbor-db    restart: always    cap_drop:      - ALL    cap_add:      - CHOWN      - DAC_OVERRIDE      - SETGID      - SETUID    volumes:      - /data/database:/var/lib/postgresql/data:z    networks:      harbor:    dns_search: .    env_file:      - ./common/config/db/env    depends_on:      - log    logging:      driver: "syslog"      options:          syslog-address: "tcp://127.0.0.1:1514"        tag: "postgresql"  core:    image: goharbor/harbor-core:v1.8.1    container_name: harbor-core    env_file:      - ./common/config/core/env    restart: always    cap_drop:      - ALL    cap_add:      - SETGID      - SETUID    volumes:      - /data/ca_download/:/etc/core/ca/:z      - /data/psc/:/etc/core/token/:z      - /data/:/data/:z      - ./common/config/core/certificates/:/etc/core/certificates/:z      - type: bind        source: ./common/config/core/app.conf        target: /etc/core/app.conf      - type: bind        source: /data/secret/core/private_key.pem        target: /etc/core/private_key.pem      - type: bind        source: /data/secret/keys/secretkey        target: /etc/core/key    networks:      harbor:    dns_search: .    depends_on:      - log      - registry    logging:      driver: "syslog"      options:          syslog-address: "tcp://127.0.0.1:1514"        tag: "core"  portal:    image: goharbor/harbor-portal:v1.8.1    container_name: harbor-portal    restart: always    cap_drop:      - ALL    cap_add:      - CHOWN      - SETGID      - SETUID      - NET_BIND_SERVICE    networks:      - harbor    dns_search: .    depends_on:      - log      - core    logging:      driver: "syslog"      options:        syslog-address: "tcp://127.0.0.1:1514"        tag: "portal"  jobservice:    image: goharbor/harbor-jobservice:v1.8.1    container_name: harbor-jobservice    env_file:      - ./common/config/jobservice/env    restart: always    cap_drop:      - ALL    cap_add:      - CHOWN      - SETGID      - SETUID    volumes:      - /data/job_logs:/var/log/jobs:z      - type: bind        source: ./common/config/jobservice/config.yml        target: /etc/jobservice/config.yml    networks:      - harbor    dns_search: .    depends_on:      - redis      - core    logging:      driver: "syslog"      options:        syslog-address: "tcp://127.0.0.1:1514"        tag: "jobservice"  redis:    image: goharbor/redis-photon:v1.8.1    container_name: redis    restart: always    cap_drop:      - ALL    cap_add:      - CHOWN      - SETGID      - SETUID    volumes:      - /data/redis:/var/lib/redis    networks:      harbor:    dns_search: .    depends_on:      - log    logging:      driver: "syslog"      options:        syslog-address: "tcp://127.0.0.1:1514"        tag: "redis"  proxy:    image: goharbor/nginx-photon:v1.8.1    container_name: nginx    restart: always    cap_drop:      - ALL    cap_add:      - CHOWN      - SETGID      - SETUID      - NET_BIND_SERVICE    volumes:      - ./common/config/nginx:/etc/nginx:z    networks:      - harbor    dns_search: .    ports:      - 80:80    depends_on:      - postgresql      - registry      - core      - portal      - log    logging:      driver: "syslog"      options:          syslog-address: "tcp://127.0.0.1:1514"        tag: "proxy"networks:  harbor:    external: false[root@Harbor harbor]# 

安装 Harbor

安装前,需要去修改一下harbor.yml这个文件的配置,至少要把主机名改掉,之前已经说过了。其他配置按需要修改,不改也能够安装了。

一切准备就行,就可以安装了:

[root@Harbor harbor]# ./install.sh [Step 0]: checking installation environment ...Note: docker version: 19.03.1Note: docker-compose version: 1.18.0[Step 1]: loading Harbor images ...ba58b7bb3f17: Loading layer  33.32MB/33.32MB......略过......Loaded image: goharbor/clair-photon:v2.0.8-v1.8.1[Step 2]: preparing environment ...prepare base dir is set to /opt/harborGenerated configuration file: /config/log/logrotate.conf......略过......Generated certificate, key file: /secret/core/private_key.pem, cert file: /secreCreating harbor-log ... doneGenerated configuration file: /compose_location/docker-compose.ymlClean up the input dirCreating registry ... doneCreating harbor-core ... done[Step 3]: starting Harbor ...Creating harbor-portal ... doneCreating nginx ... doneCreating harbor-db ... Creating redis ... Creating registryctl ... Creating registry ... Creating harbor-core ... Creating harbor-portal ... Creating harbor-jobservice ... Creating nginx ... ✔ ----Harbor has been installed and started successfully.----Now you should be able to visit the admin portal at http://HarborStudy. For more details, please visit https://github.com/goharbor/harbor .[root@Harbor harbor]# 

安装成功,可以看看监听的端口,安装了哪些镜像,启动了哪些容器:

$ ss -tnl$ docker images$ docker ps

登录 Harbor

默认的密码在harbor.yml有设置的:

harbor_admin_password: Harbor12345

用户名是admin,密码没改的话就是默认的,可以登录进去。

使用浏览器访问Web页面,可以看到一些管理界面。
另外要上传或下载镜像,需要在命令行使用docker命令,在那之前也需要登录Harbor,使用docker login命令来完成登录:

[root@Harbor harbor]# docker login localhostUsername: adminPassword: WARNING! Your password will be stored unencrypted in /root/.docker/config.json.Configure a credential helper to remove this warning. Seehttps://docs.docker.com/engine/reference/commandline/login/#credentials-storeLogin Succeeded[root@Harbor harbor]# 

登录成功之后,才能推送镜像。

停止 Harbor

要想停止或启动harbor,需要通过docker-compose命令。
在操作之前,最好先切换目录到要操作的docker-compose.yml所在的目录,这样docker-compose能够自动找到模板文件并进行操作。
停止harbor:

[root@Harbor harbor]# cd /opt/harbor/[root@Harbor harbor]# docker-compose stopStopping nginx             ... doneStopping harbor-portal     ... doneStopping harbor-jobservice ... doneStopping harbor-core       ... doneStopping registryctl       ... doneStopping harbor-db         ... doneStopping registry          ... doneStopping redis             ... doneStopping harbor-log        ... done[root@Harbor harbor]# 

然后再次启动:

[root@Harbor harbor]# docker-compose startStarting log         ... doneStarting registry    ... doneStarting registryctl ... doneStarting postgresql  ... doneStarting core        ... doneStarting portal      ... doneStarting redis       ... doneStarting jobservice  ... doneStarting proxy       ... done[root@Harbor harbor]# 
0