registry

registry

Oracle Linux上运行docker registry报错

lindong 回复了问题 • 2 人关注 • 3 个回复 • 5857 次浏览 • 2017-09-30 19:23 • 来自相关话题

Docker运行的Jenkins报“ERROR: Failed to push image: failed to respond”

回复

maxwell92 回复了问题 • 1 人关注 • 1 个回复 • 3225 次浏览 • 2017-05-02 14:37 • 来自相关话题

[求助] 私有registry镜像已有层重推问题

回复

pekemon 发起了问题 • 1 人关注 • 0 个回复 • 1947 次浏览 • 2017-04-21 20:36 • 来自相关话题

容器生态系统简介

cizixs 发表了文章 • 0 个评论 • 4712 次浏览 • 2017-03-15 14:02 • 来自相关话题

原文地址:http://cizixs.com/2017/03/15/container-ecosystem。 很少有技术能够像 Docker 这样一出来就收到关注,并在很短的时间里发展壮大,而且几乎所有的技术公司都开始使用或者希望使用 ...查看全部
原文地址:http://cizixs.com/2017/03/15/container-ecosystem。

很少有技术能够像 Docker 这样一出来就收到关注,并在很短的时间里发展壮大,而且几乎所有的技术公司都开始使用或者希望使用。随着 docker 的出现,配置管理、微服务、数据中心自动化、devops 多个领域都重新焕发新机,好像 IT 行业的整个架构都要重新定义一样。

【上海站|3天烧脑式微服务架构训练营】培训内容包括:DevOps、微服务、Spring Cloud、Eureka、Ribbon、Feign、Hystrix、Zuul、Spring Cloud Config、Spring Cloud Sleuth等。

这篇文章我会介绍一下目前(2017年 3月)容器圈子(主要还是 docker) 一些主要的参与者,它们共同组成了繁荣的容器生态圈。
docker.png

容器引擎

容器引擎(Engine)或者容器运行时(Runtime)是容器系统的核心,也是很多人使用“容器”这个词语的指代对象。容器引擎能够创建和运行容器,而容器的定义一般是以文本方式保存的,比如 Dockerfile。

  • Docker Engine :目前最流行的容器引擎,也是业界的事实标准
  • Rkt:CoreOS 团队推出的容器引擎,目前处于活跃发展阶段,被 kubernetes 调度系统支持
云提供商(国外篇)容器飞速发展的时候,很多公司反应迅速,都相继推出了自己的公有云或者私有云的容器解决方案。国外比较有名的容器云提供商包括:
  • Amazon EC2 Container Serveice(ECS):云计算巨头 AWS 推出的容器服务,比较吸引人的是构建在 EC2 上面的 ECS 是免费的,用户只需要为底层的 EC2 资源付费
  • Google Container Engine(GKE):谷歌在错过大数据的福利之后,在云计算领域开始醒悟。在社区推出 kubernetes,企图制定容器调度集群的标准,而同时推出公有的 GKE 服务
  • Azure Container Service:作为巨头,微软也积极推出了容器服务,凭借积累的技术和商业资源迅速崛起
  • Jelastic
  • Docker Cloud:docker 自家的容器云服务,在收购了 Tutum 公司之后,利用 docker swarm 集群管理技术推出了方便使用的产品
云提供商(国内篇)每次新技术的出现都会催生一堆公司,有大公司也有创业公司。不管是大数据、Iaas、人工智能还是现在的容器。国内公司目前对技术已经非常敏感,追逐和使用新技术的脚步从来没有落后过。虽然现在还没有在核心技术上制定标准和掀起浪潮,但是我相信不久之后中国会出现能够影响世界的技术。目前国内做容器比较知名的公司包括:
  • 阿里云:作为国内云服务的一哥,阿里云反应迅速,和 docker 建立 官方合作,也开始为自己的容器产品布道
  • 网易蜂巢:网易在自家的 IaaS 平台成熟之后,在此之上推出了容器云服务,据说内部产品已经大都迁移到容器
  • 灵雀云:云雀科技成立于2014年,由原微软Azure云平台的核心创始团队创立
  • 时速云:tenxcloud,基于 Kubernetes 的容器云计算平台,提供公有云和企业云服务
  • 数人云:基于 mesos 研发的轻量级 Pass 平台
  • 才云:使用的是 kubernetes 方案,2015 年成立的公司,提供私有云服务和人工智能解决方案
  • daocloud:企业级应用云平台及解决方案,坐标上海
容器编排系统容器与虚拟机相比有个很大的优势就是轻量,这个特性的量变很快就引发了质变,让容器在各个技术角落施展拳脚。不过轻量级的容很容易造成混乱,面对成百上千乃至更多的容器,必须要有统一的管理平台。所以目前容器技术最热烈的激战也在这个领域,所有要使用容器的企业必须要在容器管理系统做出自己的抉择。
  • Kubernetes:Google 家开源的容器管理系统,起源于内部历史悠久的 Borg 系统。因为其丰富的功能被多家公司使用,不仅支持 docker ,还支持其他容器(比如 Rkt),但是也相对复杂,易用性差一点
  • Docker Swarm: 从 docker1.12.0 版本之后,docker 就推出了 docker swarm 模式。用户能够轻松快速搭建出来 docker 容器集群,几乎完全兼容 docker API 的特性让它很容易被用户接受。可以说潜力很大,至于最后能发展成什么样子还要时间检验
  • Mesosphere:起源于 Apache Mesos 的调度框架,目标是成为数据中心的操作系统,完全接管数据中心的管理工作
  • Rancher:其易用的界面和完全开源的特性吸引不少刚接触容器的技术人员,同时兼容 kubernetes、mesos 和 swarm 集群系统。但目前社区不是很活跃,二次开发的难度较大
  • Nomad:HashiCorp 开源的集群管理和调度系统,如果需要其他功能(比如服务发现、密码管理等)需要自己使用其他工具进行集成
容器基础镜像容器虽然轻量,但是传统的基础镜像并非如此。因此有很多企业尝试着打造专门为容器而生的操作系统,希望能成为容器时代的新选择。
  • CoreOS:以容器为中心的操作系统,配置管理、自动扩容、安全等方面有一套完整的工具
  • Project Atomic:一个轻量级的操作系统,可以运行 docker、kubernetes、rpm 和 systemd
  • Ubuntu Core:轻量级 ubuntu 操作系统,适合运行 IoT 设备或者容器集群
  • Rancher OS:只有 50M+ 的操作系统,为运行 docker 容器打造。有趣的是,它可以让系统容器和用户容器运行在不同的 Docker Daemon 上,从而实现隔离效果
  • Project Photon:VMware 开源的项目,旨在提供极简化的容器主机系统
镜像 registry镜像 registry 是存储镜像的地方,可以方便地在团队、公司或者世界各地分享容器镜像,也是运行容器最基本的基础设施。
  • Docker Registry:Docker 公司提供的开源镜像服务器,也是目前最流行的自建 registry 的方案
  • Dockerhub:docker 公司提供的公共镜像 registry,可以通过 UI 来查看和管理镜像,上面也有大量的标准镜像可以下载
  • Quay:提供镜像管理和安全检查服务的 公有 registry
  • Harbor:企业级的镜像 registry,提供了权限控制和图形界面
容器监控
  • cAdvisor:Google 开源的容器使用率和性能监控工具
  • Datadog Docker:能够收集 docker 的运行信息,并发送到 Datadog 进行分析
  • NewRelic Docker:收集 docker 的运行信息,并发送到 NewRelic 进行分析
  • Sysdig:同时提供开源版本和企业版本,能够监控容器使用率和性能,并对性能就行分析
网络容器的大规模使用,也对网络提供了更高的要求。网络的不灵活也是很多企业的短板,目前也有很多公司和项目在尝试解决这些问题,希望提出容器时代的网络方案。
  • Weave Net:weaveworks 给出的网络的方案,使用 vxlan 技术, 支持网络的隔离和安全
  • Flannel:CoreOS 开源的网络方案,为 kubernetes 设计,支持不同的后端实现
  • Calico:一个纯三层的网络解决方案,使用 BGP 协议进行路由,可以集成到 openstack 和 docker
  • Contiv: 能够打通物理机、虚拟机和容器之间连通性的网络方案
服务发现容器和微服务的结合创造了另外的热潮,也让服务发现成功了热门名词。可以轻松扩展微服务的同时,也要有工具来实现服务之间相互发现的需求。目前主要有三种工具,当然它们可能已经集成到其他的容器管理系统中。
  • etcd:CoreOS 开源的分布式 key-value 存储,通过 HTTP 协议提供服务,因此使用起来简单。但是 etcd 只是一个 key-value 存储,默认不支持服务发现,需要三方工具来集成。kubernetes 默认就使用 etcd 作为存储
  • consul:HashiCorp 开源的服务发现和配置管理工具,自带服务发现特性(DNS Server)。它是强一致性的数据存储,使用 gossip 协议形成动态集群
  • zookeeper:比较悠久的服务发现项目,起源于 Hadoop 社区,优点是成熟、可靠、功能丰富,缺点是使用 Java 开发,配置比较麻烦
参考资料

如何创建一个有密码保护的私有Docker Registry

Rancher 发表了文章 • 1 个评论 • 6695 次浏览 • 2017-02-04 09:47 • 来自相关话题

上篇文档中,我已经详细介绍了如何快速简单的部署Rancher Server,启用Github认证以及数据保持方便后续的升级操作。在这篇文档中,我将梳理下如何创建一个有密码保护的私有Docker Registry以及如何和Rancher整合。我们将下载一个容器镜 ...查看全部
上篇文档中,我已经详细介绍了如何快速简单的部署Rancher Server,启用Github认证以及数据保持方便后续的升级操作。在这篇文档中,我将梳理下如何创建一个有密码保护的私有Docker Registry以及如何和Rancher整合。我们将下载一个容器镜像,为其设置标签并推送至此Registry。最后,我们将通过Rancher Server部署此容器镜像。

虽然我建议大家使用AWS S3,但是我在此将使用registry:2,把所有的数据存放在主机本地。

我们需要提前准备如下工作:

  • 域名所对应的证书,我将使用regv2.piel.io
  • 一个兼容.htaccess的密码
我将通过letsencrypt.org以及一个Docker脚本来快速创建第一个证书。
  • 复制 git@github.com:fatk/docker-letsencrypt-nginx-proxy-companion-examples.git
  • 修改docker-letsencrypt-nginx-proxy-companion-examples/dockerdocker-run/simple-site/docker-run.sh,将site.example.com修改为你将使用的域名
  • 运行脚本
$ git clone git@github.com:fatk/docker-letsencrypt-nginx-proxy-companion-examples.git$ cd docker-letsencrypt-nginx-proxy-companion-examples# Modify the script and replace site.example.com $ vi dockerdocker-run/simple-site/docker-run.sh$ ./docker-run.sh
脚本运行后,将启动一个nginx实例,一个docker-gen实例,一个letsencrypt-nginx-proxy-companion实例以及最终的nginx实例。 我们来看下脚本运行成功后有哪些容器启动了:看上去已经成功了,但是我们刚刚创建的证书在哪儿?
$ ls volumes/proxy/certsdhparam.pem  regv2.piel.io  regv2.piel.io.crt  regv2.piel.io.dhparam.pem  regv2.piel.io.key
以及:
$ ls volumes/proxy/certs/regv2.piel.ioaccount_key.json  cert.pem  fullchain.pem  key.pem
很好,接下来我们可以将regv2.piel.io.key以及fullchain.pem用于容器registry:2. 下面我们创建registry可以访问到的证书目录
$ mkdir -p /data/docker-registry-certs$ cp volumes/proxy/certs/regv2.piel.io.key /data/docker-registry-certs/$ cp volumes/proxy/certs/regv2.piel.io/fullchain.pem /data/docker-registry-certs/$ mkdir /data/docker-registry-auth$ mkdir /data/docker-registry
最后一步,创建访问registry的用户名和密码,此为访问docker registry:2的最低安全措施配置。
$ docker run --entrypoint htpasswd registry:2 -Bbn pieltestuser \"mkakogalb47" > /data/docker-registry-auth/htpasswd
该命令要求主机上已经存在registry:2 镜像,所以在运行htpasswd命令前它会自动下载此镜像。之后,此容器会自动停止。 检查下htpasswd是否已经被创建:
$ cat /data/docker-registry-auth/htpasswdpieltestuser:$2y$05$w3IqOzTdsDbot9ls1JpeTeHYr/2vv.PTx3dObRvT.JkfGaygfTkJy
最后,运行registry:2
$ docker run -d -p 5000:5000 --restart=always --name docker-registry \  -v /data/docker-registry:/var/lib/registry \  -v /data/docker-registry-auth:/auth \  -e "REGISTRY_AUTH=htpasswd" \  -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \  -e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" \  -v /data/docker-registry-certs:/certs \  -e "REGISTRY_HTTP_TLS_CERTIFICATE=/certs/fullchain.pem" \  -e "REGISTRY_HTTP_TLS_KEY=/certs/regv2.piel.io.key" \  registry:2 $ docker run -d -p 5000:5000 --restart=always --name docker-registry \  -v /data/docker-registry:/var/lib/registry \  -v /data/docker-registry-auth:/auth \  -e "REGISTRY_AUTH=htpasswd" \  -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \  -e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" \  -v /data/docker-registry-certs:/certs \  -e "REGISTRY_HTTP_TLS_CERTIFICATE=/certs/fullchain.pem" \  -e "REGISTRY_HTTP_TLS_KEY=/certs/regv2.piel.io.key" registry:2
我们试一下是否可以登陆:
$ docker login -u pieltestuser -p "mkakogalb47" -e wayne@wayneconnolly.com regv2.piel.io:5000$ docker login -u pieltestuser -p "mkakogalb47" -e wayne@wayneconnolly.com regv2.piel.io:5000WARNING: login credentials saved in /root/.docker/config.jsonLogin Succeeded
接下来我们试下是否可以下载、标记、上传容器镜像至我们的新镜像仓库。例如,下载一个jenkins https://hub.docker.com/_/jenkins/
$ docker pull jenkins$ docker tag jenkins:latest regv2.piel.io:5000/piel-jenkins:latest
验证下是否可用 很好,上传到我们的镜像仓库。
$ docker push regv2.piel.io:5000/piel-jenkins:latest
直到写这篇文章的时候,除了用Curl,还没有很好的方法可以直接看到镜像库中的镜像列表
$ curl -u pieltestuser:mkakogalb47 https://regv2.piel.io:5000/v2/_catalog{"repositories":["piel-jenkins"]}
可以通过JSON看到我们的新Jenkins镜像在我们的私有镜像库中 现在可以在我们的Rancher-test.piel.io环境中应用我们的registry了。 登陆Rancher,在基础架构 > 主机中点击添加主机。 将自动生成的命令在Rancher Host上运行。
$ sudo docker run -e CATTLE_AGENT_IP='45.32.190.15'  \  -d --privileged \  -v /var/run/docker.sock:/var/run/docker.sock \  -v /var/lib/rancher:/var/lib/rancher \  rancher/agent:v1.0.1 http://rancher-test.piel.io/v1/scripts/FF42DCE27F7C88BD7733:1461042000000:ryU0BaXJFo6c9zuHgeULdAtbCE$ sudo docker run -d --privileged \  -v /var/run/docker.sock:/var/run/docker.sock \  -v /var/lib/rancher:/var/lib/rancher \   rancher/agent:v0.11.0http://rancher.piel.io/v1/scripts/BE455B92EA48EA1C1F12:1461042000000:mi433ChYRN9nfQSwB2FIlBnpPk
一两分钟后主机将在Rancher管理界面中出现。由于我还没有配置主机信息,主机显示名称依然为“vultr.guest”, 我们可以通过菜单修改主机名称并添加标签。 接下来,我们添加私有registry并在新增加的主机上部署Jenkins。 在基础架构菜单 > 镜像库中点击“添加镜像库”,并选择自定义,添加相应的信息完成配置。 几分钟之后,Rancher server的私有镜像仓库就可以使用了。 下面让我们部署Jenkins容器。在基础架构 > 容器菜单中,点击“添加容器” 填写所需信息,在选择image一处输入regv2.piel.io:5000/piel-jenkins: latest并设置端口映射为Jenkins 8080到主机的80端口。 此处将需要一点时间下载镜像。 下面我们将看到我们又一个容器叫做“my-jenkins”已经启动了。 访问到Jenkins URL,http://regv2.piel.io。 通过docker ps再确认一次: 成功!我们现在已经完成了:
  • 创建并加密了我们自己的私有镜像库
  • 添加并标记了一个容器镜像
  • 为Rancher Server添加了一个主机
  • 为Rancher Server增加了一个私有镜像库
  • 在主机上部署了一个Jenkins容器
  • 确认容器已经部署成功


注意:在本教程中使用的服务器现在已经退役啦。



原文来源:Rancher Labs

registry v2 删除镜像后,catalog仍然可以看到,如何解决

braveht 回复了问题 • 3 人关注 • 3 个回复 • 3014 次浏览 • 2016-12-07 13:38 • 来自相关话题

VMware Harbor:基于 Docker Distribution 的企业级 Registry 服务

Rancher 发表了文章 • 2 个评论 • 4851 次浏览 • 2016-12-06 08:12 • 来自相关话题

原文来源:Rancher Labs 前言 对于 Harbor 这样一个优秀的 Docker Registry 管理开源项目,以下内容基本上来自前人已有的研究,我只是将其在实践中进行了测试,并整理汇集了相关资料 ...查看全部
原文来源:Rancher Labs

前言

对于 Harbor 这样一个优秀的 Docker Registry 管理开源项目,以下内容基本上来自前人已有的研究,我只是将其在实践中进行了测试,并整理汇集了相关资料供大家参考,同时针对 Harbor 与 Rancher产品的整合做了一些实验性的工作,以更好更全面的理解 Harbor 这个工具,也更加了解 Rancher 在快速一键部署、弹性伸缩高可用等方面的优势。

Harbor 简介

Harbor 是一个企业级 Registry 服务。它对开源的 Docker Registry 服务进行了扩展,添加了更多企业用户需要的功能。Harbor 被设计用于部署一套组织内部使用的私有环境,这个私有 Registry 服务对于非常关心安全的组织来说是十分重要的。另外,私有 Registry 服务可以通过避免从公域网下载镜 像而提高企业生产力。这对于没有良好的 Internet 连接状态,使用 Docker Container 的用户是一个福音。

  • 基于角色的访问控制:用户与 Docker 镜像仓库通过“项目”进行组织管理,一个用户可以对多个镜像仓库在同一命名空间(project)里有不同的权限。
  • 图形化用户界面:用户可以通过浏览器来浏览,检索当前 Docker 镜像仓库,管理项目和命名空间。
  • 审计管理 :所有针对镜像仓库的操作都可以被记录追溯,用于审计管理。
  • 国际化:基于英文与中文语言进行了本地化。可以增加更多的语言支持。
  • RESTful API - RESTful API :提供给管理员对于 Harbor 更多的操控, 使得与其它管理软件集成变得更容易。
Harbor 架构介绍 #(1)主要组件Harbor 在架构上主要由五个组件构成:
  • Proxy:Harbor 的 registry, UI, token 等服务,通过一个前置的反向代理统一接收浏览器、Docker 客户端的请求,并将请求转发给后端不同的服务。
  • Registry:负责储存 Docker 镜像,并处理 docker push/pull 命令。由于我们要对用户进行访问控制,即不同用户对 Docker image 有不同的读写权限,Registry 会指向一个 token 服务,强制用户的每次 docker pull/push 请求都要携带一个合法的 token, Registry 会通过公钥对 token 进行解密验证。
  • Core services:这是 Harbor 的核心功能,主要提供以下服务:
UI:提供图形化界面,帮助用户管理 registry 上的镜像(image),并对用户进行授权; webhook:为了及时获取 registry 上 image 状态变化的情况, 在 Registry 上配置 webhook,把状态变化传递给 UI 模块; token 服务:负责根据用户权限给每个 docker push/pull 命令签发 token。Docker 客户端向Registry 服务发起的请求,如果不包含 token,会被重定向到这里,获得 token 后再重新向 Registry进行请求;
  • Database:为 core services 提供数据库服务,负责储存用户权限、审计日志、Docker image 分组信息等数据。
  • Log collector:为了帮助监控 Harbor 运行,负责收集其他组件的 log,供日后进行分析。各个组件之间的关系如下图所示:
#(2)实现Harbor 的每个组件都是以 Docker 容器的形式构建的,因此很自然地,我们使用 Docker Compose 来对它进行部署。在源代码中 (https://github.com/vmware/harbor),用于部署 Harbor 的 Docker Compose 模板位于 /Deployer/docker-compose.yml. 打开这个模板文件,会发现 Harbor 由 5 个容器组成:
  • proxy:由 Nginx 服务器构成的反向代理。
  • registry:由 Docker 官方的开源 registry 镜像构成的容器实例。
  • ui:即架构中的 core services, 构成此容器的代码是 Harbor 项目的主体。
  • mysql:由官方 MySql 镜像构成的数据库容器。
  • log: 运行着 rsyslogd 的容器,通过 log-driver 的形式收集其他容器的日志。
这几个容器通过 Docker link 的形式连接在一起,这样,在容器之间可以通过容器名字互相访问。对终端用户而言,只需要暴露 proxy (即 Nginx)的服务端口。#(3)工作原理下面以两个 Docker 命令为例,讲解主要组件之间如何协同工作。 1) docker login假设我们将 Harbor 部署在主机名为 registry.yourdomainname.com 的虚机上。用户通过 docker login 命令向这个 Harbor 服务发起登录请求:docker login registry.yourdomainname.com当用户输入所需信息并点击回车后,Docker 客户端会向地址“registry.yourdomainname.com/v2/” 发出 HTTP GET 请求。 Harbor 的各个容器会通过以下步骤处理:(a) 首先,这个请求会由监听 80 端口的 proxy 容器接收到。根据预先设置的匹配规则,容器中的 Nginx会将请求转发给后端的 registry 容器;(b) 在 registry 容器一方,由于配置了基于 token 的认证,registry 会返回错误代码 401,提示 Docker客户端访问 token 服务绑定的 URL。在 Harbor 中,这个 URL 指向 Core Services;(c) Docker 客户端在接到这个错误代码后,会向token服务的URL发出请求,并根据HTTP协议的BasicAuthentication 规范,将用户名密码组合并编码,放在请求头部(header); (d)类似地,这个请求通过 80 端口发到 proxy 容器后,Nginx 会根据规则把请求转发给 ui 容器,ui 容器监听 token 服务网址的处理程序接收到请求后,会将请求头解码,得到用户名、密码;(e) 在得到用户名、密码后,ui 容器中的代码会查询数据库,将用户名、密码与 mysql 容器中的数据进行比对(注:ui 容器还支持 LDAP 的认证方式,在那种情况下 ui 会试图和外部 LDAP 服务进行通信并校验用户名/密码)。比对成功,ui 容器会返回表示成功的状态码, 并用密钥生成 token,放在响应体中返回给 Docker 客户端。这个过程中组件间的交互过程如下图所示:至此,一次 docker login 成功地完成了,Docker 客户端会把步骤(c)中编码后的用户名密码保存在本地的隐藏文件中。 2) docker push用户登录成功后用 docker push 命令向 Harbor 推送一个 Docker 镜像:docker push registry.youdomainname.com/library/hello-world(a) 首先,docker 客户端会重复 login 的过程,首先发送请求到 registry,之后得到 token 服务的地址;(b) 之后,Docker 客户端在访问ui容器上的token服务时会提供额外信息,指明它要申请一个对imagelibrary/hello-world 进行 push 操作的 token;(c) token 服务在经过 Nginx 转发得到这个请求后,会访问数据库核实当前用户是否有权限对该 image进行 push。如果有权限,它会把 image 的信息以及 push 动作进行编码,并用私钥签名,生成 token返回给 Docker 客户端;(d) 得到 token 之后 Docker 客户端会把 token 放在请求头部,向 registry 发出请求,试图开始推送image。 Registry 收到请求后会用公钥解码 token 并进行核对,一切成功后,image 的传输就开始了。我们省去 proxy 转发的步骤,下图描述了这个过程中各组件的通信过程 :Harbor 单机安装调试步骤此次示范以 CentOS 7.2.1511 x86_64 为例:
[root@registry ~]# yum install https://yum.dockerproject.org/repo/main/centos/7/Packages/docker-engine-selinux-1.11.2-1.el7.centos.noarch.rpm[root@registry ~]# yum install https://yum.dockerproject.org/repo/main/centos/7/Packages/docker-engine-1.11.2-1.el7.centos.x86_64.rpm[root@registry ~]# systemctl enable docker[root@registry ~]# systemctl start docker[root@registry ~]# yum install git[root@registry ~]# git clone https://github.com/vmware/harbor[root@registry ~]# cd harbor/[root@registry harbor]# cd Deploy/[root@registry Deploy]# vi harbor.cfg
修改的重点内容如下:
hostname = registry.yourdomainname.comui_url_protocol = httpsemail_server = smtp.yourmailserver.comemail_server_port = 25email_username = registry_admin@yourdomainname.comemail_password = yourpasswordemail_from = registry_admin@yourdomainname.comemail_ssl = falseharbor_admin_password = myharborpasswordauth_mode = db_authdb_password = yoursqlpasswordself_registration = offcustomize_crt = off
修改完成假设已经准备好站点的数字证书文件 registry.yourdomainname.com.crt 和registry.yourdomainname.com.key,则可以配置 https 的访问模式:
[root@registry Deploy]# cd config/nginx/[root@registry nginx]# ls cert/registry.yourdomainname.com.crt registry.yourdomainname.com.key[root@registry nginx]# mv nginx.conf nginx.conf.bak[root@registry nginx]# cp nginx.https.conf nginx.conf[root@registry nginx]# vi nginx.conf
修改内容如下:修改内容结束安装 docker-compose 命令:添加 harbor 的启停脚本: 添加 harbor 为 systemd 服务:管理 Harbor 的生命周期:关于数字证书,上面的描述适用于向第三方根证书颁发机构申请得到的数字证书文件,如果是自签名数字证书,可参考 Harbor 官方文档:https://github.com/vmware/harbor/blob/master/docs/configure_https.md访问 Harbor:[list=1]
  • 网页访问方式 https://registry.yourdomainname.com
  • [list=1]
  • Linux Docker 客户端如需要访问这个仓库服务器,如果数字证书的根证书颁发机构不在系统列表里,则需要手动添加信任关系(需要将证书文件 registry.yourdomainname.com.crt 拷贝至指定目录),然后更新证书缓存:


  • cp registry.yourdomainname.com.crt /usr/local/share/ca-certificates/update-ca-certificates



    以上两条命令适用于 Ubuntu 系列


    cp registry.yourdomainname.com.crt /etc/pki/ca-trust/source/anchors/update-ca-trust



    以上两条命令适用于 RHEL 或 CentOS 系列

    登陆及 push image 过程:


    [root@RancherHost01 ~]# docker login
    registry.yourdomainname.com
    Username: admin
    Password:
    Login Succeeded
    [root@RancherHost01 ~]#




    登陆 Web 端即可看见已经上传的 image 了:



    新增用户界面:



    Harbor 作为 Mirror Registry

    Mirror 是 Docker Registry 的一种特殊类型,它起到了类似代理服务器的缓存角色,在用户和Docker Hub 之间做 Image 的缓存。

    其基本工作原理是,当用户 pull 一个镜像时,若镜像在 mirror 服务器存在,则直接从 mirror 服务器拉取,否则若不存在该镜像,则由 mirror server 自动代理往 dockerhub(可配置)中拉取镜像,并缓存到 mirror 服务器中,当客户再次拉取这个镜像时,直接从 mirror server 中拉取,不需要再次从docker hub 中拉取。

    Harbor 目前不支持 pull cache 功能,已提交 Github issue #120。
    https://github.com/vmware/harbor/issues/120

    不过我们只需要手动修改下配置即可完成,具体配置可查看官方 Registry as a pull through cache.
    https://github.com/vmware/harbor/commit/5e3d3afb1184b91c7aaac8618cc5ca1a5fe85bc7

    我们在运行./prepare 之前修改 config/registry/config.yml 文件,追加以下配置


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


    如果需要访问私有仓库,需要填写 Docker Hub 的用户名和密码


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


    然后重新启动 Harbor 服务:(注意不要执行./prepare)


    docker-compose stop
    docker-compose rm -f
    docker-compose up -d


    除了设置 Harbor(或者 registry),还需要配置本地 docker 服务,指定--registry-mirror 参数,修改docker 配置文件


    Ubuntu:/etc/default/docker

    DOCKER_OPTS="$DOCKER_OPTS --registry-mirror=https://registry.yourdomainname.com





    DOCKER_OPTS="$DOCKER_OPTS --registry-mirror=https://registry.yourdomainname.com --insecure-registry

    registry.yourdomainname.com"


    或者


    RHEL/CentOS:/usr/lib/systemd/system/docker.service):
    [Service]
    ExecStart=
    ExecStart=/usr/bin/docker daemon -H fd:// --registry-mirror=https://registry.yourdomainname.com


    注意:修改了 docker 配置文件,必须重启 docker 服务才能生效。



    Harbor 由于引进了认证功能,因此 push 操作时,必须保证 project 存在,比如 push krystism/ffmpeg,必须保证 Harbor 创建了 krystism project,否则会失败。为了能够正常 push/pulldockerhub 的官方镜像,务必创建 library project,如图:




    #(1)假设本地不存在 python 镜像:

    我们第一次 pull python 后,Harbor 发现不存在该镜像,于是自己作为代理往 Docker Hub 里拉取,拉取后保存到本地,可以通过 Web UI 查看。客户端再次拉取 python 镜像时,由于 Harbor 已经存在该镜像,因此不需要再往 Docker Hub 拉取,速度大幅度提高!

    注意,对于 Mirror Registry 模式,虽然可以 pull cache 了,但是 push 功能却不被支持了:https://github.com/vmware/harbor/issues/220

    #(2)与 Rancher 的整合:

    1)Add Harbor deploy stack and 5 services in Rancher: (在 Rancher 系统里添加包含 5 个 services 的stack)



    2)Add Registry server in Rancher: (在 Rancher 系统里添加 Registry 服务器,供 Rancher Agent Hosts调用)



    3)Build a Catalog entry in Rancher:(为 Harbor 创建一个 Rancher 专有的应用模板项,实现一键部署,使安装调试复杂的 Harbor 产品简单化、并实现弹性伸缩及高可用等特性)



    #(3)对接 LDAP 认证:

    Harbor 支持两种认证方式,默认为本地存储,即账号信息存储在 mysql 下,上文已经具体介绍。接下来介绍另外一种认证方式 LDAP,只需要修改配置文件即可。需要提供 ldap url 以及 ldap basedn 参数,并且设置 auth_mode 为 ldap_auth。

    快速部署 LDAP 服务:

    为了测试方便,我们使用 Docker 启动一个 LDAP 服务器,启动脚本如下:


    !/bin/bash
    NAME=ldap_server
    docker rm -f $NAME 2>/dev/null
    docker run --env LDAP_ORGANISATION="Unitedstack Inc." \--env LDAP_DOMAIN="ustack.com" \
    --env LDAP_ADMIN_PASSWORD="admin_password" \
    -v pwd/containers/openldap/data:/var/lib/ldap \
    -v pwd/containers/openldap/slapd.d:/etc/ldap/slapd.d \--detach --name $NAME osixia/openldap:1.1.2


    创建新用户,首先需要定义 ldif 文件,


    new_user.ldif:dn: uid=test,dc=ustack,dc=com
    uid: test
    cn: test
    sn: 3
    objectClass: topobjectClass: posixAccountobjectClass: inetOrgPersonloginShell: /bin/bashhomeDirectory:

    /home/testuidNumber: 1001gidNumber: 1001userPassword: 1q2w3e4rmail: test@example.comgecos: test


    通过以下脚本创建新用户,其中 ldap_server 为 LDAP 服务容器名称。


    docker cp new_user.ldif ldap_server:/
    docker exec ldap_server ldapadd -x \
    -D "cn=admin,dc=ustack,dc=com" \
    -w admin_password \-f /new_user.ldif -ZZ


    查看用户是否创建成功:


    docker exec ldap_server ldapsearch -x -h localhost \
    -b dc=ustack,dc=com -D "cn=admin,dc=ustack,dc=com" \
    -w admin_password


    检查 test 用户是否存在,若存在,则说明创建成功,否则需要使用 docker logs 查看日志。

    配置 Harbor 使用 LDAP 认证
    修改 harbor.cfg 文件关于 LDAP 配置项,如下


    :auth_mode = ldap_auth
    ldap_url = ldap://42.62.x.x
    ldap_basedn = uid=%s,dc=ustack,dc=com


    然后重新部署 Harbor:


    ./prepare
    docker-compose stop
    docker-compose rm -f
    docker-compose up -d


    测试是否能够使用 test 用户登录:


    docker login -u test -p 1q2w3e4r \
    -e test@example.com 42.62.x.x

    SUSE Portus + Docker Registry在Rancher环境下的部署实战

    Rancher 发表了文章 • 1 个评论 • 2179 次浏览 • 2016-12-02 09:51 • 来自相关话题

    原文来源:Rancher Labs 在正文之前,我们先来看一下,如果没有容器,通常会如何部署 Docker Registry?关于这个问题,我简单画了一个草图: 下面简单解释一下 ...查看全部
    原文来源:Rancher Labs

    在正文之前,我们先来看一下,如果没有容器,通常会如何部署 Docker Registry?关于这个问题,我简单画了一个草图:



    下面简单解释一下:

    Nginx:用来做 Docker Registry 的代理和软件负载均衡Keepalived 采用主备加虚拟 IP 的方式,解决 Nginx 的单点问题,保证 Nginx 服务的高可用性。

    Docker Registry:这是 Docker 官方开源的私有镜像仓库项目,对应 github 上的 docker-distribution 项目,也是私有镜像仓库的核心。

    Redis:大名鼎鼎的 Key-Value 数据库,很多应用场景中,将其作为缓存使用。在 Docker Registry中也不例外,用来缓存 Docker Image 的 laryer metadata,带来的好处即是 laryer metadata 的快速访问。

    Storage Cluster Docker Registry:以存储驱动的方式支持多种后端存储。例如:Docker Registry2.3 目前支持如下的存储驱动:



    这里简单做个补充,官方文档也有介绍如何贡献新的 Docker Registry 存储驱动。

    下面我们来看一下,在 Rancher 环境下,一个简化版 Docker Registry 的部署结构图,如下图所示:



    这个图是以 Rancher 下服务的视角画的,部署这样一个简单的 Docker Registry,需要四个服务,分别是外部存储服务、Redis Cache 服务、Docker Registry 服务和负载均衡服务。用户访问 Docker Registry 通过使用负载均衡服务的IP和端口。Docker Registry 的负载均衡服务,需要做源 IP会话保持配置。

    到此为止,我们就在 Rancher 环境下部署了一个简化版的 Docker Registry 服务。至于我为什么说其是简化版呢?是因为现在这个版本存在一些问题。

    首先,Docker Registry 本身没有 Web UI,镜像的检索,只能通过命令行工具完成,使用起来非常不方便。

    其次,Docker Registry 自身没有基于角色权限访问控制,所有可以访问负载均衡服务的用户都能随意的推送和拉取镜像。

    最后,Docker Registry 本身是提供了基于 token 的认证机制,需要接入 Authorization Service,这个服务官方没有实现,需要我们自己实现或者借助开源实现。

    SUSE Portus 完美地解决了上述问题。下面我们看一下,在 Rancher 环境下加入 SUSE Portus的服务结构图:



    Portus Core Cluster 服务负责给 Docker Registry 提供 token 认证服务和接收 Docker Registry 发送的镜像推送的通知,同步 Docker Registry 中的镜像信息到 SUSE Portus 的数据库中。该服务本身无状态,可以水平扩展PortusCronSync负责定时请求DockerRegistryAPI 同步镜像数据到SUSEPortus的数据库中。

    当用户向 Docker Registry 推送一个镜像后,Docker Registry 会发送通知给 SUSE Portus,如果网络闪断,或者 SUSE Portu 服务中断,会做有限次数的重试。这样可能会导致 SUSE Portu 无法收到镜像推送的通知,造成两端数据的不一致。Portus Cron Sync 就是为了解决这个问题而存在的。

    SUSE Portus 的 token 认证服务完全满足官方的认证模型,Docker 官方的认证模型如下图所示:



    Docker Registry 关于认证服务的配置和通知目标服务的配置,都在 Docker Registry 容器的/etc/docker/registry/config.yml 中:




    最后,我们可以按照 Rancher Catalog 的规范,制作一些基础镜像,然后把这个服务 Catalog化,做成一键部署。

    docker registry的ui界面,harbor和Portus哪个好

    clouding 回复了问题 • 6 人关注 • 4 个回复 • 7133 次浏览 • 2016-09-23 16:35 • 来自相关话题

    harbor使用中,利用私有镜像库做mirror registry 报 405 78 错误

    kilisky 回复了问题 • 4 人关注 • 3 个回复 • 4188 次浏览 • 2016-08-14 07:41 • 来自相关话题

    条新动态, 点击查看
    jamlee

    jamlee 回答了问题 • 2014-12-15 15:34 • 9 个回复 不感兴趣

    docker-registry 的搭建

    赞同来自:

    经过尝试,在我的<strong>客户端</strong>运行: ``` docker -d ----insecure-registry 10.0.1.44:5000 ``... 显示全部 »
    经过尝试,在我的<strong>客户端</strong>运行: ``` docker -d ----insecure-registry 10.0.1.44:5000 ``` 成功,问题完美解决。

    Windows的Docker Beta版本

    绝地魔影 发表了文章 • 0 个评论 • 5757 次浏览 • 2016-04-25 22:37 • 来自相关话题

    【编者的话】本文为Docker Saigon社区于其官方网站中发布的文章Docker For Windows Beta,此文描述了在Windows上的Docker Beta版本的一些功能,并且做了演示。Docker Saigon社区是由越南的Docker社区用 ...查看全部
    【编者的话】本文为Docker Saigon社区于其官方网站中发布的文章Docker For Windows Beta,此文描述了在Windows上的Docker Beta版本的一些功能,并且做了演示。Docker Saigon社区是由越南的Docker社区用户创建的,位于胡志明市。

    @Container容器技术大会将于6月4日在上海光大会展中心国际大酒店举办,来自Rancher、携程、PPTV、蚂蚁金服、京东、浙江移动、海尔电器、唯品会、eBay、道富银行、麻袋理财、土豆网、阿里百川、腾讯游戏、数人云、点融网、华为、轻元科技、中兴通讯等公司的技术负责人将带来实践经验分享,5月7日之前购票只需438元,欢迎感兴趣的同学抢购。

    注释:这篇文章的研究已在Beta客户端完成了,并且技术细节有可能发生变化。

    正如之前发布的帖子描述的那样,我们已经在Windows的Hyper-V上使用Docker有一阵子了。听说了新的Windows的Docker客户端是基于Alpine的,并且会专注于Hyper-V,这使得我们很渴望亲眼看一看。

    Hyper-V 配置
    第一个要克服的问题是当在Windows上使用Hyper-V时缺乏DNS/DHCP和NAT服务。新的Docker客户端为我们接管虚拟交换机的NAT配置并且为DNS与DHCP添加了一个很巧妙的解决方案。

    作为安装过程的一部分,将创建一个内部DockerNAT虚拟交换机,并且该Windows主机上的虚拟接口将会为这个虚拟交换机获得一个静态IP:
    New-VMSwitch -Name "DockerNAT" -SwitchType Internal
    Get-NetAdapter "vEthernet (DockerNAT)" | New-NetIPAddress -AddressFamily IPv4 `
    -IPAddress "10.0.75.1" -PrefixLength 24


    同时,也创建了一个为“10.0.75.0/24”子网提供网络地址转换(Network Address Translation)的NAT对象。
    New-NetNat –Name $SwitchName `
    –InternalIPInterfaceAddressPrefix "10.0.75.0/24"


    提示: 如果有任何的步骤失败了,须确保名为“DockerNAT”的交换机是被创建的,并且IP已经被分配给了该虚拟接口(Virtual Interface)的。此外通过Get-NetNat命令所显示的NAT是属于正确的子网内的。同时要确保物理网络与现有存在的接口不重叠(我们已经在测试beta版本的时候手动地将这些问题修复了)。
    接下来,MobyLinuxVM虚拟机已经在Hyper-V里建立起来了。MobyLinuxVM使用Alpine bootcd集成的Hyper-V服务,例如Key-Value Pair Exchange服务(hv_kvp_daemon)。Hyper-V KVP的守护进程允许Hyper-V和Linux客户机之间通信(例如检索客户IP和发送双向的消息,这我们将在后面看到)。
    最终,Docker捆绑了com.docker.proxy.exe源代码,它代理了在Windos主机上的MobyLinuxVM端口。在写该文的时候(Docker Beta 7),它已经包含了DNS(TCP/UDP 53),DHCP(UDP 67)和Docker 守护进程(TCP2375)。
    如果你一直在为你的Hyper-V配置运行一个替代解决方案,那么需要确保以上所有端口是可用的,如下所示。

    查看是否有任何进程在占用53端口:
    netstat -aon | findstr :53

    一旦你发现任何进程号再占用该端口(),那么先获取进程名:
    tasklist /SVC | findstr 

    com.docker.proxy.exe将会把你笔记本内部网络所有的DNS请求通过Windows主机代理到DNS服务器上,当你移动你的笔记本的时候可以有效地从网络配置上隔离MobyLinuxVM。
    为了确保该进程工作正常,docker自动地创建了DockerTcp和DockerUdp防火墙规则,并且可以在我们关闭客户端的时候移除它。
    New-NetFirewallRule -Name "DockerTcp" -DisplayName "DockerTcp"  `
    -Program "C:\\\com.docker.proxy.exe" -Protocol TCP `
    -Profile Any -EdgeTraversalPolicy DeferToUser -Enabled True

    New-NetFirewallRule -Name "DockerUdp" -DisplayName "DockerUdp" `
    -Program "C:\\\com.docker.proxy.exe" -Protocol UDP `
    -Profile Any -EdgeTraversalPolicy DeferToUser -Enabled True

    Docker的守护进程在本地打开,允许你的docker客户端与本地主机通信,可是-它看起来在使用一个命名管道的方案去替代它, 如果该VM被正确地创建, 那么你应该看到连接到其COM口的命名管道。
    那么同样也可以看到docker客户端代码在处理Windows命名管道
    Get-VMComPort -VMName MobyLinuxVM | fl | Out-String

    如果MobyLiunxVM正常地启动,我们就应该可以确认Hyper-V集成服务是在运行着的。
    Get-VMIntegrationService -VMName MobyLinuxVM -Name "Key-Value Pair Exchange"

    并且com.docker.proxy.exe的DHCP服务提供了一个到VM的IP,通过该IP我们可以查询Hyper-V集成服务:
    $(Get-VM MobyLinuxVM).NetworkAdapters[0]

    排错
    所有的配置都放在%APPDATA%\Docker\文件夹下面,当漫游设置开启的时候,这个文件夹被复制在该主机的企业设置中。
    所有日志存放在%LOCALAPPDATA%\Docker\文件夹下面。
    可以通过如下PowerShell脚本去监控最新的日志:
     gc $(gi $env:LocalAppData\Docker\* | sort LastAccessTime -Desc | select -First -
    1) -Wait

    一旦有事件写入日志文件将会被自动刷新。
    Docker ToolBox 迁移
    在Windows上切换至Hyper-V角色的话将会关闭VirtualBox(其实直到你关闭Hypver-V并重启之前都不可能用Docker ToolBox)。
    如果检测到Docker Toolbox已经安装了,那么会提供一个整合路径(基于qemu-img方式的)。这将会把%USERPROFILE%\.docker\machine\machines\\disk.vmdk路径下的磁盘转换成vhdx格式:
    qemu-img.exe convert  -O vhdx -o subformat=dynamic 
    -p "C:\Users\Public\Documents\Hyper-V\Virtual hard disks\MobyLinuxVM.vhdx\"

    如果你已经通过Hyper-V使用Docker-Machine和Docker-Compose了,你也可以同时用Docker的Windows客户端这么做一遍。
    挂载卷
    基于Windows下的Docker的其中一个较大的改进是承诺的卷如何挂载的问题。
    一个便利的对话框模式提供了我们所需要的一切。

    beta7-shares.png


    目前的改进将是共享整个存储(不包括单独的文件夹)。开启共享的时候需要提供凭据。
    凭据信息伴随着“Docker Host Filesystem Access”目标被存储在了Windows > Control Panel > Credential Manager > Windows Credentials Store路径下,这是通过System.Security.Cryptography随着当前用户进行加密的。
    如果凭据管理器已经包含了指定的目标凭据,他们将被覆盖。
    接下来,可以看到存储器被共享在了Windows主机上:
    net share C=C:\ /grant:,FULL /CACHE:None

    Samba的共享方式现在将会被挂载到MobyLinuxVM上,并且会通过Hyper-V的Key-Value交换服务进行自动操作。这里是细节方面的解释
    工作方式应该像下面描述的那样:Windows主机将一个mount authentication token令牌打包放进了VMBus中的KvpExchangeDataItem类里:
    class Msvm_KvpExchangeDataItem : CIM_ManagedElement
    {
    uint16 Source = 0;
    string Name = "cifsmount";
    string Data = "authToken";
    };

    认证令牌是包含挂载点和安装选项的序列化的字符串:
    /c;/C;username=,password=,noperm

    在Alpine上,是hv_utils核心驱动模块通知hv_kvp_daemon。这个守护进程把kvp写进了池文件里(/var/lib/hyperv/.kv_pool_**)。
    此时,MobyLinuxVM需要构建一个目录,并且从主机上挂载该共享目录-但是这一次写入的时候是失败了的:
    #for both upper and lower case
    mount -t cifs //10.0.75.1/C /C -o username=,
    password=,noperm

    如果共享是工作正常的,那么我们的docker客户端将会经由com.docker.proxy.exe通过开启的端口发送任何卷的挂载信息,该代理会在需要的时候重写该路径:例如C:\Users\test\变成/C/Users/test,这可以让我们把Windows的目录挂载到我们的Docker容器中。
    然而,由于SMB协议的原因(缺少inotify和symlinks的支持)使得我们这么做这仍然会有限制,这将会导致实时重置。
    排错:我们可以通过以下的PowerShell脚本来验证令牌是否存在:
    $VmMgmt = Get-WmiObject -Namespace root\virtualization\v2 
    -Class ` Msvm_VirtualSystemManagementService
    $vm = Get-WmiObject -Namespace root\virtualization\v2
    -Class ` Msvm_ComputerSystem -Filter {ElementName='MobyLinuxVM'}

    ($vm.GetRelated("Msvm_KvpExchangeComponent")[0] `
    ).GetRelated("Msvm_KvpExchangeComponentSettingData").HostExchangeItems | % { `
    $GuestExchangeItemXml = ([XML]$_).SelectSingleNode(`
    "/INSTANCE/PROPERTY[@NAME='Name']/VALUE[child::text() = 'cifsmount']")

    if ($GuestExchangeItemXml -ne $null)
    {
    $GuestExchangeItemXml.SelectSingleNode(`
    "/INSTANCE/PROPERTY[@NAME='Data']/VALUE/child::text()").Value
    }
    }

    目前为止,我还没有弄清楚在Alpine主机上是由哪个进程去监控var/lib/hyperv/.kv_pool_0这个文件的。
    私有仓库
    现在的Windows Beta版本目前还不支持DOCKER_OPTS和TLS证书。
    像下面一样,我们可以获得到MobyLinuxVM的根账号访问权限:
    #get a privileged container with access to Docker daemon
    docker run --privileged -it --rm
    -v /var/run/docker.sock:/var/run/docker.sock
    -v /usr/bin/docker:/usr/bin/docker alpine sh

    #run a container with full root access to MobyLinuxVM and no seccomp profile
    (so you can mount stuff)
    docker run --net=host --ipc=host --uts=host --pid=host -it
    --security-opt=seccomp=unconfined --privileged
    --rm -v /:/host alpine /bin/sh

    #switch to host FS
    chroot /host

    闲逛该VM的时候发现了下面的一些东西:
    这个基于Alpine的VM使用OpenRC作为它的初始化系统
    rc-status

    显示所有的服务状态的时候,我们会发现一些定义的脚本并没有部署状态,并且显示是“崩溃的”,尽管这些进程看起来其实是运行的(ps -a)。
    Docker初始化脚本依赖于/usr/bin/mobyconfig脚本。该脚本要求内核伴随着com.docker.database标签定义的文件配置的位置启动。如果该标签存在-/Database使用 Docker for Mac的原始文件系统Plan 9 Filesystem Protocol挂载。
    mobyconfig可以检索网络并且为Docker守护进程取消加密,或者从/etc/docker/daemon.json中获取配置文件。一旦全面实施,将会是一个很有前景的解决方案。
    由于整个磁盘是一个只有/var/固定挂载点的临时文件的系统是固定存在的(挂载到/dev/sda2),更改的任何脚本在重新引导时不会持续运行。这将可以临时改变Docker选项并且通过/etc/init.d/docker restart命令重启守护进程。

    总结
    许多的改进将会随着基于Windows的Docker客户端而来,我们期待下次在MAC上的Docker客户端的测试。

    原文链接:Docker For Windows Beta (翻译:薛开成)

    ===========================================
    译者介绍
    薛开成,趋势科技南京研发中心工程工具服务事业部基础架构高级工程师,负责容器仓库实施及落地。

    DockOne技术分享(三十四):搭建企业私有Docker Registry实战分享

    nevermosby 发表了文章 • 1 个评论 • 9446 次浏览 • 2015-11-25 15:49 • 来自相关话题

    【编者的话】对于企业内部搭建Docker Registry来说,部署和运维尤为重要。今天为大家简单分享下惠普企业R&D团队在这两方面的项目实战和应用。 @Container容器技术大会将于2016年1月24日在北京举行,来自爱奇艺、微 ...查看全部
    【编者的话】对于企业内部搭建Docker Registry来说,部署和运维尤为重要。今天为大家简单分享下惠普企业R&D团队在这两方面的项目实战和应用。

    @Container容器技术大会将于2016年1月24日在北京举行,来自爱奇艺、微博、腾讯、去哪儿网、美团云、京东、蘑菇街、惠普、暴走漫画等知名公司的技术负责人将分享他们的容器应用案例。
    实战聊天运维ChatOps
    # 什么是ChatOps
    ChatOps这个概念最初是由Github团队提出,简单来说,是基于对话驱动的开发方式。实际做法是:把你的工具带到您的沟通过程中,并使用一个聊天机器人编写定制化的脚本,使团队可以自动执行相应任务和协同工作,使运维工作更透明更高效。

    因此,实施ChatOps需要两个重要组成部分:聊天室和机器人。聊天室也就是我们常说的团队协作平台,比较知名的有:

    * Flowdock,知名团队协作平台,目前我们在使用它。
    * Slack,国外著名的团队协作平台,界面美观。
    * HipChat,国外著名的团队协作平台,界面简洁。
    * Zulip,Dropbox旗下的group chat平台,已开源。
    * Teambition,国内知名的团队协作工具,具有文档管理功能。

    这里是一篇比较Slack、Flowdock和HipChat的文章:
    http://www.slant.co/topics/1359/compare/~slack_vs_hipchat_vs_flowdock

    机器人选取了由Github团队开发的,当下最广泛使用Hubot。它是基于Node.js+CoffeeScript编写的,支持众多协作平台,如果没有你在用的,自己写adapter也很简单。除此之外,还有一些机器人:

    * lita,Ruby写的robot。
    * Errbot,Python写的robot。

    团队中的任何一个人,只要在Flowdock这样的协作平台上,像聊天一样,输入相应指令,比如`hubot show registry status`,收到这条指令的Hubot就会根据后台定制的脚本,自动把相应信息通过一条聊天信息返回给你。
    # 为什么要使用ChatOps
    ChatOps的实施使运维工作更加透明,更加简洁。这样的好处很多:

    * 把过去团队成员在各自工具中输入命令的这个黑匣子过程前端化、透明化了。团队每个成员都能随时了解其他成员的一举一动,打造真正的无死角透明团队。
    * 非常有利于新人的培养。显然,能够直观看到团队的微观运作,对于刚入职的新手来说,比任何培训的效果都更好。

    # 目前是如何利用ChatOps
    我们公司目前内部署了私有Docker Registry,我们希望监控它的运行和使用情况,并且能够快速地对一些可预知的问题进行处理。通过Flowdock+Hubot(Hubot运行在Docker容器里)就能实现这点:

    * 通过Hubot监控Registry是否正常运行。主要使用了Sensu来做Registry的health check。一旦发现Registry没有正常运行,hubot就会发送一条信息到flowdock里,使用@team来通知团队。然后团队的成员可以使用hubot指令`hubot fetch registry error cause`,让hubot帮我们调查并返回出错的原因。根据出错原因,再使用hubot指令进行应急处理。
    * 通过Hubot定时发Registry运行情况到Flowdock Inbox里。通过Sensu作为服务监控,收集Registry本身一些运行数据,包括CPU,内存等,发送到Graphite,生成时序统计图,发布到flowdock上。
    * 通过Hubot实时获取Registry的使用情况。首先Registry进行了notification配置,Registry使用元信息会被发送到定制的收集服务(Notification analysis service)中去。通过分析这些使用元信息,获取不同Registry镜像的pull/push数量,由Notification analysis service提供相应的聚合搜索API。调用这些API,可以获取每小时、每天的Registry使用情况(json),将这些信息发送给相应的GraphOps平台,就能生成相应的图像,发布到flowdock上。我们目前比较常用的指令,就是`hubot graph me registry usage since 24 hours`,hubot立刻会返回最近24小时内Registry的使用情况,包括pull/push的数量等。

    # 对于ChatOps未来计划

    * 目前hubot对于我们的Registry的运维还比较基础,将来我们希望通过增强hubot的运维能力(添加自动化脚本),来提高Registry的负载能力。例如通过hubot监测到Registry运行负载剧增,然后使用hubot实施auto scaling来保证Registry运行稳定。
    * hubot可以作为连接和协同众多独立的微服务的一种桥梁,扩展的便利性尤为重要,而目前手动编写自定义的脚本不是特别方便。我们计划在企业内开发一套图形化扩展hubot的平台,集成企业内常用的各种服务,包括代码管理服务(SVN、Git)、通知服务(邮件、Flowdock)和部署服务(企业私有云)。对于特有应用的服务,可以提供自定义脚本扩展。

    使用Rancher实现Docker容器集群环境的部署和管理
    # 为什么使用Rancher
    我们需要一个平台来管理生产环境中的容器,Rancher是一个开源项目,使用起来非常简单,容易上手,一方面Rancher提供UI,可视化创建开关容器,另一方面,当时我们对docker-compose已有一定的了解,Rancher是支持标准化docker-compose.yml的。除此以外,Rancher实现了跨主机的overlay network。基于以上考虑,我们采用Rancher,基本上满足我们对于容器部署管理的需求。
    # 准备环境

    * 安装Rancher的Server,其名为rancher/server的docker image,主要用于提供用户界面、追踪集群中容器状态、meta data和容器的调度、处理API请求等。
    * 给Rancher添加host,即在host上运行rancher/agent 这个docker image。Rancher的environment对应一个overlay network,把多个主机加入到一个environment中,Rancher根据资源和端口,自主调配容器在哪个主机上运行,每个容器将获得一个IP(10.42.0.0/16),容器之间是网络联通的。

    # Rancher进行部署

    * Rancher根据docker-compose.yml来部署容器,一个docker-compose.yml定义的container cluster,在Rancher里,被称为Stack。一个environment可以起多个Stack。对于docker compose中的link, Rancher有自己的Distributed DNS Service discovery的功能,根据link,生成service name对应IP的DNS record。Rancher也支持Docker volume, 并且提供其快照和备份的功能。我们通常还配有一个私有Registry,这样部署的时候Rancher可以从私有Registry去pull image.
    * 与docker-compse.yml一起工作的有rancher-compose.yml,在rancher-compose.yml中定义service scale,即一个service的container数量。例如
    db:
    scale: 2


    * Rancher内置的load balancer,我们用来做流量的路由。例如,在docker-compose.yml中,有如下定义
    lb:
    image: rancher/load-balancer-service
    labels:
    io.rancher.loadbalancer.target.service1: example.com:443/service1=3000
    io.rancher.loadbalancer.target.service2: example.com:80/service2=5000
    service1:
    ...
    service2:
    ...

    意思是我们定义了一个lb的service,是rancher/load-balancer-service的image,labels中的内容则配置lb的路由规则,即访问example.com:443/service1,流量会被分发到service1,而example.com:80/service2,流量被分发到service2。我们常常在一个envrionment中,指定一台host,专门用于运行lb。然后,云服务上配置DNS,使域名绑定到这个主机的IP。这样无论如何部署,总可以很顺利地通过域名来访问这些服务。

    * 容器编排scheduling的功能。Rancher允许用户给每个host定义label,比如我们常常给专门来运行load balance的主机定义一个label是for=lb,如果要lb这个service一定在此主机上运行,那么可以在docker-compose.yml中这样定义:
    lb:
    labels:
    io.rancher.scheduler.affinity:host_label: for=lb


    Rancher有更多高级的scheduling规则编写的功能,包括否定,软指定等。
    `io.rancher.scheduler.affinity:host_label_ne: for=lb` 指service一定不能在for=lb的host上运行。
    `io.rancher.scheduler.affinity:host_label_soft: for=lb` 指service在条件允许的情况下尽量在for=lb的host上运行。

    * 可以从用户界面上部署容器,Rancher自动生成docker-compose.yml,并且提供Service之间相互link的拓扑图,如图
    RancherServiceLink.JPG


    * Rancher有rancher-compose命令行工具,方便容器部署自动化,与其他流程进行整合。

    # 生产环境使用Rancher

    * 发布新的image,可以用Rancher upgrade的功能,实现无缝更新。本质上Rancher启动新的service,然后切换link到新的service。如果需要回滚,则可以很方便的切换回之前的service。
    * Rancher对于主机和容器进行实时监控,通过用户界面可以查看cpu和memory的使用情况。
    * Service Health Check,是基于HAProxy开发的对于service状态的监控。

    # 目前发现的缺点

    * 缺乏自主修复的功能。如果有些host无法和Rancher Server连接,Rancher无法重新调配container。

    团队

    * 惠普企业RnD部门,从事DevOps及Docker的研究和相关工具的研发,开源社区贡献者。
    * 成员:李文权、林箐、王春阳。

    Q&A
    Q:目前有没有尝到监控Register运行和使用情况的好处,或者在维护私有Register有没有遇到过什么问题?

    A:能够实时监控Registry,就能观察用户的行为,当我们在负载量很大的时候,能够有效保持Registry稳定运行。维护私有的Registry的问题,就是要跟进官方的更新,看看是否也需要同步。



    Q:Rancher实际上是基于Docker的开源PaaS,基于容器技术的开源PaaS很多,比如Deis、Flynn等,但是Rancher跟这些项目不同的地方是,它尽可能的和Docker生态圈工具兼容。请问当初为什么会选择Rancher,在你看来,Rancher最吸引你的地方是什么?

    A:Rancher的UI比较方便于上手和使用。而且Rancher的概念也更接近Docker compose,目前官方的文档也比较齐全。



    Q:Flowdock+Hubot这种方式下的监控是否必须用Sensu,是否支持采用zabbix作监控,Zabbix的远程脚本可以实现一些自动重启等等操作?

    A:Sensu不是必须的,你可以使用你熟悉的监控服务,比如Zabbix。



    Q:Flowdock+Hubot在一些安全性要求比较高的生产环境上是否可用,其发布的命令采用什么方式连接到容器\虚拟机或者主机上?要不要建立SSH免密码连接之类的操作?

    A:Hubot是拉取Flowdock的信息,所以Hubot可以部署在公司防火墙内。目前Hubot使用docker remote API来控制虚拟机上的容器。



    Q:请教一下,Rancher可以理解为Compose的增强版吗,特别是可视化部分?

    Rancher自己有一套rancher-compose,提供load balance和auto scaling,可以算是Compose的增强版。可视化部分,是Rancher的一个Feature。



    Q:Rancher的lb是用的HAProxy么?

    A:是的。



    Q:有没有做过横向比较,Kubernetes和Swarm+Compose,Rancher+Compose,在这几种选择间做过比较,或者说为什么最终选择了Rancher?

    A:最初是选择Swarm+Compose,但是由于那个时候的Swarm不太稳定,有bug,集群管理工作不起来。Rancher部署方便,操作简单,所以就用了它。



    Q:Rancher的网络具体是怎么做的呢?

    A:据目前了解,是overlay模式。各主机之间采用IPsec Tunneling来实现通信,使用udp的500和4500端口。启动时在各个主机部署容器之前启动一个Network Agent管理容器网络。具体可以参看文档:docs.rancher.com



    Q:rancher master如何实现的高可用?之前看了文档搭建之后,cpu等监控图无法显示了

    A:通过rancher-compose提供load balance和auto scaling实现高可用。监控图无法显示也是我们遇到的问题,目前正在解决。



    Q:从描述看Rancher的网络类似于weave吧,给每个容器分配固定IP,对集群规模比较大的或者IP地址段受限的似乎不太够用?

    A:从我们目前的经验来看,的确有这样的限制,如果有大规模集群的需求下,需要重新评估Rancher来管理和部署。



    Q: Hubot是不是也支持非容器方式的部署,比如部署在虚拟机上?

    A:可以,可以参照https://hubot.github.com。



    Q:Hubot使用docker remote API是否采用了安全策略,另外Docker Registry采用了何种安全策略?

    A:Remote API使用了TLS验证。目前我们的private registry使用了LDAP+token作为安全认证。



    Q:在部署方面很重要的是动态伸缩和灰度发布,在这两方面你们是怎么考虑的?Rancher在这两个方面有支持吗?

    A:通过rancher-compose提供load balance和auto scaling实现动态伸缩。其他方面,还没有考虑过。



    Q:Rancher的管理数据是不是都放在了MySQL里面?MySQL需要搭建在物理机上吗?

    A:MySQL是rancher server自己提供的,无需手工部署。



    Q:Rancher能支持云存储吗?

    A:最新版本的Rancher对Docker volume插件有了支持,可以通过它来实现Container的数据存储管理。



    Q:请问你们实践或了解到的基于Rancher的集群规模有多大?

    A:目前我们的使用规模比较小,还没有这方面的准确数据。



    Q:从介绍看整个系统是搭建在OpenStack上的,采用Swift作为存储,那Docker的部署是不是采用的nova-docker呢?容器是部署在物理机上还是虚机上的,如果是虚拟机采用的是哪种hypervisor,性能方面如何,有没有做过相关的压测?

    A:Docker是部署在KVM的虚拟机上,使用的企业私有云平台,目前没有做过性能测试。



    Q:Rancher 实际应用中有哪些要特别注意的问题,麻烦分享下?

    A:Rancher版本更新快,较低的版本会有很多bug。



    Q:有考虑过升级问题么?比如Registry从v1升级到v2?或者docker 升级到1.9?

    A:目前我们使用的就是v2,使用rancher upgrade来升级。 升级Docker的成本较大,目前还没有相关最佳实践。



    Q: Rancher中文资料多嘛,有推荐嘛?

    A:目前我们看的都是官方英文文档,这样能看到最新的信息,中文文档没有关注。



    ===========================================================
    以上内容根据2015年11月24日晚微信群分享内容整理。分享人: 李文权,去年开始参与关于OpenStack的项目forj,这是一个持续集成和分发的开源平台。负责搭建公司内部使用的Docker Registry,跟Docker社区成员一起贡献了OpenStack Swift作为Registry V2的代码。 DockOne每周都会组织定向的技术分享,欢迎感兴趣的同学加微信:liyingjiesx,进群参与,您有想听的话题可以给我们留言。

    DockOne技术分享(二十六):Docker Registry V1 to V2

    oilbeater 发表了文章 • 1 个评论 • 13001 次浏览 • 2015-10-17 17:30 • 来自相关话题

    【编者的话】Docker Registry 2.0版本在安全性和性能上做了诸多优化,并重新设计了镜像的存储的格式。我们将详细介绍Docker Registry V1与V2的区别,并在此基础上分享了灵雀云的实时同步迁移实践。 1. 相关概念 ...查看全部
    【编者的话】Docker Registry 2.0版本在安全性和性能上做了诸多优化,并重新设计了镜像的存储的格式。我们将详细介绍Docker Registry V1与V2的区别,并在此基础上分享了灵雀云的实时同步迁移实践。
    1. 相关概念
    首先讲一下Registry相关的概念。大家对Docker应该比较了解了,就是容器技术使用了Cgroups、Namespaces、Union FS等一系列机制来保证隔离。但我们实际使用中可能并不会直接接触这些技术,更直接使用的是pull image、run image,再进阶一点会使用build image和push image。我们日常的使用主要还是围绕image展开的。

    而image和Registry的关系可以想象成自己机器上的源码和远端SVN或者Git服务的关系。Registry是一个几种存放image并对外提供上传下载以及一系列API的服务。可以很容易和本地源代码以及远端Git服务的关系相对应。

    然后再说一下Hub,很多人不太清楚Docker Registry和Docker Hub到底有什么区别。其实依然可以利用Git的概念来类比,Registry 和Hub的关系可以类比Git和GitHub的关系。Git是一个服务端程序,GitHub是全球最大的同性社交网站,那么 GitHub比Git多了些什么?首先是UI,然后就是用户鉴权,public-private partnerships各种组织机构服务,评论issue管理,Search webhook等工具的集合。Hub和Registry的关系也是类似的,大家在 DockerHub上看到的界面和各种功能就是Hub的一部分,而且处于商业的考量Hub是不开源的。
    2. V1 Python Registry
    下面来说一下V1的Registry以及为啥Docker官方不给他饭吃了。V1的项目地址在 https://github.com/docker/docker-registry 已经小半年没有更新了,很早就是废弃态。但说实话还是比较稳定的,API设计也比健全,使用和扩展也还算方便。至少在我使用的过程中没有碰到太多的坑,反而是V2把我坑的够呛。
    1.jpg

    这是一张V1 Registry存储镜像的目录树。可以看到最上面是两层结构images和repositories,关注一下images里面的内容,最叶子节点有一个layer和Ancestry。layer就是这一层文件系统的tar包,Ancestry中存储的是它父亲层ID,可以看到layer之间在V1是通过一个链表的形式进行关系组织的。大家学过数据结构应该知道,链表的特点是插入删除方便,随机读取性能差,而layer之间显然是没有插入删除这个需求的,所以这个设计在我看来是有些问题的。这个组织结构的另一个缺点就是pull layer只能单线程,下完一层才能知道父亲是谁,就只能按序下载,没有发挥多核的优势。

    当然这只是一个很小的问题,最主要的问题出现在那一长串Image ID 上。不知道大家有没有想过这个ID是如何生成的。这个ID是在本地build时随机生成的,随机生成的,随机生成的。随机生成的意思就是ID和内容完全没有关系,同样的layer再次build生成的ID就是不同的。

    这会造成很大的安全隐患。docker pull和push判断image layer存在都是根据这个ID所以在双向都存在造假的可能。恶意用户可以伪造ID直接 push 上去,这样以后再有别人同样的ID就上传不上去了,因为Registry会认为layer已经存在了,但内容其实是不一样的。这个倒是还好,因为碰撞概率没那么高。

    另一方面恶意的 Registry 也可以根据ID伪造内容,反正你只校验ID也不知道是不是这个内容和ID是关联的。类似于前一阵xcode的木马,下下来一看名字是xcode就以为是真的。安全性的因素也是Docker官方想要重新设计Registry的主要理由。

    同样这种随机ID也会造成push性能下降,因为可能重复内容被多次 push。其他原因还有V1是Python实现的与Golang的理念不符,尽管Golang写的也不咋地。

    另一个比较重要的原因是tag的问题。Docker很多方面都学Git 也学得很成功,偏偏版本控制的东西学残了,最明显的就是tag。tag 的问题在于Docker images的tag是可变的,你没有办法通过tag来确定唯一的版本,这一点在latest上尤为明显。因为latest是可以自己定义的,如果你在 Dockerfile里from latest很可能你过一阵build出来的镜像和之前不一样了,这个问题还很难发现。其他tag也存在同样的问题,我们现在的做法是用代码 commit ID做tag,每次都是按照commit ID作部署,尽量远离latest。
    3. V2 Golang Distribution
    上面说了V1的一堆不好,下面来看一下V2。

    项目地址是:https://github.com/docker/distribution,实话说目前的开发进度很缓慢,和Docker Engine的热度完全不是一个量级,很多基本的功能都很缺失。
    2.jpg

    他的存储目录树十分复杂,我就简单列一下,可以看到最顶层还是两个,只不过images改名为Blobs,最叶子节点变为了data,他的目录是一串长ID,需要注意的是这个ID和Image ID是没有关系的。由于一些兼容性的历史问题,Docker并没有取消Image ID的概念,这里的一长串ID是把data的内容经过sha256做hash得出的结果。

    这样就很好的解决了之前V1所存在的随机ID的大问题。

    通过这种方式ID和内容是一一对应的了,同样的内容总会生成同样的ID,而且这种key->value的形式也很利于缓存,为未来的优化也埋下伏笔。这样就可以变原来的链表顺序查找为数组的随机读取,这也是V2 pull可以并行的一个基础,并行pull大概也是客户端唯一能感受到的比较大的和V1的区别。大家可能发现这里没有Ancestry这种链表结构了,V2中会有一个新的文件,叫manifest,它会记录改镜像所有layer的信息。manifest中还有大量其他信息,感兴趣的可以看一下 spec https://github.com/docker/distribution/blob/master/docs/spec/manifest-v2-1.md。

    这一长串ID在Docker叫digest, 从Docker的想法来看他是希望通过digest来取代tag达到可以指定唯一版本的目的。但是由于Image ID历史遗留的问题太长远了,现在看改起来十分艰辛。还需要注意的是 这一串ID是服务器端计算得出的,这样也杜绝了客户端造假ID的行为,当然这个做法也带来其他的问题。

    其他的新的地方还包括新的auth方式,notification机制,以及全新的API。这里全新的API的意思是和之前完全不兼容,如果现有系统想迁移需要考虑一下这点。然后他是go实现的,我自己的感觉吞吐量有两三倍的提升。

    再说一下V2存在的问题。

    首先是API的缺失,delete、search这种基本功能都没有,而且tag和digest的关系很难找,而所有API又都是基于digest的。然后push和pull的速度有了新瓶颈。之前V1是把文件系统做tar包V2变成了gzip包,只要一push镜像CPU就会打满,而且压缩解压都是单核的,如果是内网话很有可能push和pull都变慢了。最后一点就是V1和V2镜像格式不兼容,不兼容,不兼容。
    4. V1 V2 共存及同步实践
    我们做的就是让V1和V2两个版本共存,并且镜像在两个Registry中都存在。Docker目前1.6之后支持V2,但我们的用户从0.9到1.8都有使用,Docker自己给我们挖了坑然后提提裤子就跑了,我们需要让用户无感知。而且用户可能会升级降级版本,不能发现镜像不在了。

    先说一下共存,这一点相对容易,需要一个域名支持两套Registry,由于V1和V2的后接url是不一样的,所以可以很容易的通过Nginx做一个转发。官方也给出了一个示例:https://github.com/docker/distribution/blob/master/docs/nginx.md,但是读的时候一定要仔细,并根据具体情况进行调整,直接不看拿过来就是坑。
    3.jpg

    我们搭好的一个网络拓扑大概是这样的,之所以把网络拓扑放出来是希望大家想一下,这种大文件传输的服务在网络拓扑上要考虑什么?最主要的就是超时,你需要考虑每条链路的超时设置。其次是body size ,buffer size之类的参数保证链路的通畅。

    然后再讲一下V1和V2之间的同步,由于镜像是不兼容的,肯定要涉及到同步迁移。大思路上有两个方案,第一读懂两种镜像的格式,直接做文件级别的更新,把V1的文件翻译成V2,这个华为的马道长在做大家有兴趣可以找他。另一种是利用Docker 1.6之后的版本可以和两个Registry进行通信,我们从一个registry pull再push到另一个Registry才用Docker Engin 的Runtime来解决,我们当时合计了一下觉得第二个省劲就用了第二个方案。

    之后我们发现官方也给给出了个迁移工具,大家也可以看一下: https://github.com/docker/migrator,思路基本也是一样的,但问题这个工具有很多缺陷。首先他是一个单一的shell脚本,只能做离线同步,我们想要的是实时,因为我们每天量还是很大,离线很可能不收敛,而且用户体验也不好.其次它只能做V1到V2的单向同步,扩展性,和性能也不好,并且也没有相关的统计监控功能,只是个玩具产品。

    接下来看一下我们做的:
    4.jpg

    思路还是用1.6之后的特性。在两个Registry上分别加hook实时获取tag更新信息发送到消息队列,消息队列再把消息发送到分布式的worker集群上进行一个同步,这个过程中每一步都落数据库,方便我们之后的监控和错误恢复。

    把上面的数据流反过来再画一遍,就是我们线上的工作流了。这里有许多细节的问题大家可以之后想一下。首先是如果我做双向同步,那么我的同步也是一个push事件,这样会再触发一个同步这样一直循环下去该怎么办?还有就是一个埋的比较深的问题,也是latest最容易引起,两次间隔很近的latest push,很有可能后一个latest同步先完成,第一个同步后完成,这样就会同步的结果就是一个旧的版本,如何避免这种情况?其实就是一个事务的问题,如何确定那些操作可以并行,那些必须串行,这两个问题大家可以想一想。
    5. 同步海外镜像实践
    我们有了这套同步工具其实可以干很多别的事情。理论上任意一个Registry只要我能爬到它的更新就可以同步过来。我们同步官方library和一些其他库现在也是基于这套工具,但是这里会碰到一个更头疼的问题,就是网络。墙的问题大家都是中国人。而且我们这种同步都是最新的镜像,mirror也帮不了什么忙,用VPN的话这种走流量的很快就会被封IP。最后我们发现七牛有个海外上传加速可以在海外很快的上传文件到国内,我们就写了一个七牛的driver来进行这种同步。架构图就变成这个样子了,相当于部署了两套同步节点,一套在海外负责Dockerhub同步到qiniu,一套在国内负责qiniu同步到我们自己。
    5.jpg

    这种方案解决了很多问题,但是问题依然很多。首先是只有上传文件走加速节点,所有的控制流比如mv rename等对象存储操作还是走国内,这样这一段依然高延时容易被墙,失败频率依然比较高。另一反面我们也好几次碰到了七牛服务不稳定的情况。所以我们虽说是按照一个实时同步进行设计的,现在的结果是大部分情况是分钟级别同步,故障时可能会到天级别,不过我们认为大部分情况下还OK。如果当初设计就是天同步或者周同步很可能最后就同步不完了,所以给大家的启发就是不妨把目标设置高点,反正目标再低也是完不成的。

    额外想说的就是,尽管这套东西我做出来了,但我觉得这个东西是不该存在的。不知道大家有没有听过有个博士的论文写得是如何在奶粉中检测三氯氰胺,不能说这件事情没意义,但是这件事情有意义很可悲,我觉得我现在做的也是类似的事情。我们都把太多时间和精力花在了毫无意义的和网络作斗争上,我希望有一天可以把这套海外同步的机制干掉,或者只是做个简单的国内镜像站而已,而不是大费周折的可以画一个很花哨的图来讲。
    Q&A
    Q:想问下,那你们的layer数据是不是要存两份,V1、V2各一份?

    A:是要分开存两份的,因为他们的格式其实都是不一样的一个是tar包一个是gzip包,但内容一样。



    Q:为啥tar变为gzip会耗费CPU和网络,不就是不同的压缩格式么?

    A:网络其实是节省的,但是压缩是很耗CPU的tar其实并不太消耗。



    Q:V1如果做些优化,一次获取Ancestry,然后并行下载layer,是不是也可以提高吞吐量么?

    A:理论上是这样的,我看1.8的代码在pull v1也一次会拿到所有的Image ID但是并没有去并行下载,估计Docker自己把这块放弃了吧。



    Q:请问,您提到的利用Registry的hook,来获取image更新的信息,指的是利用Registry的notification API?

    A:V2是这样,V1是自己在Registry那里做了个hook。



    Q:请问关于镜像删除的问题,V2的删除感觉坑很多,如何删除,还有,如果同一个镜像名称及版本但是内容并不同的镜像重复push,有没有办法检测,以及同步?

    A:我们用的AWS对象存储,存储还比较便宜,所以没太关注,GitHub上有一个v2 gc的项目可以删除无用镜像,官方叫着做停机gc,叫了好久了,目前还没实现,只能自己造轮子了;重复push和刚才提到的乱序类似,我们会保证这种情况是串行的。



    Q:V2这么不成熟,眼下上还是不上,push到V2 registry的image能不能查询?

    A:我们当初的想法是照着Docker这么任性的态度,没准1.8就不支持V1了,所以就赶紧调研用上了。查询没有直接的API,我们很多tar没有的API都是自己造轮子造出来的。



    Q:V2.1后,Registry提供一个叫catalog API,具有一定image搜索的功能,但还不够完美?

    A:catalog会遍历整个存储消耗还是蛮大的,可以通过catalog做离线,然后notify做实时更新来实现search的一个索引。



    Q:请问,灵雀云的registry backend storage是什么类型,文件系统么,理由是什么?

    A:直接AWS在中国的s3,目前官方支持的最好的,不用自己造轮子,就酱紫。



    Q:针对V2的auth方式,有没有什么好的建议,对于平台类的开发?

    A:我的建议是使用token auth的方式,虽然复杂一步到位,可以做一些复杂的权限认证。类似的项目还是:https://github.com/SUSE/Portus ,不过建议每次Docker版本更新都跟着测一遍。



    Q:有没有类似docker_auth的项目?

    A:https://github.com/SUSE/Portus 一个开源的 auth server,但是比较坑的是Docker Engine老变,一升级可能就不一样,我们自己的auth server也改了好几次。



    Q:由V1升级到V2,为什么非得把旧仓库上的镜像迁移到新的V2这么折腾,直接两个版本并存一段时间不行吗,新上传用新的V2的url,如果要回退旧版本旧库上镜像url也还有吧,一段时间后旧库就能退役了?

    A:因为我们有用户的push而用户很多还在用旧版本,也有用户发现新版本不合适回滚的,如果只顾一头用户一变就发现镜像没了。



    Q:alauda云push的时候443端口拒绝连接怎么办?

    A:这个应该不会吧……,可以先下再联系复现一下,我们的两个版本Registry都是走HTTPS的。



    Q:V2好像仍然没有解决Registry最大的痛:单点,你们怎么对待这个问题的?

    A:Registry一直都是可以水平扩展的,只是一个HTTP的服务器是无状态的不存在单点问题。



    Q:企业私有云场景下用多个Registry实现HA该如何选择后端存储,京东的Speedy是否合适?

    A:Registry有Swift的driver私有云可以考虑,或者根据已有的情况选择自己的存储自己写个driver也是可以的,写的难度其实不大,七牛那个一个下午就能写出来。要求不高的话还是不难的。京东的不是太了解,我觉得主要看现有的技术框架和产品选一个易上手的就行。把Registry水平扩展挂载lb后面就好了。



    Q:V1已经被官方deprecated,V2仍然缺少一些基本的管理API,请问现在私有Registry升级到V2是否还为时过早?

    A:看需求了吧,我觉得要是稳定考虑deprecated也没啥影响,V2的很多好处确实在私有云表现不出来,反而会有一些表现不如V1的地方。



    Q:用七牛海外加速之前用哪种方案的?

    A:我先答一下这个吧,这个挺有意思的,我们发现一个tcp的拥塞算法是用于卫星通信的,卫星这种高延迟高丢包的拥塞算法貌似还蛮合适国外往国内传数据。



    ===========================
    以上内容根据2015年10月16日晚微信群分享内容整理。分享人刘梦馨,灵雀云软件工程师,前阿里系统保障部系统工程师,容器技术爱好者,个人博客:oilbeater.com。DockOne每周都会组织定向的技术分享,欢迎感兴趣的同学加微信:liyingjiesx,进群参与,您有想听的话题可以给我们留言。

    实战 | 如何搭建安全可靠的Docker Registry?

    wulonghui 发表了文章 • 2 个评论 • 10988 次浏览 • 2015-08-28 15:03 • 来自相关话题

    【编者的话】Docker Registry用来存储和管理Docker Image, 本文说明如何基于Docker Registry(V2)构建安全可靠的Docker Registry。 #Docker Registry安全 ##TLS ...查看全部
    【编者的话】Docker Registry用来存储和管理Docker Image, 本文说明如何基于Docker Registry(V2)构建安全可靠的Docker Registry。
    #Docker Registry安全
    ##TLS
    需获取证书, 建议从CA机构申请。信任域内可以使用自签名证书:
    mkdir -p certs && openssl req \
    -newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key \
    -x509 -days 365 -out certs/domain.crt


    注: Common Name输入Docker Registry使用的域名
    注: 如果使用自签名证书,使用Docker Registry的Docker机需要将domain.crt拷贝到
    /etc/docker/certs.d//ca.crt,然后重启docker同时将domain.crt内容放入系统的CA bundle文件当中,使操作系统信任我们的自签名证书。



    CentOS 6 / 7中bundle文件的位置在/etc/pki/tls/certs/ca-bundle.crt:
    cat domain.crt >> /etc/pki/tls/certs/ca-bundle.crt

    启动Docker Registry容器使用证书开启TLS:
    docker run -d -p 5000:5000 --restart=always --name registry \
    -v /path/to/certs:/certs \
    -e REGISTRY_HTTP_SECRET=mytokensecret \
    -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
    -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
    registry:2

    ##Basic Authentication
    创建账号密码:
    mkdir auth
    docker run --entrypoint htpasswd registry:2 -Bbn auth/htpasswd

    启动Docker Registry容器设置启动Authentication:
    docker run -d -p 5000:5000 --restart=always --name registry \
    -v /path/to/auth:/auth \
    -e "REGISTRY_AUTH=htpasswd" \
    -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
    -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
    -v /path/to/certs:/certs \
    -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
    -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
    registry:2

    使用Docker Registry的Docker机需要使用账号密码登陆:
    docker login 

    #Docker Registry可靠性
    ##存储
    Docker Registry支持多种存储方式:

    • inmemory:A temporary storage driver using a local inmemory map. This exists solely for reference and testing.
    • filesystem:A local storage driver configured to use a directory tree in the local filesystem.
    • s3:A driver storing objects in an Amazon Simple Storage Solution (S3) bucket.
    • Azure:A driver storing objects in Microsoft Azure Blob Storage.
    • rados:A driver storing objects in a Ceph Object Storage pool.
    • swift:A driver storing objects in Openstack Swift.
    • oss:A driver storing objects in Aliyun OSS.
    我这里采用Filesystem Storage Driver + MooseFS:
    捕获.PNG
    搭建MooseFS,然后文件系统挂载到Docker Registry节点, Docker Registry将数据存入MooseFS文件系统。启动Docker Registry容器挂载Volume:
    docker run -d -p 5000:5000 --restart=always --name registry \  -v /path/to/data:/var/lib/registry \  registry:2
    ##集群Docker Registry多实例需要保持以下数据一致:
    • Storage Driver
    • HTTP Secret
    • Redis Cache (if configured)

    Docker Registry多实例可以主备或者负载分担,其中负载分担方式需要保证一次docker push/pull都只是和一个Docker Registry实例交互,比较简单的做法可以是基于源IP做会话保持, 以haproxy为例:
    frontend https_frontend
    bind *:443
    mode tcp
    default_backend docker_registry

    backend docker_registry
    mode tcp
    balance roundrobin
    stick-table type ip size 200k expire 30m
    stick on src
    server s1 docker_registry_server1:5000
    server s2 docker_registry_server2:5000

    注:在每个节点上Docker Registry容器启动方式如下:
    docker run -d -p 5005:5000 --restart=always  \
    -v /home/docker_registry:/var/lib/registry \

    -e REGISTRY_HTTP_SECRET=watokensecret \
    -v /home/docker_registry/auth:/auth \
    -e "REGISTRY_AUTH=htpasswd" \
    -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
    -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \

    -v /home/docker_registry/certs:/certs \
    -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
    -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \

    registry:2


    ==========================================================
    作者简介
    吴龙辉,现任网宿科技高级运营工程师,致力于云计算PaaS的研究和实践,活跃于CloudFoundry,Docker,Kubernetes等开源社区,贡献代码和撰写技术文档。
    邮箱:wulh@chinanetcenter.com/wlh6666@qq.com

    OSCON上最受欢迎的Docker演讲

    henrysher 发表了文章 • 1 个评论 • 5299 次浏览 • 2015-08-25 11:24 • 来自相关话题

    【编者的话】本文介绍了上个月OSCON大会有关Docker最受欢迎的一个分享:真实线上环境的Docker技巧。分享者是一名运维工程师叫Bridget,她所在的公司DramaFever在2013年10月开始在线上环境部署使用Docker。然而那个时候,Docke ...查看全部
    【编者的话】本文介绍了上个月OSCON大会有关Docker最受欢迎的一个分享:真实线上环境的Docker技巧。分享者是一名运维工程师叫Bridget,她所在的公司DramaFever在2013年10月开始在线上环境部署使用Docker。然而那个时候,Docker官网还挂着“请勿在线上环境使用”的警示条。从2013年到现在,DramaFever积累大量Docker线上使用的实际经验。这些经验的分享,吸引了大量的与会者,当天会场爆满,组织者只好请Bridget第二天再讲了一遍。可见这个分享还是蛮有价值,这篇博文介绍的有些过于简单,有兴趣的话,可以直接去读她的演讲稿或者当天的视频。

    上个月在波特兰举行的OSCON开源大会上,有关Docker和容器的分享最令人印象深刻的,一定会是Bridget Kromhout的“线上环境使用Docker,真实不炒作”。整个会场爆满,只剩下站的地方,后来者都被挤到门外面。组织者只好请Bridget第二天再讲了一遍。

    毫无疑问,Docker非常非常的火,Bridget带来她对DevOps和容器化的深度经验:她是一名运维工程师,博主,演讲者,明尼阿波利斯DevOps日的组织者,也是”被捕获的DevOps“频道的主持人。

    Bridget的公司,DramaFever,自2013年10月开始在线上环境使用Docker,那个时候Docker官网上还写着警示语:"不要在线上环境使用Docker"。DramaFever是一家流媒体视频公司,起初播放韩国的肥皂剧,现在给docclub.comshudder.com提供额外的视频服务。目前有来自70个内容提供商的15000集电视剧,将近2000万的观看者。高峰时刻,公司要处理来自不同的终端每秒上万次的请求--观看者会经常在节目中间切换终端设备。

    为了能够满足上述需要且提供好的用户体验,DramaFever将原先单体的Python应用拆分成了微服务。整个团队在AWS上面运行服务,主网站使用Python,微服务用Go语言。DramaFever依赖Docker来提供持续的开发和部署。

    在线上环境改用Docker的过程中,Bridget和她的团队学到了很多教训。下面五个主要的经验,是她在OSCON上分享的。

    1.小心Docker Registry过度负载

    DramaFever开始它的容器旅程之时,Docker还没有私有的Registry,但是他们对这点很不满意:Registry在Docker中成为不被控制的单点故障源。DramaFever网站当时依赖于Jenkins机器上部署的单个Registry服务器,可是,当多于20个机器需要使用时,Registry就出故障了。现在DramaFever的每台EC2机器(甚至笔记本)上都会运行着一个私有的registry容器,并辅以AWS S3作存储。这个解决方案不需要占用很多的资源,而且能解决机器扩充的瓶颈。

    2.编制自己的基础镜像

    为了保证Docker的镜像是最新的,DramaFever的运维团队每周都会尝试更新“基础镜像”,包括不频繁的依赖变化,比如Ubuntu包依赖或者Python的依赖文件等等。其他的部分都是基于这些镜像,所以启动会非常快。

    3.避免有问题的线上推送

    一定要确保没有人知道在线上环境能够执行 docker push 命令的账号和密码。我们要保证这些命令只会在Jenkins服务器触发。这样可以避免在没有其他人在场的情况下,发生有问题的线上环境推送。

    4.记得清理

    容器和镜像都会占用大量的硬盘空间。如果Docker源码区空间被用光,“非常非常糟糕的情况就会发生,甚至会导致硬盘的损坏”,Bridget解释道。她建议每天执行一个脚本来移除停掉且无标识的容器和镜像。

    5.注意你的系统时间

    AWS S3服务对你的系统时间非常在意。不幸的是,尽管boot2docker这款应用可以让Docker运行在Windows和MacOS环境,但如果你的笔记本开始休眠,这个应用将不能正常工作,因为虚拟机里的系统时钟会停滞。这时,任何AWS API请求会得到RequestTimeTooSkewed的错误。为了解决这个问题,所有DramaFever的工具都包含这行代码:
    ` boot2docker ssh sudo date --set \"$(env TZ=UTC date '+%F %H:%M:%S')\"

    这是一个已知的问题,boot2docker正在修正。

    Bridget的观点对于正在考虑线上使用Docker的人来说,非常有价值。你可以浏览一下她的演讲稿,读读她的博客文章

    其中最重要的是,虽然Docker很伟大,不过也没那么神奇。容器提供了一些非常酷的且引人注目的优点,但是就如同任何新技术一样,Docker需要我们尽职研究,以确保它会正常工作,并满足特定环境的需求。

    Tori Wieldt是New Relic的攻城狮激励师,她写博客,在New Relic的用户组演讲,并给New Relic开发者提供建议和培训。之前她一直在科技界,是一名系统管理员,技术作家和销售。



    原文链接:5 Real-World Docker Tips From OSCON's Most Popular Session(翻译:Henry Huang)

    ===================================
    译者介绍
    Henry Huang,目前供职于趋势科技 Trend Micro(南京),负责集群运维的工作。

    DockOne技术分享(三):Docker Registry的定制和性能分析

    难易 发表了文章 • 5 个评论 • 9360 次浏览 • 2015-05-12 22:07 • 来自相关话题

    【编者的话】本文介绍了Docker Registry服务几个组件的构成,以及怎么规划定制一个私有镜像库,以及镜像服务pull/push操作性能分析、并发性能分析,帮助大家按照需求搭建自己需要的镜像服务。 Docker I ...查看全部
    【编者的话】本文介绍了Docker Registry服务几个组件的构成,以及怎么规划定制一个私有镜像库,以及镜像服务pull/push操作性能分析、并发性能分析,帮助大家按照需求搭建自己需要的镜像服务。


    Docker Index

    • Web UI
    • Meta-data 元数据存储(附注、星级、公共库清单)
    • 访问认证
    • token管理
    Docker Registry
    • 存储镜像、以及镜像层的家族谱系
    • 没有用户账户数据
    • 不知道用户的账户和安全性
    • 把安全和认证委托给docker-hub来做,用token来保证传递安全
    • 不需要重新发明轮子,支持多种存储后端
    • 没有本地数据库
    后端存储
    • 因为镜像最终是以tar.gz的方式静态存储在服务端
    • 适用于对象存储而不是块存储
    • registry存储驱动
    • 官方支持的驱动有文件、亚马逊AWS S3、ceph-s3、Google gcs、OpenStack swift,glance
    一次Docker Pull发生的交互
    图片2.png
    [list=1]
  • Client向Index请求,知道从哪里下载samlba/busybox
  • Index回复:
  • samalba/busybox在RegistryA
  • samalba/busybox的checksum,所有层的token
  • Client向Registry A请求,samalba/busybox的所有层。Registry A负责存储samalba/busybox,以及它所依赖的层
  • Regsitry A向Index发起请求,验证用户/token的合法性
  • Index返回这次请求是否合法
  • Client从registry下载所有的层
  • Registry从后端存储中获取实际的文件数据,返给Client
  • 搭建私有镜像库的方案
    图片1.png

    上面的index、nginx、后端存储3者都是可选的。registry分0.9的python版实现和2.0版的go实现。
    #认证和权限
    如果镜像库不直接提供给用户使用,仅仅是私有PaaS的一部分,可以不用index组件,直接上Registry就行。Index的开源实现包括docker-registry-web,docker-registry-frontend。支持较好的是马道长的wharf。
    #后端存储
    我们环境使用的是网易的内部的对象存储NOS,类似于S3。其他的方案没用过,如果要自己搭,可能靠谱的是ceph-s3。如果在公网环境或者已经购买了公有云服务,可以考虑自己实现一个registry-对象存储的驱动。
    #集群和分布式
    Registry本身是无状态的,可以水平扩展,然后在前面做ngix的负载均衡。
    性能测试
    #v1协议 vs v2协议
    1.png

    做了性能对比测试,同样为docker1.6,v2协议比v1协议快5-6%左右,基本可以忽略不计。
    #单次Pull和Push的性能分析
    2.png

    3.png

    经过对比测试,单次docker pull和push的最大耗时在客户端,也可以观察到每次做docker pull和push的时候系统CPU占用率都在100%。也就是说50%以上的时间花在本地做的压缩、计算md5等操作。
    #并发分析
    4.png

    并发测试的结果是在一个2核2G内存的registry-0.9服务器,直接用文件存储,大约能负载50个docker client的并发。如果换用对象存储的后端,估计10个docker client的并发就是极限了。

    registry-2.0的并发性能很奇特,一方面,同样的镜像下载的比registry-1.0要慢,另一方面,只有一个进程,占了20%左右的CPU和内存,对系统资源消耗很少,不像python版的占用了所有的CPU核和内存。
    ##Q&A
    问:2.0的性能也没什么变化啊,优势在哪里?
    答:客户端优化有限,在超过100个节点同时pull一个镜像时,2.0服务端资源占用少。

    问:服务端的并发瓶颈在哪里?
    答:服务端的代码还没做过更多的分析,从经验判断主要还是IO,python的内存占用比较多。

    问:考虑过多机房image存储CDN没?
    答:这个还真没考虑过,目前我们的镜像服务是个内部PaaS平台用的,只要保证集群所在机房能快速访问就行。

    问:那还不如每机房加缓存?
    答:是的,也可以考虑registry的mirror机制,用了mirror后可以一个点push,其他点pull。

    问:你们的调度器是自己开发的吗?
    答:我们底层用的是Kubernetes,调度器做一定的修改,主要是为了保证多个可用域。

    问:内部的PaaS有没有做资源限制、网络隔离?
    答:有,目前我们的Docker是跑在kvm上。

    问:昨天网易好多服务断片了,据说是网络攻击,那这些服务有跑在Docker上吗?
    答:断片是因为BGP的核心交换机问题,我也很好奇是什么引起的,目前还没有组织和个人声称对此事负责。

    问:有没有考虑过nova-docker?
    答:社区不是很活跃,我们没有采用这个方案,但对于中小公司来说这是最快的方案。

    问:为啥不考虑自己实现调度器?
    答:忙不过来,我们也想做啊,这个放在后面实现。

    问:我们准备在某公有云上跑Docker集群。
    答:先这么用呗,我觉得Docker的优势就是底层平台无关,今后换了底层迁移也没有那么困难。

    ===========================

    以上内容根据2015年5月12日晚微信群分享内容整理。分享人钟成,网易PaaS平台开发者,写过一些开源软件,期望能在未来的云端世界中有一席之地,目前做的项目是在实现一个构建到部署运行的私有PaaS平台,目标用户是网易各种互联网产品。接下来,DockOne每周都会组织定向的技术分享,欢迎感兴趣的同学加我微信(liyingjiesx)参与。

    生产环境下如何部署Docker Registry

    xianlubird 发表了文章 • 3 个评论 • 6259 次浏览 • 2015-04-24 16:33 • 来自相关话题

    【编者的话】Registry是Docker用来存放镜像的,由于目前2.0刚出不久,1.0是目前比较健全的。本文描述了如何配置在Nginx代理下运行Registry,提供了用户验证、TLS加密支持。 在网上看了不少帖子,介绍搭建Doc ...查看全部
    【编者的话】Registry是Docker用来存放镜像的,由于目前2.0刚出不久,1.0是目前比较健全的。本文描述了如何配置在Nginx代理下运行Registry,提供了用户验证、TLS加密支持。

    在网上看了不少帖子,介绍搭建Docker Registry的很多,但是大部分要么是直接拿官方镜像拉下来run一下,要么就是配置Nginx在外面而并没有把Nginx容器化,再加上TLS各种证书的恶心,就没有找到一篇靠谱些的。当然,GitHub上官方的Docker Distribution里面的deploy这个markdown文档写的相当好,但是这个比较针对registry 2.0,目前公司内部急于上线产品,因此只能先用1.0来撑撑场面,逐渐向2.0转变。

    首先是Nginx的配置,使用官方的`nginx:latest`镜像,然后对于Registry,也是直接使用官方的`registry:latest`,目前官方的`registry:latest`还是Registry 1.0版本。

    由于需要覆盖原镜像中Nginx的配置文件,而且同时要启动Registry和Redis,因此直接使用Docker Compose来启动这些,一个YML文件搞定。所有的这些代码和配置文件都已经上传GitHub

    在这个registry-compose文件夹下面,克隆下来直接运行`docker-compose up`就可以了,具体的配置文件也在里面,有兴趣可以看看。

    在这个文件里面有一个localCA文件,里面是客户端需要的CA文件,因为认证证书是自己签发的,Docker不认可,因此需要把这个文件:

    sudo mkdir -p /etc/docker/certs.d/localhost:9443
    sudo cp devdockerCA.crt /etc/docker/certs.d/localhost:9443/
    sudo service docker restart

    这样就可以直接`docker login`了。


    对于创建证书的这些问题,首先使用这个命令产生客户端文件:

    openssl genrsa -out devdockerCA.key 2048

    然后再产生一个crt文件:

    openssl req -x509 -new -nodes -key devdockerCA.key -days 10000 -out devdockerCA.crt

    产生server文件:

    openssl genrsa -out dev-docker-registry.com.key 2048

    剩下的具体请参考[这篇文章](https://www.digitalocean.com/community/tutorials/how-to-set-up-a-private-docker-registry-on-ubuntu-14-04
    ),里面的产生证书部分些的很详细。

    所有的代码如下部署好的Registry。功能就是使用HTTPS协议,可以对Registry进行用户名密码的认证。你可以直接`docker-compose up`启动。

    下一篇文章中我们将看一下怎么集成分布式存储文件系统。

    Docker Workflow(一):一个可用于生产环境的Docker工作流

    sean 发表了文章 • 1 个评论 • 15053 次浏览 • 2015-03-26 18:14 • 来自相关话题

    【编者的话】作者工作于墨西哥IIIEPE研究院,他将通过一系列文章,为我们逐一讲述他们在Docker实际应用过程中的经验与教训,给后来者提供一些参考。本文主要介绍了他基于Docker的开发工作流,包括GitLab、Jenkins、Registry、Nginx。 ...查看全部
    【编者的话】作者工作于墨西哥IIIEPE研究院,他将通过一系列文章,为我们逐一讲述他们在Docker实际应用过程中的经验与教训,给后来者提供一些参考。本文主要介绍了他基于Docker的开发工作流,包括GitLab、Jenkins、Registry、Nginx。

    Docker现在已经两岁了(译者注:Docker于2013年3月13日首次发布),IIIEPE已经在生产环境中使用Docker3个来月。在此,我分享一些我们的经验和设计的工作流。

    我们运行着多个使用Drupal、PHP和Node.js的网站,我们的目标是使用Docker运行所有的应用,因此我们设计了以下工作流:

      []所有开发人员使用Docker来创建应用。[/][]我们的GitLab实例配置了Webhook,当检测到一个新的推送时,它将命令Jenkins运行一个任务。[/][]每个Jenkins任务都包含相同的布置:从GitLab中克隆最新代码,运行测试,登录到我们的私有Docker Registry,使用最新代码构建一个新的镜像,然后将镜像推送上去。[/][]最后,我们的编排软件Maestro-NG将部署新版本的镜像。[/][]我们的负载均衡器将检测这些变化,并重载新的配置。[/]

    每一个步骤都需要几天的规划、测试和工作来设计基本准则。

    我们做的第一件事是构建满足自己要求的基础镜像。镜像发布到Docker Hub中,它们包含了除了应用本身之外所有用于运行应用的东西。每次修改其中一个基础镜像,我们就会运行一个Jenkins任务来拉取新镜像,并触发后续任务来重新构建依赖此基础镜像的所有镜像。

    创建完镜像之后,我们需要为所有应用定义一个标准结构。我们所有的应用都使用以下结构来组织:

    /application
    /logs
    /files
    Dockerfile
    fig.yml.example
    docker-compose.yml.example
    Makefile

    /application目录是应用的根目录。

    /logs/files目录用于开发,以便应用可以写入日志和文件。这两个目录会被Git忽略,并在生产环境中完全排除。

    Dockerfile是Jenkins用于构建镜像的文件,开发人员几乎不需要接触这个文件,后面详述。

    fig.yml.exampledocker-compose-yml.example是开发人员用于启动应用的文件。这二者均不用于生产环境,当开发人员克隆一个项目时,他需要复制这个example文件并填入他/她的值。

    Makefile是拼图的最后一块,通过它我们可以拥有一个标准的命令集用于所有应用,并对开发人员隐藏各种各样的复杂性。
    # Dockerfile
    每个应用的Dockerfile与其它应用非常类似,这个文件的最重要工作就是构建包含所有待部署代码的最终镜像。我们来看一个例子:

    FROM iiiepe/nginx-drupal6

    ENV MYSQL_ENV_MYSQL_DATABASE somedb
    ENV MYSQL_ENV_MYSQL_USER root
    ENV MYSQL_ENV_MYSQL_PASSWORD 123
    ENV MYSQL_PORT_3306_TCP_ADDR localhost
    ENV MYSQL_PORT_3306_TCP_PORT 3306
    ENV BASE_URL http://example.com
    ENV DRUPAL_ENVIRONMENT production

    EXPOSE 80

    RUN usermod -u 1000 www-data
    RUN usermod -a -G users www-data

    ADD ./application /var/www
    RUN chown -R www-data:www-data /var/www

    Dockerfile依赖于我们构建的基础镜像,在此之上,它只是设置了一些环境变量默认值、声明要暴露的端口,并将应用代码添加到`/var/www`。

    正因为我们构建镜像的这种方式,在Jenkins和开发人员之间唯一的差别是,Jenkins将添加整个应用目录到`/var/www`中,而开发人员只是映射一下目录。

    接下来这个是Docker Compose,他非常酷。

    mysql:
    image: mysql:latest
    expose:
    - "3306"
    ports:
    - "3307:3306"
    environment:
    MYSQL_DATABASE: database
    MYSQL_USER: root
    MYSQL_PASSWORD: admin123
    MYSQL_ROOT_PASSWORD: admin123
    web:
    image: iiiepe/nginx-drupal6
    volumes:
    - application:/var/www
    - logs:/var/log/supervisor
    - files:/var/www/sites/default/files
    ports:
    - "80:80"
    links:
    - mysql:mysql
    environment:
    BASE_URL: http://local.iiiepe.net
    DRUPAL_ENVIRONMENT: development

    Docker Compose用此文件来初始化。在本例中,我们定义了一个应用,它包括两个容器:一个MySQL容器和一个Web容器。

    MySQL容器定义了mysql镜像要使用的环境变量。同时将宿主的3307端口映射到窗口的3306端口上。这允许我们使用任何客户端访问MySQL服务器。

    web容器使用了与Jenkins构建最终镜像时使用的相同镜像(见上述Dockerfile),但它同时共享了一些数据卷。在宿主和容器间共享的卷有应用、文件和日志。这实际是开发环境和生产环境间最大的改变:在生产环境中,容器的代码是在镜像中的,这允许我们在任何服务器上启动容器;而在开发环境中,目录只是共享的,因此在应用目录里,任何新的文件或对文件的修改都将即时地反映到容器里。

    BASE_URL变量指向了http://local.iiiepe.net,这不是个真实的地址,只是用于标准化应用访问的一个方式。因为我们有些人使用Mac和Boot2Docker,我们需要一个标准的地址以便所有人可以将其写入到/etc/hosts文件中。

    我的Mac上的/etc/hosts是这样的:

    127.0.0.1 localhost
    192.168.59.103 local.iiiepe.net

    在一台Linux机器上,看起来是这样的:

    127.0.0.1 localhost local.iiiepe.net

    最后,我们定义了两个环境变量来决定应用的配置文件的一些设置。
    # 自定义设置
    Drupal需要一个settings.php来存储数据库信息,包括密码。该文件将被Git忽略,以免将你的密码提交上去,我们决定修改这个文件,让它使用环境变量并将其提交。

    以下是一个Drupal 6网站的settings.php里的重要部分:

    $username = getenv("MYSQL_ENV_MYSQL_USER");
    $password = getenv("MYSQL_ENV_MYSQL_PASSWORD");
    $host = getenv("MYSQL_PORT_3306_TCP_ADDR");
    $port = getenv("MYSQL_PORT_3306_TCP_PORT");
    $database = getenv("MYSQL_ENV_MYSQL_DATABASE");

    $db_url = 'mysql://' . $username . ':' . $password . '@' . $host . '/' . $database;

    正如你所看到的,没有密码会被提交。密码和其它敏感值将通过ENV变量注入。

    有些网站使用Apache Solr作为搜索引擎,但在开发时,我们不希望能写入到Apache Solr,因此需要一个类似DRUPAL_ENVIRONMENT的ENV变量,完成类似下面的settings.php文件的事情:

    $conf = array();
    if(getenv("DRUPAL_ENVIRONMENT") === "development") {
    // Disable apache solr writting
    $conf["apachesolr_read_only"] = 1;
    }

    # Makefile
    由于命令很长,使用Docker非常不便,因此Docker Compose(fig)对此很有帮助。我们更进一步尝试让事情变得更简单一些。

    这是我们使用在一个Drupal网站上的Makefile:

    CURRENT_DIRECTORY := $(shell pwd)

    start:
    @fig up -d

    clean:
    @fig rm --force

    stop:
    @fig stop

    status:
    @fig ps

    cli:
    @fig run --rm web bash

    log:
    @tail -f logs/nginx-error.log

    cc:
    @fig run --rm web drush cc all

    restart:
    @fig stop web
    @fig start web
    @tail -f logs/nginx-error.log

    .PHONY: clean start stop status cli log cc restart

    使用Makefile比使用Docker Compose或Fig简单得多,因为我们可以创建类似`make cc`的快捷方式来运行类似`drush cc all`这样频繁使用的命令。

    有关Makefile的最后一点说明是:我们依然使用Fig。因为在我们设计这个工作流时,Docker Compose还不可用,而且我们团队里的一些开发人员还在使用它,我们决定为Docker Compose建立名为Fig的符号连接,名称更短且更实用。安装Docker Compose后,你可以删除fig并创建符号连接:

    sudo rm /usr/local/bin/fig
    sudo ln -s /usr/local/bin/docker-compose /usr/local/bin/fig

    # 走的弯路
    我们走过一些弯路,我将在别的文章中做介绍,不过有一个我想特别说一下。使用Docker最大的好处是,开发人员可以在与生产环境相同的环境上运行应用,且只损失一点点性能。

    我看过一些文章,说他们在Docker之外做开发,然后在需要部署时构建镜像并发送到生产环境。如果你这么做,那你就错了,因为你开发所用的环境与生产机上运行的不一致。不要每次都构建镜像,相反的,在宿主和容器间共享卷,让别人在你每次推送时构建镜像。

    未完待续……

    文章还远未结束,不过它已经太长了。我们依然需要说明我们是如何整合Maestro-NG、配置Jenkins以及负载均衡器是如何工作的。咱们回见!

    原文链接:A production ready Docker workflow(翻译:梁晓勇 校对:李颖杰)

    Oracle Linux上运行docker registry报错

    回复

    lindong 回复了问题 • 2 人关注 • 3 个回复 • 5857 次浏览 • 2017-09-30 19:23 • 来自相关话题

    Docker运行的Jenkins报“ERROR: Failed to push image: failed to respond”

    回复

    maxwell92 回复了问题 • 1 人关注 • 1 个回复 • 3225 次浏览 • 2017-05-02 14:37 • 来自相关话题

    [求助] 私有registry镜像已有层重推问题

    回复

    pekemon 发起了问题 • 1 人关注 • 0 个回复 • 1947 次浏览 • 2017-04-21 20:36 • 来自相关话题

    registry v2 删除镜像后,catalog仍然可以看到,如何解决

    回复

    braveht 回复了问题 • 3 人关注 • 3 个回复 • 3014 次浏览 • 2016-12-07 13:38 • 来自相关话题

    docker registry的ui界面,harbor和Portus哪个好

    回复

    clouding 回复了问题 • 6 人关注 • 4 个回复 • 7133 次浏览 • 2016-09-23 16:35 • 来自相关话题

    harbor使用中,利用私有镜像库做mirror registry 报 405 78 错误

    回复

    kilisky 回复了问题 • 4 人关注 • 3 个回复 • 4188 次浏览 • 2016-08-14 07:41 • 来自相关话题

    docker-registry 的搭建

    回复

    allansun 回复了问题 • 12 人关注 • 9 个回复 • 28812 次浏览 • 2016-06-02 01:31 • 来自相关话题

    官方没有registry:2镜像?

    回复

    yingz 回复了问题 • 2 人关注 • 1 个回复 • 2693 次浏览 • 2016-05-30 18:46 • 来自相关话题

    Docker Trusted Registry 和 Docker OpenSource Engine 的疑问

    回复

    Adrian 回复了问题 • 2 人关注 • 1 个回复 • 3067 次浏览 • 2016-05-09 08:16 • 来自相关话题

    私有仓库push镜像时提示failed to upload metadata...docker-registry: no such host

    回复

    holmes86 回复了问题 • 2 人关注 • 1 个回复 • 2718 次浏览 • 2015-12-11 09:59 • 来自相关话题

    容器生态系统简介

    cizixs 发表了文章 • 0 个评论 • 4712 次浏览 • 2017-03-15 14:02 • 来自相关话题

    原文地址:http://cizixs.com/2017/03/15/container-ecosystem。 很少有技术能够像 Docker 这样一出来就收到关注,并在很短的时间里发展壮大,而且几乎所有的技术公司都开始使用或者希望使用 ...查看全部
    原文地址:http://cizixs.com/2017/03/15/container-ecosystem。

    很少有技术能够像 Docker 这样一出来就收到关注,并在很短的时间里发展壮大,而且几乎所有的技术公司都开始使用或者希望使用。随着 docker 的出现,配置管理、微服务、数据中心自动化、devops 多个领域都重新焕发新机,好像 IT 行业的整个架构都要重新定义一样。

    【上海站|3天烧脑式微服务架构训练营】培训内容包括:DevOps、微服务、Spring Cloud、Eureka、Ribbon、Feign、Hystrix、Zuul、Spring Cloud Config、Spring Cloud Sleuth等。

    这篇文章我会介绍一下目前(2017年 3月)容器圈子(主要还是 docker) 一些主要的参与者,它们共同组成了繁荣的容器生态圈。
    docker.png

    容器引擎

    容器引擎(Engine)或者容器运行时(Runtime)是容器系统的核心,也是很多人使用“容器”这个词语的指代对象。容器引擎能够创建和运行容器,而容器的定义一般是以文本方式保存的,比如 Dockerfile。

    • Docker Engine :目前最流行的容器引擎,也是业界的事实标准
    • Rkt:CoreOS 团队推出的容器引擎,目前处于活跃发展阶段,被 kubernetes 调度系统支持
    云提供商(国外篇)容器飞速发展的时候,很多公司反应迅速,都相继推出了自己的公有云或者私有云的容器解决方案。国外比较有名的容器云提供商包括:
    • Amazon EC2 Container Serveice(ECS):云计算巨头 AWS 推出的容器服务,比较吸引人的是构建在 EC2 上面的 ECS 是免费的,用户只需要为底层的 EC2 资源付费
    • Google Container Engine(GKE):谷歌在错过大数据的福利之后,在云计算领域开始醒悟。在社区推出 kubernetes,企图制定容器调度集群的标准,而同时推出公有的 GKE 服务
    • Azure Container Service:作为巨头,微软也积极推出了容器服务,凭借积累的技术和商业资源迅速崛起
    • Jelastic
    • Docker Cloud:docker 自家的容器云服务,在收购了 Tutum 公司之后,利用 docker swarm 集群管理技术推出了方便使用的产品
    云提供商(国内篇)每次新技术的出现都会催生一堆公司,有大公司也有创业公司。不管是大数据、Iaas、人工智能还是现在的容器。国内公司目前对技术已经非常敏感,追逐和使用新技术的脚步从来没有落后过。虽然现在还没有在核心技术上制定标准和掀起浪潮,但是我相信不久之后中国会出现能够影响世界的技术。目前国内做容器比较知名的公司包括:
    • 阿里云:作为国内云服务的一哥,阿里云反应迅速,和 docker 建立 官方合作,也开始为自己的容器产品布道
    • 网易蜂巢:网易在自家的 IaaS 平台成熟之后,在此之上推出了容器云服务,据说内部产品已经大都迁移到容器
    • 灵雀云:云雀科技成立于2014年,由原微软Azure云平台的核心创始团队创立
    • 时速云:tenxcloud,基于 Kubernetes 的容器云计算平台,提供公有云和企业云服务
    • 数人云:基于 mesos 研发的轻量级 Pass 平台
    • 才云:使用的是 kubernetes 方案,2015 年成立的公司,提供私有云服务和人工智能解决方案
    • daocloud:企业级应用云平台及解决方案,坐标上海
    容器编排系统容器与虚拟机相比有个很大的优势就是轻量,这个特性的量变很快就引发了质变,让容器在各个技术角落施展拳脚。不过轻量级的容很容易造成混乱,面对成百上千乃至更多的容器,必须要有统一的管理平台。所以目前容器技术最热烈的激战也在这个领域,所有要使用容器的企业必须要在容器管理系统做出自己的抉择。
    • Kubernetes:Google 家开源的容器管理系统,起源于内部历史悠久的 Borg 系统。因为其丰富的功能被多家公司使用,不仅支持 docker ,还支持其他容器(比如 Rkt),但是也相对复杂,易用性差一点
    • Docker Swarm: 从 docker1.12.0 版本之后,docker 就推出了 docker swarm 模式。用户能够轻松快速搭建出来 docker 容器集群,几乎完全兼容 docker API 的特性让它很容易被用户接受。可以说潜力很大,至于最后能发展成什么样子还要时间检验
    • Mesosphere:起源于 Apache Mesos 的调度框架,目标是成为数据中心的操作系统,完全接管数据中心的管理工作
    • Rancher:其易用的界面和完全开源的特性吸引不少刚接触容器的技术人员,同时兼容 kubernetes、mesos 和 swarm 集群系统。但目前社区不是很活跃,二次开发的难度较大
    • Nomad:HashiCorp 开源的集群管理和调度系统,如果需要其他功能(比如服务发现、密码管理等)需要自己使用其他工具进行集成
    容器基础镜像容器虽然轻量,但是传统的基础镜像并非如此。因此有很多企业尝试着打造专门为容器而生的操作系统,希望能成为容器时代的新选择。
    • CoreOS:以容器为中心的操作系统,配置管理、自动扩容、安全等方面有一套完整的工具
    • Project Atomic:一个轻量级的操作系统,可以运行 docker、kubernetes、rpm 和 systemd
    • Ubuntu Core:轻量级 ubuntu 操作系统,适合运行 IoT 设备或者容器集群
    • Rancher OS:只有 50M+ 的操作系统,为运行 docker 容器打造。有趣的是,它可以让系统容器和用户容器运行在不同的 Docker Daemon 上,从而实现隔离效果
    • Project Photon:VMware 开源的项目,旨在提供极简化的容器主机系统
    镜像 registry镜像 registry 是存储镜像的地方,可以方便地在团队、公司或者世界各地分享容器镜像,也是运行容器最基本的基础设施。
    • Docker Registry:Docker 公司提供的开源镜像服务器,也是目前最流行的自建 registry 的方案
    • Dockerhub:docker 公司提供的公共镜像 registry,可以通过 UI 来查看和管理镜像,上面也有大量的标准镜像可以下载
    • Quay:提供镜像管理和安全检查服务的 公有 registry
    • Harbor:企业级的镜像 registry,提供了权限控制和图形界面
    容器监控
    • cAdvisor:Google 开源的容器使用率和性能监控工具
    • Datadog Docker:能够收集 docker 的运行信息,并发送到 Datadog 进行分析
    • NewRelic Docker:收集 docker 的运行信息,并发送到 NewRelic 进行分析
    • Sysdig:同时提供开源版本和企业版本,能够监控容器使用率和性能,并对性能就行分析
    网络容器的大规模使用,也对网络提供了更高的要求。网络的不灵活也是很多企业的短板,目前也有很多公司和项目在尝试解决这些问题,希望提出容器时代的网络方案。
    • Weave Net:weaveworks 给出的网络的方案,使用 vxlan 技术, 支持网络的隔离和安全
    • Flannel:CoreOS 开源的网络方案,为 kubernetes 设计,支持不同的后端实现
    • Calico:一个纯三层的网络解决方案,使用 BGP 协议进行路由,可以集成到 openstack 和 docker
    • Contiv: 能够打通物理机、虚拟机和容器之间连通性的网络方案
    服务发现容器和微服务的结合创造了另外的热潮,也让服务发现成功了热门名词。可以轻松扩展微服务的同时,也要有工具来实现服务之间相互发现的需求。目前主要有三种工具,当然它们可能已经集成到其他的容器管理系统中。
    • etcd:CoreOS 开源的分布式 key-value 存储,通过 HTTP 协议提供服务,因此使用起来简单。但是 etcd 只是一个 key-value 存储,默认不支持服务发现,需要三方工具来集成。kubernetes 默认就使用 etcd 作为存储
    • consul:HashiCorp 开源的服务发现和配置管理工具,自带服务发现特性(DNS Server)。它是强一致性的数据存储,使用 gossip 协议形成动态集群
    • zookeeper:比较悠久的服务发现项目,起源于 Hadoop 社区,优点是成熟、可靠、功能丰富,缺点是使用 Java 开发,配置比较麻烦
    参考资料

    如何创建一个有密码保护的私有Docker Registry

    Rancher 发表了文章 • 1 个评论 • 6695 次浏览 • 2017-02-04 09:47 • 来自相关话题

    上篇文档中,我已经详细介绍了如何快速简单的部署Rancher Server,启用Github认证以及数据保持方便后续的升级操作。在这篇文档中,我将梳理下如何创建一个有密码保护的私有Docker Registry以及如何和Rancher整合。我们将下载一个容器镜 ...查看全部
    上篇文档中,我已经详细介绍了如何快速简单的部署Rancher Server,启用Github认证以及数据保持方便后续的升级操作。在这篇文档中,我将梳理下如何创建一个有密码保护的私有Docker Registry以及如何和Rancher整合。我们将下载一个容器镜像,为其设置标签并推送至此Registry。最后,我们将通过Rancher Server部署此容器镜像。

    虽然我建议大家使用AWS S3,但是我在此将使用registry:2,把所有的数据存放在主机本地。

    我们需要提前准备如下工作:

    • 域名所对应的证书,我将使用regv2.piel.io
    • 一个兼容.htaccess的密码
    我将通过letsencrypt.org以及一个Docker脚本来快速创建第一个证书。
    • 复制 git@github.com:fatk/docker-letsencrypt-nginx-proxy-companion-examples.git
    • 修改docker-letsencrypt-nginx-proxy-companion-examples/dockerdocker-run/simple-site/docker-run.sh,将site.example.com修改为你将使用的域名
    • 运行脚本
    $ git clone git@github.com:fatk/docker-letsencrypt-nginx-proxy-companion-examples.git$ cd docker-letsencrypt-nginx-proxy-companion-examples# Modify the script and replace site.example.com $ vi dockerdocker-run/simple-site/docker-run.sh$ ./docker-run.sh
    脚本运行后,将启动一个nginx实例,一个docker-gen实例,一个letsencrypt-nginx-proxy-companion实例以及最终的nginx实例。 我们来看下脚本运行成功后有哪些容器启动了:看上去已经成功了,但是我们刚刚创建的证书在哪儿?
    $ ls volumes/proxy/certsdhparam.pem  regv2.piel.io  regv2.piel.io.crt  regv2.piel.io.dhparam.pem  regv2.piel.io.key
    以及:
    $ ls volumes/proxy/certs/regv2.piel.ioaccount_key.json  cert.pem  fullchain.pem  key.pem
    很好,接下来我们可以将regv2.piel.io.key以及fullchain.pem用于容器registry:2. 下面我们创建registry可以访问到的证书目录
    $ mkdir -p /data/docker-registry-certs$ cp volumes/proxy/certs/regv2.piel.io.key /data/docker-registry-certs/$ cp volumes/proxy/certs/regv2.piel.io/fullchain.pem /data/docker-registry-certs/$ mkdir /data/docker-registry-auth$ mkdir /data/docker-registry
    最后一步,创建访问registry的用户名和密码,此为访问docker registry:2的最低安全措施配置。
    $ docker run --entrypoint htpasswd registry:2 -Bbn pieltestuser \"mkakogalb47" > /data/docker-registry-auth/htpasswd
    该命令要求主机上已经存在registry:2 镜像,所以在运行htpasswd命令前它会自动下载此镜像。之后,此容器会自动停止。 检查下htpasswd是否已经被创建:
    $ cat /data/docker-registry-auth/htpasswdpieltestuser:$2y$05$w3IqOzTdsDbot9ls1JpeTeHYr/2vv.PTx3dObRvT.JkfGaygfTkJy
    最后,运行registry:2
    $ docker run -d -p 5000:5000 --restart=always --name docker-registry \  -v /data/docker-registry:/var/lib/registry \  -v /data/docker-registry-auth:/auth \  -e "REGISTRY_AUTH=htpasswd" \  -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \  -e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" \  -v /data/docker-registry-certs:/certs \  -e "REGISTRY_HTTP_TLS_CERTIFICATE=/certs/fullchain.pem" \  -e "REGISTRY_HTTP_TLS_KEY=/certs/regv2.piel.io.key" \  registry:2 $ docker run -d -p 5000:5000 --restart=always --name docker-registry \  -v /data/docker-registry:/var/lib/registry \  -v /data/docker-registry-auth:/auth \  -e "REGISTRY_AUTH=htpasswd" \  -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \  -e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" \  -v /data/docker-registry-certs:/certs \  -e "REGISTRY_HTTP_TLS_CERTIFICATE=/certs/fullchain.pem" \  -e "REGISTRY_HTTP_TLS_KEY=/certs/regv2.piel.io.key" registry:2
    我们试一下是否可以登陆:
    $ docker login -u pieltestuser -p "mkakogalb47" -e wayne@wayneconnolly.com regv2.piel.io:5000$ docker login -u pieltestuser -p "mkakogalb47" -e wayne@wayneconnolly.com regv2.piel.io:5000WARNING: login credentials saved in /root/.docker/config.jsonLogin Succeeded
    接下来我们试下是否可以下载、标记、上传容器镜像至我们的新镜像仓库。例如,下载一个jenkins https://hub.docker.com/_/jenkins/
    $ docker pull jenkins$ docker tag jenkins:latest regv2.piel.io:5000/piel-jenkins:latest
    验证下是否可用 很好,上传到我们的镜像仓库。
    $ docker push regv2.piel.io:5000/piel-jenkins:latest
    直到写这篇文章的时候,除了用Curl,还没有很好的方法可以直接看到镜像库中的镜像列表
    $ curl -u pieltestuser:mkakogalb47 https://regv2.piel.io:5000/v2/_catalog{"repositories":["piel-jenkins"]}
    可以通过JSON看到我们的新Jenkins镜像在我们的私有镜像库中 现在可以在我们的Rancher-test.piel.io环境中应用我们的registry了。 登陆Rancher,在基础架构 > 主机中点击添加主机。 将自动生成的命令在Rancher Host上运行。
    $ sudo docker run -e CATTLE_AGENT_IP='45.32.190.15'  \  -d --privileged \  -v /var/run/docker.sock:/var/run/docker.sock \  -v /var/lib/rancher:/var/lib/rancher \  rancher/agent:v1.0.1 http://rancher-test.piel.io/v1/scripts/FF42DCE27F7C88BD7733:1461042000000:ryU0BaXJFo6c9zuHgeULdAtbCE$ sudo docker run -d --privileged \  -v /var/run/docker.sock:/var/run/docker.sock \  -v /var/lib/rancher:/var/lib/rancher \   rancher/agent:v0.11.0http://rancher.piel.io/v1/scripts/BE455B92EA48EA1C1F12:1461042000000:mi433ChYRN9nfQSwB2FIlBnpPk
    一两分钟后主机将在Rancher管理界面中出现。由于我还没有配置主机信息,主机显示名称依然为“vultr.guest”, 我们可以通过菜单修改主机名称并添加标签。 接下来,我们添加私有registry并在新增加的主机上部署Jenkins。 在基础架构菜单 > 镜像库中点击“添加镜像库”,并选择自定义,添加相应的信息完成配置。 几分钟之后,Rancher server的私有镜像仓库就可以使用了。 下面让我们部署Jenkins容器。在基础架构 > 容器菜单中,点击“添加容器” 填写所需信息,在选择image一处输入regv2.piel.io:5000/piel-jenkins: latest并设置端口映射为Jenkins 8080到主机的80端口。 此处将需要一点时间下载镜像。 下面我们将看到我们又一个容器叫做“my-jenkins”已经启动了。 访问到Jenkins URL,http://regv2.piel.io。 通过docker ps再确认一次: 成功!我们现在已经完成了:
    • 创建并加密了我们自己的私有镜像库
    • 添加并标记了一个容器镜像
    • 为Rancher Server添加了一个主机
    • 为Rancher Server增加了一个私有镜像库
    • 在主机上部署了一个Jenkins容器
    • 确认容器已经部署成功


    注意:在本教程中使用的服务器现在已经退役啦。



    原文来源:Rancher Labs

    VMware Harbor:基于 Docker Distribution 的企业级 Registry 服务

    Rancher 发表了文章 • 2 个评论 • 4851 次浏览 • 2016-12-06 08:12 • 来自相关话题

    原文来源:Rancher Labs 前言 对于 Harbor 这样一个优秀的 Docker Registry 管理开源项目,以下内容基本上来自前人已有的研究,我只是将其在实践中进行了测试,并整理汇集了相关资料 ...查看全部
    原文来源:Rancher Labs

    前言

    对于 Harbor 这样一个优秀的 Docker Registry 管理开源项目,以下内容基本上来自前人已有的研究,我只是将其在实践中进行了测试,并整理汇集了相关资料供大家参考,同时针对 Harbor 与 Rancher产品的整合做了一些实验性的工作,以更好更全面的理解 Harbor 这个工具,也更加了解 Rancher 在快速一键部署、弹性伸缩高可用等方面的优势。

    Harbor 简介

    Harbor 是一个企业级 Registry 服务。它对开源的 Docker Registry 服务进行了扩展,添加了更多企业用户需要的功能。Harbor 被设计用于部署一套组织内部使用的私有环境,这个私有 Registry 服务对于非常关心安全的组织来说是十分重要的。另外,私有 Registry 服务可以通过避免从公域网下载镜 像而提高企业生产力。这对于没有良好的 Internet 连接状态,使用 Docker Container 的用户是一个福音。

    • 基于角色的访问控制:用户与 Docker 镜像仓库通过“项目”进行组织管理,一个用户可以对多个镜像仓库在同一命名空间(project)里有不同的权限。
    • 图形化用户界面:用户可以通过浏览器来浏览,检索当前 Docker 镜像仓库,管理项目和命名空间。
    • 审计管理 :所有针对镜像仓库的操作都可以被记录追溯,用于审计管理。
    • 国际化:基于英文与中文语言进行了本地化。可以增加更多的语言支持。
    • RESTful API - RESTful API :提供给管理员对于 Harbor 更多的操控, 使得与其它管理软件集成变得更容易。
    Harbor 架构介绍 #(1)主要组件Harbor 在架构上主要由五个组件构成:
    • Proxy:Harbor 的 registry, UI, token 等服务,通过一个前置的反向代理统一接收浏览器、Docker 客户端的请求,并将请求转发给后端不同的服务。
    • Registry:负责储存 Docker 镜像,并处理 docker push/pull 命令。由于我们要对用户进行访问控制,即不同用户对 Docker image 有不同的读写权限,Registry 会指向一个 token 服务,强制用户的每次 docker pull/push 请求都要携带一个合法的 token, Registry 会通过公钥对 token 进行解密验证。
    • Core services:这是 Harbor 的核心功能,主要提供以下服务:
    UI:提供图形化界面,帮助用户管理 registry 上的镜像(image),并对用户进行授权; webhook:为了及时获取 registry 上 image 状态变化的情况, 在 Registry 上配置 webhook,把状态变化传递给 UI 模块; token 服务:负责根据用户权限给每个 docker push/pull 命令签发 token。Docker 客户端向Registry 服务发起的请求,如果不包含 token,会被重定向到这里,获得 token 后再重新向 Registry进行请求;
    • Database:为 core services 提供数据库服务,负责储存用户权限、审计日志、Docker image 分组信息等数据。
    • Log collector:为了帮助监控 Harbor 运行,负责收集其他组件的 log,供日后进行分析。各个组件之间的关系如下图所示:
    #(2)实现Harbor 的每个组件都是以 Docker 容器的形式构建的,因此很自然地,我们使用 Docker Compose 来对它进行部署。在源代码中 (https://github.com/vmware/harbor),用于部署 Harbor 的 Docker Compose 模板位于 /Deployer/docker-compose.yml. 打开这个模板文件,会发现 Harbor 由 5 个容器组成:
    • proxy:由 Nginx 服务器构成的反向代理。
    • registry:由 Docker 官方的开源 registry 镜像构成的容器实例。
    • ui:即架构中的 core services, 构成此容器的代码是 Harbor 项目的主体。
    • mysql:由官方 MySql 镜像构成的数据库容器。
    • log: 运行着 rsyslogd 的容器,通过 log-driver 的形式收集其他容器的日志。
    这几个容器通过 Docker link 的形式连接在一起,这样,在容器之间可以通过容器名字互相访问。对终端用户而言,只需要暴露 proxy (即 Nginx)的服务端口。#(3)工作原理下面以两个 Docker 命令为例,讲解主要组件之间如何协同工作。 1) docker login假设我们将 Harbor 部署在主机名为 registry.yourdomainname.com 的虚机上。用户通过 docker login 命令向这个 Harbor 服务发起登录请求:docker login registry.yourdomainname.com当用户输入所需信息并点击回车后,Docker 客户端会向地址“registry.yourdomainname.com/v2/” 发出 HTTP GET 请求。 Harbor 的各个容器会通过以下步骤处理:(a) 首先,这个请求会由监听 80 端口的 proxy 容器接收到。根据预先设置的匹配规则,容器中的 Nginx会将请求转发给后端的 registry 容器;(b) 在 registry 容器一方,由于配置了基于 token 的认证,registry 会返回错误代码 401,提示 Docker客户端访问 token 服务绑定的 URL。在 Harbor 中,这个 URL 指向 Core Services;(c) Docker 客户端在接到这个错误代码后,会向token服务的URL发出请求,并根据HTTP协议的BasicAuthentication 规范,将用户名密码组合并编码,放在请求头部(header); (d)类似地,这个请求通过 80 端口发到 proxy 容器后,Nginx 会根据规则把请求转发给 ui 容器,ui 容器监听 token 服务网址的处理程序接收到请求后,会将请求头解码,得到用户名、密码;(e) 在得到用户名、密码后,ui 容器中的代码会查询数据库,将用户名、密码与 mysql 容器中的数据进行比对(注:ui 容器还支持 LDAP 的认证方式,在那种情况下 ui 会试图和外部 LDAP 服务进行通信并校验用户名/密码)。比对成功,ui 容器会返回表示成功的状态码, 并用密钥生成 token,放在响应体中返回给 Docker 客户端。这个过程中组件间的交互过程如下图所示:至此,一次 docker login 成功地完成了,Docker 客户端会把步骤(c)中编码后的用户名密码保存在本地的隐藏文件中。 2) docker push用户登录成功后用 docker push 命令向 Harbor 推送一个 Docker 镜像:docker push registry.youdomainname.com/library/hello-world(a) 首先,docker 客户端会重复 login 的过程,首先发送请求到 registry,之后得到 token 服务的地址;(b) 之后,Docker 客户端在访问ui容器上的token服务时会提供额外信息,指明它要申请一个对imagelibrary/hello-world 进行 push 操作的 token;(c) token 服务在经过 Nginx 转发得到这个请求后,会访问数据库核实当前用户是否有权限对该 image进行 push。如果有权限,它会把 image 的信息以及 push 动作进行编码,并用私钥签名,生成 token返回给 Docker 客户端;(d) 得到 token 之后 Docker 客户端会把 token 放在请求头部,向 registry 发出请求,试图开始推送image。 Registry 收到请求后会用公钥解码 token 并进行核对,一切成功后,image 的传输就开始了。我们省去 proxy 转发的步骤,下图描述了这个过程中各组件的通信过程 :Harbor 单机安装调试步骤此次示范以 CentOS 7.2.1511 x86_64 为例:
    [root@registry ~]# yum install https://yum.dockerproject.org/repo/main/centos/7/Packages/docker-engine-selinux-1.11.2-1.el7.centos.noarch.rpm[root@registry ~]# yum install https://yum.dockerproject.org/repo/main/centos/7/Packages/docker-engine-1.11.2-1.el7.centos.x86_64.rpm[root@registry ~]# systemctl enable docker[root@registry ~]# systemctl start docker[root@registry ~]# yum install git[root@registry ~]# git clone https://github.com/vmware/harbor[root@registry ~]# cd harbor/[root@registry harbor]# cd Deploy/[root@registry Deploy]# vi harbor.cfg
    修改的重点内容如下:
    hostname = registry.yourdomainname.comui_url_protocol = httpsemail_server = smtp.yourmailserver.comemail_server_port = 25email_username = registry_admin@yourdomainname.comemail_password = yourpasswordemail_from = registry_admin@yourdomainname.comemail_ssl = falseharbor_admin_password = myharborpasswordauth_mode = db_authdb_password = yoursqlpasswordself_registration = offcustomize_crt = off
    修改完成假设已经准备好站点的数字证书文件 registry.yourdomainname.com.crt 和registry.yourdomainname.com.key,则可以配置 https 的访问模式:
    [root@registry Deploy]# cd config/nginx/[root@registry nginx]# ls cert/registry.yourdomainname.com.crt registry.yourdomainname.com.key[root@registry nginx]# mv nginx.conf nginx.conf.bak[root@registry nginx]# cp nginx.https.conf nginx.conf[root@registry nginx]# vi nginx.conf
    修改内容如下:修改内容结束安装 docker-compose 命令:添加 harbor 的启停脚本: 添加 harbor 为 systemd 服务:管理 Harbor 的生命周期:关于数字证书,上面的描述适用于向第三方根证书颁发机构申请得到的数字证书文件,如果是自签名数字证书,可参考 Harbor 官方文档:https://github.com/vmware/harbor/blob/master/docs/configure_https.md访问 Harbor:[list=1]
  • 网页访问方式 https://registry.yourdomainname.com
  • [list=1]
  • Linux Docker 客户端如需要访问这个仓库服务器,如果数字证书的根证书颁发机构不在系统列表里,则需要手动添加信任关系(需要将证书文件 registry.yourdomainname.com.crt 拷贝至指定目录),然后更新证书缓存:


  • cp registry.yourdomainname.com.crt /usr/local/share/ca-certificates/update-ca-certificates



    以上两条命令适用于 Ubuntu 系列


    cp registry.yourdomainname.com.crt /etc/pki/ca-trust/source/anchors/update-ca-trust



    以上两条命令适用于 RHEL 或 CentOS 系列

    登陆及 push image 过程:


    [root@RancherHost01 ~]# docker login
    registry.yourdomainname.com
    Username: admin
    Password:
    Login Succeeded
    [root@RancherHost01 ~]#




    登陆 Web 端即可看见已经上传的 image 了:



    新增用户界面:



    Harbor 作为 Mirror Registry

    Mirror 是 Docker Registry 的一种特殊类型,它起到了类似代理服务器的缓存角色,在用户和Docker Hub 之间做 Image 的缓存。

    其基本工作原理是,当用户 pull 一个镜像时,若镜像在 mirror 服务器存在,则直接从 mirror 服务器拉取,否则若不存在该镜像,则由 mirror server 自动代理往 dockerhub(可配置)中拉取镜像,并缓存到 mirror 服务器中,当客户再次拉取这个镜像时,直接从 mirror server 中拉取,不需要再次从docker hub 中拉取。

    Harbor 目前不支持 pull cache 功能,已提交 Github issue #120。
    https://github.com/vmware/harbor/issues/120

    不过我们只需要手动修改下配置即可完成,具体配置可查看官方 Registry as a pull through cache.
    https://github.com/vmware/harbor/commit/5e3d3afb1184b91c7aaac8618cc5ca1a5fe85bc7

    我们在运行./prepare 之前修改 config/registry/config.yml 文件,追加以下配置


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


    如果需要访问私有仓库,需要填写 Docker Hub 的用户名和密码


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


    然后重新启动 Harbor 服务:(注意不要执行./prepare)


    docker-compose stop
    docker-compose rm -f
    docker-compose up -d


    除了设置 Harbor(或者 registry),还需要配置本地 docker 服务,指定--registry-mirror 参数,修改docker 配置文件


    Ubuntu:/etc/default/docker

    DOCKER_OPTS="$DOCKER_OPTS --registry-mirror=https://registry.yourdomainname.com





    DOCKER_OPTS="$DOCKER_OPTS --registry-mirror=https://registry.yourdomainname.com --insecure-registry

    registry.yourdomainname.com"


    或者


    RHEL/CentOS:/usr/lib/systemd/system/docker.service):
    [Service]
    ExecStart=
    ExecStart=/usr/bin/docker daemon -H fd:// --registry-mirror=https://registry.yourdomainname.com


    注意:修改了 docker 配置文件,必须重启 docker 服务才能生效。



    Harbor 由于引进了认证功能,因此 push 操作时,必须保证 project 存在,比如 push krystism/ffmpeg,必须保证 Harbor 创建了 krystism project,否则会失败。为了能够正常 push/pulldockerhub 的官方镜像,务必创建 library project,如图:




    #(1)假设本地不存在 python 镜像:

    我们第一次 pull python 后,Harbor 发现不存在该镜像,于是自己作为代理往 Docker Hub 里拉取,拉取后保存到本地,可以通过 Web UI 查看。客户端再次拉取 python 镜像时,由于 Harbor 已经存在该镜像,因此不需要再往 Docker Hub 拉取,速度大幅度提高!

    注意,对于 Mirror Registry 模式,虽然可以 pull cache 了,但是 push 功能却不被支持了:https://github.com/vmware/harbor/issues/220

    #(2)与 Rancher 的整合:

    1)Add Harbor deploy stack and 5 services in Rancher: (在 Rancher 系统里添加包含 5 个 services 的stack)



    2)Add Registry server in Rancher: (在 Rancher 系统里添加 Registry 服务器,供 Rancher Agent Hosts调用)



    3)Build a Catalog entry in Rancher:(为 Harbor 创建一个 Rancher 专有的应用模板项,实现一键部署,使安装调试复杂的 Harbor 产品简单化、并实现弹性伸缩及高可用等特性)



    #(3)对接 LDAP 认证:

    Harbor 支持两种认证方式,默认为本地存储,即账号信息存储在 mysql 下,上文已经具体介绍。接下来介绍另外一种认证方式 LDAP,只需要修改配置文件即可。需要提供 ldap url 以及 ldap basedn 参数,并且设置 auth_mode 为 ldap_auth。

    快速部署 LDAP 服务:

    为了测试方便,我们使用 Docker 启动一个 LDAP 服务器,启动脚本如下:


    !/bin/bash
    NAME=ldap_server
    docker rm -f $NAME 2>/dev/null
    docker run --env LDAP_ORGANISATION="Unitedstack Inc." \--env LDAP_DOMAIN="ustack.com" \
    --env LDAP_ADMIN_PASSWORD="admin_password" \
    -v pwd/containers/openldap/data:/var/lib/ldap \
    -v pwd/containers/openldap/slapd.d:/etc/ldap/slapd.d \--detach --name $NAME osixia/openldap:1.1.2


    创建新用户,首先需要定义 ldif 文件,


    new_user.ldif:dn: uid=test,dc=ustack,dc=com
    uid: test
    cn: test
    sn: 3
    objectClass: topobjectClass: posixAccountobjectClass: inetOrgPersonloginShell: /bin/bashhomeDirectory:

    /home/testuidNumber: 1001gidNumber: 1001userPassword: 1q2w3e4rmail: test@example.comgecos: test


    通过以下脚本创建新用户,其中 ldap_server 为 LDAP 服务容器名称。


    docker cp new_user.ldif ldap_server:/
    docker exec ldap_server ldapadd -x \
    -D "cn=admin,dc=ustack,dc=com" \
    -w admin_password \-f /new_user.ldif -ZZ


    查看用户是否创建成功:


    docker exec ldap_server ldapsearch -x -h localhost \
    -b dc=ustack,dc=com -D "cn=admin,dc=ustack,dc=com" \
    -w admin_password


    检查 test 用户是否存在,若存在,则说明创建成功,否则需要使用 docker logs 查看日志。

    配置 Harbor 使用 LDAP 认证
    修改 harbor.cfg 文件关于 LDAP 配置项,如下


    :auth_mode = ldap_auth
    ldap_url = ldap://42.62.x.x
    ldap_basedn = uid=%s,dc=ustack,dc=com


    然后重新部署 Harbor:


    ./prepare
    docker-compose stop
    docker-compose rm -f
    docker-compose up -d


    测试是否能够使用 test 用户登录:


    docker login -u test -p 1q2w3e4r \
    -e test@example.com 42.62.x.x

    SUSE Portus + Docker Registry在Rancher环境下的部署实战

    Rancher 发表了文章 • 1 个评论 • 2179 次浏览 • 2016-12-02 09:51 • 来自相关话题

    原文来源:Rancher Labs 在正文之前,我们先来看一下,如果没有容器,通常会如何部署 Docker Registry?关于这个问题,我简单画了一个草图: 下面简单解释一下 ...查看全部
    原文来源:Rancher Labs

    在正文之前,我们先来看一下,如果没有容器,通常会如何部署 Docker Registry?关于这个问题,我简单画了一个草图:



    下面简单解释一下:

    Nginx:用来做 Docker Registry 的代理和软件负载均衡Keepalived 采用主备加虚拟 IP 的方式,解决 Nginx 的单点问题,保证 Nginx 服务的高可用性。

    Docker Registry:这是 Docker 官方开源的私有镜像仓库项目,对应 github 上的 docker-distribution 项目,也是私有镜像仓库的核心。

    Redis:大名鼎鼎的 Key-Value 数据库,很多应用场景中,将其作为缓存使用。在 Docker Registry中也不例外,用来缓存 Docker Image 的 laryer metadata,带来的好处即是 laryer metadata 的快速访问。

    Storage Cluster Docker Registry:以存储驱动的方式支持多种后端存储。例如:Docker Registry2.3 目前支持如下的存储驱动:



    这里简单做个补充,官方文档也有介绍如何贡献新的 Docker Registry 存储驱动。

    下面我们来看一下,在 Rancher 环境下,一个简化版 Docker Registry 的部署结构图,如下图所示:



    这个图是以 Rancher 下服务的视角画的,部署这样一个简单的 Docker Registry,需要四个服务,分别是外部存储服务、Redis Cache 服务、Docker Registry 服务和负载均衡服务。用户访问 Docker Registry 通过使用负载均衡服务的IP和端口。Docker Registry 的负载均衡服务,需要做源 IP会话保持配置。

    到此为止,我们就在 Rancher 环境下部署了一个简化版的 Docker Registry 服务。至于我为什么说其是简化版呢?是因为现在这个版本存在一些问题。

    首先,Docker Registry 本身没有 Web UI,镜像的检索,只能通过命令行工具完成,使用起来非常不方便。

    其次,Docker Registry 自身没有基于角色权限访问控制,所有可以访问负载均衡服务的用户都能随意的推送和拉取镜像。

    最后,Docker Registry 本身是提供了基于 token 的认证机制,需要接入 Authorization Service,这个服务官方没有实现,需要我们自己实现或者借助开源实现。

    SUSE Portus 完美地解决了上述问题。下面我们看一下,在 Rancher 环境下加入 SUSE Portus的服务结构图:



    Portus Core Cluster 服务负责给 Docker Registry 提供 token 认证服务和接收 Docker Registry 发送的镜像推送的通知,同步 Docker Registry 中的镜像信息到 SUSE Portus 的数据库中。该服务本身无状态,可以水平扩展PortusCronSync负责定时请求DockerRegistryAPI 同步镜像数据到SUSEPortus的数据库中。

    当用户向 Docker Registry 推送一个镜像后,Docker Registry 会发送通知给 SUSE Portus,如果网络闪断,或者 SUSE Portu 服务中断,会做有限次数的重试。这样可能会导致 SUSE Portu 无法收到镜像推送的通知,造成两端数据的不一致。Portus Cron Sync 就是为了解决这个问题而存在的。

    SUSE Portus 的 token 认证服务完全满足官方的认证模型,Docker 官方的认证模型如下图所示:



    Docker Registry 关于认证服务的配置和通知目标服务的配置,都在 Docker Registry 容器的/etc/docker/registry/config.yml 中:




    最后,我们可以按照 Rancher Catalog 的规范,制作一些基础镜像,然后把这个服务 Catalog化,做成一键部署。

    使用Squid3搭建Docker镜像下载代理

    FanLin 发表了文章 • 9 个评论 • 11812 次浏览 • 2016-06-13 00:27 • 来自相关话题

    这篇文章来聊一聊怎么搭建用于Docker下载镜像的代理服务。 Squid3是啥 先说点废话,什么是代理服务器,以及为什么要使用代理服务器。 在国内下载DockerHub的镜像老慢 ...查看全部
    这篇文章来聊一聊怎么搭建用于Docker下载镜像的代理服务。

    Squid3是啥

    先说点废话,什么是代理服务器,以及为什么要使用代理服务器。

    在国内下载DockerHub的镜像老慢了有木有,时不时还超时出错有木有,gcr.io仓库访问不了有木有,换用国内仓库又要修改镜像名字,各种麻烦有木有。

    (注:gcr.io是由Google CloudPlatform提供的Docker镜像仓库)

    现在都云时代了,在搞一个在海外的云主机多容易的事,阿里云首都在线早都有国外机房了。可是总不能把所有主机都往国外搬,毕竟业务还在国内,远水不解近渴。

    代理服务器就可以让处在国内的服务器在需要的时候通过一条通往外界的管道,间接的下载到国内无法下载或者下载不稳定的镜像。

    proxy.png


    代理服务器依据使用的方式可以分成正向代理、反向代理、透明代理等许多种,依据代理的协议又可以分为HTTP、HTTPS、FTP、SOCK5等众多类型。Docker能够使用的是HTTP和HTTPS的代理服务,而Squid是目前功能最完善且支持HTTPS正向代理的开源服务软件。

    Squid目前的版本已经更新到3.x版本,因此称为Squid3,以示与前两版本的区别。

    光速搭建Squid服务

    怎样搭建Squid服务器最快呢?当然是使用Docker啦。我们可以直接使用『sameersbn/squid』这个镜像,这个镜像是DockerHub上Squid镜像中依然在持续更新的、文档比较全面的、下载次数比较多的,在我写这篇文章时候,这个镜像的最新版本是『3.3.8-14』。

    这个镜像的最简单使用方法是:

    ``` docker run -d -p 3128:3128 sameersbn/squid:3.3.8-14 ```

    这样一个内网使用的HTTP的代理就搭建完成了。Squid默认使用3128作为代理端口,可以将内网主机的代理服务设置为这个代理服务器的IP地址加上3128端口,试一试能否访问因特网的资源。如果遇到问题,可以进入容器内查看一下/var/log/squid3/cache.log这个文件看看是不是有什么错误。

    配置Squid代理服务

    默认的sameersbn/squid镜像只允许来自内网IP段的主机使用代理,并且包含了许多用于其他协议的配置内容。

    然而使用Docker的服务器可能也有非内网IP段的地址,因此需要对Squid3配置进行适当的删改。以下为一个最简单的配置内容:

    ``` acl all src 0.0.0.0/0.0.0.0
    acl SSL_ports port 443
    acl Safe_ports port 80 # http
    acl Safe_ports port 443 # https
    acl CONNECT method CONNECT
    http_access allow all
    http_port 3128
    visible_hostname proxy
    ```

    将这个文件保存为『squid.conf』,保存到主机的/etc/squid3目录,然后让我们使用这个配置文件来启动Squid的容器。

    由于Squid服务本身具备代理和缓存两个功能(缓存的功能这里不做详细介绍,可以问度娘自行搜索),建议为这个容器设置一下CPU、内存和磁盘的限额,防止极端情况下会把主机资源耗尽。为了方便调试和使用,可以给容器起一个容易记忆的名字,顺便将Squid的缓存和日志目录也挂载到主机上。完整命令如下:

    ```
    docker run -d --name squid3 --restart=always \
    -m 1G \
    -p 3128:3128 \
    -v /etc/squid3/squid.conf:/etc/squid3/squid.conf \
    -v /var/log/squid3:/var/log/squid3 \
    -v /var/spool/squid3:/var/spool/squid3 \
    sameersbn/squid:3.3.8-14 ```

    现在这个代理服务就可以作为通用的HTTP和HTTPS代理了!

    让Docker使用Squid下载镜像

    那么最后一个问题就是,怎样让Docker去使用这个代理服务器呢?

    首先我们需要找到Docker启动的配置,以Systemd管理的系统为例,首先使用『systemctl show docker』命令找到Docker服务的配置文件。例如:

    ``` $ systemctl show docker | grep /lib/systemd/system/docker.service
    FragmentPath=/lib/systemd/system/docker.service ```

    然后编辑这个文件:

    ``` $ sudo vim /lib/systemd/system/docker.service ```

    在[Unit]段加上下面这两行:

    ``` Environment=HTTP_PROXY={SERVER_IP}:3128 ```
    ``` Environment=HTTPS_PROXY={SERVER_IP}:3128 ```

    (注:将{SERVER_IP}替换为实际的服务器IP地址)

    然后重新启动Docker服务就可以啦~

    ``` $ sudo systemctl daemon-reload ```
    ``` $ sudo restart docker ```

    现在可以尝试一下获取一个gcr.io仓库的镜像,是不是就已经可以了呢 ^^:

    ``` $ docker pull gcr.io/google_containers/pause:2.0
    2.0: Pulling from google_containers/pause
    8f216013977d: Pull complete
    a3ed95caeb02: Pull complete
    Digest: sha256:9ce5316f9752b8347484ab0f6778573af15524124d52b93230b9a0dcc987e73e
    Status: Downloaded newer image for gcr.io/google_containers/pause:2.0
    ```

    -----------------------------------------------------------------------------------
    本文首发于DockOne,转发请标明出处『http://dockone.io/article/1380』

    Windows的Docker Beta版本

    绝地魔影 发表了文章 • 0 个评论 • 5757 次浏览 • 2016-04-25 22:37 • 来自相关话题

    【编者的话】本文为Docker Saigon社区于其官方网站中发布的文章Docker For Windows Beta,此文描述了在Windows上的Docker Beta版本的一些功能,并且做了演示。Docker Saigon社区是由越南的Docker社区用 ...查看全部
    【编者的话】本文为Docker Saigon社区于其官方网站中发布的文章Docker For Windows Beta,此文描述了在Windows上的Docker Beta版本的一些功能,并且做了演示。Docker Saigon社区是由越南的Docker社区用户创建的,位于胡志明市。

    @Container容器技术大会将于6月4日在上海光大会展中心国际大酒店举办,来自Rancher、携程、PPTV、蚂蚁金服、京东、浙江移动、海尔电器、唯品会、eBay、道富银行、麻袋理财、土豆网、阿里百川、腾讯游戏、数人云、点融网、华为、轻元科技、中兴通讯等公司的技术负责人将带来实践经验分享,5月7日之前购票只需438元,欢迎感兴趣的同学抢购。

    注释:这篇文章的研究已在Beta客户端完成了,并且技术细节有可能发生变化。

    正如之前发布的帖子描述的那样,我们已经在Windows的Hyper-V上使用Docker有一阵子了。听说了新的Windows的Docker客户端是基于Alpine的,并且会专注于Hyper-V,这使得我们很渴望亲眼看一看。

    Hyper-V 配置
    第一个要克服的问题是当在Windows上使用Hyper-V时缺乏DNS/DHCP和NAT服务。新的Docker客户端为我们接管虚拟交换机的NAT配置并且为DNS与DHCP添加了一个很巧妙的解决方案。

    作为安装过程的一部分,将创建一个内部DockerNAT虚拟交换机,并且该Windows主机上的虚拟接口将会为这个虚拟交换机获得一个静态IP:
    New-VMSwitch -Name "DockerNAT" -SwitchType Internal
    Get-NetAdapter "vEthernet (DockerNAT)" | New-NetIPAddress -AddressFamily IPv4 `
    -IPAddress "10.0.75.1" -PrefixLength 24


    同时,也创建了一个为“10.0.75.0/24”子网提供网络地址转换(Network Address Translation)的NAT对象。
    New-NetNat –Name $SwitchName `
    –InternalIPInterfaceAddressPrefix "10.0.75.0/24"


    提示: 如果有任何的步骤失败了,须确保名为“DockerNAT”的交换机是被创建的,并且IP已经被分配给了该虚拟接口(Virtual Interface)的。此外通过Get-NetNat命令所显示的NAT是属于正确的子网内的。同时要确保物理网络与现有存在的接口不重叠(我们已经在测试beta版本的时候手动地将这些问题修复了)。
    接下来,MobyLinuxVM虚拟机已经在Hyper-V里建立起来了。MobyLinuxVM使用Alpine bootcd集成的Hyper-V服务,例如Key-Value Pair Exchange服务(hv_kvp_daemon)。Hyper-V KVP的守护进程允许Hyper-V和Linux客户机之间通信(例如检索客户IP和发送双向的消息,这我们将在后面看到)。
    最终,Docker捆绑了com.docker.proxy.exe源代码,它代理了在Windos主机上的MobyLinuxVM端口。在写该文的时候(Docker Beta 7),它已经包含了DNS(TCP/UDP 53),DHCP(UDP 67)和Docker 守护进程(TCP2375)。
    如果你一直在为你的Hyper-V配置运行一个替代解决方案,那么需要确保以上所有端口是可用的,如下所示。

    查看是否有任何进程在占用53端口:
    netstat -aon | findstr :53

    一旦你发现任何进程号再占用该端口(),那么先获取进程名:
    tasklist /SVC | findstr 

    com.docker.proxy.exe将会把你笔记本内部网络所有的DNS请求通过Windows主机代理到DNS服务器上,当你移动你的笔记本的时候可以有效地从网络配置上隔离MobyLinuxVM。
    为了确保该进程工作正常,docker自动地创建了DockerTcp和DockerUdp防火墙规则,并且可以在我们关闭客户端的时候移除它。
    New-NetFirewallRule -Name "DockerTcp" -DisplayName "DockerTcp"  `
    -Program "C:\\\com.docker.proxy.exe" -Protocol TCP `
    -Profile Any -EdgeTraversalPolicy DeferToUser -Enabled True

    New-NetFirewallRule -Name "DockerUdp" -DisplayName "DockerUdp" `
    -Program "C:\\\com.docker.proxy.exe" -Protocol UDP `
    -Profile Any -EdgeTraversalPolicy DeferToUser -Enabled True

    Docker的守护进程在本地打开,允许你的docker客户端与本地主机通信,可是-它看起来在使用一个命名管道的方案去替代它, 如果该VM被正确地创建, 那么你应该看到连接到其COM口的命名管道。
    那么同样也可以看到docker客户端代码在处理Windows命名管道
    Get-VMComPort -VMName MobyLinuxVM | fl | Out-String

    如果MobyLiunxVM正常地启动,我们就应该可以确认Hyper-V集成服务是在运行着的。
    Get-VMIntegrationService -VMName MobyLinuxVM -Name "Key-Value Pair Exchange"

    并且com.docker.proxy.exe的DHCP服务提供了一个到VM的IP,通过该IP我们可以查询Hyper-V集成服务:
    $(Get-VM MobyLinuxVM).NetworkAdapters[0]

    排错
    所有的配置都放在%APPDATA%\Docker\文件夹下面,当漫游设置开启的时候,这个文件夹被复制在该主机的企业设置中。
    所有日志存放在%LOCALAPPDATA%\Docker\文件夹下面。
    可以通过如下PowerShell脚本去监控最新的日志:
     gc $(gi $env:LocalAppData\Docker\* | sort LastAccessTime -Desc | select -First -
    1) -Wait

    一旦有事件写入日志文件将会被自动刷新。
    Docker ToolBox 迁移
    在Windows上切换至Hyper-V角色的话将会关闭VirtualBox(其实直到你关闭Hypver-V并重启之前都不可能用Docker ToolBox)。
    如果检测到Docker Toolbox已经安装了,那么会提供一个整合路径(基于qemu-img方式的)。这将会把%USERPROFILE%\.docker\machine\machines\\disk.vmdk路径下的磁盘转换成vhdx格式:
    qemu-img.exe convert  -O vhdx -o subformat=dynamic 
    -p "C:\Users\Public\Documents\Hyper-V\Virtual hard disks\MobyLinuxVM.vhdx\"

    如果你已经通过Hyper-V使用Docker-Machine和Docker-Compose了,你也可以同时用Docker的Windows客户端这么做一遍。
    挂载卷
    基于Windows下的Docker的其中一个较大的改进是承诺的卷如何挂载的问题。
    一个便利的对话框模式提供了我们所需要的一切。

    beta7-shares.png


    目前的改进将是共享整个存储(不包括单独的文件夹)。开启共享的时候需要提供凭据。
    凭据信息伴随着“Docker Host Filesystem Access”目标被存储在了Windows > Control Panel > Credential Manager > Windows Credentials Store路径下,这是通过System.Security.Cryptography随着当前用户进行加密的。
    如果凭据管理器已经包含了指定的目标凭据,他们将被覆盖。
    接下来,可以看到存储器被共享在了Windows主机上:
    net share C=C:\ /grant:,FULL /CACHE:None

    Samba的共享方式现在将会被挂载到MobyLinuxVM上,并且会通过Hyper-V的Key-Value交换服务进行自动操作。这里是细节方面的解释
    工作方式应该像下面描述的那样:Windows主机将一个mount authentication token令牌打包放进了VMBus中的KvpExchangeDataItem类里:
    class Msvm_KvpExchangeDataItem : CIM_ManagedElement
    {
    uint16 Source = 0;
    string Name = "cifsmount";
    string Data = "authToken";
    };

    认证令牌是包含挂载点和安装选项的序列化的字符串:
    /c;/C;username=,password=,noperm

    在Alpine上,是hv_utils核心驱动模块通知hv_kvp_daemon。这个守护进程把kvp写进了池文件里(/var/lib/hyperv/.kv_pool_**)。
    此时,MobyLinuxVM需要构建一个目录,并且从主机上挂载该共享目录-但是这一次写入的时候是失败了的:
    #for both upper and lower case
    mount -t cifs //10.0.75.1/C /C -o username=,
    password=,noperm

    如果共享是工作正常的,那么我们的docker客户端将会经由com.docker.proxy.exe通过开启的端口发送任何卷的挂载信息,该代理会在需要的时候重写该路径:例如C:\Users\test\变成/C/Users/test,这可以让我们把Windows的目录挂载到我们的Docker容器中。
    然而,由于SMB协议的原因(缺少inotify和symlinks的支持)使得我们这么做这仍然会有限制,这将会导致实时重置。
    排错:我们可以通过以下的PowerShell脚本来验证令牌是否存在:
    $VmMgmt = Get-WmiObject -Namespace root\virtualization\v2 
    -Class ` Msvm_VirtualSystemManagementService
    $vm = Get-WmiObject -Namespace root\virtualization\v2
    -Class ` Msvm_ComputerSystem -Filter {ElementName='MobyLinuxVM'}

    ($vm.GetRelated("Msvm_KvpExchangeComponent")[0] `
    ).GetRelated("Msvm_KvpExchangeComponentSettingData").HostExchangeItems | % { `
    $GuestExchangeItemXml = ([XML]$_).SelectSingleNode(`
    "/INSTANCE/PROPERTY[@NAME='Name']/VALUE[child::text() = 'cifsmount']")

    if ($GuestExchangeItemXml -ne $null)
    {
    $GuestExchangeItemXml.SelectSingleNode(`
    "/INSTANCE/PROPERTY[@NAME='Data']/VALUE/child::text()").Value
    }
    }

    目前为止,我还没有弄清楚在Alpine主机上是由哪个进程去监控var/lib/hyperv/.kv_pool_0这个文件的。
    私有仓库
    现在的Windows Beta版本目前还不支持DOCKER_OPTS和TLS证书。
    像下面一样,我们可以获得到MobyLinuxVM的根账号访问权限:
    #get a privileged container with access to Docker daemon
    docker run --privileged -it --rm
    -v /var/run/docker.sock:/var/run/docker.sock
    -v /usr/bin/docker:/usr/bin/docker alpine sh

    #run a container with full root access to MobyLinuxVM and no seccomp profile
    (so you can mount stuff)
    docker run --net=host --ipc=host --uts=host --pid=host -it
    --security-opt=seccomp=unconfined --privileged
    --rm -v /:/host alpine /bin/sh

    #switch to host FS
    chroot /host

    闲逛该VM的时候发现了下面的一些东西:
    这个基于Alpine的VM使用OpenRC作为它的初始化系统
    rc-status

    显示所有的服务状态的时候,我们会发现一些定义的脚本并没有部署状态,并且显示是“崩溃的”,尽管这些进程看起来其实是运行的(ps -a)。
    Docker初始化脚本依赖于/usr/bin/mobyconfig脚本。该脚本要求内核伴随着com.docker.database标签定义的文件配置的位置启动。如果该标签存在-/Database使用 Docker for Mac的原始文件系统Plan 9 Filesystem Protocol挂载。
    mobyconfig可以检索网络并且为Docker守护进程取消加密,或者从/etc/docker/daemon.json中获取配置文件。一旦全面实施,将会是一个很有前景的解决方案。
    由于整个磁盘是一个只有/var/固定挂载点的临时文件的系统是固定存在的(挂载到/dev/sda2),更改的任何脚本在重新引导时不会持续运行。这将可以临时改变Docker选项并且通过/etc/init.d/docker restart命令重启守护进程。

    总结
    许多的改进将会随着基于Windows的Docker客户端而来,我们期待下次在MAC上的Docker客户端的测试。

    原文链接:Docker For Windows Beta (翻译:薛开成)

    ===========================================
    译者介绍
    薛开成,趋势科技南京研发中心工程工具服务事业部基础架构高级工程师,负责容器仓库实施及落地。

    开源Registry项目Harbor源代码结构解析

    project_harbor 发表了文章 • 1 个评论 • 2303 次浏览 • 2016-04-11 12:11 • 来自相关话题

    上周我们介绍了Harbor开源企业级容器Registry的架构,获得了社区很多朋友的反馈和建议,再次一并感谢,希望和大家一起,共同建设一个优秀的开源项目。本文请Harbor项目工程师尹文开介绍源码结构,帮助开发和运维人员理解代码的工作原理。 ...查看全部
    上周我们介绍了Harbor开源企业级容器Registry的架构,获得了社区很多朋友的反馈和建议,再次一并感谢,希望和大家一起,共同建设一个优秀的开源项目。本文请Harbor项目工程师尹文开介绍源码结构,帮助开发和运维人员理解代码的工作原理。

    Harbor项目概览

    容器应用的开发和运行离不开可靠的镜像管理。从安全和效率等方面考虑,在企业私有环境内部署的Registry服务是非常必要的。Harbor(https://github.com/vmware/harbor)是由VMware中国研发团队为企业用户设计的Registry Server开源项目,包括了权限管理(RBAC)、图形管理界面、LDAP/AD集成、审计、自我注册、HA等企业必需的功能,同时针对中国用户的特点,原生支持中文,并计划实现镜像复制(roadmap)等功能。

    本文主要介绍Harbor项目的源码结构,帮助开发和运维人员理解其工作原理。
    主要组件

    Harbor系统由五个容器组成:Proxy、Core Services(包含UI, tokenservice和webhook)、Database、Registry和Log Collector。

    Proxy提供反向代理服务,用户的不同请求由Proxy分发到后端的UI或者Registry。Harbor中使用的是官方的nginx镜像。
    Core Services是Harbor项目的核心组件,主要提供权限管理、审计、管理界面UI、token service以及可供其他系统调用的API等功能。
    Database提供数据持久化服务,采用了官方的mysql镜像。
    Registry是Docker官方的开源的Registry镜像,主要提供镜像的存储和分发功能。
    Log Collector负责收集其他容器的日志并进行日志轮转。

    各个容器之间的关系如下图所示:

    源码结构

    以下所述主要为Core Services组件的源码结构,通过根目录下的Dockerfile可以构建出Core Services的镜像。另外Deploy目录下的db和log分别对应Database和Log Collector的Dockerfile镜像构建文件,而Nginx和Registry则都是采用的官方镜像。

    | -- api (Harbor提供的外部调用的API)
    | -- auth (认证模块,目前提供两种方式:数据库和LDAP)
    | -- db (数据库认证)
    | -- ldap (LDAP认证)
    | -- controllers (控制器相关代码)
    | -- dao (数据持久层)
    | -- Deploy (部署相关代码)
    | -- db (构建Database镜像的源码)
    | -- log (构建Log Collector镜像的源码)
    | -- docker-compose.yml (运行Harbor的docker compose文件)
    | -- docs (文档)
    | -- log (log工具)
    | -- models (数据库映射的模型代码)
    | -- routers (路由相关代码)
    | -- service (服务)
    | -- notification.go (处理Registry发来的镜像上传或下载等事件)
    | -- token.go (为Registry提供鉴权服务)
    | -- static (js、css等文件)
    | -- utils (工具类)
    | -- vendor (依赖的第三方源码)
    | -- views (html模版文件)
    | -- Dockerfile (构建Core Services镜像的Dockerfile)
    | -- main.go (入口函数)
    源码分析

    下面以获取项目列表和获取某个项目的详细信息为例来分析Harbor源码。

    Harbor项目使用了go语言开发,WEB框架采用beego。main.go、routers目录和controllers目录分别对应了入口函数、路由函数目录和控制器函数目录。当Core Services启动时,routers目录下的相应函数会将各个控制器与其所对应的用户请求URL进行注册,这样当不同的用户请求到达的时候,不同的控制器逻辑就会被触发。主要处理流程如下图所示:

    当获取项目列表时会发送请求http://hostname/api/projects/,该请求首先到达Nginx。Nginx的配置文件如下:

    server {
    listen 80;

    location / {
    proxy_passhttp://ui/;

    }

    location /v1/ {
    return 404;
    }

    location /v2/ {
    proxy_passhttp://registry/v2/;

    }

    location/service/ {
    proxy_passhttp://ui/service/;

    }
    }

    根据配置文件该请求会被转发到http://ui/,也即Core Services中的UI。根据UI中routers/router.go中定义的规则:

    beego.Router( "/api/projects/?:id",&api.ProjectAPI{} )

    可知该请求最终是由api包中的ProjectAPI的Get方法来处理的。ProjectAPI结构体的定义如下:

    typeProjectAPI struct {
    BaseAPI
    userID int
    projectID int64
    }

    在beego中,控制器处理用户请求的方法执行之前首先会执行Prepare()方法来进行一些准备或者校验操作,ProjectAPI定义的Prepare()方法如下:

    func(p *ProjectAPI) Prepare() {
    p.userID = p.ValidateUser()

    }

    Prepare()中调用BaseAPI中的ValidateUser方法检查用户的合法性,并将用户ID赋值给ProjectAPI的userID属性。之后执行Get方法来处理用户的请求:

    func(p *ProjectAPI) Get() {
    queryProject :=models.Project{UserID: p.userID}

    projectList, err :=dao.QueryProject(queryProject)

    for i := 0; i < len(projectList); i++{
    if isProjectAdmin(p.userID,projectList[i].ProjectID) {
    projectList[i].Togglable= true
    }
    }
    p.Data["json"] = projectList
    p.ServeJSON()
    }

    Get方法中调用dao包中的QueryProject()方法来获取项目列表,之后遍历列表判断该用户是否对此项目具有administrator的权限,最终返回项目列表的JSON数据,此次用户请求处理完毕。

    当获取某个项目的详细信息时会发送请求http://hostname/registry/detail,该请求同样会经过Nginx和Router并最终到达其对应的Controller的处理方法如下:

    func (idc *ItemDetailController) Get() {
    //具体处理逻辑

    idc.ForwardTo("page_title_item_details","item-detail")
    }

    具体的处理逻辑此处忽略。该方法的最后一步调用idc.ForwardTo(“page_title_item_details”,”item-detail”)定位对应的HTML模版文件。模版文件默认的存放目录为views,“item-detail”为模板文件名,因此该语句最终定位到views/item-detail.tpl的文件。经过数据填充最终生成对应的HTML文件并返回。

    欢迎广大用户使用Harbor项目并反馈意见和建议,也欢迎加入我们贡献代码。如果您是Harbor的用户或开发者,请长按下面二维码加入Harbor开源项目群,以方便沟通。Github网址:
    https://github.com/vmware/harbor

    【Docker实战】Registry & Portus搭建详解

    Mona 发表了文章 • 2 个评论 • 11892 次浏览 • 2016-03-22 13:18 • 来自相关话题

    【编者的话】本文根据云舒网络博客整理发布。文章详细介绍了Docker Registry以及带UI管理的仓库管理软件 Portus搭建过程。 前言: 首先,Docker Hub是一个很好的用于管理公共镜 ...查看全部
    【编者的话】本文根据云舒网络博客整理发布。文章详细介绍了Docker Registry以及带UI管理的仓库管理软件 Portus搭建过程。

    前言:

    首先,Docker Hub是一个很好的用于管理公共镜像的地方,我们可以在上面找到想要的镜像(Docker Hub的下载量已经达到数亿次);而且我们也可以把自己的镜像推送上去。但是,有的时候,使用场景需要我们有一个私有的镜像仓库用于管理自己的镜像,这个时候我们就通过Registry来实现此目的。本文详细介绍了本地镜像仓库Docker Registry & Portus的搭建过程(Portus是一个带UI管理的仓库管理软件),对于文中细节有兴趣或有疑问的朋友欢迎加群讨论。

    Registry搭建篇


    Docker & Registry环境准备

    在谈到Registry的部署之前,我们首先要考虑设计一个什么样Registry的仓库环境,是部署测试环境,还是生产环境。如果是用于生产环境发布Registry,必须考虑如下因素:
    a. 应在何处存储镜像?
    b. 用户的权限是否受控?
    c. 当发生问题,如何解决?日志是否可以查看?
    d. 如何快速提取镜像?(注:这是至关重要的,如果依赖镜像进行构建测试环境、生产环境或自动化系统,这是取决仓库是否有生命力的最重要指标。)

    本实例把存储镜像的路径放置到宿主机的文件路径下。例如:/opt/myregistry目录中。这样即使宿主机中Docker Registry 出现问题,我们再重创建一个,把此路径添加到新Registry Server中,那么之前上传的镜像文件仍然存在,这就更方便大家使用。下面是安装之前进行的一些准备工作:

    1.Docker安装

    首先,选择一个合适的PC机做宿主机,其配置参数如下:
    CPU: Intel E8400 Duo CPU 3.0GHz RAM: 2G disk:300G
    CPU查看命令: more /proc/cpuinfo |grep "model name"
    Mem查看命令: grep MemTotal /proc/meminfo


    1.png




    2.Registry安装

    由于Docker和Registry更新比较快,所以我们在此宿主机中进行安装的时候,选择Registry2.1版本进行安装。

    yum -y install docker-registry


    2.png


    3.png



    至此,Docker和registry的安装已经完成,下面开始进行配置和测试。


    5.png



    注:安装完成后需要对Docker和Registry进行enable and start。

    Registry原理

    Docker模型的核心部分是有效的利用分层镜像机制,镜像可以通过分层来进行继承,基于基础镜像,可以制作各种具体的应用镜像。不同的Docker容器可以共享一些基础的文件系统层,同时再加上自己独有的改动层,大大提高了存储的效率。由于最终镜像最终是以tar.gz的方式静态存储在服务器端,这种存储适用于对象存储而不是块存储。

    一次docker pull 发生的交互



    6.png



    1. Client向Index请求,知道从哪里下载CentOS

    1. Index回复

    1. CentOS在RegistryA

    1. CentOS的Checksum,所有层的Token

    1. Client向Registry A请求, CentOS的所有层。Registry A负责存储CentOS,以及它所依赖的层、

    1. Regsitry A向Index发起请求,验证用户Token的合法性

    1. Index返回这次请求是否合法

    1. Client从Registry下载所有的层

    1. Registry从后端存储中获取实际的文件数据,返给Client

    Registry配置

    1.启动Registry容器

    sudo docker run –d –p 80:5000 --restart=always --name registry -v /opt/myregistry:/var/lib/registry registry:2



    8.jpg




    Registry服务默认会将上传的镜像保存在容器的/var/lib/registry,我们将主机的/opt/registry目录挂载到该目录,即可实现将镜像保存到主机的/opt/registry目录了。运行docker ps看一下容器情况:


    7.png





    说明我们已经启动了Registry服务,打开浏览器输入http://127.0.0.1:80/v2,出现下面情况说明Registry运行正常。



    9.0_.png



    2.客户机访问Registry

    对于需要访问Registry仓库的客户机来说,首先需要修改/etc/sysconfig/docker的配置文件:添加 --insecure-registry 192.168.0.70:80


    9.1_.jpg



    3.客户端向Registry存放镜像

    首先,需要docker tag给需要上传的镜像文件打标。然后再从本地上传镜像到仓库。



    9.1_.jpg




    4.客户端向仓库Pull镜像

    在另外一台主机上使用pull从192.168.0.70的仓库中把镜像给Pull下来


    9.3_.png


    9.4_.jpg



    通过以上操作就可以看到我们已经Pull的镜像,然后可以运行此镜像,开始你的应用之旅。到此应该说Registry基本搭建完成,但是仍然不适合实际的使用。因为不方便管理和查看到上传的镜像和权限设置。接下来我们介绍一个带UI管理的仓库管理软件—【Portus】

    Portus搭建篇

    注:请勿将本篇作为上篇Registry安装内容延续,以下内容为全新环境下的Portus搭建。

    Portus安装

    Portus(by SUSE)是用于 Docker Registry API(v2)的开源前端和授权工具,最低要求注册表版本是 2.1。它可以作为授权服务器和用户界面,用于新一代的 Docker Registry。具有以下优点:


    1.)安全:Portus 实现了最新的Docker Registry中定义的新的授权方案。它允许对你所有的镜像进行细颗粒度控制,你可以决定哪个用户和团队可 push/pull 镜像。

    2.)轻松管理用户: 在 Portus 映射你的公司,可以定义任意数量的 Team,并从 Team 添加和移除用户。Team 有三种类型的用户:Viewers ,只能 pull 镜像;Contributors,可以 push/pull 镜像;Owners,类似 contributors,但可以从 team 添加或移除用户。

    3.)搜索: Portus 提供你的私人注册表的内容的预览,同时有一个快速搜索镜像的功能。

    4.)审计: 用户的所有相关事件都会被Portus自动记录,并可被管理员进行用户分析。

    1.安装Docker-Compose

    首先,yum添加源

    [ root@bogon]# yum -y install epel-release

    安装python-pip

    [root@ bogon]# yum -y install python-pip

    安装docker-compose

    pip install -U docker-compose


    10.jpg



    到这里docker-compse就完成了。


    2.从Git到Portus的代码搭建

    正常安装方法: 需要到Git Clone https://github.com/SUSE/Portus.git上获取Portus的源码。下载包Portus_git.tar.gz,解压此源码包,并修改Gemfile.lnk 的第一行:“https://rubygems.org”修改为“http://rubygems.org”。运行compose-setup.sh -e server IP。进行构建安装。(此处省略掉)


    11.png



    由于Portus在安装过程中,需要下载几个依赖的镜像包,例如: Portus安装依赖MariaDB,portus_web.tar、rails4.2.2tar,Registry2.1.1.tar安装过程中下载比较慢。我们先下载了再进行安装过程。


    12.png



    由于我先把这几个已经下载完成,所以首先拷贝到宿主机的目录中了,需要直接解压。


    13.jpg



    3. 安装Portus程序

    安装之前需要把拷贝到宿主机中的几个依赖镜像给load到Images中。


    14.jpg



    关于Registry的存储路径修改,请在安装前先到compose中修改docker-compose.yml.template文件。这里面包含web端口和挂载volumes等参数。然后,再执行安装脚本 ./compose-setup.sh -e 192.168.0.70。(由于本实例重新安装了Registry,所以,此处宿主机和容器的端口都是5000。)


    15.png



    然后到Portus源代码文件中执行./compose-setup.sh。


    16.jpg



    到此,Portus的安装已经完成.。

    4. 修改Docker配置文件

    此时,我们还需要修改vi /lib/systemd/system/docker.service 把--insecure-registry 192.168.0.70:5000这句加到ExecStart=/usr/bin/docker这个配置项后。


    17.png



    重启Docker

    *systemctl daemon-reload
    systemctl restart docker*

    重启portus容器
    *docker start portus_db_1
    portus_web_1 portus_crono_1 portus_registry_1*

    可以在浏览器中打开登录窗口。


    18.png



    在客户机中需要修改 /etc/sysconfig/docker下的文件。


    17.png



    Portus配置与验证

    1.登录配置程序

    Portus的登录界面需要创建用户名和密码。然后进行Registry的设置。

    20.png


    21.png


    22.png



    创建test01和test02帐户,并Enabled帐户,然后进行登录测试。


    2.上传镜像测试


    23.jpg


    24.png


    25.png



    3.下载镜像测试



    26.jpg



    总结

    Docker Registry的创建私有仓库的方法有很多种。像京东的Docker镜像存储系统--Speedy,Registry+Nginx &SSL等后续将进一步探究, 实现开发、测试以及生产的一体化流程,敬请期待!

    本文电子书下载:

    网页下载:
    http://www.cloudsoar.com/down/ddoc/v1.1/

    百度云盘下载:
    http://pan.baidu.com/s/1jHfP9Dc

    博客期刊:
    http://www.cloudsoar.com/about/BlogNews/content/0/133/v1.1/

    _________________________________________________________________________________________________________

    温馨提示:

    云舒网络携手Rancher Labs推出【Rancher | 实战微信群】,在线为您分享Docker技术干货,更有往期回顾精选期刊等你拿!

    本群汇集了Rancher中国最强技术精英团队及业内技术派高人,宗旨是为了大家拥有更专业的平台交流Rancher实战技术,实时与Rancher创始团队面对面!同时欢迎各位分享自己的经验、疑难问题,我们将定期邀请分享嘉宾做各类话题分享及回顾,共同实践研究Docker容器生态圈。

    对Rancher和Docker技术感兴趣、或对本文中细节需继续探讨的朋友,欢迎加入本群参与讨论!

    加微信群方法:

    1.关注【云舒网络】公众号

    2.留言”我要加群”

    QQ群号:216521218


    wx.jpg



    访问私有镜像服务器 (包含最新的 Docker Trusted Registry)

    ozbillwang 发表了文章 • 1 个评论 • 3809 次浏览 • 2016-02-29 18:43 • 来自相关话题

    如果你想连接私有镜像服务器,请看下面的简单步骤。 ​ 比如你有一台私有镜像服务器 `test.example.com:443` ​ 1) 先得到该服务器的 公钥(public key) ​ ...查看全部
    如果你想连接私有镜像服务器,请看下面的简单步骤。

    比如你有一台私有镜像服务器 `test.example.com:443`

    1) 先得到该服务器的 公钥(public key)


        $ openssl s_client -showcerts -connect test.example.com:443


    将其输出结果中的公钥复制出来

    $ openssl s_client -showcerts -connect test.example.com:443
    CONNECTED(00000003)
    depth=0 C = US, O = Docker, OU = Docker, L = San Francisco, CN = test.example.com
    verify error:num=18:self signed certificate
    verify return:1
    depth=0 C = US, O = Docker, OU = Docker, L = San Francisco, CN = test.example.com
    verify return:1
    ---
    Certificate chain
    0 s:/C=US/O=Docker/OU=Docker/L=San Francisco/CN=test.example.com
    i:/C=US/O=Docker/OU=Docker/L=San Francisco/CN=test.example.com
    -----BEGIN CERTIFICATE-----
    MIIFsjCCA5qgAwIBAgIRALRtKdj9DyxVtWXgQYDUIOAwDQYJKoZIhvcNAQELBQAw
    YjELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkRvY2tlcjEPMA0GA1UECxMGRG9ja2Vy
    MRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRkwFwYDVQQDExB0ZXN0LmV4YW1wbGUu
    Y29tMB4XDTE2MDIyODIwMzYzNVoXDTE3MDIyNzIwMzYzNVowYjELMAkGA1UEBhMC
    VVMxDzANBgNVBAoTBkRvY2tlcjEPMA0GA1UECxMGRG9ja2VyMRYwFAYDVQQHEw1T
    YW4gRnJhbmNpc2NvMRkwFwYDVQQDExB0ZXN0LmV4YW1wbGUuY29tMIICIjANBgkq
    hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAqVOIkSOQGdTN+/xv01lZo2ICs+VVGU+Q
    auPF/bKI/5WUQCIjb9QF+voprzRD5Etwym11QIqnIk6XnQwe25mJwMu1ZkGN3ZF/
    gcCXlh44Yam2VB2VU0A0wAFO395ZJbj20ma2R8b9+XQkk3SnnpSKWzkCJphvn6PV
    8nk3GN3l+U6lSBZhNQkybvya9no0IOcEVXkDNf4aoRJukRxcl/8kJqgJchyk1Qs4
    UY3KFSSuxDqMGOcX3zbIhIZfW7yVlVtt4H/BnzzxAkdJvgiKOMXg8ekvf3hz3WTM
    waMv9BzF1X2KMFaMupz0pVGOCLpRiLJCENYAbVHJq7i3JGprQWtH9nMGa5OdPJy1
    ZI2m87jDmf6kGXiylcjPlFbcy77/fTgNr5ZoBSVdiDOhA4NznuQTBevIpCJaIOcw
    dNsiKOWLI0aTZfQlCYDU6km43W5P6Wpet39whm5ENNBLAUffpEm2ykMxOFZa6Irm
    pTtvNFZcgN6r9wftJ4jBAFdMIiEFbJtJWf8JlLPx7ehMMpbXit0xppspv5072jE8
    5+NQY1kAzuwJxDkshDC0FVgh4p8e6IuObWIkyWBPg4nQxFhyBu0cbBO31rKWfbbd
    Id3fWmNl+7VcI81w1I1tbc4yrT24Yst1XYRRQJYxkDuhwhh6FY8+0XoSX7Vee9F+
    VWRMMwTes48CAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgKkMA8GA1UdEwEB/wQFMAMB
    Af8wHQYDVR0OBBYEFGy9bakVCvc9FBSee6gsZ4NZlM4bMB8GA1UdIwQYMBaAFGy9
    bakVCvc9FBSee6gsZ4NZlM4bMA0GCSqGSIb3DQEBCwUAA4ICAQBOFHSBIgkvOybo
    2lnm9WvL1mL0WLitHmY1krrFEnlva+h1U2YUbpFunZbEx61fC6rhy8jpiEFF4mdI
    zCXd1b0fQb5+LtDO2rvqZXhANqCtXeoRf3gNPBDORca7w3BoSm3KaAOCE3zKYHqj
    TE7lwZCwNlNslVMuVBfsZ5mk1K6NBzQMai+AzxSQVOYIW8hA7YaS2qumTe7Hulce
    1NVUVRA0wtMBSXRWelrTXi8LJtRtU5W3nkq9TefaWK+dI3EYENflOSO4Cw+IBJX8
    bA9hWgvKzFZKu5p4rfpqCHygi3Bbr+VLiKaGKbdlj9p3ro4hMCbYEIZQFullGubS
    N8Rk+a9WTEPmZ/J7rgi7y1v+nwnrhMsRU4sg7H4JXaEE0pA4MBQbJexstXvSk2YP
    9eWjHinmhNjfFSudt7hRXoH2kwlcd8pwA6PbaLTHTUCzESy1oFnSRVVYA2pJC5jt
    vFXQU2vz4b25zIrDYuRr37GSKJXCzc6HcsGlu6+EumkA7kvUGZRX7oZmod9v6GU1
    klTb370cFMy7Dn2Fq4iubM85P3bOMai8hT48nVa2WTJPik1b6WvJhzl1ZZOVc9Jt
    1uO61+oSMZWm2unIyyZ3ZQZE0q1da++JXqGW7VKJDZbVw4GQyCtDji/cgrfFnopB
    tnVd5ASYgCpXEgB+aGP5Cu00isU47A==
    -----END CERTIFICATE-----
    ---
    Server certificate
    subject=/C=US/O=Docker/OU=Docker/L=San Francisco/CN=test.example.com
    issuer=/C=US/O=Docker/OU=Docker/L=San Francisco/CN=test.example.com


    2) 复制公钥到文件 `/etc/docker/certs.d/test.example.com:443/ca.crt`

    3) 验证该CA证书


        cd /etc/docker/certs.d/test.example.com:443
    curl -u user:password --cacert ca.crt https://test.example.com:443



    4) 即可成功登录镜像服务器


        docker login -u user -p password -e mailbox test.example.com:443


    5) 做个测试

    docker build -t hello-world . 
    docker tag test.example.com:443/ACCOUNT/hello-world:0.1
    docker push test.example.com:443/ACCOUNT/hello-world:0.1

    openshift中使用registry及router

    jxjhu 发表了文章 • 0 个评论 • 4909 次浏览 • 2016-02-17 15:44 • 来自相关话题

    openshift中使用registry及router 上次试验了一下openshift的搭建,这次我们去具体运行一个应用在openshift 1.打开浏览器访问(https://master.openshift.example.c ...查看全部
    openshift中使用registry及router
    上次试验了一下openshift的搭建,这次我们去具体运行一个应用在openshift
    1.打开浏览器访问(https://master.openshift.example.com:8443)以本地域名为准

    i.png


    1.设置用户名及密码
    htpasswd /etc/origin/htpasswd admin
    我这里创建的用户为admin
    1. 创建registry
    echo '{"kind":"ServiceAccount","apiVersion":"v1","metadata":{"name":"registry"}}' | oc create -f -
    echo '{"kind":"ServiceAccount","apiVersion":"v1","metadata":{"name":"router"}}' | oc create -f -
    oc edit scc privileged
    oadm policy add-cluster-role-to-user cluster-admin admin
    oadm registry --credentials=/etc/origin/master/openshift-registry.kubeconfig --config=/etc/origin/master/admin.kubeconfig

    查看是否创建成功

    r.png



    1. 安装router
    oadm router router --replicas=1 --credentials=/etc/origin/master/openshift-router.kubeconfig --service-account=router
    成功后的状态如下

    s.png


    4.安装默认的image-streams
    curl -sk https://raw.githubusercontent.com/openshift/origin/master/examples/image-streams/image-streams-centos7.json | oc create -n openshift -f -
    检查image-streams

    n.png


    5.创建演示应用

    ttt.png

    启动成功后,可以看到下面页面

    vvvv.png

    以上就是应用部署启动的一个简单流程