天天看點

搭建一個私有的Docker registry搭建一個私有的Docker registry

搭建一個私有的Docker registry搭建一個私有的Docker registry

[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 &gt; applications &gt; docker 1.4.1 on 14.04)

搭建一個私有的Docker registry搭建一個私有的Docker registry

你将會以郵件的方式收到一個根使用者憑證。登入進去,然後運作<code>docker ps</code>指令來檢視系統狀态。

我們現在将使用amazo simple storage service(s3)作為我們registry/repository的存儲層。我們将需要建立一個桶(bucket)以及使用者憑證(user credentials)來允許我們的docker容器通路它。

搭建一個私有的Docker registry搭建一個私有的Docker registry

點選 create bucket,為你的桶輸入一個名字(把它記下來,我們一會需要用到它),然後點選create。

搭建一個私有的Docker registry搭建一個私有的Docker registry

ok!我們已經搭建好存儲部分了。

我們現在将要建立一個新的使用者。退回到aws控制台然後選擇iam(identity &amp; access management)。

搭建一個私有的Docker registry搭建一個私有的Docker registry

在dashboard的左邊,點選users。然後選擇 create new users。

如圖所示:

搭建一個私有的Docker registry搭建一個私有的Docker registry

輸入一個使用者名(例如 docker-registry)然後點選create。寫下(或者下載下傳csv檔案)你的access key以及secret access key。回到你的使用者清單然後選擇你剛剛建立的使用者。

在permission section下面,點選attach user policy。之後在下一屏,選擇custom policy。

搭建一個私有的Docker registry搭建一個私有的Docker registry

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 &lt;[email protected]&gt;</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] &amp;" &amp;</code>

分開闡述:

<code>boot2docker ssh</code>允許你以參數的形式傳遞給boot2docker虛拟機一條執行的指令;

最後面那個<code>&amp;</code>表明這條指令将在背景執行;

<code>ssh -o 'stricthostkeychecking no' -i /users/michelangelo/.ssh/id_boot2docker -n -l 5000:localhost:5000 [email protected] &amp;</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中國”