【IT168 方案】Docker Hub作为Docker官方镜像仓库,提供了大量Docker镜像的托管服务。但使用它来托管企业私有Docker镜像存在一些问题,比如:
Docker Hub托管私有镜像的服务目前只面对收费账户;
使用Docker Hub托管私有镜像并不适合一些特殊场景,比如工作环境网络是内网,不允许访问外网,那就更不可能到Docker Hub去下载镜像。
在这种情况下,如果能构建一个安全可靠的Docker私有库,将会是一个更好的选择。本文将介绍在AWS ECS基础上结合AWS Elastic LoadBalancer、AWS Autoscaling Group、AWS S3及Docker官方提供的Registry镜像构建安全、高可用的Docker私有库的方案,帮助您轻构实现这一需求。
2.方案详解
我们会使用AWS CloudFormation服务,使用自定义的模板脚本声明所需的资源,实现自动化构建。接下来结合我们的模板脚本对本方案进行详细介绍。
注意:以下内容与代码相关部分只贴出主要代码,部分代码用…表示省略;完整模板代码地址:
https://s3-us-west-2.amazonaws.com/blog.leonli.org/registry.yml
2.1 架构图
根据以上架构图,基本数据传输过程为:
1)Docker客户端向镜像仓库发送的pull/push等命令事实上都是通过Docker dDaemon转换成Restful请求的形式再发送给镜像仓库的。在本架构中,我们利用AWS Elastic LoadBalancer(简称ELB)接收客户端发来的请求,作为整个架构的接入层。由于我们要求数据是通过TLS加密传输的,所以我们需要使用AWS IAM中的Server Certificate(由AWS IAM账户上传的TLS证书)与ELB关联,实现对客户端发来的请求进行加密。
2)ELB会将请求反向代理给后端分布在不同可用区的两台Container Instance(安装了Docker运行环境的EC2实例),Container Instance中运行了Docker Registry服务。当请求到达Registry时,我们需要首先使用内置在Registry中的用户认证文件(比如本架构中使用Apache Htpasswd创建的基本用户名密码保护文件),进行用户认证,认证不通过,则驳回请求,认证通过,才可以读写数据。
3)将数据统一存储在一个只供创建者使用的S3 Bucket中。
2.2 基于AWS ECS运行Docker Registry服务
Amazon EC2 Container Service (ECS) 是一项高度可扩展的高性能容器管理服务,它让您能够在托管的 Amazon EC2 实例群集上轻松运行Docker应用程序。 Amazon ECS主要有以下几个组件:ECS Cluster、 Container Instance、Task、ECS Service。这里基于ECS运行了Docker Registry服务,架构如下:
(1)首先在模板中定义了一个ECS Cluster,用来管理相关的Container Instance。ECS提供了ECS-Optimize AMI来创建EC2实例作为Container Instance,ECS-Optimize AMI已经内置Docker运行环境和Container Agent代理,可以为我们节省安装这些环境所需的时间。
Container Instance在启动时可以由Container Agent根据配置文件/etc/ecs/ecs.config中的ClusterName属性的值知道需要将实例注册到哪个ECS Cluster上。
因为我们要使用Auto Scaling服务实现对EC2实例的伸缩控制。所以我们使用Auto Scaling的Launch Config组件声明我们的Container Instance。并通过UserData传入Shell脚本,此脚本主要完成以下三件事:
调用 echo ECS_CLUSTER=${ECSCluster} >> /etc/ecs/ecs.config ,将Container Instance注册到我们的ECS Cluster中。
创建/docker-registry/certs目录和/docker-registry/auth目录,并调用aws s3 copy命令从指定的S3 Bucket中复制TLS证书文件和htpasswd用户认证文件。这些文件将在运行Docker Registry时使用到。
调用cfn-signal命令,通知AutoScaling Group资源EC2实例已经启动完毕。