1. 程式人生 > >龍芯Fedora21部署Docker registry

龍芯Fedora21部署Docker registry

http://ask.loongnix.org/?/article/88

 

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的語法,明確每一條指令的意義,才能更好的理解編譯報錯的根本原因以及如何解決。

1.png