久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

如何通過自己build構(gòu)建docker的私有倉庫

259次閱讀
沒有評論

共計 12891 個字符,預計需要花費 33 分鐘才能閱讀完成。

這篇文章將為大家詳細講解有關(guān)如何通過自己 build 構(gòu)建 docker 的私有倉庫,丸趣 TV 小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

Docker Registry 說明

(注意,我是 ubuntu14.04 構(gòu)建的,修改過 /etc/default/docker 文件,添加

 DOCKER_OPTS= $DOCKER_OPTS — insecure-registry=10.32.170.108:5000,然后 service restart docker, 可能可以解決 https 證書錯誤問題。)

關(guān)于如何創(chuàng)建和使用本地倉庫,其實已經(jīng)有很多文章介紹了。因為 docker 技術(shù)正處于發(fā)展和完善階段,所以有些文章要么內(nèi)容已經(jīng)過時,要么給出了錯誤的配置,導致無法正常創(chuàng)建倉庫。本文記錄的是個人完整的搭建過程,docker version 為 1.1.2。

官方提供了 Docker Hub 網(wǎng)站來作為一個公開的集中倉庫。然而,本地訪問 Docker Hub 速度往往很慢,并且很多時候我們需要一個本地的私有倉庫只供網(wǎng)內(nèi)使用。

Docker 倉庫實際上提供兩方面的功能,一個是鏡像管理,一個是認證。前者主要由 docker-registry 項目來實現(xiàn),通過 http 服務(wù)來上傳下載;后者可以通過 docker-index(閉源)項目或者利用現(xiàn)成認證方案(如 nginx)實現(xiàn) http 請求管理。

docker-registry 既然也是軟件應(yīng)用,自然最簡單的方法就是使用官方提供的已經(jīng)部署好的鏡像 registry。官方文檔中也給出了建議,直接運行 sudo docker run -p 5000:5000 registry 命令。這樣確實能啟動一個 registry 服務(wù)器,但是所有上傳的鏡像其實都是由 docker 容器管理,放在了 /var/lib/docker/…. 某個目錄下。而且一旦刪除容器,鏡像也會被刪除。因此,我們需要想辦法告訴 docker 容器鏡像應(yīng)該存放在哪里。registry 鏡像中啟動后鏡像默認位置是 /tmp/registry,因此直接映射這個位置即可,比如到本機的 /opt/data/registry 目錄下。

2. 在 CentOS 上搭建 docker 私服 2.1 安裝 docker-registry

方法有多種,直接運行下面的命令:

# docker run -d -e SETTINGS_FLAVOR=dev -e STORAGE_PATH=/tmp/registry -v /opt/data/registry:/tmp/registry -p 5000:5000 registry(此為鏡像名字,上面是 local-sean, 可修改其 tag 為 registry)

如果本地沒有拉取過 docker-registry,則首次運行會 pull registry,運行時會映射路徑和端口,以后就可以從 /opt/data/registry 下找到私有倉庫都存在哪些鏡像,通過主機的哪個端口可以訪問。
你也可以把項目 https://github.com/docker/docker-registry.git 克隆到本地,然后使用 Dockerfile 來 build 鏡像:

# git clone https://github.com/docker/docker-registry.git# cd docker-registry   mkdir -p /opt/data/registry# docker build -t  local-sean  .build 完成后,就可以運行這個 docker-registry
docker run -d -e SETTINGS_FLAVOR=dev -e STORAGE_PATH=/tmp/registry -v /opt/data/registry:/tmp/registry -p 5000:5000 registry

2.2 客戶端使用

要從私服上獲取鏡像或向私服提交鏡像,現(xiàn)在變得非常簡單,只需要在倉庫前面加上私服的地址和端口,形如 172.29.88.222:5000/centos6。注意,這里可以選擇不使用 IP,而是用 hostname,如 registry.domain.com:5000,但不能僅用不帶. 的主機名 registry,docker 會認為 registry 是用戶名,建議使用帶域名的 hostname 加 port 來表示。

于是在另外一臺要使用 docker 的主機上就可以通過這臺私服拉取和推送鏡像了:

 從私服上搜索存在哪些可用鏡像 # curl -X GET http://sean.domain.com:5000/v1/search{num_results : 2,  query :  ,  results : [{ description :  ,  name :  library/centos6}, {description :  ,  name :  library/nginx}]}
按條件搜索 nginx# curl -X GET http://sean.domain.com:5000/v1/search?q=centos6 拉取 image 到本地
docker pull library/centos6##  本地對份鏡像啟動起來,形成 container##  給 container 去另外一個名字 # docker tag 68edf809afe7 registry.domain.com:5000/centos6-test##  最后將新的 docker images 推送到私服上 docker push registry.domain.com:5000/centos6-test

第一次 push 到私服上時會提示用戶名、密碼和郵箱,創(chuàng)建即可。也可以在 docker 私服端加入認證機制。

3. 加入 nginx 認證

(請在實際操作以前,先閱讀完本節(jié),再確定是否在前端加入 nginx)

3.1 安裝及配置 nginx

從上面的過程可以看到,除非防火墻限制,否則任何主機可以創(chuàng)建賬號并想私服推送鏡像,更安全的做法是在外層加入登錄認證機制。

 最好安裝 1.4.x 版本,不然下面的有些配置可能會不兼容
# yum install nginx  創(chuàng)建兩個登錄用戶  # htpasswd -c /etc/nginx/docker-registry.htpasswd sean New password: Re-type new password: Adding password for user sean # htpasswd -c /etc/nginx/docker-registry.htpasswd itsection

為了讓 nginx 使用這個密碼文件,并且轉(zhuǎn)發(fā) 8080 端口的請求到 Docker Registry,新增 nginx 配置文件
vi /etc/nginx/sites-enabled/docker-registry:

# For versions of Nginx   1.3.9 that include chunked transfer encoding support# Replace with appropriate values where necessaryupstream docker-registry {
 server localhost:5000;
server {
 listen 8080;
 server_name sean.domain.com; -- your registry server_name # ssl on;
 # ssl_certificate /etc/ssl/certs/docker-registry;
 # ssl_certificate_key /etc/ssl/private/docker-registry;
 proxy_set_header Host $http_host; # required for Docker client sake
 proxy_set_header X-Real-IP $remote_addr; # pass on real client IP
 client_max_body_size 0; # disable any limits to avoid HTTP 413 for large image uploads
 # required to avoid HTTP 411: see Issue #1486 (https://github.com/dotcloud/docker/issues/1486)
 chunked_transfer_encoding on;
 location / { # let Nginx know about our auth file
 auth_basic  Restricted 
 auth_basic_user_file docker-registry.htpasswd;
 proxy_pass http://docker-registry;
 }
 location /_ping {
 auth_basic off;
 proxy_pass http://docker-registry;
 } 
 location /v1/_ping {
 auth_basic off;
 proxy_pass http://docker-registry;
 }
}
 讓 nginx 來使用這個 virtual-host# ln -s /etc/nginx/sites-enabled/docker-registry /etc/nginx/conf.d/docker-registry.conf 重啟 nginx 來激活虛擬主機的配置 # service nginx restart

3.2 加入認證后使用 docker-registry

此時主機的 5000 端口應(yīng)該通過防火墻禁止訪問(或者在 docker run 端口映射時只監(jiān)聽回環(huán)接口的 IP -p 127.0.0.1:5000:5000)。

# curl localhost:5000 docker-registry server (dev) (v0.8.1)

如果直接訪問訪問將得到未授權(quán)的信息:

# curl localhost:8080 html head title 401 Authorization Required /title /head body bgcolor= white center h2 401 Authorization Required /h2 /center hr center nginx/1.4.7 /center /body /html

帶用戶認證的 docker-registry:

# curl http://sean:sean@sean.domain.com:8080/v1/search{num_results : 2,  query :  ,  results : [{ description :  ,  name :  library/centos6}, {description :  ,  name :  library/nginx}]}# docker login registry.domain.com:8080Username: seanPassword: Email: zhouxiao@domain.comLogin Succeeded# docker pull registry.domain.com:8080/library/centos6

不出意外的話,上面的 docker pull 會失敗:

# docker pull registry.domain.com:8080/library/centos6Pulling repository registry.domain.com:8080/library/centos62014/11/11 21:00:25 Could not reach any registry endpoint# docker push registry.domain.com:8080/ubuntu:seanThe push refers to a repository [registry.domain.com:8080/ubuntu] (len: 1)
Sending image list
Pushing repository registry.domain.com:8080/ubuntu (1 tags)2014/11/12 08:11:32 HTTP code 401, Docker will not send auth headers over HTTP.
nginx 日志 2014/11/12 07:03:49 [error] 14898#0: *193 no user/password was provided for basic authenticatGET /v1/repositories/library/centos6/tags HTTP/1.1 , host:  registry.domain.com:8080

本文后的第 1 篇參考文檔沒有出現(xiàn)這個問題,但評論中有提及。
有人說是 backend storage 的問題,這里是本地存儲鏡像,不應(yīng)該。經(jīng)過查閱大量資料,并反復操作驗證,是 docker-registry 版本的問題。從 v0.10.0 開始,docker login 雖然 Succeeded,但 pull 或 push 的時候,~/.dockercfg 下的用戶登錄信息將不允許通過 HTTP 明文傳輸。(如果你愿意可以查看 v0.10.0 的源碼 registry.go,在分支 v0.9.1 及以前是沒有 HTTP code 401, Docker will not send auth headers over HTTP 的)
目前的辦法三個:

撤退,這就是為什么先說明在操作前線查看到這的原因了

換成 v0.9.1 及以下版本。現(xiàn)在都 v1.3.1 了,我猜你不會這么做

修改源碼 session.go,去掉相應(yīng)的判斷行,然后 git 下來重新安裝。我猜你更不會這么做

安裝 SSL 證書,使用 HTTPS 傳輸。這是明智的選擇,新版本 docker 也推薦我們這么做,往下看。

3.3 為 nginx 安裝 ssl 證書

首先打開 nginx 配置文件中 ssl 的三行注釋

# vi /etc/nginx/conf.d/docker-registry.conf...
server {
 listen 8000;
 server_name registry.domain.com;

 ssl_certificate /etc/nginx/ssl/nginx.crt;  ssl_certificate_key /etc/nginx/ssl/nginx.key; ...

保存之后,nginx 會分別從 /etc/nginx/ssl/nginx.crt 和 /etc/nginx/ssl/nginx.key 讀取 ssl 證書和私鑰。如果你自己愿意花錢買一個 ssl 證書,那就會變得非常簡單,把證書和私鑰拷貝成上面一樣即可。關(guān)于 SSL 以及簽署 ssl 證書,請參考其他文章。
這里我們自簽署一個 ssl 證書,把當前系統(tǒng)作為(私有)證書頒發(fā)中心(CA)。

創(chuàng)建存放證書的目錄

# mkdir /etc/nginx/ssl

確認 CA 的一些配置文件

# vi /etc/pki/tls/openssl.cnf...
[ CA_default ]
dir = /etc/pki/CA # Where everything is keptcerts = $dir/certs # Where the issued certs are keptcrl_dir = $dir/crl # Where the issued crl are keptdatabase = $dir/index.txt # database index file.#unique_subject = no # Set to  no  to allow creation of
 # several ctificates with same subject.new_certs_dir = $dir/newcerts # default place for new certs.certificate = $dir/cacert.pem # The CA certificateserial = $dir/serial # The current serial numbercrlnumber = $dir/crlnumber # the current crl number
 # must be commented out to leave a V1 CRLcrl = $dir/crl.pem # The current CRLprivate_key = $dir/private/cakey.pem # The private keyRANDFILE = $dir/private/.rand # private random number file...
default_days = 3650 # how long to certify for...
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = CN
countryName_min = 2countryName_max = 2stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = GD
...[ req_distinguished_name ] 部分主要是頒證時一些默認的值,可以不動 

(1) 生成根密鑰

# cd /etc/pki/CA/# openssl genrsa -out private/cakey.pem 2048

為了安全起見,修改 cakey.pem 私鑰文件權(quán)限為 600 或 400,也可以使用子 shell 生成 (umask 077; openssl genrsa -out private/cakey.pem 2048),下面不再重復。

(2) 生成根證書

# openssl req -new -x509 -key private/cakey.pem -out cacert.pem

會提示輸入一些內(nèi)容,因為是私有的,所以可以隨便輸入,最好記住能與后面保持一致。上面的自簽證書 cacert.pem 應(yīng)該生成在 /etc/pki/CA 下。

(3) 為我們的 nginx web 服務(wù)器生成 ssl 密鑰

# cd /etc/nginx/ssl# openssl genrsa -out nginx.key 2048

我們的 CA 中心與要申請證書的服務(wù)器是同一個,否則應(yīng)該是在另一臺需要用到證書的服務(wù)器上生成。

(4) 為 nginx 生成證書簽署請求

# openssl req -new -key nginx.key -out nginx.csr...Country Name (2 letter code) [AU]:CNState or Province Name (full name) [Some-State]:GDLocality Name (eg, city) []:SZOrganization Name (eg, company) [Internet Widgits Pty Ltd]:COMPANYOrganizational Unit Name (eg, section) []:IT_SECTIONCommon Name (e.g. server FQDN or YOUR name) []:your.domain.comEmail Address []:Please enter the following  extra  attributes
to be sent with your certificate requestA challenge password []:An optional company name []:...

同樣會提示輸入一些內(nèi)容,其它隨便,除了 Commone Name 一定要是你要授予證書的服務(wù)器域名或主機名,challenge password 不填。

(5) 私有 CA 根據(jù)請求來簽發(fā)證書

# openssl ca -in nginx.csr -out nginx.crt

上面簽發(fā)過程其實默認使用了 -cert cacert.pem -keyfile cakey.pem,這兩個文件就是前兩步生成的位于 /etc/pki/CA 下的根密鑰和根證書。

到此我們已經(jīng)擁有了建立 ssl 安全連接所需要的所有文件,并且服務(wù)器的 crt 和 key 都位于配置的目錄下,唯有根證書 cacert.pem 位置不確定放在 CentOS6 下的哪個地方。
經(jīng)驗證以下幾個位置不行:(Adding trusted root certificates to the server)
/etc/pki/ca-trust/source/anchors、/etc/pki/ca-trust/source、/etc/pki/ca-trust/extracted、
/etc/pki/ca-trust/extracted/pem/、/etc/pki/tls/certs/cacert.crt
都會報錯:

# docker login https://registry.domain.com:8000Username (sean): sean2014/11/14 02:32:48 Error response from daemon: Invalid Registry endpoint: Get https://registry.domain.com:8000/v1/_ping: x509: certificate signed by unknown authority# curl https://sean:sean@registry.domain.com:8000/curl: (60) Peer certificate cannot be authenticated with known CA certificates
More details here: http://curl.haxx.se/docs/sslcerts.htmlcurl performs SSL certificate verification by default, using a  bundle 
 of Certificate Authority (CA) public keys (CA certs). If the default bundle file isn t adequate, you can specify an alternate file using the --cacert option. If this HTTPS server uses a certificate signed by a CA represented in the bundle, the certificate verification probably failed due to a problem with the certificate (it might be expired, or the name might not match the domain name in the URL). If you d like to turn off curl s verification of the certificate, use the -k (or --insecure) option.

(6) 目前讓根證書起作用的只發(fā)現(xiàn)一個辦法:

# cp /etc/pki/tls/certs/ca-bundle.crt{,.bak}  備份以防出錯 # cat /etc/pki/CA/cacert.pem   /etc/pki/tls/certs/ca-bundle.crt# curl https://sean:sean@registry.domain.com:8000 docker-registry server (dev) (v0.8.1)

將 cacert.pem 根證書追加到 ca-bundle.crt 后一定要重啟 docker 后臺進程才行。

如果 docker login 依然報錯 certificate signed by unknown authority,參考 Running Docker with https,啟動 docker 后臺進程時指定信任的 CA 根證書:

# docker -d --tlsverify --tlscacert /etc/pki/CA/cacert.pem 或者將 cacert.pem 拷貝到~/.docker/ca.pem# mkdir ~/.docker   cp /etc/pki/CA/cacert.pem ~/.docker/ca.pem# docker - d 最好重啟一下 registry# docker restart  registry_container_id

上面用“如果”是因為一開始總提示 certificate signed by unknown authority,有人說將根證書放在 /etc/docker/certs.d 下,還有人說啟動 docker daemon 收加入 –insecure-registry .. 但終究是因為版本差異不成功。但后來又奇跡般的不需要 –tlscacert 就好了。
這個地方掙扎了很久,重點關(guān)注一下這個下面幾個 issue:

https://github.com/docker/docker-registry/issues/82

https://github.com/docker/docker/pull/2687

https://github.com/docker/docker/pull/2339

(7) 最終搞定:

# docker login https://registry.domain.com:8000Username: sean
Password: 
Email: zhouxiao@domain.com
Login Succeeded# curl https://sean:sean@registry.domain.com:8000 docker-registry server (dev) (v0.8.1) # docker push registry.domain.com:8000/centos6:test_privThe push refers to a repository [registry.domain.com:8000/centos6] (len: 1)
Sending image listPushing repository registry.domain.com:8000/centos6 (1 tags)511136ea3c5a: Image successfully pushed 
5b12ef8fd570: Image successfully pushed 
68edf809afe7: Image successfully pushed 
40627956f44c: Image successfully pushed 
Pushing tag for rev [40627956f44c] on {https://registry.domain.com:8000/v1/repositories/centos6/tags/test_priv}

但還有一個小問題沒解決,雖然已經(jīng)可以正常使用,但每次請求在 nginx 的 error.log 中還是會有 [error] 8299#0: *27 no user/password was provided for basic authentication,應(yīng)該是這個版本 docker 暫未解決的 bug。

3.3 其它問題

(1) docker 后臺進程意外中斷后,重新 docker start container_id 報錯

# docker start b36bd796bd3d Error: Cannot start container b36bd796bd3d: Error getting container b36bd796bd3d463c4fedb70d98621e7318ec3d5cd14b2f60b1d182ad3cbcc652 from driver devicemapper: Error mounting  /dev/mapper/docker-253:0-787676-b36bd796bd3d463c4fedb70d98621e7318ec3d5cd14b2f60b1d182ad3cbcc652  on  /var/lib/docker/devicemapper/mnt/b36bd796bd3d463c4fedb70d98621e7318ec3d5cd14b2f60b1d182ad3cbcc652 : device or resource busy2014/11/08 15:14:57 Error: failed to start one or more containers

經(jīng)分析產(chǎn)生這個問題的原因是做了一個操作:在 docker 后臺進程啟動的終端,繼續(xù)回車后會臨時退出后臺進程的日志輸出,我就在這個 shell 下使用 yum 安裝軟件包,但由于網(wǎng)絡(luò)原因 yum 卡住不動,于是我就另起了一個終端 kill 了這個 yum 進程,不知為何會影響到表面已經(jīng)退出前臺輸出的 docker。解決辦法是 umount 容器的掛載點:(見這里)

# umount /var/lib/docker/devicemapper/mnt/b36bd796bd3d463c4fedb70d98621e7318ec3d5cd14b2f60b1d182ad3cbcc652# service docker start  正常 

能想到的另外一個辦法是,啟動 docker 后臺進程時,重定向輸出 docker -d /dev/null 2 1(/var/log/docker 已自動記錄了一份日志)。

(2) 配置完 nginx 的 docker-registry.conf 后啟動報錯

# service nginx start[emerg] 14714#0: unknown directive  upstream  in /etc/nginx/conf.d/docker-registry.conf:4

原因是 nginx 版本太低,一些配置指令不兼容,使用 yum install nginx 默認安裝了 1.0.x,卸載重新下載 nginx-1.4.7-1.el6.ngx.x86_64.rpm 安裝解決。

(3) 網(wǎng)絡(luò)設(shè)置代理問題
pull, push 官網(wǎng)的鏡像時由于 GFW 的原因需要設(shè)置代理,但不是 http_proxy 而是 HTTP_PROXY,對于 docker 來說同時設(shè)置這兩個值就會出問題,有時出于安裝軟件包的需要設(shè)置 http_proxy,就會導致沖突。在 docker-registry 中如果忘記了當前哪一個在起作用,找遍所有問題都發(fā)現(xiàn)不了原因,而 docker 返回給我們的錯誤也難以判斷。切記~

關(guān)于“如何通過自己 build 構(gòu)建 docker 的私有倉庫”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

正文完
 
丸趣
版權(quán)聲明:本站原創(chuàng)文章,由 丸趣 2023-08-16發(fā)表,共計12891字。
轉(zhuǎn)載說明:除特殊說明外本站除技術(shù)相關(guān)以外文章皆由網(wǎng)絡(luò)搜集發(fā)布,轉(zhuǎn)載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 霞浦县| 綦江县| 开远市| 遵化市| 巨野县| 连平县| 周至县| 左云县| 乌恰县| 北票市| 林周县| 福清市| 绥棱县| 秦皇岛市| 合山市| 承德县| 遂溪县| 吉林市| 安乡县| 英德市| 双桥区| 延安市| 新乐市| 杭锦旗| 兴国县| 临邑县| 永川市| 华容县| 临泉县| 宁安市| 东乌珠穆沁旗| 台东市| 图片| 蓬溪县| 固始县| 嘉善县| 大埔区| 汉川市| 托克逊县| 乳源| 沂南县|