03月09, 2018

容器镜像仓库Harbor解析之基础环境

私有云玩容器,镜像仓库是核心组件之一,与使用Docker Hub等公有云仓库相比,自建的镜像仓库,在安全性、速度、与内部系统集成等方面都有很大的优势。

Docker的镜像规范,是事实标准,同时也提供了镜像仓库的开源组件“Registry”,但Docker Registry仅实现了核心的镜像存储功能,其他比如权限管理等高级功能没有提供,很明显他是希望大家买他的Docker Hub服务嘛,然而,vmware公司的开源项目Harbor,填补了这个空白,本文主要介绍Harbor基础环境方面的一些技术。

Docker Registry

部署Docker开源的registry,非常简单:

# docker run -d -p 5000:5000 --name registry registry:2

这样就在localhost运行起来了registry服务,然后就可以愉快的pull、push镜像了:

# docker push localhost:5000/myfirstimage

Registry的镜像存储,默认使用文件系统,同时支持很多其他后端存储技术,比如:S3, Microsoft Azure, OpenStack Swift, and Aliyun OSS

另外,上面push镜像的示例,没有权限控制,这在生产环境是不行的,不能任何人对任何仓库都可以随意的pull、push;

在权限控制方面,Registry这次两种方式:

  • htpasswd,基于Apache htpasswd file,功能比较基础
  • token,实现认证系统与registry自己解耦,更灵活,安全性更高,但是需要对接第三方认证系统

使用htpasswd的认证方式,docker pull、engine、registry的交互大概是这样的:

alt

使用token的认证方式,需要集成一个第三方认证系统,交互大概是这样的:

alt

  1. pull、push操作,与registry通信
  2. registry返回HTTP 401 Unauthorized,提示需要先认证,并告知该去哪里认证等一些信息
  3. 携带用户名、密码等credentials,向认证服务发起请求,获取Bearer token
  4. 认证服务利用提供的credentials进行鉴权,返回token,token里携带着用户的实际权限(比如[pull, push], [pull])
  5. 使用token,重新向registry发起请求
  6. registry通过token携带的实际权限,允许或者拒绝用户的请求

简单说,Harbor就是上面这种token认证方式的一种实现,对Registry的功能补强,除了RBAC(基于角色的权限控制)的认证功能,还实现了镜像远程复制、LDAP/AD支持、镜像安全漏洞扫描、审计、RESTful API等。

Harbor

部署

Harbor安装部署是基于Docker镜像的,部署还是比较简单的,简单写一点,详情参考官方文档吧。

# tar -zxvf harbor-online-installer-v1.4.0.tgz
# cd harbor
# ll
total 80
drwxrwxr-x 3 wanghaoyu wanghaoyu  4096 Mar  9 13:37 common
-rw-r--r-- 1 wanghaoyu wanghaoyu  1133 Feb  7 18:28 docker-compose.clair.yml
-rw-r--r-- 1 wanghaoyu wanghaoyu  1725 Feb  7 18:28 docker-compose.notary.yml
-rw-r--r-- 1 wanghaoyu wanghaoyu  3314 Feb  7 18:28 docker-compose.yml
drwxr-xr-x 3 wanghaoyu wanghaoyu  4096 Feb  7 18:28 ha
-rw-r--r-- 1 wanghaoyu wanghaoyu  5954 Feb  7 18:28 harbor.cfg
-rwxr-xr-x 1 wanghaoyu wanghaoyu  5773 Feb  7 18:28 install.sh
-rw-r--r-- 1 wanghaoyu wanghaoyu 10771 Feb  7 18:28 LICENSE
-rw-r--r-- 1 wanghaoyu wanghaoyu   482 Feb  7 18:28 NOTICE
-rwxr-xr-x 1 wanghaoyu wanghaoyu 25791 Feb  7 18:28 prepare

需要根据实际情况修改下Harbor主配置文件harbor.cfg,比如主要的一些配置项:

#vim harbor.cfg
hostname = reg.mydomain.com
ui_url_protocol = http
ssl_cert = /data/cert/server.crt
ssl_cert_key = /data/cert/server.key
auth_mode = db_auth
db_host = mysql
db_password = root123
db_port = 3306
db_user = root

Harbor是由多个容器组件一起组合提供服务的,common/templates目录下存放的就是各个组件容器的配置文件模板,每个组件的配置文件都应该根据实际情况修改:

# tree -L 2 common/templates/
common/templates/
├── adminserver
│   └── env
├── clair
│   ├── config.yaml
│   ├── postgres_env
│   └── postgresql-init.d
├── db
│   └── env
├── jobservice
│   ├── app.conf
│   └── env
├── log
│   └── logrotate.conf
├── nginx
│   ├── nginx.http.conf
│   ├── nginx.https.conf
│   ├── notary.server.conf
│   └── notary.upstream.conf
├── notary
│   ├── mysql-initdb.d
│   ├── notary-signer-ca.crt
│   ├── notary-signer.crt
│   ├── notary-signer.key
│   ├── server-config.json
│   ├── signer-config.json
│   └── signer_env
├── registry
│   ├── config_ha.yml
│   ├── config.yml
│   └── root.crt
└── ui
    ├── app.conf
    ├── env
    └── private_key.pem

最后,Harbor是利用Docker Compose这个工具,统一管理这多个容器组件的,docker-compose.yml这个文件也需要根据情况需改(一般改动不大,如果使用外部DB,可以删掉文件中services配置中的mysql):

# vim docker-compose.yml
version: '2'
services:
  log:
    image: vmware/harbor-log:v1.4.0
    container_name: harbor-log
    restart: always
    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: vmware/registry-photon:v2.6.2-v1.4.0
    container_name: registry
    restart: always
    volumes:
      - /data/registry:/storage:z
      - ./common/config/registry/:/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:
    image: vmware/harbor-db:v1.4.0
    container_name: harbor-db
    restart: always
    volumes:
      - /data/database:/var/lib/mysql: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: "mysql"
  adminserver:
    image: vmware/harbor-adminserver:v1.4.0
    container_name: harbor-adminserver
    env_file:
      - ./common/config/adminserver/env
    restart: always
    volumes:
      - /data/config/:/etc/adminserver/config/:z
      - /data/secretkey:/etc/adminserver/key:z
      - /data/:/data/:z
    networks:
      - harbor
    ...
    ...
    ...

最后执行install.sh即可启动Harbor服务,这个脚本主要做了这么几件事:

  1. 检查环境,比如Docker版本
  2. 根据harbor.cfg中的配置项,选择性处理配置文件,通过common/templates下的文件,在common/config目录生成最终使用的配置文件
  3. 使用Docker Compose,启动所有组件容器
# ./install.sh

# docker-compose ps
       Name                     Command               State                                            Ports                                          
------------------------------------------------------------------------------------------------------------------------------------------------------
harbor-adminserver   /harbor/start.sh                 Up                                                                                              
harbor-jobservice    /harbor/start.sh                 Up                                                                                              
harbor-log           /bin/sh -c /usr/local/bin/ ...   Up      127.0.0.1:1514->10514/tcp                                                               
harbor-ui            /harbor/start.sh                 Up                                                                                              
nginx                nginx -g daemon off;             Up      0.0.0.0:443->443/tcp, 0.0.0.0:4443->4443/tcp, 0.0.0.0:80->80/tcp, 0.0.0.0:8360->8360/tcp
registry             /entrypoint.sh serve /etc/ ...   Up      5000/tcp

架构

上面命令行显示Harbor服务,由6个组件容器组成,他们之间是怎样的关系呢,可以参考网上的这张图(官网的架构图已经不准确了):

alt

  • proxy,由nginx容器负责,分离流量
  • ui容器,核心组件,前端方面实现了dashboard,后端方面实现API、读写数据库、token鉴权等
  • registry,就是Docker开源的版本
  • adminserver,为ui、jobservice提供配置管理
  • jobservice,主要负责镜像复制
  • log,主要负责日志汇总

总结

熟悉掌握Harbor基础运行环境,是排查问题、研究源码、二次开发的必备基础,本文仅是简要介绍了最主要的技术点,其实还有很多细节值得深究,比如Registry设计的认证框架的很多细节,这个在Docker官网文档中有很多说明,再比如Harbor对Docker Compose的充分利用,个人觉得是个很好的案例,统一管理多个服务、卷、服务间依赖关系、端口流量关系、日志统一处理,很值得细细品味。

后续的文章可能会逐步深入源码、探讨可能的功能优化或者新的feature等。

参考

https://docs.docker.com/registry/configuration/

https://docs.docker.com/registry/spec/auth/token/

https://github.com/vmware/harbor/blob/master/docs/installation_guide.md

https://docs.docker.com/compose/compose-file/

http://www.adocker.cn/archives/3337

本文链接:https://www.opsdev.cn/post/introducton-of-private-registry-harbor.html

-- EOF --

Comments

评论加载中...

注:如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理。