docker 私有 仓库
Docker提供了一个称为“ Distribution”的开源注册表实现 ,使任何人都可以轻松运行私有Docker注册表。 在本文中,我将简要介绍与Docker集成的AWS服务,并描述如何使用AWS托管您自己的注册表。
在AWS云中运行服务器软件具有以下优点:
- 复杂的网络基础架构管理
- 完善的访问控制工具
- 弹性负载平衡器
- 集成DNS管理
AWS还通过Elastic Container Service(ECS)和Elastic Beanstalk提供Docker容器管理服务。 这两种服务的不同之处在于一种重要方式:ECS专注于在预先配置和配置的硬件上管理任务和服务(作为容器运行),而Elastic Beanstalk是一种用于供应旨在运行指定应用程序的整个堆栈的工具。
Elastic Beanstalk用于为其运行的应用程序定义平台和上下文。 现在,通过Docker集成,您可以在容器中运行与平台无关的应用程序,并且ECS优于Elastic Beanstalk,从而更加突出了基于Docker的部署优势。 因此,考虑到Elastic Beanstalk上现有内容的丰富性,本文将使用ECS。
弹性容器服务(ECS)不是主机供应服务。 虽然管理控制台确实提供了用于配置基本群集基础结构的屏幕,但它仅在后端使用CloudFormation模板。 在为群集配置了该模板之后,必须直接使用特定于资源的工具对新的基础结构进行更改。 这也意味着,使用该自动化群集配置器很难实现与现有基础架构或专业化的集成。 如果您总体上对AWS感到满意,则应置备自己的ECS集成的EC2主机(稍后对此进行详细介绍)。
ECS负责管理“集群”,“任务”和“服务”。 群集是解析为一组成员主机的名称。 ECS主机联机后,它将启动连接到ECS服务的代理,并向命名集群注册。 任务是一个“运行一次”容器,服务是一个容器,如果该容器停止运行,则应重新启动。 创建新任务或服务时,请指定应在其中运行的群集。 群集处理计划任务和服务实例到成员主机。
为了整合所有码头工人的主机与ECS集群,主机必须运行ECSAgent容器,并要在加入设置集群名称/etc/ecs/ecs.config
主机上。 如果您准备将ECS主机配置为在名为“默认”的群集中运行,则可以将启动配置的用户数据设置为以下脚本:
#!/bin/bash
echo ECS_CLUSTER=default >> /etc/ecs/ecs.config
目前,使用AWS管理控制台的ECS部分创建默认集群。 它将把所有内容置备到新的VPC中。 您可以自己构建一个,但这样做乏味且细微。 如果沿着那条路走,请准备一个更长的项目。 使用Amazon Linux AMI创建ECS实例,其中已预安装Docker和ECS Agent。
在开始之前,请确保您已经创建了一个AWS账户,安装了AWS命令行界面(CLI)并配置了环境以使用您的账户。 您可以在此处找到有关安装和配置CLI的信息。
为您的私有Docker注册表准备AWS资源
Docker Distribution项目是Docker Registry API的开源实现。 虽然应该已经为ECS群集提供了运行容器所需的所有AWS资源,但Distribution项目具有与S3的(可选)应用程序级别集成。 要利用这一点,您将需要提供一些应用程序级别的AWS依赖项。
您将创建的第一个AWS资源是S3存储桶,注册表将在其中存储其数据。 您可以通过管理控制台或从命令行创建新存储桶。 在以下命令中,用您选择的存储桶名称替换“ my-docker-registry-data”:
# Use the AWS ClI and "make bucket" (mb) command.
aws s3 mb s3://my-docker-registry-data
之前我提到过AWS的复杂访问控制工具。 好吧,如果您的私有Docker注册表无法读取或写入新的S3存储桶,则没有用。 下一步是创建一个新的IAM策略,该策略向存储桶授予读取/写入权限。
创建一个名为“ registry-policy.json”的新文件,并包含以下文档。 确保用您为新S3存储桶选择的名称交换“ my-docker-registry-data”。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my-docker-registry-data"
]
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::my-docker-registry-data/*"
]
}
]
}
保存策略文件后,使用以下命令在AWS中注册它。 此操作将需要IAM管理权限:
aws iam create-policy --policy-name registryaccess --policy-document file://registry-policy.json
接下来,为您的注册表创建一个新的IAM用户和凭据,并附加刚创建的策略。 选择特定于该用例的用户名。 我曾经用过“注册表”。 您可以使用以下两个命令从命令行创建用户:
# Create a user
aws iam create-user --user-name Registry
# Create credentials for the new user
aws iam create-access-key --user-name Registry
# Output similar to:
# {
# "AccessKey": {
# "UserName": "Registry",
# "Status": "Active",
# "CreateDate": "2015-03-09T18:39:23.411Z",
# "SecretAccessKey": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
# "AccessKeyId": "AKIAXXXXXXXXXXXXX"
# }
# }
注意响应输出提供的AccessKeyId和SecretAccessKey。 您将需要向注册表提供这些值,以便它可以作为注册表用户向AWS进行身份验证。 在继续之前,请使用以下命令将创建的策略附加到新用户。 确保将<YOUR AWS ACCOUNT ID
>替换为您的实际账户ID。
aws iam attach-user-policy --policy-arn arn:aws:iam::<YOUR AWS ACCOUNT ID>:policy/registryaccess --user-name Registry
附加策略后,注册表用户将能够(并且只能)读取,写入和列出您创建的存储桶中的文件。 这是启动注册表之前所需的最后准备工作。
使用ECS启动私有Docker注册中心
在ECS群集中启动任何应用程序都意味着标识您要运行的一个或多个图像,定义将使用这些图像的容器以及设置缩放选项。 在此示例中,您将启动"registry:2"
映像的特殊化。
您可以使用config.yml和Dockerfile来构建自己的专业化,类似于后面的两个。 您可以在此处找到Docker Distribution配置文件的文档 。 如果您想重用资源,而不用担心创建Docker Hub存储库,那么您应该使用我使用此确切配置发布的映像。 存储库名称为"allingeek/registry:2-s3."
如果要进一步专门化配置,则需要构建自己的或派生现有映像。
# config.yml
version: 0.1
log:
fields:
service: registry
http:
addr: :5000
storage:
cache:
layerinfo: inmemory
s3:
accesskey: <your awsaccesskey>
secretkey: <your awssecretkey>
region: <your bucket region>
bucket: <your bucketname>
encrypt: true
secure: true
v4auth: true
chunksize: 5242880
rootdirectory: /
# Dockerfile
FROM registry:2
COPY config.yml /etc/docker/registry/config.yml
无论发生什么情况,都不要在这些文件中包括您的AWS Access Key或AWS Secret Key。 这些都必须提交给版本控制才能使用,最后要做的就是将秘密提交给版本控制。 在下一节中,您将看到在运行时注入配置的更好方法。 确定要在ECS中运行的映像后,您需要定义任务系列和服务。
任务族定义了一组版本化的容器定义。 在这个例子中,我们只需要一个容器。 创建一个名为“ registry-task.json”的新文件,并粘贴到以下文档中。 将<YOUR NEW IAM USER ACCESS KEY>
和<YOUR NEW IAM USER SECRET ACCESS KEY>
替换为您先前运行的create-user
命令返回的AccessKey和SecretAccessKey。 您还需要用适当的值替换<YOUR S3 BUCKET REGION>
和<YOUR S3 BUCKET NAME>
。
[
{
"name": "registry",
"image": "allingeek/registry:2-s3",
"cpu": 1024,
"memory": 1000,
"entryPoint": [],
"environment": [
{
"name": "REGISTRY_STORAGE_S3_ACCESSKEY",
"value": "<YOUR NEW IAM USER ACCESS KEY>"
},
{
"name": "REGISTRY_STORAGE_S3_SECRETKEY",
"value": "<YOUR NEW IAM USER SECRET ACCESS KEY>"
},
{
"name": "REGISTRY_STORAGE_S3_REGION",
"value": "<YOUR S3 BUCKET REGION>"
},
{
"name": "REGISTRY_STORAGE_S3_BUCKET",
"value": "<YOUR S3 BUCKET NAME>"
}
],
"command": ["/etc/docker/registry/config.yml"],
"portMappings": [
{
"hostPort": 5000,
"containerPort": 5000,
"protocol": "tcp"
}
],
"volumesFrom": [],
"links": [],
"mountPoints": [],
"essential": true
}
]
在此容器定义中声明的环境变量将覆盖与映像一起包装的config.yml文件中相应条目的值。 本文档将在AWS中进行版本控制,并且只有拥有ECS服务权限的用户才能访问。 由于本文档包含机密材料,因此请勿将该文件提交版本控制或在任何公共位置使用。
创建容器定义列表文件后,请使用以下命令注册新的任务系列:
aws ecs register-task-definition --family registry --container-definitions file://registry-task.json
接下来,您需要定义将在集群上运行的服务。 您可以在此处找到create-service命令的CLI文档 。 ECS提供的负载平衡器成员资格功能可节省大量时间,因此您应在此处尝试使用。
创建一个描述您的服务的新文档。 将新文件命名为“ registry-service.json”。 将以下内容复制并粘贴到该文件中,然后将<YOUR ELB NAME...
替换为为集群创建的负载平衡器的名称。 如果使用了管理控制台提供的群集配置器,则它应该是该VPC中唯一的负载平衡器。 如果您已在自己的VPC中构建了自己的ECS节点并注册了自己的集群,则应在该VPC中创建一个新的ELB。
{
"serviceName": "s3-registry-elb",
"taskDefinition": "registry",
"loadBalancers": [
{
"loadBalancerName": "<YOUR ELB NAME, something like: EC2Contai-EcsElast-S06278JGSJCM>",
"containerName": "registry",
"containerPort": 5000
}
],
"desiredCount": 1,
"role": "ecsServiceRole"
}
关于名为“ ecsServiceRole”的IAM角色的快速说明。 这是应该在群集配置期间创建的IAM角色。 如果遇到尚未创建此角色的问题,则可以使用以下策略自行创建它:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"elasticloadbalancing:Describe*",
"elasticloadbalancing:DeregisterInstancesFromLoadBalancer",
"elasticloadbalancing:RegisterInstancesWithLoadBalancer",
"ec2:Describe*",
"ec2:AuthorizeSecurityGroupIngress"
],
"Resource": [
"*"
]
},
{
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::ecs-registry-demo"
]
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::ecs-registry-demo/*"
]
}
]
}
一旦创建了服务描述文档(并创建了必需的IAM角色),请继续使用群集启动该服务。 默认情况下,ECS创建一个名为“ default”的集群,您可以在以下命令中省略“ cluster”参数。 但是,如果您创建了自己的名称,则需要将<YOUR CLUSTER NAME>
替换为您选择的名称。
aws ecs create-service --service-name s3-registry-elb --cluster <YOUR CLUSTER NAME> --cli-input-json file://ecs-simple-service-elb.json
群集启动后,检查ELB的实例成员资格和侦听器配置。 您应该发现端口80已转发到已部署服务的ECS节点上的端口5000。 启用时,启动Web浏览器并点击http://<YOUR ELB CNAME>/v2/
。 您应该得到如下响应:
{ }
现在,这就是我所说的防斜线! 您已部署了不安全且未经身份验证的Docker注册表。 更好的测试是将图像推入并尝试再次拉出它。 如果要这样做,则需要在本地Docker守护程序上进行配置更改 。
结论
弹性容器服务和ECS节点可轻松与AWS现有的扩展和负载平衡技术集成。 它与Docker Hub的集成使入门变得简单。 使用此服务的大部分复杂性在于配置群集和相关基础架构。 有了这些,ECS使得定义和部署服务变得非常简单。
您可以通过几种不同的方式独立扩展此示例。 首先,通过将SSL证书上传到AWS来保护私有Docker注册表的安全,并使用HTTPS侦听器配置负载均衡器。 其次,考虑实现注册表身份验证机制。 这样做的说明可以在Distribute配置文档中找到 。 最后,尝试将服务扩展到多个实例,并查看该服务如何维护ELB实例成员身份。