暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

容器学习:从0开始搭建企业级私有镜像仓库及日常运维管理 | 运维进阶

1963
【导读】容器需要通过容器镜像来运行,那么在容器云环境中如何有效地保存、管理和分发所创建的镜像呢?本文将介绍镜像仓库在容器云生态中的地位,并以docker registry为例搭建一个简单的私有镜像仓库;介绍如何获取基础镜像并推送应用镜像到私有镜像仓库,以及其它常见的镜像操作和运维管理;介绍企业级镜像仓库如何选型和构建,如何管理用户权限,如何清理过期的镜像,如何做到不同环境之间镜像的同步,如何做到镜像的安全漏洞扫描等等。通过本文学习,可以从0到1搭建一个完整的企业级私有镜像仓库,并能掌握私有镜像仓库的日常运维管理工作。

【分享者】王志昌,某知名互联网企业资深工程师。主要负责PaaS平台建设、容器云的运维,对云计算以及容器技术比较擅长。


1 容器镜像OCI规范与镜像仓库

容器镜像是分层结构,如下图所示,都遵循开放容器计划Open Container Initiative(OCI)的规范(请参考https://github.com/opencontainers/image-spec),使在不同的容器运行时环境中构建的容器镜像可以自由地分发到其它的容器运行时,如,containerd、cri-o、podman,在其中正常运行,而不会有兼容性的问题。


容器镜像仓库做为企业的应用系统容器的资产仓库,同样需要兼容OCI的规范,无论容器镜像来自公共镜像仓库、Dockerfile构建、自源代码到镜像Source to image(S2I)构建,都能够正确地存储、管理和分发,保证从容器运行时环境上传与下载的容器镜像一致。在容器镜像仓库中,镜像文件也是按照分层结构单独存储,并通过依赖关系组合成一体。


2 最简的私有镜像仓库的搭建、使用和维护

2.1 公共镜像仓库

公有镜像仓库,全互联网都可以访问, 常见的如下表:

公共镜像仓库,你可以搜索到有用的镜像并拉取下来,也可以上传自己的镜像管理并分享给其他人。

2.2 私有镜像仓库

公共镜像仓库是托管并在互联网开放的服务,适合用于分享交流,但并不适合企业使用,上传和下载都受限于网速,并且经常会出现各种不确定的状况导致失败,镜像的管理也受限于托管服务。因此,企业需要自己的私有镜像仓库,做到自主可控。

2.2.1 使用Docker Registry搭建简易私有镜像仓库

首先需要一台安装好Linux (以下都以CentOS 8.2 minimal安装为例)主机,建议配置4C8G或以上,且有独立的500G以上的数据盘存储镜像文件。

假设IP为10.231.238.238, HOSTNAME为registry.twt.io,数据盘挂载在/data

运行如下命令安装:

yum install -y bash-completion curl wget httpd-tools bind-utils podmandocker-distribution

其中, docker-distribution是Docker Registry镜像仓库,podman是容器运行时,其它是工具。

生成密钥和自签证书:

注意,由于是自签证书,所有要使用镜像仓库的机器都需要配置证书的信任,或者在podman命令中通过--tls-verify=false忽略证书校验。

生成登录用户的用户名和密码的文件:

htpasswd -cBb htpasswd twttest123

用户名为twt,密码为test123,密码使用bcrypt算法

编辑/etc/docker-distribution/registry/config.yaml文件,添加或修改如下内容:

配置防火墙开放https端口:

firewall-cmd --permanent --add-service=https

firewall-cmd --reload

启动Docker Registry,并配置自动启动:

systemctl enable docker-distribution

systemctl start docker-distribution

通过如下命令检查registry是否运行正常

curl -s -k -u twt:test123https://registry.twt.io/v2/_catalog

如果返回{"repositories":[]}则表示我们搭建成功

2.2.2 使用podman运行私有镜像仓库

使用podman的好处是无须用root用户或启动系统守护进程,任意用户都可以方便地使用容器运行时。

用root用户配置防火墙开放5000端口:

firewall-cmd --permanent --add-port=5000/tcp

firewall-cmd --reload

下载Docker Registry镜像:

podman pull docker.io/library/registry:2

运行Docker Registry容器:

生成密钥、证书、用户密码文件等,请参考2.2.1中的步骤。

2.3 私有镜像仓库的使用

2.3.1 推送镜像

  • 从docker hub上拉取nginx镜像, 版本1.16.1

podmanpull nginx:1.16.1

  • 把nginx:1.16.1重新打tag为私有镜像仓库中的命名

podman images

podman tag docker.io/library/nginx:1.16.1 registry.twt.io:5000/library/nginx:1.16.1

  • 推送镜像到私有仓库

podman login -u twt -p test123 registry.twt.io:5000

podmanpush registry.twt.io:5000/library/nginx:1.16.1

  • 检查nginx镜像是否已经推送到私有镜像仓库

curl -s -k -u twt:test123 https://registry.twt.io:5000/v2/_catalog

curl -s -k -u twt:test123https://registry.twt.io:5000/v2/library/nginx/tags/list

如果分别返回

{"repositories":["library/nginx"]}

{"name":"library/nginx","tags":["1.16.1"]}

则表示推送成功

使用du命令,检查私有镜像仓库目前使用磁盘大小

du -sh data/registry/

52M/data/registry/

由于Docker Registry使用文件目录保存镜像文件,在本机的bash下也可以通过find命令查看镜像仓库中的镜像:

find data/registry -print | \

grep 'v2/repositories' | \

grep 'current' | \

grep -v 'link' | \

sed -e 's/\/_manifests\/tags\//:/' | \

sed -e 's/\/current//' | \

sed -e 's/^.*repositories\///' | \

sort

library/nginx:1.16.1

2.3.2 下载镜像

下载镜像前,先删除本地的镜像

podman rmi docker.io/library/nginx:1.16.1

podman rmi registry.twt.io:5000/library/nginx:1.16.1

podman images

下载镜像并查看本地镜像

podman login -u twt -p test123 registry.twt.io:5000

podman pullregistry.twt.io:5000/library/nginx:1.16.1

podman images

2.4 私有镜像仓库的维护

2.4.1 删除具体镜像

以上面私有仓库的镜像registry.twt.io:5000/library/nginx:1.16.1为例,如何将其从私有镜像仓库中删除?只需要如下两步

  • 首先是获取这个镜像的manifest元数据,并从镜像仓库中删除元数据

curl -k -u twt:test123 --head --silent -H "Accept: application/vnd.docker.distribution.manifest.v2+json" -X GET https://registry.twt.io:5000/v2/library/nginx/manifests/1.16.1 | grep docker-content-digest | awk '{print ($2)}'

sha256:02bab24df17e31f2795d0ac42c404d4de1312a4a745c8c46b10665cc6ad6faa2

  • 然后,将元数据从镜像仓库中删除, 返回202则表示删除成功

curl -v -k -u twt:test123 -X DELETE

https://registry.twt.io:5000/v2/library/nginx/manifests/sha256:02bab24df17e31f2795d0ac42c404d4de1312a4a745c8c46b10665cc6ad6faa2

  • 检查下是否删除成功

curl -s -k -u twt:test123https://registry.twt.io:5000/v2/library/nginx/tags/list

{"name":"library/nginx","tags":null}

  • 最后,删除这个镜像相关联的blob文件

可以看到,有6个blob被清理掉

  • 再次查看registry占用磁盘空间, 已经从52M降低到128K

du -sh data/registry/

128K data/registry/

2.4.2 自动清理私有镜像仓库的过期镜像

随着应用越来越多,镜像仓库中包含的镜像和版本也越来越多,特别是测试环境,构建次数非常多镜像版本也非常多,如何做到自动清理过期的镜像呢?

比如

  • 只保留每个镜像的最近10个版本?

  • 只保留最近1个月内的镜像版本?

  • ...

可以参考 https://github.com/burnettk/delete-docker-registry-image

或者https://github.com/andrey-pohilko/registry-cli/blob/master/registry.py


3 企业级镜像仓库

上一章我们搭建了docker registry私有镜像仓库,虽然能够配合容器云使用,但企业级的使用和维护还是不方便,主要有:

  • 缺少UI界面

  • 缺少用户管理、权限管控、行为审计

  • 无法和企业的统一登录或者LDAP对接

  • 缺少对镜像的漏洞扫描等安全防护

  • 缺少镜像其它镜像仓库的能力

  • 缺少高效的镜像文件分发能力,如,使用BT协议进行分发

  • 缺少镜像仓库的运行时监控

  • 缺少企业级的服务支持,如, bug fix、安全漏洞补丁的通知、产品升级等

  • 不适合大规模容器集群的使用,特别是跨地域的在多个数据中心进行镜像的同步

有没有可以解决上述问题的开源镜像仓库解决方案呢?

有,Harbor 和 Quay Enterprise。

3.1 Harbor

Harbor (https://goharbor.io/, https://github.com/goharbor/harbor)是vmware公司开源的企业级云原生Registry项目,包含在vmware tanzu产品中,用来存储、签名并扫描存储工件,能够提供诸如用户管理,访问控制,活动审计,和节点间的复制等一系列高级功能,可以让你迅速的搭建自己的私有镜像仓库。

Harbor扩展了DockerRegistry,并支持以下特性:

  • RBAC基于角色的权限控制

  • 基于策略的镜像复制

  • 漏洞扫描

  • LDAP/AD支持

  • 镜像删除和垃圾清理

  • Notary镜像签名

  • 用户界面

  • 审计

  • RESTful Api

  • 安装简单(基于docker-compose)

但Harbor的开源版本并没有与Kubernetes进行深度集成,不能运行在Kubernetes平台上,这也体现了VMware的策略,令人遗憾。

3.1.1 Harbor核心组件

Harbor包含如下组件

  • API Routing:他是一个nginx的前端代理,代理Harbor的registry,UI, token等服务。

  • Database:负责储存用户权限、审计日志、Dockerimage分组信息等数据。

  • Core Service:提供图形化界面,帮助用户管理registry上的镜像, 并对用户进行授权。

  • Job Service:Job Service是负责镜像复制工作的,他和registry通信,从一个registry pull镜像然后push到另一个registry,并记录job_log。

  • Admin Service:是系统的配置管理中心附带检查存储用量,ui和jobserver启动时候回需要加载adminserver的配置。

  • Registry:镜像仓库,负责存储镜像文件。

https://www.cncf.io/blog/2018/07/31/cncf-to-host-harbor-in-the-sandbox/

Creating redis ... done

Creating harbor-core ... done

Creating network "harbor_harbor" with the default driver

Creating nginx ... done

Creating registryctl ...

Creating harbor-portal ...

Creating registry ...

Creating harbor-db ...

Creating redis ...

Creating harbor-core ...

Creating nginx ...

Creating harbor-jobservice ...

3.1.2 Harbor安装

Harbor必须要基于Docker和Docker Compose安装和运行,因此必须以root权限先进行docker和 docker compose的安装。

  • 如有旧的版本,需要删除

    yum remove docker docker-common docker-selinux docker-engine
    • 安装docker ce并启动

      yum install -y yum-utils device-mapper-persistent-data lvm2
      yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
      yum -y install docker-ce docker-ce-cli containerd.iodocker-ce-selinux
      systemctl start docker && sudo systemctl enable docker
      • 下载并安装docker compose

      以下按harbor v1.10.1版本为例,进行搭建

      • 下载并解压

      • 加载Harbor v1.10.1组件的镜像

      • 修改harbor.yml 中的配置

      harbor.yml 中的hostname修改为具体IP,为了演示我们这里把https相关配置全部注释

      • 开始安装Harbor

      • 打开https://registry.twt.io 页面, 输入默认账号admin密码Harbor12345

      信任证书,继续,看到登录页面,至此Harbor搭建完毕

      3.1.3 Harbor管理和维护

      3.1.3.1 用户管理

      打开https://registry.twt.io/harbor/users页面,创建用户名readonly,密码Harbor12345的用户

      创建好用户后,可以勾选特定用户成为管理员

      3.1.3.2 项目管理

      Harbor中的仓库,新建私有项目os

      在其他机器上 使用docker login命令登录10.231.238.238 , 输入密码即可完成

      docker login -u admin registry.twt.io

      拉取镜像 nginx:1.16.1,并推送到私有镜像仓库

      docker pull nginx:1.16.1

      docker tag docker.io/library/nginx:1.16.1registry.twt.io/os/nginx:1.16.1

      docker push registry.twt.io/os/nginx:1.16.1

      我们可以从浏览器中确认 nginx:1.16.1 已经被推送到Harbor中。

      而且可以从“日志”中确认 是哪个用户在什么时间点做了什么事情。

      3.1.3.3 镜像复制同步

      在多个环境或者数据中心的情况下,多个私有镜像仓库可能会遇到某些项目需要同步一致。Harbor提供了非常友好的复制管理功能:

      • 首先,需要在仓库管理中,配置远端的镜像仓库, 比如pubreg.twt.io:5000

      • 然后在复制管理中新建规则

      • 点击“复制” 触发同步

      校验远端镜像仓库, 确认镜像已经同步

      3.2 Quay Enterprise

      quay.io是第一个使用私有存储库的托管镜像仓库。CoreOS于2014年收购了Quay,以推出首个企业级的镜像仓库。2018年CoreOS被Red Hat收购之后,Red Hat也将Quay Enterprise产品开源( https://github.com/quay/ )并持续提供企业级的支持服务。

      Quay Enterprise 也是最早支持 OCI 规范的企业级镜像仓库,与 Kubernetes 集成为 Operator 提供良好的支持,并提供以下的特性:

      • 异地复制

      • 高可用性和可扩展性

      • 安全扫描

      • 自动构建触发器

      • 时间机器image回滚(基于build版本的回退)

      • 细粒度的访问控制

      • 详细的日志和审计

      • 自动连续垃圾收集,无需停机

      • 与多个存储后端集成 (如 ceph 等)

      • 支持多种身份提供商:LDAP,OAuth,OpenStack Keystone等。

      • 加密的CLI密码

      • 洪流分布

      • 容器和应用程序注册

      • 与Quay.io保持一致的UI和代码库

      3.2.1Quay Enterprise架构

      Quay Enterprise支持各类的使用,提供了高可用的部署架构,使用对象存储保存镜像文件,通过Redis加速,使用PostgreSQL数据库保存配置和操作,通过Clair服务为镜像进行安全扫描,保障企业使用容器镜像的安全。

      3.2.2Quay Enterprise 安装和配置

      首先请确认Quay Enterprise所依赖的postgresql 10和redis 5可用。若需要部署高可用的Quay Enterprise则需要postgresql和对象存储都是高可用的部署。

      其中Postgresql的在kubernetes上的高可用部署,可以参考

      https://github.com/CrunchyData/postgres-operator 。

      对象存储可以用Ceph的RGW,Ceph本身高可用,在kubernetes上部署请参考

      https://ceph.io/community/rook-automating-ceph-kubernetes/3/ 。

      Quay Enterprise在kubernetes上的高可用部署请参考

      https://docs.projectquay.io/deploy_quay_on_openshift.html 。

      以下是在 podman 上以容器的方式运行 Quay Enterprise 的步骤。

      • 有已经运行的PostgreSQL 10和Redis 5。创建数据库quay,创建用户quay为超级用户, 为quay数据库增加pg_trgm 扩展:

      • 下载Quay Enterprise的镜像 (需要注册Red Hat开发者账户,参考https://access.redhat.com/solutions/3533201 ),并用root权限启动

      • 打开浏览器,访问https://registry.twt.io,通过页面进行配置:

      1. 输入用户名quayconfig和密码passwd登录 (用户名指定,密码是容器启动时的参数)

      2. 选择开始配置一个新的镜像仓库

      3. 配置数据库连接,Quay应用自动创建好数据库结构

      4. 设置管理员用户

      5. 对 Quay 镜像仓库进行配置

      配置CA证书

      配置企业LOGO

      配置镜像仓库服务器名称和TLS证书

      配置行为与审计日志的数据一致性

      配置过期时间,默认是两周 (2w)

      配置Redis

      配置镜像仓库的镜像同步

      配置如何存储镜像文件

      配置行为日志的存储,数据库或者ES

      配置行为日志的回旋和归档

      配置镜像安全扫描clair集成

      配置应用镜像仓库功能,支持k8s menifests, helm chart

      配置邮件服务器

      配置内部登录认证,可以是本地数据库,LDAP,或者JWT

      配置外部登录认证,如,github

      配置用户访问的功能等

      配置镜像仓库的协议,禁止docker registry v1协议

      配置从git仓库 通过dockerfile自动构建镜像

      6. 保存,配置验证通过之后下载配置

      • 停止并删除Quay Enterprise的容器,将下载的配置展开到目录,配置防火墙策略,并重启启动Quay Enterprise

      • 访问https://registry.twt.io,以admin用户登录,创建组织和仓库,并使用

      3.2.3 配置clair漏洞扫描

      • 在postgresql数据中创建名为clair的库和用户

      在/data/quay/clair-conf目录中创建clair配置文件config.yaml

      • 下载clair镜像文件并启动

      • 更新漏洞定义

      Quay Enterprise会根据镜像的版本找到对应的漏洞定义;在离线环境中,则需要手动下载漏洞定义文件并更新到clair的数据库中。

      参考

      https://access.redhat.com/documentation/en-us/red_hat_quay/3.3/html-single/manage_red_hat_quay/index#clair-sources

      下载对应的操作系统的漏洞定义。


      4 总结

      以上我们介绍的私有镜像仓库的简易搭建、日常管理和维护、企业级镜像仓库的搭建和使用,以下是几点经验总结和建议,希望对读者有帮助:

      • 私有镜像仓库最好使用域名方式,不建议使用IP方式;

      • 根据服务水平,私有镜像仓库可以多环境共用,也可以分环境独立部署,看具体的网络情况和安全要求;

      • 私有镜像仓库的高可用建设,特别是生产环境,高可用方案可以从镜像仓库运行时的高可用、底层存储的高可用等角度考虑;

      • 私有镜像仓库的基础环境镜像的保护、镜像漏洞扫描等安全管理,需要格外关注;

      • 大规模集群环境下,需要考虑拉取镜像的速度和效率,可以考虑BT方案。

      本文为容器云职业技能大赛课程,点击阅读原文可下载
      觉得本文有用,请转发、点赞或点击在看,让更多同行看到

       资料/文章推荐:




      文章转载自戏说数据那点事,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

      评论