
[tl;dr] 這是系列的第二篇文章,這系列講述了我的公司如何把基礎服務從paas遷移到docker上
為什麼需要搭建一個私有的registry呢?嗯,對于新手來說,docker hub(一個docker公共倉庫)隻允許你擁有一個免費的私有版本庫(repo)。其他的公司也開始提供類似服務,但是價格可不便宜。另外,如果你需要用docker部署一個用于生産環境的應用,恐怕你不希望将這些鏡像放在公開的docker hub上吧!
這篇文章提供了一個非常務實的方法來處理搭建私有docker registry時出現的各種錯綜複雜的情況。我們将會使用一個運作于digitalocean(之後簡稱為do)的非常小巧的512mb vps 執行個體。并且我會假定你已經了解了docker的基本概念,因為我必須集中精力在複雜的事情上!
<a target="_blank"></a>
首先你需要安裝boot2docker以及docker cli。如果你已經搭建好了基本的docker環境,你可以直接跳過這一步。
從終端運作以下指令(我假設你使用os x,使用 homebrew 來安裝相關軟體,你可以根據你的環境使用不同的包管理軟體來安裝):
<code>brew install boot2docker docker</code>
<code>boot2docker up</code>
按照螢幕顯示的說明,複制粘貼book2docker在終端輸出的指令。如果你現在運作<code>docker ps</code>指令,終端将有以下顯示。
<code>container id image command created status ports names</code>
好了,docker已經準備就緒,這就夠了,我們回過頭去搭建registry。
登入進你的do賬号,選擇一個預安裝了docker的鏡像檔案,建立一個新的drople。(本文寫成時選擇的是 image > applications > docker 1.4.1 on 14.04)
你将會以郵件的方式收到一個根使用者憑證。登入進去,然後運作<code>docker ps</code>指令來檢視系統狀态。
我們現在将使用amazo simple storage service(s3)作為我們registry/repository的存儲層。我們将需要建立一個桶(bucket)以及使用者憑證(user credentials)來允許我們的docker容器通路它。
點選 create bucket,為你的桶輸入一個名字(把它記下來,我們一會需要用到它),然後點選create。
ok!我們已經搭建好存儲部分了。
我們現在将要建立一個新的使用者。退回到aws控制台然後選擇iam(identity & access management)。
在dashboard的左邊,點選users。然後選擇 create new users。
如圖所示:
輸入一個使用者名(例如 docker-registry)然後點選create。寫下(或者下載下傳csv檔案)你的access key以及secret access key。回到你的使用者清單然後選擇你剛剛建立的使用者。
在permission section下面,點選attach user policy。之後在下一屏,選擇custom policy。
custom policy的内容如下:
<code>{</code>
<code>"version": "2012-10-17",</code>
<code>"statement": [</code>
<code>"sid": "somestatement",</code>
<code>"effect": "allow",</code>
<code>"action": [</code>
<code>"s3:*"</code>
<code>],</code>
<code>"resource": [</code>
<code>"arn:aws:s3:::docker-registry-bucket-name/*",</code>
<code>"arn:aws:s3:::docker-registry-bucket-name"</code>
<code>]</code>
<code>}</code>
這個配置将允許使用者(也就是regitstry)來對桶上的内容進行操作(讀/寫)(確定使用你之前建立aws s3時使用的桶名)。總結一下:當你想把你的docker鏡像從你的本機推送到倉庫中時,伺服器就會将他們上傳到s3。
輸入如下指令,開啟registry。
<code>docker run \</code>
<code>-e settings_flavor=s3 \</code>
<code>-e aws_bucket=bucket-name \</code>
<code>-e storage_path=/registry \</code>
<code>-e aws_key=your_aws_key \</code>
<code>-e aws_secret=your_aws_secret \</code>
<code>-e search_backend=sqlalchemy \</code>
<code>-p 5000:5000 \</code>
<code>--name registry \</code>
<code>-d \</code>
<code>registry</code>
docker将會從docker hub上拉取所需的檔案系統分層(fs layers)并啟動守護容器(daemonised container)。
如果上述操作奏效,你可以通過ping指令,或者查找它的内容來測試registry(雖然這個時候容器還是空的)。
我們的registry非常基礎,而且沒有提供任何“驗明正身”的方式。因為添加身份驗證可不是一件輕松事(至少我認為沒有一種部署方法是簡單的,像是為了證明你努力過似的),我覺得“查詢/拉取/推送”倉庫内容的最簡單方法就是通過ssh通道的未加密連接配接(通過http)。
打開ssh通道的操作非常簡單:
<code>ssh -n -l 5000:localhost:5000 root@your_registry.com</code>
這條指令建立了一條從registry伺服器(前面執行<code>docker run</code>指令的時候我們見過它)的5000号端口到本機的5000号端口之間的 ssh 管道連接配接。
<code>{}</code>
<code>"num_results": 2,</code>
<code>"query": "",</code>
<code>"results": [</code>
<code>"description": "",</code>
<code>"name": "username/first-repo"</code>
<code>},</code>
<code>"name": "username/second-repo"</code>
我們現在建立一個非常簡單的docker鏡像,來檢驗我們新弄好的registry。在我們的本機上,用如下内容建立一個dockerfile(這裡隻有一點代碼,在下一篇文章裡我将會展示給你如何将一個rails應用綁定進docker容器中。):
<code># ruby 2.2.0 的基礎鏡像</code>
<code>from ruby:2.2.0</code>
<code></code>
<code>maintainer michelangelo chasseur <[email protected]></code>
并建立它:
<code>docker build -t localhost:5000/username/repo-name .</code>
<code>localhost:5000</code>這個部分非常重要:docker鏡像名的最前面一個部分将告知<code>docker push</code>指令我們将要把我們的鏡像推送到哪裡。在我們這個例子當中,因為我們要通過ssh管道連接配接遠端的私有registry,<code>localhost:5000</code>精确地指向了我們的registry。
如果一切順利,當指令執行完成傳回後,你可以輸入<code>docker images</code>指令來列出新近建立的鏡像。執行它看看會出現什麼現象?
接下來是更好玩的部分。實作我所描述的東西着實花了我一點時間,是以如果你第一次讀的話就耐心一點吧,跟着我一起操作。我知道接下來的東西會非常複雜(如果你不自動化這個過程就一定會這樣),但是我保證到最後你一定都能明白。在下一篇文章裡我将會使用到一大波shell腳本和rake任務,通過它們實作自動化并且用簡單的指令實作部署rails應用。
你在終端上運作的docker指令實際上都是使用boot2docker虛拟機來運作容器及各種東西。是以當你執行像<code>docker push some_repo</code>這樣的指令時,是boot2docker虛拟機在與registry互動,而不是我們自己的機器。
接下來是一個非常重要的點:為了将docker鏡像推送到遠端的私有倉庫,ssh管道需要在boot2docker虛拟機上配置好,而不是在你的本地機器上配置。
有許多種方法實作它。我給你展示最簡短的一種(可能不是最容易了解的,但是能夠幫助你實作自動化)
在這之前,我們需要對 ssh 做最後一點工作。
讓我們把boot2docker 的 ssh key添加到遠端伺服器的“已知主機”裡面。我們可以使用ssh-copy-id工具完成,通過下面的指令就可以安裝上它了:
<code>brew install ssh-copy-id</code>
然後運作:
<code>ssh-copy-id -i /users/username/.ssh/id_boot2docker [email protected]</code>
用你ssh key的真實路徑代替<code>/users/username/.ssh/id_boot2docker</code>。
這樣做能夠讓我們免密碼登入ssh。
現在我們來測試以下:
<code>boot2docker ssh "ssh -o 'stricthostkeychecking no' -i /users/michelangelo/.ssh/id_boot2docker -n -l 5000:localhost:5000 [email protected] &" &</code>
分開闡述:
<code>boot2docker ssh</code>允許你以參數的形式傳遞給boot2docker虛拟機一條執行的指令;
最後面那個<code>&</code>表明這條指令将在背景執行;
<code>ssh -o 'stricthostkeychecking no' -i /users/michelangelo/.ssh/id_boot2docker -n -l 5000:localhost:5000 [email protected] &</code>是boot2docker虛拟機實際運作的指令;
<code>-o 'stricthostkeychecking no'</code>——不提示安全問題;
<code>-i /users/michelangelo/.ssh/id_boot2docker</code>指出虛拟機使用哪個ssh key來進行身份驗證。(注意這裡的key應該是你前面添加到遠端倉庫的那個)
最後我們将打開一條端口5000映射到localhost:5000的ssh通道。
你現在将可以通過下面的簡單指令将你的鏡像推送到遠端倉庫:
<code>docker push localhost:5000/username/repo_name</code>
如有錯誤,請不吝指出。祝你docker之路順利!
原文釋出時間:2015-05-04
本文來自雲栖合作夥伴“linux中國”