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时,存储和分发自制 ...
随机推荐
- Native VS React Native VS 微信小程序
随着React Native和 微信小程序的出现,Native一家独大的局面出现裂痕,很多小公司使用已经正在着手微信小程序和React Native了,我公司就已经走上React Native之路.那 ...
- XML代码生成器——XMLFACTORY 简介(四)
XML代码生成器——XMLFACTORY 简介(四) 这一篇我们讲“类属性”页签的配置功能,您将了解到:如何为元素子值指定类属性的名称,数据类型,及容器类型. 如果,你没看过这个系列的第一篇文章,请先 ...
- 第三个Sprint团队贡献分
201306114322 邵家文 50分 201306114319 陈俊金 10分 201306114320 李新 10分 201306114324 朱浩龙 10分
- nexus私服update repair index索引失败解决方案(转)
转载地址:http://blog.csdn.net/first_sight/article/details/51559086 问题描述: 搭建Maven的Nexus私服仓库,一般安装完Nexus后,默 ...
- JSP基础——属性保存范围和request对象
JSP属性保存范围 JSP中提供了四种属性保存范围,分别为page,request,session及application. 1.page范围,指设置的属性只在当前页面有效.通过pageContext ...
- Java方法调用中的别名处理
将一个对象传递到方法内部时,也会产生别名现象.//: PassObject.java// Passing objects to methods can be a bit tricky62class L ...
- Android.os.NetworkOnMainThreadException
出现Android.os.NetworkOnMainThreadException错误提示的原因原因:不允许在主线程中进行网络访问解决办法:将网络访问的操作单独放到一个线程中
- DOm4解析xml
1.创建XML文档对象的的方式有两种 1)Document document=DocumentHelper.createDocument(); 2)DocumentFactory documentFa ...
- linux文件系统节点详解
linux文件系统有两层结构,逻辑结构和物理结构.也就是inode和block. 每个文件都有一个inode, 记录文件属性:权限,时间还有最重要的block号码. block是实际存放文件内容的地方 ...
- .lib文件 .h文件 .dll文件
.lib代表的是静态数据连接库,在windows系统中起到链接程序和函数的作用,存放的是函数的是函数调用的信息,是obj文件的集合.相当于linux中的.a或.0. .so文件.lib文件是不对外公开 ...