(精品)(Docker系列之八)Fedora21部署Docker registry

1. Docker registry简介
Docker registry作为一个镜像仓库,主要功能是通过网络存储和分发Docker镜像。
在本文中,Docker registry的编译结果是生成一个Docker镜像,可以方便的提供给管理员直接部署使用。

2. 谁需要部署Docker registry?
通常情况下,Docker用户会从Docker公有仓库(hub.docker.com)进行镜像的发行,即开发者提交镜像、使用者拉取镜像,对应于docker的命令push、pull。对于部分用户来说,只需要使用公有仓库上的镜像就完全能够满足需求了,但是很多情况下是不够的,比如用户自己开发的应用、不想公开代码到公有仓库,或者是公司开发的、面向特定用户的镜像,就需要维护一个私有仓库;或者对于一些项目,在开发、测试和持续整合阶段,也需要一个本地镜像仓库。

3. Docker registry部署过程
实验环境:3A3000+Loongnix(Fedora21-20170726);
准备条件:本机已经安装好Docker Engine平台,并且制作好一个 fedora21-base 镜像,
具体过程请参照http://ask.loongnix.org/?/article/81 。

3.1 下载源码
# git clone git://github.com/docker/docker-registry.git

若本机没有安装git命令,请首先执行yum install git。

3.2 编译registry镜像
编译命令如下:
# cd docker-registry
# docker build -t fedora-registry:1 .

上面的命令中,fedora-registry:1为要编译成的镜像名称及tag号。
由于官方的docker-registry是适配X86平台,基础镜像也是X86平台的Ubuntu,因此直接在龙芯上进行编译会出现各种错误。
所以需要对源代码进行修改,按照下面各节的方法进行解决。

3.2.1 默认编译平台为x86_64,修改为mips64el
# cd docker-registry
# grep x86_64 . -r
 
能找到4个文件,需要修改如下3个:
contrib/golang_impl/fixtures/index/images/e0acc43660ac918e0cd7f21f1020ee3078fec7b2c14006603bbc21499799e7d5/json
contrib/golang_impl/fixtures/index/images/0e03f25112cd513ade7c194109217b9381835ac2298bd0ffb61d28fbe47081a8/json
tests/data/511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158/json

将文件中”"architecture":"x86_64"”修改为“"architecture":"mips64el"”。

3.2.2 修改Dockerfile
 问题类型和修改思路:
● 官方代码的Dockerfile中,基础镜像的名称是Ubuntu ,需要改成龙芯镜像的名称,fedora21-base:21(tag号若不是latest,则必须写明);
● docker-registry镜像的制作,需要编译源代码,依赖很多其它软件。这些软件在默认Ubuntu软件源是都能够提供的,但是Loongnix的yum源并不一定都提供。如果Loongnix的yum源没有提供,需要找替代的软件包,比如另一个相同功能、但是名称不同的软件包。如果仍然找不到合适软件包,可以尝试暂时去掉,绕过这个软件包,先保证编译成功。如果在编译或者运行时发现还是存在依赖问题,再回头找到依赖软件包的源代码进行编译以解决问题。
下面我们对修改前的Dockerfile文件进行逐条指令分析。

Step 1:


# Latest Ubuntu LTS
FROM ubuntu:14.04


默认依赖镜像从dockerhub获取Ubuntu,我们制作的镜像依赖于龙芯平台的fedora21-base,需要修改为


# Latest Loongnix
FROM fedora21-base:21


如果你遇到如下报错,那就需要检查你的基础镜像是否能够成功获取。
Trying to pull repository docker.io/library/fedora21-base ...  
Pulling repository docker.io/library/fedora21-base
Network timed out while trying to connect to
https://index.docker.io/v1/repositories/library/fedora21-base/images.
You may want to check your internet connection or if you are behind a proxy

Step 2:


# 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 \
    && rm -rf /var/lib/apt/lists/*


这条命令比较长,意思是在基础镜像上,进行软件升级以及对registry所依赖却不包含在基础镜像的软件进行下载。
首先Fedora属RedHat系列,常用安装包为rpm包,常见包管理方式为yum,那么apt-get就应该替换为yum。
另外我们在本地对loongnix yum源进行yum search发现python-mysqldb、libssl-dev和liblzma-dev没有找到,暂且先注释掉;而python-dev和libevent1-dev在loongnix yum源中命名为python-devel和libevent-devel,修改好。
这一步的主要错误都是找不到软件包,按照上述修改步骤就不会报该种错误。在后面的其他步骤会出现缺少软件包或缺少头文件的错误,我们再返回来修改step 2。

Step 3, 4:


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


拷贝命令。

Step 5:


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


安装registry core。这步会暴露出下面的错误:
unable to execute 'gcc': No such file or directory
error: command 'gcc' failed with exit status 1
->这是因为基础镜像缺少gcc,需要在Step 2中的RUN命令行中添加gcc软件包;
Downloading/unpacking boto==2.34.0 (from docker-registry-core==2.0.3)
Cannot fetch index base URL https://pypi.python.org/simple/
Could not find any downloads that satisfy the requirement boto==2.34.0 (from docker-registry-core==2.0.3)
Cleaning up...
No distributions at all found for boto==2.34.0 (from docker-registry-core==2.0.3)
Storing debug log for failure in /root/.pip/pip.log
The command '/bin/sh -c pip install /docker-registry/depends/docker-registry-core' returned a non-zero code: 1
->国外服务器连接不上,这个情况时有发生,最好的解决办法就是修改软件源到国内服务器。解决办法为在docker-registry源码中添加pip配置文件pip.conf,拷贝到镜像中。代码如下:


[global]
 
index-url=http://pypi.douban.com/simple/



Step 6:


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


安装registry。这步会出现如下错误:
backports/lzma/_lzmamodule.c:115:18: fatal error: lzma.h: No such file or directory

->这个是缺少软件包liblzma,不安装不可行。loongnix源没有liblzma,在yum search lzma结果中搜索头文件为”lzma.h”的软件包,发现xz-devel,Step 2 中install xz_devel后该错误解决;
Running setup.py install for M2Crypto
building 'M2Crypto.__m2crypto' extension
swigging SWIG/_m2crypto.i to SWIG/_m2crypto_wrap.c
swig -python -I/usr/include/python2.7 -I/usr/include -I/usr/include/openssl -includeall -modern -D__x86_64__ -o SWIG/_m2crypto_wrap.c SWIG/_m2crypto.i
SWIG/_m2crypto.i:30: Error: Unable to find 'openssl/opensslv.h'
SWIG/_m2crypto.i:33: Error: Unable to find 'openssl/safestack.h'
SWIG/_evp.i:12: Error: Unable to find 'openssl/opensslconf.h'
SWIG/_ec.i:7: Error: Unable to find 'openssl/opensslconf.h'
error: command 'swig' failed with exit status 1

 -> pip install的m2crypto是x86_64架构的,这里需要修改源码,不使用pip命令对该软件进行下载:requirements/main.txt中删除行M2Crypto==0.22.3,然后Dockerfile在Step 2添加mips64el架构的软件包:install m2crypto。

Step 7:


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


这步是打补丁,出现如下错误:
/bin/sh: patch: command not found
->缺少patch命令,说明依赖镜像中不包含该命令软件包。同理,Step 2中install patch。

Step 8, 9, 10, 11:


ENV DOCKER_REGISTRY_CONFIG /docker-registry/config/config_sample.yml
ENV SETTINGS_FLAVOR dev
 
EXPOSE 5000
 
CMD ["docker-registry"]


ENV 配置registry镜像的环境变量。
EXPOSE 指定容器映射到宿主机的端口号为5000。
CMD 指定运行容器时的操作指令。

3.2.3 修改完成的Dockerfile
至此Dockerfile修改完成,代码如下:


# Latest Loongnix
FROM fedora21-base:21
 
# Update
RUN yum update \
# Install pip
    && yum install -y \
        swig \
        python-pip \
        gcc \            
        patch \    
        m2crypto \
# Install deps for backports.lzma (python2 requires it)
        python-devel \
        #python-mysqldb \
        python-rsa \
        #libssl-dev \
        xz-devel \
        libevent-devel \
    && 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 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"]



3.2.4 编译通过
使用前面修改后的Dockerfile,再次进行编译,
# docker build -t fedora-registry:1 .
编译成功后会有提示:Successfully built 46b2003cb477(IMAGE ID)。
为了确认镜像生成的结果,输入命令docker images能看到生成的镜像:
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry latest 46b2003cb477 2 minutes ago 589.2 MB

3.3 run registry
# docker run -d -p 5000:5000 fedora-registry:1

Screenshot-5.png


-p参数将容器5000端口号与宿主机5000端口号进行映射,-d后台运行该容器。docker ps查看容器是否启动成功,其标志是“STATUS”为“Up”:
 
3.4 push镜像进行验证
搭建好registry服务器之后,就可以使用另外一台机器作为客户端,向服务器进行push、pull操作。
在客户端上,执行下面命令,提交一个新的镜像:
# docker tag fedora21-base:21 10.20.42.45:5000/fedora:latest
# docker push 10.20.42.45:5000/fedora

10.20.42.45:5000为registry服务器的IP和映射后的端口号。
有可能在push过程中出现的下面的错误:
# docker push 10.20.42.45:5000/fedora
The push refers to a repository [10.20.42.45:5000/fedora]
Get https://10.20.42.45:5000/v1/_ping: EOF

此时需要修改客户端上的docker配置文件 /etc/sysconfig/docker


OPTIONS='--selinux-enabled --insecure-registry 10.20.42.45:5000'


这步之后重启docker服务,重新执行步骤3.4(如果客户端就是宿主机重新执行3.3)再push镜像。
push成功显示如下:
 
Screenshot-1.png


浏览器输入如下网址能看到push成功的镜像:

Screenshot.png


3.5 pull镜像进行验证
在客户端进行pull验证,如果客户端上已经有要拉取的同名镜像,要先执行docker rmi命令把镜像删除之后再进行拉取。
#docker pull 10.20.42.45:5000/fedora-registry

pull结果参考下图能看到10.20.42.45:5000/fedora:latest。
 
Screenshot-6.png


并能正确运行该容器:
 
Screenshot-8.png


4.总 结
部署docker registry一定要明确每一步的意义是什么,比如我们为什么需要移植registry而不是直接pull一个registry镜像就能建立这个私有仓库?编译docker镜像必须理解Dockerfile的语法,明确每一条指令的意义,才能更好的理解编译报错的根本原因以及如何解决。

3 个评论

楼主好,请问能提供一个编译好的registry镜像吗?谢谢
没事去dockerhub逛逛,有适用龙芯平台的镜像的。
不过我喜欢去github上找dockerfile,然后自己从头造,
从from scratch开干,
很开心
https://hub.docker.com/r/loongnix/loongnix-registry/tags/

要回复文章请先登录注册