筹建私有Docker仓库

搭建私有Docker仓库

搭建私有Docker仓库的理由林林总总。本文只关心怎么搭建,搭建好了怎么用它?

搭建私有仓库最简单的办法是用官方的docker-registry这个镜像。它可以支持多种镜像的存储方式。比如,本地,Amazon S3等。本文只探讨怎么把镜像存放在宿主机的本地磁盘上。它会涉及到在宿主机和容器的配置。

首先,在宿主机里建一个作为镜像存储的目录,然后建一个指定UID和GID的用户和用户组来作为该目录的属主。假设用户名和用户组名都为docker_r,UID和GID都是10000。然后将目录权限模式设成750。这样防止宿主机上的闲杂人员访问docker镜像。然后,运行docker-registry容器,并通过环境变量指定镜像存储目录和在容器中的registry进程的用户UID。

将上述过程自动化的完整脚本如下:

echo "############################################################"
echo ""
echo "                        ##        ."
echo "                  ## ## ##       =="
echo "               ## ## ## ##      ==="
echo "           /""""""""""""""""\___/ ==="
echo "      ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ /  ===- ~~~"
echo "           \______ o          __/"
echo "             \    \        __/"
echo "              \____\______/"
echo ""
echo "############################################################"
# run the registry itself in docker container
sudo docker pull registry

# create user/group to run docker registry
os_group=docker_r
os_user=docker_r
getent group ${os_group} > /dev/null        \
  || sudo /usr/sbin/groupadd -g 10000       \
                             ${os_group}    \
                             2>/dev/null    \
  || :
getent passwd ${os_user} > /dev/null                     \
  || sudo /usr/sbin/useradd -c "Private Docker Registry" \
                       -u 10000                          \
                       -g ${os_group}                    \
                       -s /bin/bash                      \
                       -d /var/lib/docker-registry       \
                       ${os_user} 2>/dev/null            \
  || :
# setup docker image storage diretories
sudo mkdir -p /var/lib/docker-registry
sudo chmod 750 /var/lib/docker-registry
sudo chown 10000:10000 /var/lib/docker-registry

# launch the containerized docker registry
sudo docker run                                     \
      -d                                            \
      --name private_registry                       \
      -e SETTINGS_FLAVOUR=local                     \
      -e STORAGE_PATH=/registry-storage             \
      -w /registry-storage                          \
      -v /var/lib/docker-registry:/registry-storage \
      -u 10000                                      \
      -p 5000:5000                                  \
      registry

 docker run命令中的-w选项对于registry这个容器而言至关重要,没有它的话,容器的进程因为无权限创建锁文件而异常终止。其典型的错误消息如下:

    return util.import_app(self.app_uri)
  File "/usr/local/lib/python2.7/dist-packages/gunicorn/util.py", line 356, in import_app
    __import__(module)
  File "/usr/local/lib/python2.7/dist-packages/docker_registry/wsgi.py", line 27, in <module>
    from .search import *  # noqa
  File "/usr/local/lib/python2.7/dist-packages/docker_registry/search.py", line 14, in <module>
    INDEX = index.load(cfg.search_backend.lower())
  File "/usr/local/lib/python2.7/dist-packages/docker_registry/lib/index/__init__.py", line 82, in load
    return db.SQLAlchemyIndex()
  File "/usr/local/lib/python2.7/dist-packages/docker_registry/lib/index/db.py", line 86, in __init__
    self._setup_database()
  File "/usr/local/lib/python2.7/dist-packages/docker_registry/toolkit.py", line 325, in wrapper
    lock_file = open(lock_path, 'w')
IOError: [Errno 13] Permission denied: './registry._setup_database.lock'

 

使用私有仓库主要是拉取(pull)和推送(push)操作。在推送之前需要打标签,该标签的前半部分包含私有仓库的主机名和端口。比如,运行在宿主机5000端口上的docker-registry容器,在宿主机上推送schnell18/gitserver这个镜像时可以用命令:

docker tag localhost:5000/schnell18/gitserver schnell18/gitserver

 打标签,然后用以下命令推送:

docker push localhost:5000/schnell18/gitserver

 推送之前需要打相应的标签是docker特别的地方,这样的设计可能不是特别直观,需要学习一下才能搞清楚来龙去脉。

推送到私有仓库后其他人就可以进行拉取操作来使用镜像。和从官方仓库使用镜像不同,从私有仓库拉取运行镜像需要在镜像名称前面加上私有仓库的主机名及端口。仍以上述例子为例,在宿主机里拉取私有仓库中的schnell18/gitserver这个镜像的命令为:

docker pull localhost:5000/schnell18/gitserver