本节内容:

  • Registry相关概念
  • Registry V1和V2
  • 安装Docker
  • 搭建本地registry v2
  • 搭建外部可访问的Registry
  • 添加认证
  • 更高级的认证
  • registry web ui

一、Registry相关概念

前面的文章讲过Docker的组成部分,我们一般在使用Docker的过程中更为常用的是pull image、run image、build image和push image。主要是围绕image展开的。

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

Docker hub是Docker公司提供的一些存储镜像的空间,这部分空间是有限的。我们一般会自主建设Docker私有仓库Registry。

二、Registry V1和V2

Docker Registry 2.0版本在安全性和性能上做了诸多优化,并重新设计了镜像的存储的格式。Docker目前1.6之后支持V2。

三、安装Docker

见前面发布的文章《CentOS安装Docker CE》。

四、搭建本地registry v2

环境:172.16.7.151  CentOS 7.0  主机名:node1

[root@node1 ~]# docker run -d -p : --name wisedu_registry registry:

本地push镜像到registry仓库:

[root@node1 ~]# docker pull ubuntu:16.04
[root@node1 ~]# docker tag ubuntu:16.04 localhost:/my-ubuntu
[root@node1 ~]# docker push localhost:/my-ubuntu

删除本地的ubuntu:16.04和localhost:5000/my-ubuntu镜像:

[root@node1 ~]# docker image remove ubuntu:16.04
[root@node1 ~]# docker image remove localhost:/my-ubuntu

从本地registry中拉取 localhost:5000/my-ubuntu 镜像:

[root@node1 ~]# docker pull localhost:/my-ubuntu

但是这种registry只是本地能使用,我们找另外一台主机172.16.7.152往该registry中push镜像:

[root@node2 ~]# docker pull ubuntu:16.04
[root@node2 docker]# docker tag ubuntu:16.04 172.16.7.151:/ubuntu:v1
[root@node2 docker]# docker push 172.16.7.151:/ubuntu:v1
The push refers to a repository [172.16.7.151:/ubuntu]
Get https://172.16.7.151:5000/v2/: http: server gave HTTP response to HTTPS client
[root@node2 ~]# echo $?

这是因为从docker1.13.2版本开始,使用registry时,必须使用TLS保证其安全。

停止并删除本地registry:

[root@node1 ~]# docker stop wisedu_registry
wisedu_registry
[root@node1 ~]# docker rm -v wisedu_registry
wisedu_registry

五、搭建外部可访问的Registry

官方文档:https://docs.docker.com/registry/deploying/#run-an-externally-accessible-registry

Running a registry only accessible on localhost has limited usefulness. In order to make your registry accessible to external hosts, you must first secure it using TLS.

使用TLS认证registry容器时,必须有证书。一般情况下,是要去认证机构购买签名证书。这里使用openssl生成自签名的证书。

环境信息:172.16.206.32  CentOS 7.0  主机名:spark32

1.生成自签名证书

[root@spark32 ~]# mkdir -p /opt/docker/registry/certs
[root@spark32 ~]# openssl req -newkey rsa: -nodes -sha256 -keyout /opt/docker/registry/certs/domain.key -x509 -days -out /opt/docker/registry/certs/domain.crt
Generating a bit RSA private key
...
Country Name ( letter code) [XX]:CN
State or Province Name (full name) []:JiangSu
Locality Name (eg, city) [Default City]:NanJing
Organization Name (eg, company) [Default Company Ltd]:wisedu
Organizational Unit Name (eg, section) []:edu
Common Name (eg, your name or your server's hostname) []:registry.docker.com
Email Address []:@wisedu.com

2.创建带有TLS认证的registry容器

[root@spark32 ~]# docker run -d --name registry2 -p : -v /opt/docker/registry/certs:/certs -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key registry: 

3.在每一个docker客户端宿主机上配置/etc/hosts,以使客户端宿主机可以解析域名”registry.docker.com”。并创建与这个registry服务器域名一致的目录(因为我这里的域名是假的)

# vim /etc/hosts
172.16.206.32 registry.docker.com
[root@node1 ~]# cd /etc/docker/certs.d/
[root@node1 certs.d]# mkdir registry.docker.com:

4.将证书 domain.crt 复制到每一个docker客户端宿主机/etc/docker/certs.d/registry.docker.com:5000/ca.crt,不需要重启docker

[root@spark32 ~]# scp -p /opt/docker/registry/certs/domain.crt root@172.16.7.151:/etc/docker/certs.d/registry.docker.com\:/ca.crt

5.push镜像到registry

另找一个客户机node1,push镜像到registry。

[root@node1 certs.d]# docker tag ubuntu:16.04 registry.docker.com:/my-ubuntu:v1
[root@node1 certs.d]# docker push registry.docker.com:/my-ubuntu:v1
The push refers to a repository [registry.docker.com:/my-ubuntu]
a09947e71dc0: Pushed
9c42c2077cde: Pushed
625c7a2a783b: Pushed
25e0901a71b8: Pushed
8aa4fcad5eeb: Pushed
v1: digest: sha256:634a341aa83f32b48949ef428db8fefcd897dbacfdac26f044b60c14d1b5e972 size:

6.列出私有仓库中的所有镜像

[root@node1 certs.d]# curl -X GET https://registry.docker.com:5000/v2/_catalog -k
{"repositories":["my-ubuntu"]}

7.查看存储在registry:2宿主机上的镜像

在registry:2创建的私有仓库中,上传的镜像保存在容器的/var/lib/registry目录下。创建registry:2的容器时,会自动创建一个数据卷(Data Volumes),数据卷对应的宿主机下的目录一般为:/var/lib/docker/volumes/XXX/_data。

[root@spark32 ~]# ls /var/lib/docker/volumes/91a0091963fa6d107dc988a60b61790bba843a115573e331db967921d5e83372/_data/docker/registry/v2/repositories/my-ubuntu/
_layers _manifests _uploads

可以在创建registry:2的容器时,通过-v参数,修改这种数据卷关系:

–v /opt/docker/registry/data:/var/lib/registry

除了可以将数据保存在当前主机的文件系统上,registry也支持其他基于云的存储系统,比如S3,Microsoft Azure, Ceph Rados, OpenStack Swift and Aliyun OSS等。可以在配置文件中进行配置:https://github.com/docker/distribution/blob/master/docs/configuration.md#storage

【补充】:

一般情况下,证书只支持域名访问,要使其支持IP地址访问,需要修改配置文件openssl.cnf。

在Redhat7系统中,文件所在位置是/etc/pki/tls/openssl.cnf。在其中的[ v3_ca]部分,添加subjectAltName选项:

[ v3_ca ]
subjectAltName = IP:192.168.1.104

生成证书:

...
Country Name ( letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:172.16.206.32:5000
Email Address []:

六、添加认证:Native basic auth

The simplest way to achieve access restriction is through basic authentication (this is very similar to other web servers’ basic authentication mechanism). This example uses native basic authentication using htpasswd to store the secrets.

1.创建用户密码文件,testuser,testpassword

[root@spark32 ~]# mkdir /opt/docker/registry/auth
[root@spark32 ~]# docker run --entrypoint htpasswd registry: -Bbn testuser testpassword > /opt/docker/registry/auth/htpasswd

2.运行registry容器

[root@spark32 ~]# docker run -d --name registry_native_auth -p : -v /opt/docker/registry/auth:/auth -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd -v /opt/docker/registry/certs:/certs -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key registry:

3.现在尝试拉取镜像

[root@node1 ~]# docker pull registry.docker.com:/my-ubuntu:v1
Error response from daemon: Get https://registry.docker.com:5000/v2/my-ubuntu/manifests/v1: no basic auth credentials

4.登录registry,push镜像

[root@node1 ~]# docker login registry.docker.com:
Username: testuser
Password:
Login Succeeded
[root@node1 ~]# docker tag ubuntu:16.04 registry.docker.com:/my-ubuntu:v1
[root@node1 ~]# docker push registry.docker.com:/my-ubuntu:v1

七、更高级的认证

更好的方式是在registry前使用代理,利用代理提供https的ssl的认证和basic authentication。https://docs.docker.com/registry/recipes/

1. 配置Nginx作为认证代理
https://docs.docker.com/registry/recipes/nginx/

(1)创建需要的目录

[root@spark32 ~]# mkdir -p /opt/nginx_proxy_registry/{auth,data}

(2)创建Nginx主配置文件

events {
worker_connections ;
} http { upstream docker-registry {
server registry:;
} ## Set a variable to help us decide if we need to add the
## 'Docker-Distribution-Api-Version' header.
## The registry always sets this header.
## In the case of nginx performing auth, the header will be unset
## since nginx is auth-ing before proxying.
map $upstream_http_docker_distribution_api_version $docker_distribution_api_version {
'' 'registry/2.0';
} server {
listen ssl;
server_name registry.docker.com; # SSL
ssl_certificate /etc/nginx/conf.d/domain.crt;
ssl_certificate_key /etc/nginx/conf.d/domain.key; # Recommendations from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
ssl_protocols TLSv1. TLSv1.;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m; # disable any limits to avoid HTTP for large image uploads
client_max_body_size ; # required to avoid HTTP : see Issue # (https://github.com/moby/moby/issues/1486)
chunked_transfer_encoding on; location /v2/ {
# Do not allow connections from docker 1.5 and earlier
# docker pre-1.6. did not properly set the user agent on ping, catch "Go *" user agents
if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) {
return ;
} # To add basic authentication to v2 use auth_basic setting.
auth_basic "Registry realm";
auth_basic_user_file /etc/nginx/conf.d/nginx.htpasswd; ## If $docker_distribution_api_version is empty, the header will not be added.
## See the map directive above where this variable is defined.
add_header 'Docker-Distribution-Api-Version' $docker_distribution_api_version always; proxy_pass http://docker-registry;
proxy_set_header Host $http_host; # required for docker client's sake
proxy_set_header X-Real-IP $remote_addr; # pass on real client's IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout ;
}
}
}

Nginx配置

(3)创建密码认证文件

[root@spark32 ~]# docker run --rm --entrypoint htpasswd registry: -bn testuser testpassword > /opt/nginx_proxy_registry/auth/nginx.htpasswd

(4)拷贝之前生成的证书和key到auth目录下

[root@spark32 ~]# cp /opt/docker/registry/certs/domain.crt /opt/nginx_proxy_registry/auth/
[root@spark32 ~]# cp /opt/docker/registry/certs/domain.key /opt/nginx_proxy_registry/auth/

(5)创建compose文件 

nginx:
image: "nginx:1.9"
ports:
- :
links:
- registry:registry
volumes:
- ./auth:/etc/nginx/conf.d
- ./auth/nginx.conf:/etc/nginx/nginx.conf:ro registry:
image: registry:
ports:
- 127.0.0.1::
volumes:
- ./data:/var/lib/registry

docker-compose.yml

(6)启动

[root@spark32 nginx_proxy_registry]# docker-compose up -d

(7)验证启动的服务

[root@spark32 nginx_proxy_registry]# docker-compose ps
[root@spark32 ~]# docker ps

找一台docker客户端机器登录:

创建需要的目录:

[root@node1 ~]# mkdir /etc/docker/certs.d/registry.docker.com:

把 domain.crt 传到上一步生成的目录里:

[root@spark32 ~]# scp -p /opt/nginx_proxy_registry/auth/domain.crt root@172.16.7.151:/etc/docker/certs.d/registry.docker.com:/ca.crt

登录进行测试:

[root@node1 ~]# docker login -u=testuser -p=testpassword registry.docker.com:
Login Succeeded
[root@node1 ~]# docker tag ubuntu:16.04 registry.docker.com:/ubuntu-test:v1
[root@node1 ~]# docker push registry.docker.com:/ubuntu-test:v1

(8)停止服务

[root@spark32 ~]# cd /opt/nginx_proxy_registry/
[root@spark32 nginx_proxy_registry]# docker-compose stop

(9)查看日志

[root@spark32 nginx_proxy_registry]# docker-compose logs

2. 补充Docker compose

(1)Docker compose是什么

Docker Compose是一个用来定义和运行复杂应用的Docker工具。使用Compose,你可以在一个文件中定义一个多容器应用,然后使用一条命令来启动你的应用,完成一切准备工作。

一个使用Docker容器的应用,通常由多个容器组成。使用Docker Compose,不再需要使用shell脚本来启动容器。

Docker Compose将所管理的容器分为三层,工程(project)、服务(service)以及容器(contaienr)。一个工程当中可包含多个服务,每个服务中定义了容器运行的镜像,参数,依赖。一个服务当中可包括多个容器实例,Docker Compose并没有解决负载均衡的问题,因此需要借助其他工具实现服务发现及负载均衡。

(2)安装docker compose

将变量 $dockerComposeVersion 换成指定的版本

[root@spark32 ~]# curl -L https://github.com/docker/compose/releases/download/$dockerComposeVersion/docker-compose-`uname -m` -o /usr/local/bin/docker-compose

比如下载安装1.15.0版本:

[root@spark32 ~]# curl -L https://github.com/docker/compose/releases/download/1.15.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

可能会下载失败,多试几次。实在不行就需要翻墙去下载。

赋予执行权限:

[root@spark32 ~]# chmod +x /usr/local/bin/docker-compose

查看docker compose版本:

[root@spark32 ~]# docker-compose --version
docker-compose version 1.15., build e12f3b9

(3)卸载docker compose

如果docker compose是通过curl安装的:

rm /usr/local/bin/docker-compose

如果docker compose是通过pip安装的:

pip uninstall docker-compose

八、registry web ui

搭建完了docker registry,我们可以使用 docker 命令行工具对我们搭建的 registry 做各种操作了,如 push / pull。但是不够方便,比如不能直观的查看 registry 中的资源情况,如果有一个 ui 工具,能够看到仓库中有哪些镜像、每个镜像的版本是多少。

registry web ui主要有3个,一个是 docker-registry-frontend,一个是 hyper/docker-registry-web,还有一个是Portus

关于registry ui的搭建会在后面的文章中介绍。

Registry私有仓库搭建及认证的更多相关文章

  1. Docker 之registry私有仓库搭建

    Docker 之registry私有仓库搭建 官方提供的私有仓库docker registry用法 https://yeasy.gitbooks.io/docker_practice/reposito ...

  2. Docker Registry私有仓库搭建

    部署registry 准备一个registry.mydocker.com 的证书 对私有registry取名registry.mydocker.com 目录规划 仓库数据目录:/data/docker ...

  3. docker私有仓库搭建及认证

    什么是docker? Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱机 ...

  4. Docker registry私有仓库(七)

    Docker registry私有仓库搭建基本几步流程(采用nginx+认证的方式) 1. 申请免费的ssl证书 https://buy.wosiqn.com/free 2. 设置nginx ssl证 ...

  5. 6.云原生之Docker容器Registry私有镜像仓库搭建实践

    转载自:https://www.bilibili.com/read/cv15219863/?from=readlist #1.下载registry仓库并设置数据存放的目录(并生成认证账号密码) doc ...

  6. Docker系列教程03-Docker私有仓库搭建(registry)

    简介 仓库(Repository)是集中存放镜像的地方,又分为公共镜像和私有仓库. 当我们执行docker pull xxx的时候,它实际上是从registry.docker.com这个地址去查找,这 ...

  7. Docker学习笔记 — Docker私有仓库搭建

    Docker学习笔记 — Docker私有仓库搭建   目录(?)[-] 环境准备 搭建私有仓库 测试 管理仓库中的镜像 查询 删除 Registry V2   和Mavan的管理一样,Dockers ...

  8. 拥抱 Android Studio 之四:Maven 仓库使用与私有仓库搭建

    使用.创造和分享 笔者曾经不思量力的思考过『是什么推动了互联网技术的快速发展?』这种伟大的命题.结论是,除了摩尔定律之外,技术经验的快速积累和广泛分享,也是重要的原因. 有人戏称,『写 Java,首先 ...

  9. Docker学习笔记 — Docker私有仓库搭建【转载】

    标签: Docker 2015-03-10 21:08 24190人阅读 评论(0) 收藏 举报  分类: Docker(26)    目录(?)[+]   和Mavan的管理一样,Dockers不仅 ...

随机推荐

  1. Java入门:JDK与Eclipse之类的集成开发工具的关系

    JDK是Java Development Kit,也就是说Java开发所需的工具包.有了这个东西,一切Java开发理论上都不是问题了.当然,根据你下载的版本不同,可能擅长的领域不同.通常大家都是用JD ...

  2. 利用Azure Media Services Explorer发布VOD视频

    1.连接Media Services账号, 填入Media Services的账号以及Account Key 如果使用中国的Azure的话,需要在Endpoint节上更改一下,因为国内的Azure的接 ...

  3. Python模拟登录cnblogs

    Python利用requests.Session对象模拟浏览器登录cnblogs request.Session对行可以跨请求的保持cookie,非常方便的用于模拟登录. cnblogs登录页面分析: ...

  4. scrum敏捷开发重点介绍

    参考: http://www.scrumcn.com/agile/scrum-knowledge-library/scrum.html https://www.zhihu.com/question/3 ...

  5. WCF: Retry when service is in fault state.

    Service Host: using System; using System.Configuration; using System.ServiceModel; using System.Serv ...

  6. Eclipse安卓插件安装

    首先说明下载的ADT专门真安卓开发的Eclipse下载下来后就集成了可以直接使用了 但是使用j2EE版本的Eclipse就需要安装插件支持安卓开发了 首先下载ADT Eclipse安卓插件 下载完成后 ...

  7. node的“宏任务(macro-task)”和“微任务(micro-task)”机制

    macrotask 和 microtask 表示异步任务的两种分类.在挂起任务时,JS 引擎会将所有任务按照类别分到这两个队列中,首先在 macrotask 的队列(这个队列也被叫做 task que ...

  8. springboot+mybatis使用PageHelper分页

    项目结构和spring搭建mybatis请参考springboot整合mybatis.在这个基础上配置分页. 一:导入PageHelper依赖 <dependency> <group ...

  9. HDU 1171 Big Event in HDU(01背包)

    题目链接 题意:给出n个物品的价值v,每个物品有m个,设总价值为sum,求a,b.a+b=sum,且a尽可能接近b,a>=b. 题解:01背包. #include <bits/stdc++ ...

  10. 键盘ASCII码

    回车键 -- CR 键0x0d   -- 16进制13 -- 10 进制'\r' -- 也可以 换行键 -- LF0x0a   -- 16进制10 -- 10 进制'\n' -- 也可以 esc键   ...