转载

Moving to Docker(二):搭建一个私有registry服务

Touchware是一家意大利的App公司,经历了从Heroku到Dokku,最后迁移到Docker的过程,本文是这个过程的第一篇,介绍了如何安装、测试和使用私有registry服务,其中也包含了从DigitalOcean选VPS和注册Amazon S3服务。

为什么我们想要搭建一个私有的registry?对于初学者,Docker Hub只允许你有一个免费的私有库。虽然其他公司也开始提供类似的服务,但是价格也都不便宜。并且,如果你需要部署基于Docker的生产环境,你也不想将这些镜像发布到公开的Docker Hub。

这是一个非常务实的方法来处理搭建私有Docker registry的复杂过程。在这个教程中,我们会用一个512M的DigitalOcean机器。

本地搭建

首先,你需要安装boot2docker和docker CLI。如果你已经安装了Docker的环境并运行着,可以跳过这一节了。

从终端运行下面的命令:

brew install boot2docker docker

如果这一步安装成功,就可以启动一个供Docker运行的虚拟机,命令如下:

boot2docker up

根据说明,使用export命令,boot2docker会在终端输出。如果你现在运行docker ps,你就可以看到下面的结果:

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

现在,Docker已经安装好了,下一步我们开始安装registry。

创建服务器

登录你的DigitalOcean账号,并创建一个预安装了Docker镜像的Droplet,如下图:

Moving to Docker(二):搭建一个私有registry服务

你会在Email中收到root用户的登录凭证。登陆并运行docker ps来确认机器可以正常工作。

创建一个亚马逊AWS S3

我们使用亚马逊的简单存储服务(S3)作为我们registry的物理存储。下面我们需要创建一个Bucket和用户凭证来让Docker容器使用它。

登陆AWS账号,然后选择S3服务,如下图:

Moving to Docker(二):搭建一个私有registry服务

点击创建Bucket,输入该Bucket的唯一码(记下来,后面还要用到),然后点击生成,如下图:

Moving to Docker(二):搭建一个私有registry服务

我们已经完成了创建存储的部分。

安装AWS登陆凭证

接下来我们将创建一个新用户。回到AWS的控制台界面,选择IAM(Identity & Access Management)。

Moving to Docker(二):搭建一个私有registry服务

你会看到下面这个界面:

Moving to Docker(二):搭建一个私有registry服务

用户需要授权密钥来启用通过REST或者Query协议来连接AWS的服务API。如果需要连接AWS的管理终端,在完成这个向导之后在用户面板创建一个密码就行。

设置权限

选择一个策略模板,创建一个策略或者自定义一个策略。策略是一个文档,它包含一个或者多个权限,可以通过下面这个界面来修改策略或者通过用户、组和角色页面来修改。

Moving to Docker(二):搭建一个私有registry服务

下面是一个自定义的策略:

{  "Version": "2012-10-17",  "Statement": [  {  "Sid": "SomeStatement",  "Effect": "Allow",  "Action": [   "s3:*"   ],  "Resource": [   "arn:aws:s3:::docker-registry-bucket-name/*",       "arn:aws:s3:::docker-registry-bucket-name"   ]  } ] } 

这样可以允许用户(例如:registry)在Bucket上操作(当创建AWS S3之前确认bucket已经创建完成)。简而言之:当你要准备把Docker镜像从本地机器发布到自己的库里时,服务器将会把它们保存在S3上。

安装registry

接下来,用SSH连接到DigitalOcean的虚拟机上。我们准备使用官方提供的registry镜像。

用下面的命令启动registry:

docker run /    -e SETTINGS_FLAVOR=s3 /  -e AWS_BUCKET=bucket-name /  -e STORAGE_PATH=/registry /  -e AWS_KEY=your_aws_key /  -e AWS_SECRET=your_aws_secret /  -e SEARCH_BACKEND=sqlalchemy /  -p 5000:5000 /  --name registry /  -d /  registry 

Docker会从Docker Hub上下载相应的fs层并启动守护进程容器。

测试registry

如果前面都顺利的话,接下来可以通过ping测试registry的服务并搜索它内部的内容(尽管现在它还是空的)。

我们的registry是个非常基本的安装,它并不提供任何权限上的控制。因为添加权限的方法都比较麻烦(至少我没有发现哪个方法可以容易的实现并确认权限控制),我决定用最简单的方法来查询、下载和发布来使用registry,那就是利用ssh在HTTP协议上做一个不加密的隧道连接。

通过下面的命令可以从你的机器创建一个隧道:

ssh -N -L 5000:localhost:5000 root@your_registry.com

这条命令使得服务器(就是刚才docker run启动的那个机器)的5000端口到本地的5000端口之间通过SSH协议做了一个隧道。

如果你通过http://localhost:5000/v1/_ping来请求,你会得到一个简单结果:

{}

这说明你的registry已经正常工作了。通过http://localhost:5000/v1/search可以列出整个registry中的内容,如下:

{  "num_results": 2,  "query": "",  "results": [   {    "description": "",    "name": "username/first-repo"   },   {   "description": "",   "name": "username/second-repo"   }  ] } 

创建一个镜像

下面我们尝试创建一个非常简单的镜像来测试我们的registry服务。在本地机器上创建如下内容的Dockerfile:

# Base image with ruby 2.2.0 FROM ruby:2.2.0 MAINTAINER Michelangelo Chasseur <michelangelo.chasseur@touchwa.re>

docker build -t localhost:5000/username/repo-name .

其中localhost:5000部分非常重要:一个Docker镜像的第一部分是告诉docker push应该把镜像发布到哪儿。在我们的例子中,因为我们通过SSH连接了我们的私有registy到本地的5000端口,于是localhost:5000就是指代我们的registry。

如果运行的正常,当这个命令返回结果后,你可以通过docker images来查看新创建的镜像了,请自己尝试一下。

发布到registry

接下来介绍一些技巧。我也花了一些时间来弄明白自己要介绍的东西,所以如果你第一次没看懂,请保持耐心并尝试。我知道这些东西看起来很复杂(如果你没有自动化这个过程,它确实很复杂),但是我保证它们都是有意义的。接下来的一篇,我会展示一堆shell脚本和Rake任务,它们将把整个过程自动化,方便你用一条简单的命令来部署一个Rails应用到你的registry。

你从本地终端运行的docker命令确实是用boot2docker虚拟机来运行容器并且做了所有的操作。于是我们运行一条像docker push some_repo的命令时,就是boot2docker 虚拟机在连接registry而不是我们本地的。

这是非常重要的一点:为了发布Docker镜像到远端私有registry,SSH隧道需要被boot2docker虚拟机创建而不是从给你的本机。

这里有几种方法来实现它,我会介绍最简洁的一种(它并不是最容易理解的,却是它可以帮助我们通过shell脚本来自动化这个过程)。

建立SSH

先来添加boot2docker的SSH密钥到远端registry服务器的known hosts.我们可以通过ssh-copy-id功能,它可以用如下命令来安装:

brew install ssh-copy-id

ssh-copy-id -i /Users/username/.ssh/id_boot2docker root@your-registry.com

请确保/Users/username/.ssh/id_boot2docker是你的ssh密钥的正确路径。

然后我们来测试一下:

boot2docker ssh "ssh -o 'StrictHostKeyChecking no' -i /Users/michelangelo/.ssh/id_boot2docker -N -L 5000:localhost:5000 root@registry.touchwa.re &" &
  • boot2docker ssh可以让你传递一条命令作为参数让boot2docker虚拟机来执行

  • 最后的&来保证我们的命令在后台运行

  • ssh -o 'StrictHostKeyChecking no' -i /Users/michelangelo/.ssh/id_boot2docker -N -L 5000:localhost:5000 root@registry.touchwa.re &才是虚拟机真正执行的。

    • -o 'StrictHostKeyChecking no'部分可以确保不用回答设置的安全问题

    • -i /Users/michelangelo/.ssh/id_boot2docker来说明我们希望虚拟机使用的授权SSH密钥(这个需要是在上一步添加给远端registry服务的那个密钥)。

    • 最后我们打开了一个隧道来连接远端5000端口和本地的5000端口

从别的服务器下载

现在你可以通过下面的命令来实现从远端registry服务发布镜像:

docker push localhost:5000/username/repo_name
正文到此结束
Loading...