搭建一個私有的Docker registry
[TL;DR] 這是系列的第二篇文章,這系列講述了我的公司如何把基礎服務從PaaS遷移到Docker上
為什麼需要搭建一個私有的registry呢?嗯,對於新手來說,Docker Hub(一個Docker公共倉庫)只允許你擁有一個免費的私有版本庫(repo)。其他的公司也開始提供類似服務,但是價格可不便宜。另外,如果你需要用Docker部署一個用於生產環境的應用,恐怕你不希望將這些鏡像放在公開的Docker Hub上吧!
這篇文章提供了一個非常務實的方法來處理搭建私有Docker registry時出現的各種錯綜複雜的情況。我們將會使用一個運行於DigitalOcean(之後簡稱為DO)的非常小巧的512MB VPS 實例。並且我會假定你已經了解了Docker的基本概念,因為我必須集中精力在複雜的事情上!
本地搭建
首先你需要安裝boot2docker以及docker CLI。如果你已經搭建好了基本的Docker環境,你可以直接跳過這一步。
從終端運行以下命令(我假設你使用OS X,使用 HomeBrew 來安裝相關軟體,你可以根據你的環境使用不同的包管理軟體來安裝):
brew install boot2docker docker
如果一切順利(想要了解搭建docker環境的完整指南,請參閱 http://boot2docker.io/) ,你現在就能夠通過如下命令啟動一個 Docker 運行於其中的虛擬機:
boot2docker up
按照屏幕顯示的說明,複製粘貼book2docker在終端輸出的命令。如果你現在運行docker ps
命令,終端將有以下顯示。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
好了,Docker已經準備就緒,這就夠了,我們回過頭去搭建registry。
創建伺服器
登錄進你的DO賬號,選擇一個預安裝了Docker的鏡像文件,創建一個新的Drople。(本文寫成時選擇的是 Image > Applications > Docker 1.4.1 on 14.04)
你將會以郵件的方式收到一個根用戶憑證。登錄進去,然後運行docker ps
命令來查看系統狀態。
搭建AWS S3
我們現在將使用Amazo Simple Storage Service(S3)作為我們registry/repository的存儲層。我們將需要創建一個桶(bucket)以及用戶憑證(user credentials)來允許我們的docker容器訪問它。
登錄到我們的AWS賬號(如果沒有,就申請一個http://aws.amazon.com/),在控制台選擇S3(Simpole Storage Service)。
點擊 Create Bucket,為你的桶輸入一個名字(把它記下來,我們一會需要用到它),然後點擊Create。
OK!我們已經搭建好存儲部分了。
設置AWS訪問憑證
我們現在將要創建一個新的用戶。退回到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的內容如下:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "SomeStatement",
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::docker-registry-bucket-name/*",
"arn:aws:s3:::docker-registry-bucket-name"
]
}
]
}
這個配置將允許用戶(也就是regitstry)來對桶上的內容進行操作(讀/寫)(確保使用你之前創建AWS S3時使用的桶名)。總結一下:當你想把你的Docker鏡像從你的本機推送到倉庫中時,伺服器就會將他們上傳到S3。
安裝registry
現在回過頭來看我們的DO伺服器,SSH登錄其上。我們將要使用一個官方Docker registry鏡像。
輸入如下命令,開啟registry。
docker run
-e SETTINGS_FLAVOR=s3
-e AWS_BUCKET=bucket-name
-e STORAGE_PATH=/registry
-e AWS_KEY=your_aws_key
-e AWS_SECRET=your_aws_secret
-e SEARCH_BACKEND=sqlalchemy
-p 5000:5000
--name registry
-d
registry
Docker將會從Docker Hub上拉取所需的文件系統分層(fs layers)並啟動守護容器(daemonised container)。
測試registry
如果上述操作奏效,你可以通過ping命令,或者查找它的內容來測試registry(雖然這個時候容器還是空的)。
我們的registry非常基礎,而且沒有提供任何「驗明正身」的方式。因為添加身份驗證可不是一件輕鬆事(至少我認為沒有一種部署方法是簡單的,像是為了證明你努力過似的),我覺得「查詢/拉取/推送」倉庫內容的最簡單方法就是通過SSH通道的未加密連接(通過HTTP)。
打開SSH通道的操作非常簡單:
ssh -N -L 5000:localhost:5000 root@your_registry.com
這條命令建立了一條從registry伺服器(前面執行docker run
命令的時候我們見過它)的5000號埠到本機的5000號埠之間的 SSH 管道連接。
如果你現在用瀏覽器訪問 http://localhost:5000/v1/_ping,將會看到下面這個非常簡短的回復。
{}
這個意味著registry工作正常。你還可以通過登錄 http://localhost:5000/v1/search 來查看registry內容,內容相似:
{
"num_results": 2,
"query": "",
"results": [
{
"description": "",
"name": "username/first-repo"
},
{
"description": "",
"name": "username/second-repo"
}
]
}
創建一個鏡像
我們現在創建一個非常簡單的Docker鏡像,來檢驗我們新弄好的registry。在我們的本機上,用如下內容創建一個Dockerfile(這裡只有一點代碼,在下一篇文章里我將會展示給你如何將一個Rails應用綁定進Docker容器中。):
# ruby 2.2.0 的基礎鏡像
FROM ruby:2.2.0
MAINTAINER Michelangelo Chasseur <michelangelo.chasseur@touchwa.re>
並創建它:
docker build -t localhost:5000/username/repo-name .
localhost:5000
這個部分非常重要:Docker鏡像名的最前面一個部分將告知docker push
命令我們將要把我們的鏡像推送到哪裡。在我們這個例子當中,因為我們要通過SSH管道連接遠程的私有registry,localhost:5000
精確地指向了我們的registry。
如果一切順利,當命令執行完成返回後,你可以輸入docker images
命令來列出新近創建的鏡像。執行它看看會出現什麼現象?
推送到倉庫
接下來是更好玩的部分。實現我所描述的東西著實花了我一點時間,所以如果你第一次讀的話就耐心一點吧,跟著我一起操作。我知道接下來的東西會非常複雜(如果你不自動化這個過程就一定會這樣),但是我保證到最後你一定都能明白。在下一篇文章里我將會使用到一大波shell腳本和Rake任務,通過它們實現自動化並且用簡單的命令實現部署Rails應用。
你在終端上運行的docker命令實際上都是使用boot2docker虛擬機來運行容器及各種東西。所以當你執行像docker push some_repo
這樣的命令時,是boot2docker虛擬機在與registry交互,而不是我們自己的機器。
接下來是一個非常重要的點:為了將Docker鏡像推送到遠端的私有倉庫,SSH管道需要在boot2docker虛擬機上配置好,而不是在你的本地機器上配置。
有許多種方法實現它。我給你展示最簡短的一種(可能不是最容易理解的,但是能夠幫助你實現自動化)
在這之前,我們需要對 SSH 做最後一點工作。
設置 SSH
讓我們把boot2docker 的 SSH key添加到遠端伺服器的「已知主機」裡面。我們可以使用ssh-copy-id工具完成,通過下面的命令就可以安裝上它了:
brew install ssh-copy-id
然後運行:
ssh-copy-id -i /Users/username/.ssh/id_boot2docker root@your-registry.com
用你ssh key的真實路徑代替/Users/username/.ssh/id_boot2docker
。
這樣做能夠讓我們免密碼登錄SSH。
現在我們來測試以下:
boot2docker ssh "ssh -o 'StrictHostKeyChecking no' -i /Users/michelangelo/.ssh/id_boot2docker -N -L 5000:localhost:5000 root@registry.touchwa.re &" &
分開闡述:
boot2docker ssh
允許你以參數的形式傳遞給boot2docker虛擬機一條執行的命令;- 最後面那個
&
表明這條命令將在後台執行; ssh -o 'StrictHostKeyChecking no' -i /Users/michelangelo/.ssh/id_boot2docker -N -L 5000:localhost:5000 root@registry.touchwa.re &
是boot2docker虛擬機實際運行的命令;-o 'StrictHostKeyChecking no'
——不提示安全問題;-i /Users/michelangelo/.ssh/id_boot2docker
指出虛擬機使用哪個SSH key來進行身份驗證。(注意這裡的key應該是你前面添加到遠程倉庫的那個)- 最後我們將打開一條埠5000映射到localhost:5000的SSH通道。
從其他伺服器上拉取
你現在將可以通過下面的簡單命令將你的鏡像推送到遠端倉庫:
docker push localhost:5000/username/repo_name
在下一篇文章中,我們將會了解到如何自動化處理這些事務,並且真正地容器化一個Rails應用。請繼續收聽!
如有錯誤,請不吝指出。祝你Docker之路順利!
via: http://cocoahunter.com/2015/01/23/docker-2/
作者:Michelangelo Chasseur 譯者:DongShuaike 校對:wxy
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive