Docker Registry服务启动过程浅析
当我们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服务启动过程浅析的更多相关文章
- 在Ubuntu14.04系统POWER8服务器上搭建Docker Registry服务
本文描述了如何在POWER8服务器上搭建一个本地化的Docker镜像仓库,主要涉及镜像制作,Docker Registry服务启动等.希望能够对在非X86服务器上搭建Docker仓库的同学提供参考. ...
- Linux入门——开机启动过程浅析
Linux开机启动过程浅析 Introduction 开机启动过程分为以下6个步骤,分别是BIOS, MBR, GRUB, Kernel, Init, RunLevel, RunDefinition ...
- Windows平台下Oracle监听服务启动过程中日志输出
Windows平台下Oracle监听服务启动过程中日志输出记录. 日志目录:D:\app\Administrator\diag\tnslsnr\WIN-RU03CB21QGA\listener\tra ...
- Android AudioPolicyService服务启动过程
AudioPolicyService是策略的制定者,比如什么时候打开音频接口设备.某种Stream类型的音频对应什么设备等等.而AudioFlinger则是策略的执行者,例如具体如何与音频设备通信,如 ...
- docker compose 服务启动顺序控制
概要 docker-compose 可以方便组合多个 docker 容器服务, 但是, 当容器服务之间存在依赖关系时, docker-compose 并不能保证服务的启动顺序. docker-comp ...
- A20(Cubieboard2)启动过程浅析
A20支持从NAND Flash.SPI NOR Flash.SD card(SDC 0/2)和USB启动.当系统上电时,首先检测Boot Select Pin(BSP)管脚,如果为低电平,则直接从U ...
- Framework启动过程浅析
浅显的总结一下Framework启动大概过程 总体 Android底层是linux系统,因而在开机时仍然是运行天字第一号进程inti,读取init.rc来创建第一个Dalvik进程zygote,下面是 ...
- Harbor安装部署--基于 Docker Distribution 的企业级 Registry 服务
harbor简介 Harbor 是一个企业级 Registry 服务.它对开源的 Docker Registry 服务进行了扩展,添加了更多企业用户需要的功能.Harbor 被设计用于部署一套组织内部 ...
- 部署私有Docker Registry
安装部署一个私有的Docker Registry是引入.学习和使用Docker这门技术的必经之路之一.尤其是当Docker被所在组织接受,更多人.项目和产品开始接触和使用Docker时,存储和分发自制 ...
随机推荐
- MVC 知识点学习3(linq to sql)
1.通过DbContext对象的Database.SqlQuery执行sql语句 string query = "SELECT EnrollmentDate, COUNT(*) AS Stu ...
- 常用 Java 静态代码分析工具的分析与比较
常用 Java 静态代码分析工具的分析与比较 简介: 本文首先介绍了静态代码分析的基 本概念及主要技术,随后分别介绍了现有 4 种主流 Java 静态代码分析工具 (Checkstyle,FindBu ...
- 1-Spark高级数据分析-第一章 大数据分析
1.1 数据科学面临的挑战 第一,成功的分析中绝大部分工作是数据预处理. 第二,迭代与数据科学紧密相关.建模和分析经常需要对一个数据集进行多次遍历.这其中一方面是由机器学习算法和统计过程本身造成的. ...
- GithubPage 的简单使用
这是我第一次写博客,主要是记录自己前端学习的经历.这次写一下GitHubpage 的简单使用.我用这里并没有想挂博客,主要是挂自己的一些小作品应用到简历中. 第一步: 首先先注册Github账号,创建 ...
- tabelView右滑选择进行删除
如何使用UITableViewRowAction实现右滑选择呢? 1.在iOS8以前,我们实现tableview中滑动显示删除,置顶,更多等等的按钮时,都需要自己去实现,在iOS8中系统已经写好了,只 ...
- web安全之ssrf
ssrf(服务器端请求伪造)原理: 攻击者构造形成由服务端发起请求的一个漏洞.把服务端当作跳板来攻击其他服务,SSRF的攻击目标一般是外网无法访问到的内网 当服务端提供了从其他服务器获取数据的功能(如 ...
- Android之ScrollView嵌套ListView和GridView冲突
由于ListView,GridView本身都继承于ScrollView,一旦在ScrollView中嵌套ScrollView, 在ScrollView中嵌套使用ListView或者GridView,L ...
- 此博客主人已搬家访问新家地址:http://write.blog.csdn.net/postlist
此博客主人已搬家访问新家地址:http://write.blog.csdn.net/postlist
- null和undefined区别(转)
目前,null和undefined基本是同义的,只有一些细微的差别. null表示"没有对象",即该处不应该有值.典型用法是: (1) 作为函数的参数,表示该函数的参数不是对象. ...
- Dos学习笔记(1)dir命令
这个命令是最常用的命令,就像linux的ls一样,同样他也有很多很多optionnal field供我们选择, 看了半天,觉得自己离盲打肯定还是有很大的差距的,现在只是想体验一下dos,或者说感受下这 ...