当我们pull一个registry镜像或者自己制作一个镜像之后,使用命令docker run -d -p 5000:5000 registry,就可以启动一个私有容器服务,那么究竟是怎么做到的呢?

首先docker ps显示cmd是 "docker-registry",但是启动的时候并没有输入。
  root@host-10-9-27-62:/home/opuser# docker ps
  CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  ffca4ca34c3f registry "docker-registry" 24 hours ago Up 22 hours 0.0.0.0:5000->5000/tcp desperate_lumiere

记得dockerfile中可以指定启动docker后执行的命令,下面看看创建registry镜像的Dockerfile
  root@ffca4ca34c3f:/# cat docker-registry/Dockerfile
# VERSION 0.1
# DOCKER-VERSION 0.7.3
# AUTHOR: Sam Alba <sam@docker.com>
# DESCRIPTION: Image with docker-registry project and dependecies
# TO_BUILD: docker build -rm -t registry .
# TO_RUN: docker run -p 5000:5000 registry

# Latest Ubuntu LTS
FROM ubuntu:14.04

# Update
RUN apt-get update \
# Install pip
&& apt-get install -y \
swig \
python-pip \
# Install deps for backports.lzma (python2 requires it)
python-dev \
python-mysqldb \
python-rsa \
libssl-dev \
liblzma-dev \
libevent1-dev \
# Install deps for building gevent
curl \
cython \
&& rm -rf /var/lib/apt/lists/*

COPY . /docker-registry
COPY ./config/boto.cfg /etc/boto.cfg

# Install core
RUN pip install /docker-registry/depends/docker-registry-core

# Install gevent 1.0.1 using updated config.guess and config.sub
RUN curl https://pypi.python.org/packages/source/g/gevent/gevent-1.0.1.tar.gz | tar -xzf - -C / \
&& curl -o /gevent-1.0.1/libev/config.guess \
'http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD' \
&& curl -o /gevent-1.0.1/libev/config.sub \
'http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD' \
&& cp -pf /gevent-1.0.1/libev/config.guess /gevent-1.0.1/c-ares/config.guess \
&& cp -pf /gevent-1.0.1/libev/config.sub /gevent-1.0.1/c-ares/config.sub \
&& pip install /gevent-1.0.1

# Install registry
RUN pip install file:///docker-registry#egg=docker-registry[bugsnag,newrelic,cors]

RUN patch \
$(python -c 'import boto; import os; print os.path.dirname(boto.__file__)')/connection.py \
< /docker-registry/contrib/boto_header_patch.diff

ENV DOCKER_REGISTRY_CONFIG /docker-registry/config/config_sample.yml
ENV SETTINGS_FLAVOR dev

EXPOSE 5000

CMD ["docker-registry"]

可以看到最后一句CMD ["docker-registry"] ,就是这里了。

那么这个命令是怎么启动registry服务的呢?进入registry容器里
  root@ffca4ca34c3f:/# which docker-registry
  /usr/local/bin/docker-registry

  root@ffca4ca34c3f:/# cat /usr/local/bin/docker-registry
#!/usr/bin/python
# EASY-INSTALL-ENTRY-SCRIPT: 'docker-registry==1.0.0-dev','console_scripts','docker-registry'
__requires__ = 'docker-registry==1.0.0-dev'
import sys
from pkg_resources import load_entry_point

if __name__ == '__main__':
sys.exit(
load_entry_point('docker-registry==1.0.0-dev', 'console_scripts', 'docker-registry')()
)
这里用到了Python的一个方法,不太清楚,可以参考文章
  http://blog.sina.com.cn/s/blog_85998e380101bojs.html
  http://www.cnblogs.com/babykick/archive/2012/03/09/2387808.html
继续往下看

  root@ffca4ca34c3f:/# cat /usr/local/lib/python2.7/dist-packages/docker_registry-1.0.0_dev-py2.7.egg-info/entry_points.txt
[console_scripts]
docker-registry = docker_registry.run:run_gunicorn
到这里就大概知道什么回事了,其实是调用了run.py的run_gunicorn方法

  root@ffca4ca34c3f:/# cat /usr/local/lib/python2.7/dist-packages/docker_registry/run.py
def run_gunicorn():
"""Exec gunicorn with our wsgi app.
......

args = [
gunicorn_path, 'gunicorn',
'--access-logfile', env.source('GUNICORN_ACCESS_LOG_FILE'),
'--error-logfile', env.source('GUNICORN_ERROR_LOG_FILE'),
'--max-requests', '100',
'-k', 'gevent',
'--graceful-timeout', env.source('GUNICORN_GRACEFUL_TIMEOUT'),
'-t', env.source('GUNICORN_SILENT_TIMEOUT'),
'-w', env.source('GUNICORN_WORKERS'),
'-b', address,
]

......

args += env.source('GUNICORN_OPTS')
args.append('docker_registry.wsgi:application')
# Stringify all args and call
os.execl(*[str(v) for v in args])

run_gunicorn()调用了gunicorn程序,在host上ps的时候可以看到,registry容器启动了5个gunicorn进程。
  root 17466 0.0 0.9 21504 19264 ? Ss Dec09 0:00 /usr/bin/python /usr/local/bin/gunicorn --access-logfile - --error-logfil
  root 17480 1.2 2.2 48896 45888 ? S Dec09 15:37 /usr/bin/python /usr/local/bin/gunicorn --access-logfile - --error-logfil
  root 17481 1.2 2.2 48960 46080 ? S Dec09 15:34 /usr/bin/python /usr/local/bin/gunicorn --access-logfile - --error-logfil
  root 17482 1.2 2.2 49088 46080 ? S Dec09 15:35 /usr/bin/python /usr/local/bin/gunicorn --access-logfile - --error-logfil
  root 17483 1.2 2.2 49664 46720 ? S Dec09 15:34 /usr/bin/python /usr/local/bin/gunicorn --access-logfile - --error-logfil

参考资料
  Gunicorn - Python WSGI HTTP Server for UNIX
  www.gunicorn.org

Docker Registry服务启动过程浅析的更多相关文章

  1. 在Ubuntu14.04系统POWER8服务器上搭建Docker Registry服务

    本文描述了如何在POWER8服务器上搭建一个本地化的Docker镜像仓库,主要涉及镜像制作,Docker Registry服务启动等.希望能够对在非X86服务器上搭建Docker仓库的同学提供参考. ...

  2. Linux入门——开机启动过程浅析

    Linux开机启动过程浅析 Introduction 开机启动过程分为以下6个步骤,分别是BIOS, MBR, GRUB, Kernel, Init, RunLevel, RunDefinition ...

  3. Windows平台下Oracle监听服务启动过程中日志输出

    Windows平台下Oracle监听服务启动过程中日志输出记录. 日志目录:D:\app\Administrator\diag\tnslsnr\WIN-RU03CB21QGA\listener\tra ...

  4. Android AudioPolicyService服务启动过程

    AudioPolicyService是策略的制定者,比如什么时候打开音频接口设备.某种Stream类型的音频对应什么设备等等.而AudioFlinger则是策略的执行者,例如具体如何与音频设备通信,如 ...

  5. docker compose 服务启动顺序控制

    概要 docker-compose 可以方便组合多个 docker 容器服务, 但是, 当容器服务之间存在依赖关系时, docker-compose 并不能保证服务的启动顺序. docker-comp ...

  6. A20(Cubieboard2)启动过程浅析

    A20支持从NAND Flash.SPI NOR Flash.SD card(SDC 0/2)和USB启动.当系统上电时,首先检测Boot Select Pin(BSP)管脚,如果为低电平,则直接从U ...

  7. Framework启动过程浅析

    浅显的总结一下Framework启动大概过程 总体 Android底层是linux系统,因而在开机时仍然是运行天字第一号进程inti,读取init.rc来创建第一个Dalvik进程zygote,下面是 ...

  8. Harbor安装部署--基于 Docker Distribution 的企业级 Registry 服务

    harbor简介 Harbor 是一个企业级 Registry 服务.它对开源的 Docker Registry 服务进行了扩展,添加了更多企业用户需要的功能.Harbor 被设计用于部署一套组织内部 ...

  9. 部署私有Docker Registry

    安装部署一个私有的Docker Registry是引入.学习和使用Docker这门技术的必经之路之一.尤其是当Docker被所在组织接受,更多人.项目和产品开始接触和使用Docker时,存储和分发自制 ...

随机推荐

  1. MVC 知识点学习3(linq to sql)

    1.通过DbContext对象的Database.SqlQuery执行sql语句 string query = "SELECT EnrollmentDate, COUNT(*) AS Stu ...

  2. 常用 Java 静态代码分析工具的分析与比较

    常用 Java 静态代码分析工具的分析与比较 简介: 本文首先介绍了静态代码分析的基 本概念及主要技术,随后分别介绍了现有 4 种主流 Java 静态代码分析工具 (Checkstyle,FindBu ...

  3. 1-Spark高级数据分析-第一章 大数据分析

    1.1 数据科学面临的挑战 第一,成功的分析中绝大部分工作是数据预处理. 第二,迭代与数据科学紧密相关.建模和分析经常需要对一个数据集进行多次遍历.这其中一方面是由机器学习算法和统计过程本身造成的. ...

  4. GithubPage 的简单使用

    这是我第一次写博客,主要是记录自己前端学习的经历.这次写一下GitHubpage 的简单使用.我用这里并没有想挂博客,主要是挂自己的一些小作品应用到简历中. 第一步: 首先先注册Github账号,创建 ...

  5. tabelView右滑选择进行删除

    如何使用UITableViewRowAction实现右滑选择呢? 1.在iOS8以前,我们实现tableview中滑动显示删除,置顶,更多等等的按钮时,都需要自己去实现,在iOS8中系统已经写好了,只 ...

  6. web安全之ssrf

    ssrf(服务器端请求伪造)原理: 攻击者构造形成由服务端发起请求的一个漏洞.把服务端当作跳板来攻击其他服务,SSRF的攻击目标一般是外网无法访问到的内网 当服务端提供了从其他服务器获取数据的功能(如 ...

  7. Android之ScrollView嵌套ListView和GridView冲突

    由于ListView,GridView本身都继承于ScrollView,一旦在ScrollView中嵌套ScrollView, 在ScrollView中嵌套使用ListView或者GridView,L ...

  8. 此博客主人已搬家访问新家地址:http://write.blog.csdn.net/postlist

    此博客主人已搬家访问新家地址:http://write.blog.csdn.net/postlist

  9. null和undefined区别(转)

    目前,null和undefined基本是同义的,只有一些细微的差别. null表示"没有对象",即该处不应该有值.典型用法是: (1) 作为函数的参数,表示该函数的参数不是对象. ...

  10. Dos学习笔记(1)dir命令

    这个命令是最常用的命令,就像linux的ls一样,同样他也有很多很多optionnal field供我们选择, 看了半天,觉得自己离盲打肯定还是有很大的差距的,现在只是想体验一下dos,或者说感受下这 ...