#docker #dockerhub #镜像仓库 #golang #harbor

搭建企业级的私有 Docker 镜像仓库

简介

私有镜像仓库可以方便企业,或个人开发者共享内部镜像而不会泄漏私有代码,而且可以加速镜像的拉取。能更加方便得集成到容器化的 CI/CD 中去。也可建立自己的公共镜像仓库。

背景

在没有使用 《镜像加速配置》(可参考前半部分配置) 的时候。

  • 公司或个人项目代码不能公开,如何共享镜像或快速发布?直接共享 Dockerfile 用时 build 吗?
  • 在国内直接拉取官方镜像非常缓慢。如何才能快速取官方基础镜像呢?
  • 国内的网络环境下,项目在 CI/CD 过程中拉取镜像可能会花费比较多的时间,如何能加快拉取镜像的速度?

没错,搭建私有镜像仓库吧。

方案选择

搭建私有镜像仓库有几种方式:

  • 官方 registry 推荐使用 registry:2 v2 版本的镜像
  • harbor 方案, 则是在官方的基础上增加了权限控制、界面化等功能

这里主要说说 harbor 的搭建。

开始

先看看 harbor 管理面板效果 先看看管理面板效果

系统环境及配置要求

资源 配置 说明
CPU 2核 起步 4核 更佳
Mem 4GB 起步 8GB 更佳
Disk 40GB 起步 160GB 更佳

硬盘主要存储镜像,镜像量大可以考虑加大。

软件要求:

软件 版本 说明
Python 2.7 以上 Linux 服务器基本都安装了 2.7 版本,可以 python 尝试,未装的装上
Docker 1.10 以上 《CentOS 安装 Docker》
Docker Compose 1.6.0 以上 《安装 docker-compose》
Openssl 推荐用最高版本 生成证书,自备证书的忽略

安装

安装步骤:

  • 下载安装器
  • 修改配置文件 harbor.cfg
  • 运行 install.sh 执行安装,此 shell 脚本会生成所需要的配置文件,调用 docker-compose 来进行镜像拉取及启动。

harbor 有两种方式进行安装。分为离线和在线,如果网络环境不佳可以先择离线安装。

这里选择在线方式(拉取远程镜像来安装)安装:

本示例使用当前最新稳定版本 v1.6.3

下载安装器:

$ wget https://storage.googleapis.com/harbor-releases/release-1.6.0/harbor-online-installer-v1.6.3.tgz

想要离线的可以使用(离线版本会比较大):

$ wget https://storage.googleapis.com/harbor-releases/release-1.6.0/harbor-offline-installer-v1.6.3.tgz

解压安装程序:

$ tar -zxvf harbor-offline-installer-v1.6.3.tgz

修改配置文件:

$ cd harbor
$ vim harbor.cfg

修改以下部分:

hostname = hub.zhoujiangang.com:41533 # 修改为你自己的域名,由于我机子端口限制,所以改为非 443,如果 443 可以给镜像仓库使用,则可以直接用 `hub.zhoujiangang.com`
ui_url_protocol = https # 最好换成 https 吧,如果想用 `http` 的话,需要在客户端设置支持 `http` 访问,需要重启服务。
...
ssl_cert = /data/harbor/cert/hub.zhoujiangang.com.crt # 对于目录没有要求的可以不改,由于 data 目录下有很多其它项目,所以作此修改
ssl_cert_key = /data/harbor/cert/hub.zhoujiangang.com.key # 对于目录没有要求的可以不改,由于 data 目录下有很多其它项目,所以作此修改
harbor_admin_password = Harbor12345 # 修改管理面板的登录密码

修改 docker-compose.yml 文件, 不关心安装位置、端口的可以忽略。默认 docker-compose.yml 日志放在 var/logs/ 下,端口开放 80, 443, 4443, 由于这些端口我已经被占用,需要修改。

先创建根文件夹,把所有数据全放在 /data/harbor 下面,便于以后查看。

$ mkdir -p /data/harbor

当前使用自备证书的方式,免去了所有客户端手动添加信任的操作。

还没有证书可以参考这里 《轻松全站 HTTPS,还没用上 https (可申请泛域名证书)的朋友可以操练起来了》 只要有域名,轻松申请证书。

也可以手动使用 openssl 来申请证书,只要设置双方信任即可,可参考官方配置文档 《Configuring Harbor with HTTPS Access》

用以上方法申请好证书后,把申请好的证书移动到 ssl_cert, ssl_cert_key 配置的目录中去。

注意

如果是使用 acme.sh 申请的,则可作如下配置:

ssl_cert = ~/.acme.sh/zhoujiangang.com/fullchain.cer # 实在要这么配置,最好把路径改为绝对路径 ~ 在不用用户表示不同的位置。
ssl_cert_key = ~/.acme.sh/zhoujiangang.com/hub.zhoujiangang.com.key # 实在要这么配置,最好把路径改为绝对路径 ~ 在不用用户表示不同的位置。

不过建议进行改名,并移动到 /data/harbor/cert 目录下

$ mkdir -p /data/harbor/cert
$ cp ~/.acme.sh/zhoujiangang.com/fullchain.cer /data/harbor/cert/hub.zhoujiangang.com.crt
$ cp ~/.acme.sh/zhoujiangang.com/hub.zhoujiangang.com.key /data/harbor/cert/hub.zhoujiangang.com.key

证书设置完成后,可进行 docker-compose.yml 的配置。

可直接用如下配置:

version: '2'
services:
  log:
    image: goharbor/harbor-log:v1.6.3
    container_name: harbor-log
    restart: always
    volumes:
      - /data/harbor/log/:/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.6.2-v1.6.3
    container_name: registry
    restart: always
    volumes:
      - /data/harbor/registry:/storage:z
      - ./common/config/registry/:/etc/registry/:z
      - ./common/config/custom-ca-bundle.crt:/harbor_cust_cert/custom-ca-bundle.crt:z
    networks:
      - harbor
    environment:
      - GODEBUG=netdns=cgo
    depends_on:
      - log
    logging:
      driver: "syslog"
      options:
        syslog-address: "tcp://127.0.0.1:1514"
        tag: "registry"
  postgresql:
    image: goharbor/harbor-db:v1.6.3
    container_name: harbor-db
    restart: always
    volumes:
      - /data/harbor/database:/var/lib/postgresql/data:z
    networks:
      - harbor
    env_file:
      - ./common/config/db/env
    depends_on:
      - log
    logging:
      driver: "syslog"
      options:
        syslog-address: "tcp://127.0.0.1:1514"
        tag: "postgresql"
  adminserver:
    image: goharbor/harbor-adminserver:v1.6.3
    container_name: harbor-adminserver
    env_file:
      - ./common/config/adminserver/env
    restart: always
    volumes:
      - /data/harbor/config/:/etc/adminserver/config/:z
      - /data/harbor/secretkey:/etc/adminserver/key:z
      - /data/harbor/:/data/:z
    networks:
      - harbor
    depends_on:
      - log
    logging:
      driver: "syslog"
      options:
        syslog-address: "tcp://127.0.0.1:1514"
        tag: "adminserver"
  ui:
    image: goharbor/harbor-ui:v1.6.3
    container_name: harbor-ui
    env_file:
      - ./common/config/ui/env
    restart: always
    volumes:
      - ./common/config/ui/app.conf:/etc/ui/app.conf:z
      - ./common/config/ui/private_key.pem:/etc/ui/private_key.pem:z
      - ./common/config/ui/certificates/:/etc/ui/certificates/:z
      - /data/harbor/secretkey:/etc/ui/key:z
      - /data/harbor/ca_download/:/etc/ui/ca/:z
      - /data/harbor/psc/:/etc/ui/token/:z
    networks:
      - harbor
    depends_on:
      - log
      - adminserver
      - registry
    logging:
      driver: "syslog"
      options:
        syslog-address: "tcp://127.0.0.1:1514"
        tag: "ui"
  jobservice:
    image: goharbor/harbor-jobservice:v1.6.3
    container_name: harbor-jobservice
    env_file:
      - ./common/config/jobservice/env
    restart: always
    volumes:
      - /data/harbor/job_logs:/var/log/jobs:z
      - ./common/config/jobservice/config.yml:/etc/jobservice/config.yml:z
    networks:
      - harbor
    depends_on:
      - redis
      - ui
      - adminserver
    logging:
      driver: "syslog"
      options:
        syslog-address: "tcp://127.0.0.1:1514"
        tag: "jobservice"
  redis:
    image: goharbor/redis-photon:v1.6.3
    container_name: redis
    restart: always
    volumes:
      - /data/harbor/redis:/var/lib/redis
    networks:
      - harbor
    depends_on:
      - log
    logging:
      driver: "syslog"
      options:
        syslog-address: "tcp://127.0.0.1:1514"
        tag: "redis"
  proxy:
    image: goharbor/nginx-photon:v1.6.3
    container_name: nginx
    restart: always
    volumes:
      - ./common/config/nginx:/etc/nginx:z
    networks:
      - harbor
    ports:
      - 41522:80
      - 41533:443
      - 41534:4443
    depends_on:
      - postgresql
      - registry
      - ui
      - log
    logging:
      driver: "syslog"
      options:
        syslog-address: "tcp://127.0.0.1:1514"
        tag: "proxy"
networks:
  harbor:
    external: false

以上配置作了处地方修改:

  1. 将所有挂载的目录更改为 /data/harbor
  2. 将 nginx 块配置,暴露的端口修改为(由于我测试的机子 80,443 都已经被占用,如果你希望将这些端口给 harbor 使用,则可改回去)

    ports:
    - 41522:80
    - 41533:443
    - 41534:4443
    

直接使用 80, 443 提供服务, 可改回之前的配置

ports:
  - 80:80
  - 443:443
  - 4443:4443

全部配置完成,开始安装

$ ./install.sh

执行成功可以看到有如下输出:

...
[Step 2]: checking existing instance of Harbor ...


[Step 3]: starting Harbor ...
Creating network "harbor_harbor" with the default driver
Creating harbor-log ... done
Creating harbor-adminserver ... done
Creating harbor-db          ... done
Creating registry           ... done
Creating redis              ... done
Creating harbor-ui          ... done
Creating harbor-jobservice  ... done
Creating nginx              ... done

✔ ----Harbor has been installed and started successfully.----

Now you should be able to visit the admin portal at https://hub.zhoujiangang.com:41533.
For more details, please visit https://github.com/goharbor/harbor .

[root@test-node harbor]#

执行成功后,你可以访问 https://hub.zhoujiangang.com:41533 来访问管理面板。在配置 harbor.cfg 时没有修改密码的话,默认的账号为 admin 密码为 Harbor12345

删除 harbor 使用 docker-compose down -v

[root@test-node harbor]# docker-compose down -v
Stopping harbor-jobservice  ... done
Stopping nginx              ... done
Stopping harbor-ui          ... done
Stopping registry           ... done
Stopping harbor-adminserver ... done
Stopping redis              ... done
Stopping harbor-db          ... done
Stopping harbor-log         ... done
Removing harbor-jobservice  ... done
Removing nginx              ... done
Removing harbor-ui          ... done
Removing registry           ... done
Removing harbor-adminserver ... done
Removing redis              ... done
Removing harbor-db          ... done
Removing harbor-log         ... done
Removing network harbor_harbor
[root@test-node harbor]#

新建用户,开始推着镜像

新建一个 os 用户

新建好之后,需要先设置为管理员,否则推送时会显示验证不通过。

新建一个项目

新建一个项目

Docker 客户端登录

$ docker login hub.zhoujiangang.com:41533
Username: os
Password:
Login Succeeded

输入新建账号的账号密码,登录成功后可以进行推送镜像。

更新镜像 tag 名,推送镜像

$ docker tag docker tag ubuntu:latest hub.zhoujiangang.com:41533/os/ubuntu:latest
$ docker push hub.zhoujiangang.com:41533/os/ubuntu
The push refers to repository [hub.zhoujiangang.com:41533/os/ubuntu]
b9b7103af585: Pushed
ca2991e4676c: Pushed
a768c3f3878e: Pushed
bc7f4b25d0ae: Pushed
latest: digest: sha256:acd85db6e4b18aafa7fcde5480872909bd8e6d5fbd4e5e790ecc09acc06a8b78 size: 1150

显示推送成功。 镜像推送成功,服务端查看

小结

整个私有镜像就搭建完成了,当然这只是一个简易的入门教程,还有很多配置需要在 harbor.cfg 中作修改、调优才能用到生产环境。本文权当抛砖引玉,希望能有所帮助。

需要详细的使用说明,可以参考官方 《User Guide》.

Author Mo 最后更新: 2018-12-20 18:54:06