360私有云容器镜像仓库简介

开发 开发工具
镜像仓库,顾名思义就是存储镜像的。Docker 仓库的概念跟Git 类似,注册服务器可以理解为 GitHub 这样的托管服务。本文主要介绍360私有云HULK使用的镜像仓库Harbor。

镜像仓库,顾名思义就是存储镜像的。Docker 仓库的概念跟Git 类似,注册服务器可以理解为 GitHub 这样的托管服务。用户制作好镜像push到仓库,这样下次在另外一台机器上使用这个镜像时候,只需要从仓库上 pull 下来就可以了。本文主要介绍360私有云HULK使用的镜像仓库Harbor。

一、什么是Harbor

Habor是由VMWare公司开源的容器镜像仓库,是一个用于存储和分发Docker镜像的企业级Registry服务器。

Harbor主要是提供了一些企业级的管理功能,而镜像存储用的还是docker registry,相当于docker registry的反向代理。

1. Harbor架构

如上图所示,Harbor由6个组件组成:

Proxy:nginx反向代理。上图来自官网,已经滞后了。目前到harbor的所有请求都必须走nginx,包括上图中Proxy–> Registory这条。

Registry:负责存储Docker图像和处理Docker push/pull命令。由于Harbor需要加强对映像的访问控制,因此注册中心将引导客户端到令牌服务,以便为每个pull或push请求获得一个有效的令牌。

Core services:港口的核心功能,主要提供以下服务:

  • UI:提供了一个web管理页面,当然还包括了一个前端页面和后端API。
  • Webhook:在Registory中配置,镜像复制,日志更新都是同伙该功能实现。
  • Token service:令牌服务,如果从Docker客户机发送的请求中没有令牌,注册中心将把请求重定向到令牌服务。
  • Job services:镜像复制。
  • Log collector:日是收集。

2. HULK使用的Harbor功能

(1) 用户管理

基于角色的访问控制:用户分为三种角色:项目管理员(MDRWS)、开发人员(RWS)和访客(RS),当然还有一个造物主admin系统管理员。

注:M:管理、D:删除、R:读取、W:写入、S:查询。

(2) 项目管理

项目管理是系统最主要的一个功能模块,项目是一组镜像仓库的逻辑集合,是权限管理和资源管理的单元划分。一个项目下面有多个镜像仓库,并且关联多个不同角色的成员,镜像复制也是基于项目的,通过添加复制规则,

可以将项目下面的镜像从一个harbor迁移到另一个harbor,并且可以通过日志查看复制过程,并有retry机制。

(3) 权限管理

配置管理主要是配置harbor的认证模式,企业内部使用,通常都是对接到公司LDAP上面,我们目前用的数据库认证;还可以设置token的有效时间。

(4) 镜像复制

HULK多机房就是通过镜像复制功能实现的,可在不同的数据中心、不同的运行环境之间同步镜像。

目前HULK上,用户申请容器服务后,我们会为其创建个Harbor的project(下图中的xxl-api即为Harbor中的项目名),

并为其分配两个用户名,一个RWS、一个RS,xxl-api是只读用户,还有一个对用户隐藏的xxl-api-p开发人员用户。以达到用户只能操作自己私有仓库的目的。

3. Harbor的高可用负载均衡

通过三个harbor完成高可用部署,前面通过负载均衡器(HULK上的LVS)对外提供服务。共享数据库与缓存。

多机房

多机房可以应对单机房s3异常,机房孤岛等及特殊情况,同时可以减轻主机房负担。

目前我们有bjyt(主)和shyc2(从)两套harbor,push都到主,k8s拉镜像可以选择拉主或者从。

每个机房的harbor组件完全独立,包括s3和数据库。目的就是为了即使出现孤岛也不会影响服务。

二、什么是镜像

镜像就是,联合文件系统(UnionFS),目前用的驱动是overlay2。

镜像的基础层是rootfs:任何程序运行时都会有依赖,无论是开发语言层的依赖库,还是各种系统lib、操作系统等,不同的系统上这些库可能是不一样的,或者有缺失的。为了让容器运行时一致,docker将依赖的操作系统、各种lib依赖整合打包在一起(即镜像),然后容器启动时,作为它的根目录(根文件系统rootfs),使得容器进程的各种依赖调用都在这个根目录里,这样就做到了环境的一致性。

Layer:Dockerfile中的基础是rootfs,而之后的每一个操作都是一层,如:RUN、ADD等命令。所有为了镜像体积小写,可以把多个RUN命令整合成一行,这样多层就变成一层了。

镜像只有最上一层是读写的,其余都是只读的(目录的without属性)。所谓without属性union文件系统中,如果删除的文件在只读层,最上层看到文件已经删除,但是只读层文件依然存在,在最上层做改文件without隐藏文件实现。rm mnt/haha.log操作和touch a/.wh.haha.log效果相同。

1. 容器的镜像挂载

docker支持多种graphDriver,包括vfs、devicemapper、overlay、overlay2、aufs,docker镜像存储驱动目前用的是overlay2。

docker默认的存储目录是/var/lib/docker

  1. [root@p22295v zhangzhifei]# ls -lrt /var/lib/docker/ 
  2. total 156 
  3. drwx--x--x   3 root root  4096 Dec  6  2018 containerd 
  4. drwx------   4 root root  4096 Dec  6  2018 plugins 
  5. drwx------   3 root root  4096 Dec  6  2018 image 
  6. drwx------   2 root root  4096 Dec  6  2018 trust 
  7. drwxr-x---   3 root root  4096 Dec  6  2018 network 
  8. drwx------   2 root root  4096 Dec  6  2018 swarm 
  9. drwx------   2 root root  4096 Dec  6  2018 builder 
  10. drwx------  89 root root 12288 Jul 17 11:07 volumes 
  11. drwx------   2 root root  4096 Jul 17 14:30 runtimes 
  12. drwx------   2 root root  4096 Jul 23 12:51 tmp 
  13. drwx------ 758 root root 94208 Jul 29 19:12 overlay2 
  14. drwx------  80 root root 12288 Jul 29 19:12 containers 

我们运行个容器演示下:

  1. [root@p22295v zhangzhifei]# docker run -it -d  kraken-agent:dev  
  2. 83555ad8c034682ad885fc9e320bfb1f8b75498b61a1a8684d738c411caa930b 

启动一个容器,在/var/lib/docker/overlay2目录下生成一个容器视图层,目录包括diff,link,lower,merged,work。

diff记录每一层自己内容的数据,link记录该层链接目录(实际是l目录下到层的链接),比如在容器中创建目录或在diff新增该目录。

根据存储数据及功能可以把这些层分为3部分:

  • 只读层
  • init层(夹在只读层和读写层之间,专门用来存放/etc/hosts、/etc/resolv.conf等信息。需要这样一层的原因是,这些文件本来属于只读的系统镜像层的一部分,但是用户往往需要在启动容器时写入一些指定的值比如hostname,所以就需要在可读写层对它们进行修改。可是,这些修改往往只对当前的容器有效,我们并不希望执行docker commit时,把这些信息连同可读写层一起提交掉。所以,Docker做法是,在修改了这些文件之后,以一个单独的层挂载了出来。而用户执行docker commit只会提交可读写层,所以是不包含这些内容的。)
  • 读写层(在没有写入文件之前,这个目录是空的。而一旦在容器里做了写操作,你修改产生的内容就会以增量的方式出现在这个层中)

查看容器挂载目录

  1. [root@p22295v zhangzhifei]# cat /var/lib/docker/image/overlay2/layerdb/mounts/83555ad8c034682ad885fc9e320bfb1f8b75498b61a1a8684d738c411caa930b/mount-id  
  2. 3695f349587aaa2cdc82fcde1a380c7b567ef870a47e4c28b8b279e4edc9eb40[root@p22295v zhangzhifei]#  
  3. #读写层 
  4. [root@p22295v zhangzhifei]# ls /var/lib/docker/overlay2/3695f349587aaa2cdc82fcde1a380c7b567ef870a47e4c28b8b279e4edc9eb40/diff/ 
  5. [root@p22295v zhangzhifei]# 
  6. #只读层 
  7. [root@p22295v zhangzhifei]# ls /var/lib/docker/overlay2/65e5cdd72f2995da4c73f2d9b90e8d974b9d2f18829a2479296aaec24e67d185/diff/ 
  8. bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var 
  9. #只读层(Dockerfile时ADD的二进制程序) 
  10. [root@p22295v zhangzhifei]# ls -lrt /var/lib/docker/overlay2/852fa5138c3da5070b59e6402348a5a281378b28ee08fede9c635e4101f91092/diff/usr/bin/ 
  11. total 28836 
  12. -rwxr-xr-x 1 root root 29526888 Jul 10 16:23 kraken-origin 

最终,这写层都被联合挂载到/var/lib/docker/overlay2/3695f349587aaa2cdc82fcde1a380c7b567ef870a47e4c28b8b279e4edc9eb40/merged目录下,表现为一个完整的操作系统和运行时环境供容器使用。

  1. [root@p22295v zhangzhifei]# mount | grep 3695f349587aaa2cdc82fcde1a380c7b567ef870a47e4c28b8b279e4edc9eb40 
  2. overlay on /var/lib/docker/overlay2/3695f349587aaa2cdc82fcde1a380c7b567ef870a47e4c28b8b279e4edc9eb40/merged type overlay (rw,relatime,lowerdir=/var/lib/docker/overlay2/l/Z7QMVXSKSNAKCUEJ6ZMU5YTFWG:/var/lib/docker/overlay2/l/2OYCXTK7M4QN3DT7IYJK6J7VYT:/var/lib/docker/overlay2/l/UZTDJDVUOBHU2VERRLXF5KMIQO:/var/lib/docker/overlay2/l/NAXXPRFMO4ATUIG6SFPU4LBUUV:/var/lib/docker/overlay2/l/AM4PHUFWOD4UHYIVO5Q6GVZ5L7:/var/lib/docker/overlay2/l/7XLJNT7Q3UQIKHDNV4QG4EX2C3:/var/lib/docker/overlay2/l/3RAVSDXXRS3BASAKZFPT2ESY2K:/var/lib/docker/overlay2/l/FFNAQF5ADFSTEBNZZ4O2R3CP4N:/var/lib/docker/overlay2/l/X6BOWOZKYRN3DZFY6QLLP7OFDP:/var/lib/docker/overlay2/l/P3EO3WHIM2XPDNPIFUP42EGMQI:/var/lib/docker/overlay2/l/EOSBLWDBASO7GKSDILC4XVGO45:/var/lib/docker/overlay2/l/7K7266OIDWAVXLAN6AA3SZXZQZ,upperdir=/var/lib/docker/overlay2/3695f349587aaa2cdc82fcde1a380c7b567ef870a47e4c28b8b279e4edc9eb40/diff,workdir=/var/lib/docker/overlay2/3695f349587aaa2cdc82fcde1a380c7b567ef870a47e4c28b8b279e4edc9eb40/work) 
  3. [root@p22295v zhangzhifei]# ls  /var/lib/docker/overlay2/3695f349587aaa2cdc82fcde1a380c7b567ef870a47e4c28b8b279e4edc9eb40/merged 
  4. bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var 

三、镜像在镜像仓库中的存储

1. 镜像存储的目录结构

以本地存储为例,默认在/data/registry/docker/registry/v2,镜像存储的任何一层都不会重复。

  1. ├── blobs 
  2. │   └── sha256 
  3. │       │   └── dfa94d685d1c2179324f02bf2a119f6d8ee0d380cef5506566012f7c4936a04a 
  4. │       │       └── data 
  5. │       ├── e6 
  6. │       │   └── e6ae4ac760c8457aca9be07de8ca66b3a358a19b950389a0d158ae885178f6cf 
  7. │       │       └── data 
  8. │       ├── e7 
  9. │       │   └── e71de1ca8f2b18993c258e2bf50edea8c23ea4a78a821bcfef181de50b3c32f4 
  10. │       │       └── data 
  11. └── repositories 
  12.     ├── registry-share-private 
  13.     │   ├── push-mount 
  14.     │   │   ├── _layers 
  15.     │   │   │   └── sha256 
  16.     │   │   │       ├── 1b1ad4542c99b8881265610cf5dc09e37d38445529a7584edb2a607fd783216f 
  17.     │   │   │       │   └── link 
  18.     │   │   ├── _manifests 
  19.     │   │   │   ├── revisions 
  20.     │   │   │   │   └── sha256 
  21.     │   │   │   │       └── 9e4cf4691735c02e59dd49ee561a3f5e56bccf78d57eaa94581e29f69a5162bd 
  22.     │   │   │   │           └── link 
  23.     │   │   │   └── tags 
  24.     │   │   │       └── v1 
  25.     │   │   │           ├── current 
  26.     │   │   │           │   └── link 
  27.     │   │   │           └── index 
  28.     │   │   │               └── sha256 
  29.     │   │   │                   └── 9e4cf4691735c02e59dd49ee561a3f5e56bccf78d57eaa94581e29f69a5162bd 
  30.     │   │   │                       └── link 
  31.     │   │   └── _uploads 
  32.     │   ├── push-new 
  33.     │   │   ├── _layers 
  34.     │   │   │   └── sha256 
  35.     │   │   │       ├── 1b1ad4542c99b8881265610cf5dc09e37d38445529a7584edb2a607fd783216f 
  36.     │   │   │       │   └── link 
  37.     │   │   ├── _manifests 
  38.     │   │   │   ├── revisions 
  39.     │   │   │   │   └── sha256 
  40.     │   │   │   │       └── 9e4cf4691735c02e59dd49ee561a3f5e56bccf78d57eaa94581e29f69a5162bd 
  41.     │   │   │   │           └── link 
  42.     │   │   │   └── tags 
  43.     │   │   │       └── v1 
  44.     │   │   │           ├── current 
  45.     │   │   │           │   └── link 
  46.     │   │   │           └── index 
  47.     │   │   │               └── sha256 
  48.     │   │   │                   └── 9e4cf4691735c02e59dd49ee561a3f5e56bccf78d57eaa94581e29f69a5162bd 
  49.     │   │   │                       └── link 

(1) blobs

目录是存放每层数据(gzip)以及一个镜像的manifests信息(json)的具体文件

(2) repositories

存储镜像的组织信息,类似于元数据

  • 仓库名:registry-share-private/push-mount就是一个仓库名,registry-share-private相当于project的概念,push-mount容器名
  • _layers:目录类似于blobs目录,但是它不存储真是数据仅仅以link文件保存每个layer的sha256编码。保存该repository长传过得所有layer的sha256编码信息
  • _manifests:该repository的上传的所有版本(tag)的manifest信息。其目录下有revisions目录和tags目录
  • tags:每个tag一组记录(v1), 每个tag下面有current目录和index目录, current目录下的link文件保存了该tag目前的manifest文件的sha256编码,而index目录则列出了该tag历史上传的所有版本的sha256编码信息
  • _revisions:目录里存放了该repository历史上上传版本的所有sha256编码信息
  • _uploads:是一个临时目录,一旦镜像上传完成,该目录下的文件就被删除

2. 上传镜像流程认证

  • 到认证服务获取token
  • 查询仓库中是否有欲上传的层
  • 开始上传blob
  • 大块用则分块传,小块用put。分块上传后也要以一个put请求表示完成上传。
  • 上传mainfest

当所有的blob上传完成后需上传文件清单。

注意:

  • 如果上传镜像的某一层在仓库中已经存在,并且有读的权限。docker 会先获取token,之后携带这个toke进行mount,减少重复层的上传,加快push速度
  • mount信息处理其实就是在生产对应layer的信息放在_layers目录下。
  • 对于已经存在的层,但是没有权限的,客户端需要重新上传,但是最终存储还是一份。但是文件系统做move时,先判断目的路径是否存在,存在则不进行覆盖。
  • 对于已经存在的镜像HEAD请求时世界返回200,表示不需要上传。

【本文是51CTO专栏机构360技术的原创文章,微信公众号“360技术( id: qihoo_tech)”】

戳这里,看该作者更多好文

责任编辑:赵宁宁 来源: 51CTO专栏
相关推荐

2020-08-07 17:03:24

私有镜像仓库

2022-07-11 07:37:55

HarborContainerd

2017-03-24 09:24:21

HarborDocker镜像仓库

2024-01-22 09:12:51

2020-09-18 07:59:44

GitLabCI

2019-04-10 05:45:22

容器微服务网关AI-

2022-12-08 19:27:38

2022-09-16 10:19:36

HarborContainerd

2012-06-14 15:30:58

Teradata数据仓库私有云

2011-12-08 14:52:35

360开放平台

2009-09-25 11:40:37

ibmdw云计算

2021-04-26 08:03:18

Nexus容器镜像仓库开发

2024-05-15 11:09:30

2017-08-10 15:05:07

Hulk容器镜像

2011-09-15 14:03:58

linux软件仓库

2024-09-06 09:48:06

2012-07-31 16:34:46

私有云公有云

2011-11-02 09:36:51

私有云云计算

2021-07-30 06:51:28

Nginx运维web
点赞
收藏

51CTO技术栈公众号