版權聲明:
本文爲博主原創文章,未經博主容許不得轉載。關注公衆號 技術匯(ID: jishuhui_2015) 可聯繫到做者。
Build, Ship and Run any App, Anywhere
關於Docker更多的概念將不在本文贅述了,做爲虛擬化市場的一顆冉冉升起的新星,Docker獲得了愈來愈多企業的青睞,愈來愈多的開發者決定擁入Docker的懷抱。html
「集裝箱」是Docker設計哲學之所在,它讓一臺物理機(或者虛擬機)同時運行多個彼此隔離的應用變得更爲輕鬆簡單,固然這一切仍是多虧Linux的相關底層技術,固然,也包括OS X,Windows這兩個操做系統。nginx
Docker的相關教程已經夠多了,可是因爲Docker近年來發展迅猛,版本迭代速度較快,多個版本之間還存在不兼容的狀況,若是在網上找博客文章,未必能解決本身遇到的問題。git
固然,對於Docker的環境安裝,基礎命令之類的內容,是徹底沒有問題的,通讀官網文檔內容基本都能順利掌握。然而,當筆者嘗試着搭建一套基於SSL的Docker Registry(官網推薦的作法)卻遇到了很多的麻煩,對於這部份內容,大多數博客文檔內容都是直接跳過了SSL的環節,採用了HTTP的訪問形式。github
特此分享,通讀完了此篇文章後,對於搭建Docker Registry就再也不是問題了。web
> docker --version Docker version 18.03.1-ce, build 9ee9f40
以上是個人Docker環境,建議安裝Docker1.6+以上版本。redis
除此以外,讀者還須要:docker
一、一臺安裝了CentOS_7_64bit操做系統的主機(或者虛擬機);安全
二、申請一個域名。否則,能夠改HOST文件,但不保證能成功。筆者在阿里雲申請了一個我的域名,包了5年,價值¥105;網絡
三、若是申請了域名,順便拿一個免費的CA證書,由於須要實現HTTPS訪問,SSL證書是必須的,一樣,阿里雲上有免費證書申請。否則,可使用OpenSSL本身生成,這也是不少博文所提到的作法,不保證成功;session
四、再裝上一個nginx作代理,可選。
五、熟悉Docker的基本概念和經常使用命令,但沒必要了解Dockerfile,Compose,Swarm,Kubernetes等高階知識。
抽象的概念闡述很少說了,筆者舉兩個例子,讓你們感覺一下:
一、咱們從系統之家下載來的ISO文件,除了基礎的操做系統,還可能內置了多個預裝軟件;
二、在使用maven管理jar包依賴的時候,爲了不每次都從中央倉庫拉取依賴包,使用了nexus作了代理倉庫。
能夠認爲,Docker鏡像就是一系列軟件(文件)的組合,只要將它們放在合適的宿主上,便可作到開箱即用。
關於本文須要的Docker鏡像操做,有五個經常使用的命令:
a、拉取鏡像,後跟鏡像倉庫名稱,若是要指定某個版本,能夠帶上tag。
> docker pull <repo>[:tag]
b、列出全部鏡像,能獲得鏡像的相關基本信息。
> docker images REPOSITORY TAG IMAGE ID CREATED SIZE redis latest bfcb1f6df2db 3 weeks ago 107MB registry 2 d1fd7d86a825 4 months ago 33.3MB hyper/docker-registry-web latest 0db5683824d8 19 months ago 599MB
c、刪除鏡像。能夠根據鏡像ID,或者鏡像倉庫名稱進行刪除。
> docker rmi <IMAGE ID>/<repo>
d、鏡像打標。能夠將此操做與Git打標進行類比,至關因而release一個可用的鏡像版本。
> docker tag <repo> <new_repo>[:tag]
e、鏡像推送。一樣是能夠借鑑Git領域的push操做,將打包好的鏡像推送給遠程倉庫(即爲Docker Registry)。
> docker push <new_repo>[:tag]
以上五個命令只作簡單介紹,不是本文的重點。更多鏡像操做命令,能夠自行查閱之。
進行接下來的操做以前,請讀者先將registry鏡像pull下來。
> docker pull registry:2 2: Pulling from library/registry 81033e7c1d6a: Pull complete b235084c2315: Pull complete c692f3a6894b: Pull complete ba2177f3a70e: Pull complete a8d793620947: Pull complete Digest: sha256:672d519d7fd7bbc7a448d17956ebeefe225d5eb27509d8dc5ce67ecb4a0bce54 Status: Downloaded newer image for registry:2
此過程會持續幾分鐘,視網絡情況而定,請讀者耐心等候。
注意:筆者在pull的時候,指定了TAG,即爲使用v2版本的registry,對於v1版本的registry,讀者大可沒必要在乎了,基本上是淘汰了。
對於急切想看一下Docker Registry運行效果的讀者,能夠先閱讀本節內容。
運行以下命令便可:
> docker run -d \ -p 5000:5000 \ -v /usr/local/registry:/var/lib/registry \ --restart=always \ --name registry \ registry:2
這是一條典型的run命令,不出意外的話,Registry就在5000端口啓動了。
爲了驗證,讀者能夠拉取一個busybox鏡像(由於體積小),進行實驗。
> docker pull busybox
拉取最新的busybox鏡像後,再給其打標,準備發佈到Registry中。
> docker tag busybox localhost:5000/bosybox:v1.0
最後再推送給Registry。
> docker push localhost:5000/bosybox:v1.0
此時,Registry就有了busybox:v1.0鏡像了,這時能夠不用再去Docker Hub上面拉取了,經過自建的Registry便可。
> docker pull localhost:5000/bosybox:v1.0
若是想查看遠程倉庫有哪些鏡像,能夠運行以下命令:
> curl http://localhost:5000/v2/_catalog
窺一斑而見全豹,經過以上命令,咱們能得出一個重要的結論:
對Registry的訪問都是經過一系列REST API完成的。
到此爲止,咱們已經搭建了一個Docker Registry的「半成品」,說是「半成品」是由於這個Registry只能在本機正常工做,若是在其餘主機上試圖推送鏡像上來,結果是失敗的。
若是要作到externally-accessible,就必須使用CA安全證書。
在進行本節的操做前,請讀者確認是否知足了文章開頭所列的條件。
筆者申請了一個域名:iwendao.vip,並映射出來了一個二級域名:registry.iwendao.vip,專門用來做爲Docker Registry的訪問,而後基於此二級域名申請CA證書。
不出意外的話,從阿里雲申請的免費證書都是由Symantec頒發的,將證書下載下來後,壓縮包內有兩份文件:xxxxxx.pem、xxxxxx.key。
將其改名爲server.key,server.pem,經過ftp工具上傳至主機,假設存放的目錄是:/usr/local/certs。
> ll /usr/local/certs - rw-r--r-- 1 root root 1678 May 28 13:42 server.key - rw-r--r-- 1 root root 3662 May 28 13:42 server.pem
由於頒發的是intermediate certificate,會發現沒有crt文件,可使用以下命令獲得:
> cat server.pem > server.crt
直接將pem文件內做爲crt文件的內容輸入,生成了server.crt文件。
至此,域名及其證書已準備就緒。
若是想使用nginx作代理,須要更改一下nginx.conf文件,如下是筆者的配置內容:
user root root; worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log logs/access.log main; sendfile on; keepalive_timeout 60; gzip on; server { listen 443; server_name i-wendao; ssl on; root html; index index.html index.htm; ssl_certificate /usr/local/certs/server.pem; ssl_certificate_key /usr/local/certs/server.key; ssl_session_timeout 5m; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; location ~ { proxy_pass_header Server; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Scheme $scheme; proxy_pass https://registry; } } upstream registry { server 127.0.0.1:5000; } }
在nginx.conf配置文件中,須要注意兩個地方:
一、開啓nginx的ssl,只須要配置以前下載好的pem和key文件,這是阿里雲官方給出的示例,親測有效;
二、由於對Registry的訪問都是經過REST API完成的,並且是HTTPS的訪問協議,因此location節點的配置中,proxy_pass配置的是https://registry,若是配置成http://registry,一旦Docker Registry啓用了SSL後,是訪問不通的。
宿主機的配置已經完成了,接下來對Docker容器進行配置。
對於Docker Registry Server的部署,官方給了兩個途徑:
其一,針對參數很少的狀況,能夠直接在docker run命令指定;
另外一個是經過yaml配置文件,能夠一次性配置多個參數。
在本節,筆者將使用第一種方式部署,第二種方式的部署能夠參見文末的附文。
> docker run -d \ -p 5000:5000 \ -v /usr/local/registry:/var/lib/registry \ -v /usr/local/certs:/certs \ -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/server.crt \ -e REGISTRY_HTTP_TLS_KEY=/certs/server.key \ --restart=always \ --name registry \ registry:2
若是沒有安裝nginx的讀者,可運行這條命令:
> docker run -d \ -p 443:443 \ -v /usr/local/registry:/var/lib/registry \ -v /usr/local/certs:/certs \ -e REGISTRY_HTTP_ADDR=0.0.0.0:443 \ -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/server.crt \ -e REGISTRY_HTTP_TLS_KEY=/certs/server.key \ --restart=always \ --name registry \ registry:2
能夠看到,Docker Registry Server啓用SSL的時候,用到的是crt、key兩個證書文件。
接下來,咱們實驗一下。
> docker tag busybox registry.iwendao.vip/bosybox:v1.0
最後再推送給Registry。
> docker push registry.iwendao.vip/bosybox:v1.0
查看遠程倉庫有哪些鏡像。
> curl https://registry.iwendao.vip/v2/_catalog
在另一臺主機,重複上述步驟,依然能夠成功,說明已經搭建成功了。
經過對Registry Server的搭建,咱們能明顯感受獲得,Docker對於安全控制有足夠的重視,這在全網HTTPS化的背景下是恰合時宜的作法。
這節是進階知識,目的是將Docker的安全機制作得更完全——加上登陸校驗機制。
很明顯,既然是私服,就意味着不是每一個人都能提交鏡像的,只有憑藉登陸用戶和密碼才行。
固然,登陸校驗機制的前提是有HTTPS協議,不然,用戶名和密碼都將會明文傳輸。
Docker的認證機制也有不少實現,能夠直接用代理(好比nginx)在Registry以前進行攔截驗證,高端的一些的是有Token服務端,引導用戶受權登陸,實現難度較大。
本文以最簡單的htpasswd在實現登陸校驗機制。關於htpasswd的更多介紹不在本文的範疇,請讀者自行查閱之。
若是主機上沒有安裝此命令工具,能夠運行以下命令:
> yum install httpd-tools
由於htpasswd是Apache2的附屬工具命令,若是安裝了Apache2,此命令理應是能夠用的。
若是讀者不想安裝了,能夠直接使用registry鏡像,其內置了httpd。
假設密碼文件存放在/usr/local/auth目錄下面,運行以下命令
> htpasswd -Bbn admin 123456 > /usr/local/auth/passwd
使用registry鏡像內置的httpd,以下:
> docker run --entrypoint htpasswd registry:2 -Bbn admin 123456 > /usr/local/auth/passwd
兩種方式都能達到一樣的目的:在/usr/local/auth/passwd文件中生成用戶名和密碼。
命令中的admin是用戶名,123456即爲密碼。
查看passwd文件內容:
> cat /usr/local/auth/passwd admin:$2y$05$/2H8DTcY.1JROHm0MnnK8.UulmbSclib63qTe8FGyWnnE9XWBz3cy
雖然是一樣的命令,但在不一樣的主機,生成的結果並不相同。所以,在主機A上生成的密碼文件不能用做主機B上進行認證。
接下來要啓動registry容器了:
> docker run -d \ -p 5000:5000 \ --restart=always \ --name registry \ -v /usr/local/auth:/auth \ -e REGISTRY_AUTH=htpasswd \ -e REGISTRY_AUTH_HTPASSWD_REALM=Registry_Realm \ -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/passwd \ -v /usr/local/certs:/certs \ -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/server.crt \ -e REGISTRY_HTTP_TLS_KEY=/certs/server.key \ registry:2
啓動成功後,若是試圖直接查看遠程倉庫有哪些鏡像,會提示未認證,以下:
> curl https://registry.iwendao.vip/v2/_catalog { "errors": [{ "code": "UNAUTHORIZED", "message": "authentication required", "detail": [{ "Type": "registry", "Class": "", "Name": "catalog", "Action": "*" }] }] }
包括pull,push操做也都受限了。所以,在作操做以前,須要進行登陸。
> docker login https://registry.iwendao.vip
既然有登陸,固然就有登出了。
> docker logout https://registry.iwendao.vip
當咱們把Registry Server搭建好了以後,就意味着要開始管理咱們的鏡像了。這個時候會發現,並無一個可視化的工具幫助用戶進行鏡像管理。
目前已經有不少開源的WEB UI管理工具:
一、docker-registry-frontend。截止到目前(2018年5月),其功能主要是鏡像列表查看,標籤查看,還未開放鏡像刪除功能,在GitHub上開源,stars 1k+。
二、docker-registry-web。相比docker-registry-frontend項目,此項目提供了鏡像刪除功能,還接入了角色系統,功能有了進一步完善,在GitHub上開源,stars 300+。
三、Rancher。這個平臺的定位相似Kubernetes,不只僅是鏡像管理這麼簡單了,對於整個Docker容器管理都是能勝任的。
四、shipyard。很惋惜,做者已經沒有精力維護了,從GitHub上的stars,不難看出其昔日的輝煌。
關於WEB UI的安裝部署就再也不贅述了,都有其對應的文檔。若是對於鏡像管理沒有什麼特別要求,能夠不用WEB UI,或者使用前兩個之一。
本文詳述了Docker Registry私服搭建的過程,總結了來自各種博客,官網的學習資料,幫助讀者順利搭建Docker Registry私服。
附:
一、使用yaml文件啓動registry server
假設配置文件的存放路徑是:/usr/local/registry/config.yml
編輯其內容,以下:
version: 0.1 log: fields: service: registry storage: cache: blobdescriptor: inmemory filesystem: rootdirectory: /var/lib/registry maxthreads: 100 delete: enabled: true http: addr: 0.0.0.0:5000 host: https://registry.iwendao.vip secret: yoogurt-taxi-123!@# headers: X-Content-Type-Options: [nosniff] tls: certificate: /certs/214709594090104.crt key: /certs/214709594090104.key health: storagedriver: enabled: true interval: 10s threshold: 3
更多配置項,能夠訪問Configuring a registry。
配置文件中的配置項是能夠對應到前文中-e參數的環境變量,其規則就是:
一、變量名由大寫字母組成;
二、前綴固定加上REGISTRY;
三、將YAML中的配置項的冒號(:)變成了下劃線(_)。
好比:
REGISTRY_HTTP_TLS_CERTIFICATE,對應的是http: tls: certificate配置項;
REGISTRY_AUTH_HTPASSWD_PATH,對應的是auth: htpasswd: path配置項。
值得注意的是,配置文件中所涉及的路徑都是針對容器內的,這就意味着,在啓動registry鏡像的時候,須要經過-v參數指定掛載目錄。
保存配置文件後,便可啓動容器:
> docker run -d -p 5000:5000 --restart=always --name registry \ -v /usr/local/certs:/certs -v /usr/local/registry/config.yml:/etc/docker/registry/config.yml \ registry:2
二、介紹關於Docker的書籍