14.3 使用私有仓库批量上传镜像在第一部分对Docker私有仓库的讲解中我们介绍了如何使用本地私有仓库进行上传、下载等操作。有时候本地镜像很多逐个打标记上传将十分浪费时间。这里我们给出两个自动化脚本来快速完成对大量镜像的上传操作。批量上传指定镜像可以使用下面的push_images.sh脚本批量上传本地的镜像到注册服务器中默认是本地注册服务器127.0.0.15000用户可以通过修改registry127.0.0.15000这行来指定目标注册服务器#!/bin/sh# This script will upload the given local images to a registry server ($registry is the default value).# See: https://github.com/yeasy/docker_practice/blob/master/_local/push_images.sh# Usage: push_images image1 [image2http://www.hzcourse.com/resource/readBook?path/openresources/teach_ebook/uncompressed/15029/OEBPS/Text/...]# Author: yeasygithub# Create: 2014-09-23#The registry server address where you want push the images intoregistry127.0.0.1:5000### DO NOT MODIFY THE FOLLOWING PART UNLESS YOU KNOW WHAT IT MEANS ###echo_r () {[ $# -ne 1 ] return 0echo -e \033[31m$1\033[0m}echo_g () {[ $# -ne 1 ] return 0echo -e \033[32m$1\033[0m}echo_y () {[ $# -ne 1 ] return 0echo -e \033[33m$1\033[0m}echo_b () {[ $# -ne 1 ] return 0echo -e \033[34m$1\033[0m}usage() {sudo docker imagesecho Usage: $0 registry1:tag1 [registry2:tag2http://www.hzcourse.com/resource/readBook?path/openresources/teach_ebook/uncompressed/15029/OEBPS/Text/...]}[$# -lt 1 ] usage exitecho_b The registry server is $registryfor image in $doecho_b Uploading $imagehttp://www.hzcourse.com/resource/readBook?path/openresources/teach_ebook/uncompressed/15029/OEBPS/Text/...sudo docker tag $image $registry/$imagesudo docker push $registry/$imagesudo docker rmi $registry/$imageecho_g Donedone建议把脚本存放到本地的可执行路径下例如/usr/local/bin/下面。然后添加可执行权限就可以使用该脚本了$ sudo chmod ax /usr/local/bin/push_images.sh例如推送本地的ubuntulatest和centoscentos7两个镜像到本地仓库$ ./push_images.sh ubuntu:latest centos:centos7The registry server is 127.0.0.1Uploading ubuntu:latesthttp://www.hzcourse.com/resource/readBook?path/openresources/teach_ebook/uncompressed/15029/OEBPS/Text/...The push refers to a repository [127.0.0.1:5000/ubuntu] (len: 1)Sending image listPushing repository 127.0.0.1:5000/ubuntu (1 tags)Image 511136ea3c5a already pushed skippingImage bfb8b5a2ad34 already pushed skippingImage c1f3bdbd8355 already pushed skippingImage 897578f527ae already pushed skippingImage 9387bcc9826e already pushed skippingImage 809ed259f845 already pushed skippingImage 96864a7d2df3 already pushed skippingPushing tag for rev [96864a7d2df3] on {http://127.0.0.1:5000/v1/repositories/ubuntu/tags/latest}Untagged: 127.0.0.1:5000/ubuntu:latestDoneUploading centos:centos7http://www.hzcourse.com/resource/readBook?path/openresources/teach_ebook/uncompressed/15029/OEBPS/Text/...The push refers to a repository [127.0.0.1:5000/centos] (len: 1)Sending image listPushing repository 127.0.0.1:5000/centos (1 tags)Image 511136ea3c5a already pushed skipping34e94e67e63a: Image successfully pushed70214e5d0a90: Image successfully pushedPushing tag for rev [70214e5d0a90] on {http://127.0.0.1:5000/v1/repositories/centos/tags/centos7}Untagged: 127.0.0.1:5000/centos:centos7Done上传后查看本地镜像会发现上传中创建的临时标签也同时被清理了。上传本地所有镜像在push_images工具的基础上还可以进一步的创建push_all工具来上传本地所有镜像#!/bin/sh# This script will upload all local images to a registry server ($registry is the default value).# This script requires the push_images which can be found at https://github.com/yeasy/docker_practice/blob/master/_local/push_images.sh# Usage: push_all# Author: yeasygithub# Create: 2014-09-23for image in sudo docker images|grep -v REPOSITORY|grep -v none|awk {print $1:$2}dopush_images.sh $imagedone同样读者把它放在/usr/local/bin/下面并添加可执行权限之后就可以通过push_all命令来上传本地所有镜像到本地私有仓库了。14.4 仓库配置文件Docker的Registry利用配置文件提供了一些仓库的模板flavor用户可以直接使用它们来进行开发或生产部署。我们将以下面的示例配置为例来介绍如何使用仓库配置文件来管理私有仓库。示例配置#All other flavors inherit the common config snippetcommon: commonissue: docker-registry server# 默认记录info和以上级别的日志loglevel: _env:LOGLEVEL:info# 是否启用debug模式debug: _env:DEBUG:false# 默认是standalone模式 不查询index服务standalone: _env:STANDALONE:true# 非standalone模式下的index服务默认是index.docker.ioindex_endpoint: _env:INDEX_ENDPOINT:https://index.docker.io# 默认不启用存储转向storage_redirect: _env:STORAGE_REDIRECT# 非standalone模式下启用基于口令串的认证disable_token_auth: _env:DISABLE_TOKEN_AUTH# 默认不使用特权privileged_key: _env:PRIVILEGED_KEY# 搜索后端支持search_backend: _env:SEARCH_BACKEND# SQLite搜索后端数据库地址sqlalchemy_index_database: _env:SQLALCHEMY_INDEX_DATABASE:sqlite:////tmp/docker-registry.db# 默认不启用镜像服务mirroring:source: _env:MIRROR_SOURCE # https://registry-1.docker.iosource_index: _env:MIRROR_SOURCE_INDEX # https://index.docker.iotags_cache_ttl: _env:MIRROR_TAGS_CACHE_TTL:172800 # secondscache:host: _env:CACHE_REDIS_HOSTport: _env:CACHE_REDIS_PORTdb: _env:CACHE_REDIS_DB:0password: _env:CACHE_REDIS_PASSWORD# 访问远端存储后端时 配置LRU缓存cache_lru:host: _env:CACHE_LRU_REDIS_HOSTport: _env:CACHE_LRU_REDIS_PORTdb: _env:CACHE_LRU_REDIS_DB:0password: _env:CACHE_LRU_REDIS_PASSWORD# 发生异常时发送邮件通知email_exceptions:smtp_host: _env:SMTP_HOSTsmtp_port: _env:SMTP_PORT:25smtp_login: _env:SMTP_LOGINsmtp_password: _env:SMTP_PASSWORDsmtp_secure: _env:SMTP_SECURE:falsefrom_addr: _env:SMTP_FROM_ADDR:docker-registrylocaldomain.localto_addr: _env:SMTP_TO_ADDR:noisedockerregistrylocaldomain.local# 启用bugsnagbugsnag: _env:BUGSNAG# CORS支持 默认未启用cors:origins: _env:CORS_ORIGINSmethods: _env:CORS_METHODSheaders: _env:CORS_HEADERS:[Content-Type]expose_headers: _env:CORS_EXPOSE_HEADERSsupports_credentials: _env:CORS_SUPPORTS_CREDENTIALSmax_age: _env:CORS_MAX_AGEsend_wildcard: _env:CORS_SEND_WILDCARDalways_send: _env:CORS_ALWAYS_SENDautomatic_options: _env:CORS_AUTOMATIC_OPTIONSvary_header: _env:CORS_VARY_HEADERresources: _env:CORS_RESOURCESlocal: local: *commonstorage: localstorage_path: _env:STORAGE_PATH:/tmp/registrys3: s3: *commonstorage: s3s3_region: _env:AWS_REGIONs3_bucket: _env:AWS_BUCKETboto_bucket: _env:AWS_BUCKETstorage_path: _env:STORAGE_PATH:/registrys3_encrypt: _env:AWS_ENCRYPT:trues3_secure: _env:AWS_SECURE:trues3_access_key: _env:AWS_KEYs3_secret_key: _env:AWS_SECRETboto_host: _env:AWS_HOSTboto_port: _env:AWS_PORTboto_calling_format: _env:AWS_CALLING_FORMAT# Ceph对象网关配置ceph-s3: ceph-s3: *commonstorage: s3s3_region: ~s3_bucket: _env:AWS_BUCKETs3_encrypt: _env:AWS_ENCRYPT:falses3_secure: _env:AWS_SECURE:falsestorage_path: _env:STORAGE_PATH:/registrys3_access_key: _env:AWS_KEYs3_secret_key: _env:AWS_SECRETboto_bucket: _env:AWS_BUCKETboto_host: _env:AWS_HOSTboto_port: _env:AWS_PORTboto_debug: _env:AWS_DEBUG:0boto_calling_format: _env:AWS_CALLING_FORMAT# Google云存储配置gcs:: *commonstorage: gcsboto_bucket: _env:GCS_BUCKETstorage_path: _env:STORAGE_PATH:/registrygs_secure: _env:GCS_SECURE:truegs_access_key: _env:GCS_KEYgs_secret_key: _env:GCS_SECRET# 存储服务的OAuth 2.0认证oauth2: _env:GCS_OAUTH2:false# 存储镜像文件到Openstack Swift服务swift: swift: *commonstorage: swiftstorage_path: _env:STORAGE_PATH:/registry# keystone authorizationswift_authurl: _env:OS_AUTH_URLswift_container: _env:OS_CONTAINERswift_user: _env:OS_USERNAMEswift_password: _env:OS_PASSWORDswift_tenant_name: _env:OS_TENANT_NAMEswift_region_name: _env:OS_REGION_NAME# 存储镜像文件到Open Stack Glance服务# 参见: https://github.com/docker/openstack-dockerglance: glance: *commonstorage: glancestorage_alternate: _env:GLANCE_STORAGE_ALTERNATE:filestorage_path: _env:STORAGE_PATH:/tmp/registryopenstack:: *glance# 存储镜像文件到Glance 标签信息到Swiftglance-swift: glance-swift: *swiftstorage: glancestorage_alternate: swiftopenstack-swift:: *glance-swiftelliptics:: *commonstorage: ellipticselliptics_nodes: _env:ELLIPTICS_NODESelliptics_wait_timeout: _env:ELLIPTICS_WAIT_TIMEOUT:60elliptics_check_timeout: _env:ELLIPTICS_CHECK_TIMEOUT:60elliptics_io_thread_num: _env:ELLIPTICS_IO_THREAD_NUM:2elliptics_net_thread_num: _env:ELLIPTICS_NET_THREAD_NUM:2elliptics_nonblocking_io_thread_num: _env:ELLIPTICS_NONBLOCKING_IO_THREAD_NUM:2elliptics_groups: _env:ELLIPTICS_GROUPSelliptics_verbosity: _env:ELLIPTICS_VERBOSITY:4elliptics_logfile: _env:ELLIPTICS_LOGFILE:/dev/stderrelliptics_addr_family: _env:ELLIPTICS_ADDR_FAMILY:2# 默认启用的配置选项dev: dev: *localloglevel: _env:LOGLEVEL:debugdebug: _env:DEBUG:truesearch_backend: _env:SEARCH_BACKEND:sqlalchemy# 用于测试test:: *devindex_endpoint: https://registry-stage.hub.docker.comstandalone: truestorage_path: _env:STORAGE_PATH:./tmp/test# 在环境变量SETTINGS_FLAVOR中指定启用哪个配置 例如$ export SETTINGS_FLAVORprodprod:: *s3storage_path: _env:STORAGE_PATH:/prod模板在config_sample.yml文件中可以看到一些现成的模板段·common基础配置。·local存储数据到本地文件系统。·s3存储数据到AWS S3中。·dev使用local模板的基本配置。·test单元测试使用。·prod生产环境配置基本上跟s3配置类似。·gcs存储数据到Google的云存储。·swift存储数据到OpenStack Swift服务。·glance存储数据到OpenStack Glance服务本地文件系统为后备。·glance-swift存储数据到OpenStack Glance服务Swift为后备。·elliptics存储数据到Elliptics key/value存储。用户也可以添加自定义的模板段。默认情况下使用的模板是dev要使用某个模板作为默认值可以添加SETTINGS_FLAVOR到环境变量中例如export SETTINGS_FLAVORdev另外配置文件中支持从环境变量中加载值语法格式为_env:VARIABLENAME[:DEFAULT]项基本选项如下·loglevel字符串类型标注输出调试信息的级别包括debug、info、warn、error和critical。·debug布尔类型开启后会在访问/_ping时候输出更多的信息包括库版本和主机信息等。·storage_redirect重定向存储请求。·boto_host/boto_port使用s3模板时标准boto配置文件的位置。认证选项如下·standalone布尔类型运行在独立模式下不进行用户验证等同时会配置disable_token_auth。·index_endpoint字符串配置index服务位置用来验证用户默认是https://index.docker.io。·disable_token_auth布尔类型禁止通过token进行验证此时用户需要提供自己的验证机制。搜索选项如下Docker注册服务器可以将仓库的索引信息放到数据库中供通过GET方法访问/v1/search时使用。·search_backend选择搜索后端类型目前仅支持sqlalchemy。用户也可以将它指定为自定义的模块。例如common:search_backend: foo.registry.index.xapian·sqlalchemy_index_database当使用sqlalchemy作为索引后端引擎时可以通过sqlalchemy_index_database来指定创建数据库的位置。例如common:search_backend: sqlalchemysqlalchemy_index_database: sqlite:////tmp/docker-registry.db镜像选项都放在mirroring字段下面例如common:mirroring:source: https://registry-1.docker.iosource_index: https://index.docker.iotags_cache_ttl: 172800 # 2 days默认并未启用。缓存选项包括cache字段和cache_lru字段例如cache:host: _env:CACHE_REDIS_HOSTport: _env:CACHE_REDIS_PORTdb: _env:CACHE_REDIS_DB:0password: _env:CACHE_REDIS_PASSWORD# Enabling LRU cache for small files# This speeds up read/write on small files# when using a remote storage backend (like S3).cache_lru:host: _env:CACHE_LRU_REDIS_HOSTport: _env:CACHE_LRU_REDIS_PORTdb: _env:CACHE_LRU_REDIS_DB:0password: _env:CACHE_LRU_REDIS_PASSWORD通过配置缓存事先本地要启动一个LRU模式下的redis服务器可以将小文件缓存在本地加速仓库的查询性能。Email选项为email_exceptions字段通过配置该选项当仓库发生异常时可自动发送Email。例如email_exceptions:smtp_host: _env:SMTP_HOSTsmtp_port: _env:SMTP_PORT:25smtp_login: _env:SMTP_LOGINsmtp_password: _env:SMTP_PASSWORDsmtp_secure: _env:SMTP_SECURE:falsefrom_addr: _env:SMTP_FROM_ADDR:docker-registrylocaldomain.localto_addr: _env:SMTP_TO_ADDR:noisedockerregistrylocaldomain.local存储选项为storage该选项将选择事先存储的引擎仓库默认自带两种类型的引擎file和s3。用户如果需要其他引擎支持可以通过下面的命令来进行搜索可用引擎并安装。$ pip search docker-registry-driver$ pip install docker-registry-driver-NAME安装后可能需要对引擎进行配置。目前支持的引擎包括·elliptics一种分布式键值数据存储·swiftOpenStack的子项目提供对象存储服务·gcsGoolge的子存储·glanceOpenStack的子项目提供文件存储服务file引擎file引擎意味着存储到本地文件。当使用file引擎的时候可以通过storage_path来指定存储的具体位置以local模板为例默认为/tmp/registry。local: local: *commonstorage: localstorage_path: _env:STORAGE_PATH:/tmp/registry因此我们在运行registry镜像时可以挂载本地目录到这个位置来保存仓库中的数据到本地即$ docker run -p 5000 -v /tmp/registry:/tmp/registry registrys3引擎s3引擎意味着存储到亚马逊的云服务。亚马逊s3引擎支持的选项包括·s3_access_key字符串类型s3的访问口令。·s3_secret_key字符串类型s3密钥。·s3_bucket字符串类型s3桶名称。·s3_regions3桶所在的存放域。·s3_encrypt布尔类型是否加密存储。·s3_secure布尔类型进行访问时是否启用HTTPS。·boto_bucket字符串类型对s3不兼容对象存储的桶名。·boto_host字符串类型对s3不兼容对象存储的主机。·boto_port对s3不兼容对象存储的端口。·boto_debug对s3不兼容对象存储的调试输出。·boto_calling_format字符串类型boto调用所使用格式的类名。·storage_path字符串类型镜像文件存储的子路径。例如prod:storage: s3s3_region: us-west-1s3_bucket: acme-dockerstorage_path: /registrys3_access_key: AKIAHSHB43HS3J92MXZs3_secret_key: xdDowwlK7TJajV1Y7EoOZrmuPEJlHYcNP2k4j49T14.5 本章小结本章详细介绍了使用docker-registry的两种主要方式通过容器方式运行和通过本地安装运行并注册为系统服务以及添加Nginx反向代理和添加基于HTTP的用户认证功能。接下来编写了批量上传镜像到仓库的脚本实现。最后还详细介绍了docker-registry配置文件中各个选项的含义和使用。通过本章的学习读者将能轻松搭建一套私有的仓库服务环境并对其进行管理操作。私有仓库服务是集中存储镜像的场所它的稳定性将影响整个Docker使用环节。在生产环境中笔者推荐使用负载均衡来提高仓库服务的性能还可以利用HAProxy等方式对仓库服务进行容错。同时为了安全考虑可以为仓库访问启用HTTPS等加密协议来确保通信的安全。