如何搭建及使用 docker registry

作者:腾讯云高级工程师董晓杰

本文通过Docker Compose搭建了一个简单的registry环境,使用的是docker hub官方镜像,registry镜像版本registry:2.5.0, nginx镜像版本nginx:1.11.5。主要介绍了registry环境的搭建及使用,更详细的企业级Registry服务器的搭建可参考开源的Harbor

亲自动手实验一下会理解更深刻,动手吧!

使用腾讯云容器服务无须自建registry,快速使用安全可靠的镜像仓库

registry是什么?

registry是Docker的镜像存储服务,docker hub上的registry镜像见Registry官方镜像,更多详细信息请参见源码

搭建registry

  • 在服务器上执行如下命令安装docker,这里选择腾讯云(Ubuntu Server 14.04.1 LTS 64位)镜像来创建服务器

curl -fsSL https://get.docker.com/ | sh

  • 安装docker-compose

Docker Compose是一个定义及运行多个Docker容器的工具。使用Docker Compose只需要在一个配置文件中定义多个Docker容器,然后使用一条命令将多个容器启动,Docker Compose会通过解析容器间的依赖关系,按先后顺序启动所定义的容器。详见Docker Compose

curl -L https://github.com/docker/compose/releases/download/1.8.0/docker-compose-$(uname -s)-$(uname -m) > /usr/local/bin/docker-compose
chmod a+x /usr/local/bin/docker-compose
  • 启动registry服务,此例中包含nginx和registry两个容器,涉及的配置文件请参见附录,部署好后,直接执行如下命令即可创建服务。 docker-compose up -d
  • 停止服务 docker-compose stop
  • 重启服务 docker-compose restart
  • 下线服务 docker-compose down

上传镜像

  • 因为上面搭建的registry服务是http的,所以docker启动参数需要配置--insecure-registry localhost选项,修改/etc/default/docker文件 DOCKER_OPTS="--insecure-registry localhost"
  • 重启docker service docker restart
  • 拉取上传镜像 docker pull;docker tag;docker push(tag默认为latest) docker pull hello-world docker tag hello-world localhost/library/hello-world docker push localhost/library/hello-world

下载镜像

docker pull localhost/library/hello-world

删除镜像

docker rmi localhost/library/hello-world

获取镜像仓库列表

# curl http://localhost/v2/_catalog
{"repositories":["library/hello-world"]}

未上传镜像前的输出如下:

# curl http://localhost/v2/_catalog
{"repositories":[]}

获取镜像tag列表

# curl -X GET http://localhost/v2/library/hello-world/tags/list
{"name":"library/hello-world","tags":["latest"]}

获取镜像manifests信息

# curl -H "Accept: application/vnd.docker.distribution.manifest.v2+json"  -X GET http://localhost/v2/library/hello-world/manifests/latest
{
   "schemaVersion": 2,
   "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
   "config": {
      "mediaType": "application/vnd.docker.container.image.v1+json",
      "size": 1473,
      "digest": "sha256:c54a2cc56cbb2f04003c1cd4507e118af7c0d340fe7e2720f70976c4b75237dc"
   },
   "layers": [
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": 974,
         "digest": "sha256:c04b14da8d1441880ed3fe6106fb2cc6fa1c9661846ac0266b8a5ec8edf37b7c"
      }
   ]
}

其中 c54a2cc56cbb2f04003c1cd4507e118af7c0d340fe7e2720f70976c4b75237dc即为执行docker images时看到的IMAGE ID。

layers表示了镜像的层次关系,可以通过layers中的digest来拉取blob,见下面获取镜像blob

获取镜像blob

在上面获取hello-world:latest镜像的manifests信息中可以看到其只有一个layer,以此为例来看如何获取镜像blob。从拉取的结果可以看到获取的blob与文件sha256是一致的。执行docker pull实际上就是首先获取到镜像的manifests信息后,再拉取blob的

# curl -s -X GET http://localhost/v2/library/hello-world/blobs/sha256:c04b14da8d1441880ed3fe6106fb2cc6fa1c9661846ac0266b8a5ec8edf37b7c -o hello-world.blob
# ls -l hello-world.blob 
-rw-r--r-- 1 root root 974 Nov 23 09:56 hello-world.blob
# sha256sum hello-world.blob 
c04b14da8d1441880ed3fe6106fb2cc6fa1c9661846ac0266b8a5ec8edf37b7c  hello-world.blob    

删除镜像(soft delete)

首先通过 curl -i 参数获取到镜像的 Docker-Content-Digest ,registry 2.3及以后的版本必须在header中指定Accept: application/vnd.docker.distribution.manifest.v2+json,否则默认返回的是schema1的digest,其与schema2的digest不同,使用不指定上述头信息返回的digest删除时会返回404。

# curl -i -H "Accept: application/vnd.docker.distribution.manifest.v2+json"  -X GET http://localhost/v2/library/hello-world/manifests/latest

HTTP/1.1 200 OK
Server: nginx/1.11.5
Date: Wed, 23 Nov 2016 02:17:51 GMT
Content-Type: application/vnd.docker.distribution.manifest.v2+json
Content-Length: 524
Connection: keep-alive
Docker-Content-Digest: sha256:a18ed77532f6d6781500db650194e0f9396ba5f05f8b50d4046b294ae5f83aa4
Docker-Distribution-Api-Version: registry/2.0
Etag: "sha256:a18ed77532f6d6781500db650194e0f9396ba5f05f8b50d4046b294ae5f83aa4"

{
   "schemaVersion": 2,
   "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
   "config": {
      "mediaType": "application/vnd.docker.container.image.v1+json",
      "size": 1473,
      "digest": "sha256:c54a2cc56cbb2f04003c1cd4507e118af7c0d340fe7e2720f70976c4b75237dc"
   },
   "layers": [
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": 974,
         "digest": "sha256:c04b14da8d1441880ed3fe6106fb2cc6fa1c9661846ac0266b8a5ec8edf37b7c"
      }
   ]
}

根据上一步返回的Docker-Content-Digest删除,返回202表示删除成功

# curl -k -v -s -X DELETE http://localhost/v2/library/hello-world/manifests/sha256:a18ed77532f6d6781500db650194e0f9396ba5f05f8b50d4046b294ae5f83aa4

* Hostname was NOT found in DNS cache
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 80 (#0)
> DELETE /v2/library/hello-world/manifests/sha256:a18ed77532f6d6781500db650194e0f9396ba5f05f8b50d4046b294ae5f83aa4 HTTP/1.1
> User-Agent: curl/7.35.0
> Host: localhost
> Accept: */*
> 
< **HTTP/1.1 202 Accepted**
* Server nginx/1.11.5 is not blacklisted
< Server: nginx/1.11.5
< Date: Wed, 23 Nov 2016 02:29:59 GMT
< Content-Type: text/plain; charset=utf-8
< Content-Length: 0
< Connection: keep-alive
< Docker-Distribution-Api-Version: registry/2.0
< 
* Connection #0 to host localhost left intact

确认结果

# curl -X GET http://localhost/v2/library/hello-world/tags/list
{"name":"library/hello-world","tags":null}

删除镜像(hard delete)

在上一步中,只是删除了镜像的manifests信息,解引用的blob还在占用磁盘空间,执行如下命令可以查看可以删除的blob

docker exec -it myregistry_registry_1 /bin/registry garbage-collect --dry-run /etc/registry/config.yml

要删除blob,释放磁盘空间,需要执行下面的命令。需要特别注意的是在执行下面的命令时registry必须是只读模式(只读模式可在registry配置文件中设置),否则可能会导致数据不一致。

docker exec -it myregistry_registry_1 /bin/registry garbage-collect /etc/registry/config.yml

附录

目录结构

.
|-- config
|   |-- nginx
|   |   `-- nginx.conf
|   `-- registry
|       `-- config.yml
`-- docker-compose.yml

nginx.conf

worker_processes auto;

events {
  worker_connections 1024;
  use epoll;
  multi_accept on;
}

http {
  tcp_nodelay on;

  # this is necessary for us to be able to disable request buffering in all cases
  proxy_http_version 1.1;


  upstream registry {
    server registry:5000;
  }


  server {
    listen 80;

    # disable any limits to avoid HTTP 413 for large image uploads
    client_max_body_size 0;

    location /v1/ {
      return 404;
    }

    location /v2/ {
      proxy_pass http://registry/v2/;
      proxy_set_header Host $http_host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

      # When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings.
      proxy_set_header X-Forwarded-Proto $scheme;

      proxy_buffering off;
      proxy_request_buffering off;

    }

  }
}

config.yml

version: 0.1
log:
  level: debug
  fields:
    service: registry
storage:
    cache:
        layerinfo: inmemory
    filesystem:
        rootdirectory: /var/lib/registry
    maintenance:
        uploadpurging:
            enabled: false
        readonly:
            enabled: false
    delete:
        enabled: true
http:
    addr: :5000
    secret: yoursecret

docker-comose.yaml

version: '2'
services:
  registry:
    image: library/registry:2.5.0
    restart: always
    volumes:
      - /data/registry:/var/lib/registry
      - ./config/registry/:/etc/registry/
    environment:
      - GODEBUG=netdns=cgo
    command:
      ["serve", "/etc/registry/config.yml"]
  proxy:
    image: library/nginx:1.11.5
    restart: always
    volumes:
      - ./config/nginx:/etc/nginx
    ports:
      - 80:80
      - 443:443
    depends_on:
      - registry

原创声明,本文系作者授权云+社区-专栏发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏帘卷西风的专栏

CentOS yum安装或者升级GCC到4.8

之前一直没怎么用C++11,最近的项目都开始使用,但是Centos使用yum工具安装GCC的版本是4.4.7,因此需要升级才行。

932
来自专栏Java技术栈

Maven精选系列--eclipse各种操作

在eclipse中配置maven的安装目录,使用最新的maven插件,从安装列表中可以看到eclipse自带绑定的是3.3.9,不是最新的,我们勾选自己的最新的...

33910
来自专栏xingoo, 一个梦想做发明家的程序员

CentOS下重新安装JDK,避免OpenJDK干扰

有的时候根据自己的需要,可能要不同版本的JDK,使用如下命令可以查看JDK版本 java -version Centos在安装的时候,自带了一个OpenJDK...

1766
来自专栏JavaEE

redis学习之redis的安装(linux)redis简介:redis的安装:启动redis:修改:总结:

34812
来自专栏菩提树下的杨过

ssh远程执行目标机器上的命令

一句话: ssh -t -p 端口号 用户名@远程机器IP '远程机器上的命令完整路径' 例如:   ssh -t -p 22 yangjunming@dev ...

17410
来自专栏coding

ubuntu安装lemp步骤

1084
来自专栏Ken的杂谈

【Ubuntu快速上手】六、Ubuntu环境下Nginx安装&配置

561
来自专栏linux系统运维

zip压缩以及tar打包

17110
来自专栏尾尾部落

手把手教你在centos7中安装mysql数据库

CentOS 7 版本将MySQL数据库软件从默认的程序列表中移除,用mariadb代替了。 所以要安装mysql有两种方法,一种是直接安装mariadb,另...

1154
来自专栏Java成神之路

重拾安卓_01_安卓开发环境搭建(eclipse)

(1)官网(可FQ选择):http://developer.android.com/sdk/index.html

662

扫码关注云+社区