一、引子

  首先我们要说一下为什么要是用harbor。随着docker越来越火,应用越来越广泛,我们的部分应用也开始采用docker的方式来部署,那么问题也随之而来。大量的镜像例如centos和ubuntu这类系统基础镜像,java,Tomcat这样应用基础镜像,以及我们生成的服务镜像就急需一个仓库来进行保存,docker提供的仓库registry功能上又不能满足我们的很多需求,于是就开始了harbor的填坑之旅 (实际上也算不上填坑,harbor部署使用还是比较简单的,只不过需要按照我们的部署规则修改一些东西,后面会说到一些自定义部署的东西)。


  然后说一下为什么写下这篇文章,博文很长时间都没有发过了,主要还是懒……。因为在安装使用harbor过程中很多问题都是在别人的文章帮助下解决的,同时公司这边基本上将harbor大部分的功能都应用上了,所以决定写出来帮助更多的人。


  最后说下文章大概的内容包括下面几个方面,harbor安装(部分自定义),harbor的配置(邮箱,集成域控验证),harbor备份(harbor复制),harbor代理(内网机器通过harbor拉取互联网镜像)。


  为方便阅读,约定如下内容。

  1、所有命令部分背景色为黑色

  2、需要修改的地方,包括用户名密码等信息用红字斜体

  3、配置文件内容部分字体为加粗

  4、注释内容字体带下划线


二、部署harbor

  部署harbor的前提,首先你需要有docker环境(1.10以上),以及docker-compose(1.6以上),python(2.7以上),这里就不再说如何安装docker以及docker-compose了,可以参考下面文档。

docker安装  https://docs.docker.com/engine/installation/

docker-compose安装  https://docs.docker.com/compose/install/


  当然也不能少了我们的主角harbor,我这用的是v1.1.2,由于我这是内网环境,无法使用外网所以使用的是离线安装包(其实在线安装离线安装的最大区别就是镜像,一个是在线获取镜像,一个是把镜像打包加载)。

下载地址  https://github.com/vmware/harbor/releases/download/v1.1.2/harbor-offline-installer-v1.1.2.tgz

安装文档  https://github.com/vmware/harbor/blob/master/docs/installation_guide.md


  注:由于公司的部署要求,可能和官方的安装有所区别。公司要求所有docker部署的应用所涉及的目录全部都在/work/project/目录下,docker挂载的目录conf为配置文件,data为数据文件,logs为日志文件等等。


2.1、将安装包解压,修改里面的配置文件harbor.cfg

tar -xvf harbor-offline-installer-v1.1.2.tgz

cd harbor

vim harbor.cfg


2.2、修改之后的harbor.cfg,以及部分配置说明

cat harbor.cfg |grep -v "#"


hostname = harbor.domain.com        ;主机名,可以理解为web访问时的域名
ui_url_protocol = https     ;如果能用https就不要用http,http的话docker还需要额外配置一些东西
db_password = password        ;数据库密码

max_job_workers = 3


customize_crt = on
ssl_cert = /work/harbor/cert/registry.domain.com.crt  
      ;证书位置,https需要使用
ssl_cert_key = /work/harbor/cert/registry.domain.com.key    ;秘钥位置,https需要使用
secretkey_path = /work/harbor/cert/                    ;证书目录
admiral_url = NA


email_identity =

email_server = mail.domain.com
email_server_port = 587
email_username = user@domain.com
email_password = password
email_from = admin <user@domian.com>

email_ssl = false            ;上面这部分信息是邮箱的配置,用于harbor发送邮件


harbor_admin_password = password    ;web界面管理密码
auth_mode = db_auth
ldap_url = ldaps://ldap.mydomain.com
ldap_basedn = ou=people,dc=mydomain,dc=com
ldap_uid = uid
ldap_scope = 3
ldap_timeout = 5
self_registration = on
token_expiration = 30
project_creation_restriction = everyone
verify_remote_cert = on


  注:如果按照官方文档的安装的话,接下来执行./install.sh就可以了。但是为了按照我们的部署规则,就需要麻烦一些。也许有人会问为什么一定要坚持自己的规则来部署呢?其实答案很简单,有一个统一的部署规则(不仅harbor所有的docker部署全部是一样的)可以让后期的维护更加方便,即便麻烦一些,我觉得也是值得的。同时自定义部署的话也让我们更加了解熟悉harbor的部署过程。


2.3、docker加载harbor的镜像

  解压之后的harbor文件夹中有一个harbor.v1.1.2.tar.gz,里面放的是所有涉及到的镜像。

docker load < harbor.v1.1.2.tar.gz


2.4、生成docker-compose,以及harbor涉及的服务配置文件,修改docker-compose.yml符合我们自己的部署要求,创建对应的目录,复制配置文件到对应目录。

  解压之后的harbor文件夹中有一个脚本prepare,这个脚本是用于完成安装前的准备工作,包括生产docker-yml以及其他服务的配置文件等。

./prepare

执行完以后会输出一个docker-compose.yml文件在harbor文件夹内,其他的服务配置文件在common目录中。


  我们首先来修改以下docker-compose。  

vim docker-compose.yml


  看一下修改后的docker-compose,主要就是修改的挂载目录。   

cat docker-compose.yml


version: '2'
services:
  log:
    p_w_picpath: vmware/harbor-log:v1.1.2
    container_name: harbor-log
    restart: always
    volumes:
     
- /work/harbor/logs/harbor/:/var/log/docker/:z
    ports:
      - 127.0.0.1:1514:514
    networks:
      - harbor
  registry:
    p_w_picpath: vmware/registry:2.6.1-photon
    container_name: registry
    restart: always
    volumes:
      - /work/harbor/registry/data:/storage:z
      - /work/harbor/registry/conf/:/etc/registry/:z

    networks:
      - harbor
    environment:
      - GODEBUG=netdns=cgo
    command:
      ["serve", "/etc/registry/config.yml"]
    depends_on:
      - log
    logging:
      driver: "syslog"
      options:  
        syslog-address: "tcp://127.0.0.1:1514"
        tag: "registry"
  mysql:
    p_w_picpath: vmware/harbor-db:v1.1.2
    container_name: harbor-db
    restart: always
    volumes:
      - /work/harbor/mysql/data:/var/lib/mysql:z
    networks:
      - harbor
    env_file:
      - /work/harbor/mysql/conf/env
    depends_on:
      - log
    logging:
      driver: "syslog"
      options:  
        syslog-address: "tcp://127.0.0.1:1514"
        tag: "mysql"
  adminserver:
    p_w_picpath: vmware/harbor-adminserver:v1.1.2
    container_name: harbor-adminserver
    env_file:
      - /work/harbor/adminserver/conf/env
    restart: always
    volumes:
      - /work/harbor/adminserver/conf/:/etc/adminserver/config/:z
      - /work/harbor/cert/secretkey:/etc/adminserver/key:z
      - /work/harbor/adminserver/data/:/data/:z

    networks:
      - harbor
    depends_on:
      - log
    logging:
      driver: "syslog"
      options:  
        syslog-address: "tcp://127.0.0.1:1514"
        tag: "adminserver"
  ui:
    p_w_picpath: vmware/harbor-ui:v1.1.2
    container_name: harbor-ui
    env_file:
      - /work/harbor/ui/conf/env
    restart: always
    volumes:
      - /work/harbor/ui/conf/app.conf:/etc/ui/app.conf:z
      - /work/harbor/ui/conf/private_key.pem:/etc/ui/private_key.pem:z
      - /work/harbor/cert/secretkey:/etc/ui/key:z
      - /work/harbor/ui/data/ca_download/:/etc/ui/ca/:z

    networks:
      - harbor
    depends_on:
      - log
      - adminserver
      - registry
    logging:
      driver: "syslog"
      options:  
        syslog-address: "tcp://127.0.0.1:1514"
        tag: "ui"
  jobservice:
    p_w_picpath: vmware/harbor-jobservice:v1.1.2
    container_name: harbor-jobservice
    env_file:
      - /work/harbor/jobservice/conf/env
    restart: always
    volumes:
      - /work/harbor/jobservice/job_logs:/var/log/jobs:z
      - /work/harbor/jobservice/conf/app.conf:/etc/jobservice/app.conf:z
      - /work/harbor/cert/secretkey:/etc/jobservice/key:z

    networks:
      - harbor
    depends_on:
      - ui
      - adminserver
    logging:
      driver: "syslog"
      options:  
        syslog-address: "tcp://127.0.0.1:1514"
        tag: "jobservice"
  proxy:
    p_w_picpath: vmware/nginx:1.11.5-patched
    container_name: nginx
    restart: always
    volumes:
      - /work/harbor/nginx/conf:/etc/nginx:z
    networks:
      - harbor
    ports:
      - 80:80
      - 443:443
      - 4443:4443
    depends_on:
      - mysql
      - registry
      - ui
      - log
    logging:
      driver: "syslog"
      options:  
        syslog-address: "tcp://127.0.0.1:1514"
        tag: "proxy"
networks:
  harbor:
    external: false


  然后我们来创建我们需要的这些文件夹

mkdir -p /work/harbor/adminserver/conf

mkdir -p /work/harbor/jobservice/{conf,job_logs}/

mkdir -p /work/harbor/logs/harbor/

mkdir -p /work/harbor/mysql/{conf,data}/

mkdir -p /work/harbor/nginx/conf/

mkdir -p /work/harbor/registry/{conf,data}/

mkdir -p /work/harbor/ui/{conf,data}/


  最后我们将common中的配置文件,复制到对应的服务中去。

cp common/config/adminserver/env /work/harbor/adminserver/conf/

cp common/config/db/env /work/harbor/mysql/conf/

cp common/config/jobservice/* /work/harbor/jobservice/conf/

cp -r common/config/nginx/* /work/harbor/nginx/conf/

cp common/config/registry/* /work/harbor/registry/conf/

cp common/config/ui/* /work/harbor/ui/conf/


  ok配置工作已经完成,接下来我们将docker-compose.yml文件复制到/work/harbor/目录下,启动harbor吧。

cp harbor/docker-compose.yml /work/harbor/

  在/work/harbor/目录下执行启动命令

docker-compose up -d


  你以为安装配置就到此为止了吗?NO NO NO,你会愿意每增加一个平台就去多记一个账户密码吗(哪怕你可以找回密码)?所以我们需要将用户验证和域控集成在一起,还好我们修改用户验证方式可以直接在web管理页面进行。可以登录web管理页面后在系统管理——>配置管理——>认证模式中修改。当然邮箱的配置也可以在web页面配置,然而开始安装的时候我并不知道……


三、harbor的备份,harbor从复制功能

  现在我们已经有了一个harbor用来存放镜像,但是麻烦的问题来了,安全管理要求我们有对应的备份策略,那么我们现在有下面几种方式解决。

  1、将所有的docker镜像通过docker save命令保存出来进行备份。

  2、将/work/harbor放在存储上

  3、harbor的复制功能


  好吧,我选择第三个,主要考虑的几个方面,备份方式的复杂度,成本以及恢复速度。

  第一种方式无疑是最为复杂的,镜像需要打包,需要传输到备份服务器,还要考虑删除废弃的镜像,加上镜像的数量较多(主要是同一个应用多个版本,这种情况随着使用可能会越来越严重),当然我们可以通过脚本加定时任务去完成,只不过应该也是一个不小的工作量。

  第二种方式就比较简单了,如果有现成的存储设备当然可以用,如果没有总不至于因为个harbor去上一套存储吧。

  第三种方式就是我要使用的方式,配置简单,在虚拟化主机面前一台虚拟机的成本也很低,同时当主harbor挂掉以后可以直接使用从harbor

  那么我们继续填坑harbor的复制功能。


3.1、配置从harbor

  再搭建起来一套harbor平台域名叫做harborbak.domain.com,最好是异地跨机房的,当然只要不是同和主harbor一台机器上就可以。

  那么现在我们有两套harbor一套叫做harbor另一套为harborbak,我们想要将harbor上的镜像备份到harborbak。


3.2、在主harbor上配置复制主机,以及复制规则。

  我们需要在主harbor上的web页面中进行配置,在系统管理——>复制管理——>目标,然后添加主机harborbak

wKiom1nlWSPwXv0iAABVwgUQQrE607.jpg-wh_50


  然后进入到我们想要备份的项目,选择复制——>复制规则,添加备份规则。

wKiom1nlWmSx9gxYAAByOXK1fCU997.jpg-wh_50


wKioL1nlbCXDy9TkAAB0-HbwDn4446.jpg-wh_50


  这样harbor的复制就算搞定了,过一会我们就可以看到harborbak上出现了我们复制的项目以及镜像,顺便说一下日志也是可以复制过去的。


四、harbor代理功能

  其实这个功能是在无意之间发现的,因为公司大部分的开发测试环境全部都是在内网,像centos的yum安装ubuntu的apt安装都是通过反向代理将源地址代理进来使用的。但是docker从外网拉取镜像时只能通过外网机器拉取然后保存复制再加载的方式弄到内网中,这无疑给我们使用带来了一定的不便,曾经试过使用nginx代理,然而并不好使。在研究如何解决这个问题的时候发现了harbor的另一个功能代理。然而我们现在使用的harbor是在内网之中,所以只好又申请使用那台外网机器(也就是前面说到的yum源和apt源反向代理那台),接下来进入正题。

4.1、安装harbor,配置代理

  安装过程不再重复说明,安装完成之后,修改/work/harbor/registry/conf/config.yml配置文件,配置代理信息。

vim /work/harbor/registry/conf/config.yml

在最后添加

proxy:
remoteurl: https://registry-1.docker.io

但是docker hub的速度我们是知道得,既然要弄就弄得完整一些吧,我们配置成阿里的仓储,阿里云加速地址可以访问https://dev.aliyun.com/search.html获取

wKioL1nlYFiTON3dAADYZyaKL2M241.jpg-wh_50


修改为阿里的地址

proxy:
  remoteurl: https://xxxxxxx.mirror.aliyuncs.com


当然你也可以选择其他的加速站,甚至可以选择私有仓库,配置方法如下。

proxy:
remoteurl: https://registry-1.docker.io
username:
password:


4.2、docker配置

  harbor的代理配置好了,接下来我们需要配置docker使用代理来拉取镜像。

修改启动参数,增加--registry-mirror=https://mirror.domain.com
sudo vim /lib/systemd/system/docker.service
修改如下内容
ExecStart=/usr/bin/dockerd -H fd:// --registry-mirror=https://mirror.domain.com
重启docker
sudo systemctl daemon-reload
sudo systemctl restart docker

测试
docker pull nginx


4.3、关于harbor代理的一些说明

  当你通过代理拉取一个镜像的时候,代理服务器如果有的话就会直接返回给你,如果没有的话就会向后端请求,然后再发送给你,自己会对该镜像进行缓存。


五、目前遇到的尚未解决的问题

  虽然目前harbor功能上大体能够满足需求,但是还是有一些想要的功能没有实现。

  1、镜像的备注,harbor上目前并没有发现可以给镜像写备注的地方,哪怕只能写个dockerfile也是好的啊!

  2、harbor在复制中是可以复制日志的,然而如果你使用的是ldap验证,复制过去的日志无法正确显示用户,估计是由于这些用户并没有在harborbak上登陆过的原因导致数据库中没有对应的信息。

  3、harbor安装无法实现自定义安装,像我这样有需求自定义安装目录的来说,修改docker-compose.yml文件,创建目录,复制文件等操作过于麻烦了。