• 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

  • 相关阅读:
    python面对对象编程------3:写集合类的三种方法
    python面对对象编程----2:__init__
    python面对对象编程----1:BlackJack(21点)
    wxpython下的桥梁信息管理系统
    python运行时间计算之timeit
    python单元测试之unittest
    python 下的数据结构与算法---8:哈希一下【dict与set的实现】
    python 下的数据结构与算法---7:查找
    python 下的数据结构与算法---6:6大排序算法
    分布式一致性算法Raft
  • 原文地址:https://www.cnblogs.com/rodenpark/p/5036267.html
Copyright © 2020-2023  润新知