前言最近开始研究Docker的应用,所以打算搭建一个Docker私有仓库,使用阿里云的OSS作为存储引擎。网上查到的资料大多比较陈旧。新版Registry服务与旧版的区别还是比较大的。突然觉得网上那些过时的(或者不明确的)信息真是害死人。还是要把这两天摸索的门道记录下来,方便过段时间部署Docker仓库。偶尔踩一次坑没必要,二来也是顺便给后来者提个醒。系统环境客户端dockerversiondockerversionClient:Version:1.9.1APIversion:1.21Goversion:go1.4.3Gitcommit:a34a1d5Built:FriNov2017:56:04UTC2015OS/Arch:darwin/amd64Server:Version:1.9.1API版本:1.21Go版本:go1.4.3Git提交:a34a1d5构建时间:2015年11月20日星期五17:56:04UTC操作系统/Arch:linux/amd64服务器端docker版本Boot2Docker版本1.9.1,构建大师:cef800b-11月20日星期五19:33:59UTC2015Docker版本1.9.1,构建a34a1d5客户端docker-compose版本docker-compose版本1.5.2,构建7240ff3docker-py版本:1.5.0CPython版本:2.7.9OpenSSL版本:OpenSSL1.0。1j15Oct2014如果系统没有docker-compose命令,可以执行以下命令安装:$curl-Lhttps://github.com/docker/com...uname-s-uname-m>/usr/local/bin/docker-compose$chmod+x/usr/local/bin/docker-compose启动Registry服务安装为了利用Docker容器技术,我们直接使用Docker镜像部署服务。首先在服务器端新建一个工作目录并进入:$mkdirmy_registry&&cdmy_registry在当前目录新建一个文件docker-compose.yml:registry:restart:alwaysimage:"registry:2"ports:-127.0.0.1:5000:5000volumes:-./auth:/auth-./data:/var/lib/registryenvironment:-REGISTRY_AUTH=htpasswd-REGISTRY_AUTH_HTPASSWD_REALM=RegistryRealm-REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd启动Registry服务时,需要使用下面两个目录:auth目录用来存放docker登录的账号和密码。data目录用于存放dockerpush上传的文件。执行以下命令创建这两个目录:$mkdirauth&&mkdirdata接下来,创建一个测试帐户(用户名:test,密码:123456)并将其保存到auth/htpasswd:$htpasswd-Bbntest123456>auth/htpasswdNow启动Registry服务:$docker-composeup-d由于本地没有名为registry:2的镜像,控制台可能会打印出如下信息,然后稍作停顿:Pullingregistry(registry:2)...等待一两分钟,可以看到控制台打印出如下信息,说明启动成功:Creatingdockertest_registry_1Attachingtodockertest_registry_1registry_1|time="2016-01-13T21:57:14Z"level=warningmsg="未提供HTTP密码-生成的随机密码。如果多个注册中心ar,这可能会导致上传问题e在负载均衡器后面。要提供共享密钥,在配置文件中填写http.secret或设置REGISTRY_HTTP_SECRET环境变量。time="2016-01-13T21:57:14Z"level=infomsg="redis未配置"go.version=go1.5.2instance.id=25aa4d1d-0510-4cb6-9006-1083bff5fc15version=v2.2.1registry_1|time="2016-01-13T21:57:14Z"level=infomsg="使用内存中的blob描述符缓存"go.version=go1.5.2instance.id=25aa4d1d-0510-4cb6-9006-1083bff5fc15version=v2.2.1registry_1|time="2016-01-13T21:57:14Z"level=infomsg="11分钟后开始上传清除"go.version=go1.5.2instance.id=25aa4d1d-0510-4cb6-9006-1083bff5fc15version=v2.2.1registry_1|time="2016-01-13T21:57:14Z"level=infomsg="listeningon[::]:5000"go.version=go1.5.2instance.id=25aa4d1d-0510-4cb6-9006-1083bff5fc15version=v2.2.1测试现在再打开一个命令行窗口,并进入my_registry目录执行以下命令新建镜像:$dockertagregistry:2127.0.0.1:5000/test/registry说明:镜像的名称为127.0.0.1:5000/test/registry,其中127.0.0.1:5000代表服务器地址,test/registry表示镜像名称。上传前登录:$dockerlogin127.0.0.1:5000注意:按照提示输入上面创建的用户名和密码,邮箱可以省略。登录成功后执行以下命令上传:$dockerpush127.0.0.1:5000/test/registry配置阿里云OSS首先在刚刚执行docker-composeup的命令行窗口按CTRL+C退出服务现在。将文件docker-compose.yml更改为以下内容:registry:restart:alwaysimage:"registry:2"ports:-127.0.0.1:5000:5000volumes:-./auth:/authenvironment:-REGISTRY_AUTH=htpasswd-REGISTRY_AUTH_HTPASSWD_REALM=RegistryRealm-REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd-REGISTRY_STORAGE=oss-REGISTRY_STORAGE_OSS_ACCESSKEYID=your_oss_accesskey_id-REGISTRY_STORAGE_OSS_ACCESSKEYSECRET=your_oss_accesskey_secret-REGISTRY_STORAGE_OSS_REGION=your_oss_region-REGISTRY_STORAGE_OSS_BUCKET=your_oss_bucket-REGISTRY_STORAGE_OSS_ENDPOINT=your_oss_bucket.your_oss_region.aliyuncs.com说明:由于使用阿里云OSS作为存储引擎,因此不需要在本地存储文件,所以去掉了volumes中的数据目录配置;environment增加了REGISTRY_STORAGE系列环境变量配置,这部分的值需要替换成对应的accesskey_id、accesskey_secret、region、bucket和endpoint等信息。删除data目录,重启服务:$rm-Rfdata&&docker-composeup然后执行刚才的命令上传镜像:$dockerpush127.0.0.1:5000/test/registry可以感觉到上传速度这次不是第一次快了,因为还是要上传到阿里云OSS。上传完成后,您可以打开阿里云OSS的控制台界面,查看文件是否上传正确。配置SSL证书如果我们想在客户端拉取或推送镜像(不是在服务端),docker使用https协议,所以会报unabletopingregistryendpoint的错误:Thepushrefertoarepository[注册表.示例。com:5000/test](len:1)无法ping注册表端点https://registry.example.com:...v2ping尝试失败并出现错误:获取https://registry.example.com:...拨号tcpregistry.example.com:5000:i/otimeoutv1pingattemptfailedwitherror:Gethttps://registry.example.com:...dialtcp199.99.99.9:9000:i/otimeout所以必须配置一个SSL证书。安装首先需要准备证书文件,分别保存在auth/domain.crt和auth/domain.key中。新建Nginx的配置文件auth/nginx.conf:upstreamdocker-registry{serverregistry:5000;}设置一个变量来帮助我们决定是否需要添加'Docker-Distribution-Api-Version'头。注册表总是设置这个标头。在nginx执行身份验证的情况下,标头将被取消,因为nginx在proxying.map$upstream_http_docker_distribution_api_version$docker_distribution_api_version{'registry/2.0''';默认registry/2.0;}server{listen443ssl;server_namemyregistrydomain.com;#SSLssl_certificate/etc/nginx/conf.d/domain.crt;ssl_certificate_key/etc/nginx/conf.d/domain.key;#来自https://raymii.org/s/tutorial的推荐...ssl_protocolsTLSv1.1TLSv1.2;ssl_ciphers'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';ssl_prefer_server_ciphers开启;ssl_session_cacheshared:SSL:10m;#禁用任何限制以避免HTTP413大图像上传client_max_body_size0;#需要避免HTTP411:见问题#1486(https://github.com/docker/doc...chunked_transfer_encodingon;location/v2/{#不允许来自docker1.5及更早版本的连接#dockerpre-1.6.0没有在ping上正确设置用户代理,赶上"Go*"useragentsif($http_user_agent~"^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go).*\$"){返回404;}#要向v2添加基本身份验证,请使用auth_basicsetting.auth_basic"Registryrealm";auth_basic_user_file/etc/nginx/conf.d/nginx.htpasswd;##如果$docker_distribution_api_version为空,则不会添加标头。##请参阅上面定义此变量的map指令。#需要docker客户端的sakeproxy_set_headerX-Real-IP\$remote_addr;#传递真实客户端的IPproxy_set_headerX-Forwarded-For\$proxy_add_x_forwarded_for;proxy_set_headerX-Forwarded-Proto\$scheme;proxy_read_timeout900;}}将文件docker-compose.yml更改为以下内容:nginx:image:"nginx:1.9"ports:-443:443links:-registry:registryvolumes:-。/AUTH/:/ETC/NGINX/CONF.DRIGISTR:RESTART:始终图像:“consustry:2”端口:-127.0.0.1:5000:5000:5000ENVIRNORMENT:------REGISTRY_STORAGE_OSS_BUCKET=your_oss_bucket-REGISTRY_STORAGE_OSS_ENDPOINT=your_oss_bucket.your_oss_region.aliyuncs.com说明:删除registry项目环境中以REGISTRY_AUTH开头的变量和volumes项,因为Nginx中已经配置了auth认证执行以下命令启动服务:$updocker-compose注意:如果本地没有名为nginx:1.9的镜像,控制台可能会打印Pullingnginx(nginx:1.9)...先下载镜像。测试假设刚才配置的证书域名为docker.ucdok.com。现在我们在客户端执行如下命令登录:$dockerlogindocker.ucdok.com生成新镜像:$dockerpullubuntu$dockertagubuntudocker.ucdok.com/test/ubuntu上传新镜像:$dockerpushdocker.ucdok.com/test/ubuntu其他问题增加用户可以执行htpasswd命令创建并保存到auth/htpasswd文件中:$htpasswd-Bbnusernamepassword>>auth/htpasswd后台启动服务并启动服务时添加-d参数:$docker-composeup-d停止后台服务在docker-compose.yml文件所在目录执行如下命令:$docker-composestop
