單向散列函數(shù)(one-wayfunction)有一個(gè)輸入和一個(gè)輸出,其中輸入稱為消息(message),輸出稱為散列值 (hashvalue)。單向散列函數(shù)可以根據(jù)消息的內(nèi)容計(jì)算出散列值,而散列值就可以被用來檢查消息的完整性。
成都創(chuàng)新互聯(lián)公司是一家業(yè)務(wù)范圍包括IDC托管業(yè)務(wù),雅安服務(wù)器托管、主機(jī)租用、主機(jī)托管,四川、重慶、廣東電信服務(wù)器租用,四川電信機(jī)房托管,成都網(wǎng)通服務(wù)器托管,成都服務(wù)器租用,業(yè)務(wù)范圍遍及中國大陸、港澳臺(tái)以及歐美等多個(gè)國家及地區(qū)的互聯(lián)網(wǎng)數(shù)據(jù)服務(wù)公司。
這里的消息不一定是人類能夠讀懂的文字,也可以是圖像文件或者聲音文件。單向散列函數(shù)不需要知道消息實(shí)
際代表的含義。無論任何消息,單向散列函數(shù)都會(huì)將它作為單純的比特序列來處理,即根據(jù)比特序列計(jì)算出散
列值。
散列值的長度和消息的長度無關(guān)。無論消息是1比特,還是100MB,甚至是IOOGB,單向散列函數(shù)都會(huì)計(jì)算出固 定長度的散列值。以SHA-I單向散列函數(shù)為例,它所計(jì)算出的散列值的長度永遠(yuǎn)是160比特(20字節(jié))。
單向散列函數(shù)的相關(guān)術(shù)語有很多變體,不同參考資料中所使用的術(shù)語也不同,下面我們就介紹其中的兒個(gè)。 單向散列函數(shù)也稱為 消息摘要函數(shù)(message digest function) 、 哈希函數(shù) 或者 雜湊函數(shù) 。 輸入單向散列函數(shù)的消息也稱為 原像 (pre-image) 。
單向散列函數(shù)輸出的散列值也稱為 消息摘要 (message digest)或者 指紋 (fingerprint)。 完整性 也稱為一致性。
MD4是由Rivest于1990年設(shè)計(jì)的單向散列函數(shù),能夠產(chǎn)生128比特的散列值(RFC1186,修訂版RFC1320)。不 過,隨著Dobbertin提出尋找MD4散列碰撞的方法,因此現(xiàn)在它已經(jīng)不安全了。
MD5是由Rwest于1991年設(shè)計(jì)的單項(xiàng)散列函數(shù),能夠產(chǎn)生128比特的散列值(RFC1321)。
MD5的強(qiáng)抗碰撞性已經(jīng)被攻破,也就是說,現(xiàn)在已經(jīng)能夠產(chǎn)生具備相同散列值的兩條不同的消息,因此它也已
經(jīng)不安全了。
MD4和MD5中的MD是消息摘要(Message Digest)的縮寫。
SHA-1是由NIST(NationalInstituteOfStandardsandTechnology,美國國家標(biāo)準(zhǔn)技術(shù)研究所)設(shè)計(jì)的一種能夠產(chǎn)生 160比特的散列值的單向散列函數(shù)。1993年被作為美國聯(lián)邦信息處理標(biāo)準(zhǔn)規(guī)格(FIPS PUB 180)發(fā)布的是 SHA,1995年發(fā)布的修訂版FIPS PUB 180-1稱為SHA-1。
SHA-1的消息長度存在上限,但這個(gè)值接近于2^64比特,是個(gè)非常巨大的數(shù)值,因此在實(shí)際應(yīng)用中沒有問題。
SHA-256、SHA-384和SHA-512都是由NIST設(shè)計(jì)的單向散列函數(shù),它們的散列值長度分別為256比特、384比特和
512比特。這些單向散列函數(shù)合起來統(tǒng)稱SHA-2,它們的消息長度也存在上限(SHA-256的上限接近于 2^64 比特,
SHA-384 和 SHA-512的上限接近于 2^128 比特)。這些單向散列函數(shù)是于2002年和 SHA-1 一起作為 FIPS PUB 180-2 發(fā)布的 SHA-1 的強(qiáng)抗碰撞性已于2005年被攻破, 也就是說,現(xiàn)在已經(jīng)能夠產(chǎn)生具備相同散列值的兩條不同的消 息。不過,SHA-2還尚未被攻破。
在編譯docker代碼之前肯定需要研究一下docker的代碼結(jié)構(gòu)以及官方推薦的方式,因?yàn)閐ocker是開源的,所以很多第三方開發(fā)者參與。那么官方肯定會(huì)給出開發(fā)環(huán)境搭建的文檔,所以拿到代碼肯定先研究官方的編譯方法。通過文檔和代碼了解到docker官方推薦的是在docker本身的容器里面搭建環(huán)境和編譯,官方給出的是一個(gè)基于ubuntu的dockerfile。不過正是這個(gè)dockerfile可以清楚的知道需要為了編譯準(zhǔn)備哪些依賴環(huán)境,為我們后面自己編譯提供了環(huán)境搭建的基礎(chǔ)。然后就嘗試了官方的編譯方案,結(jié)果各種網(wǎng)絡(luò)問題導(dǎo)致編譯通不過,當(dāng)然網(wǎng)上也有相應(yīng)的解決方案,基本上就是替換一些依賴源(國外的被墻了)。但是就算編譯通過了也只是一個(gè)基于ubuntu的二進(jìn)制文件,只能在ubuntu的相應(yīng)的系統(tǒng)上運(yùn)行。我們需要的是一個(gè)可以在centos7上運(yùn)行的二進(jìn)制文件,關(guān)鍵要搭建一個(gè)可以持續(xù)開發(fā)和編譯測試的環(huán)境。當(dāng)然也可以制作一個(gè)centos7的dockerfile文件,對(duì)照著官方的ubuntu的dockerfile也很簡單。但是這些都是還需要有一個(gè)前提,就是需要先安裝一個(gè)以前版本的docker來啟動(dòng)這個(gè)環(huán)境澀,好處也是杠杠的,可以在任何一臺(tái)能夠運(yùn)行docker的系統(tǒng)上進(jìn)行開發(fā)和測試,而且可以進(jìn)行持續(xù)集成。不過對(duì)于我們來說能夠編譯出一個(gè)穩(wěn)定運(yùn)行在centos7上的二進(jìn)制文件即可,所以就嘗試直接在本地進(jìn)行編譯,而不是通過docker的容器進(jìn)行。
經(jīng)過研究docker的官方編譯腳步,發(fā)現(xiàn)本地編譯也很簡單,只需要在docker源碼的目錄下執(zhí)行如下命令即可:
./hack/make.sh binary
上面這條命令就只會(huì)生成docker的二進(jìn)制文件,不過肯定不會(huì)這么順利的,執(zhí)行這個(gè)命令你就會(huì)發(fā)現(xiàn)錯(cuò)誤。如果第一次執(zhí)行報(bào)的錯(cuò)誤應(yīng)該是找不到相應(yīng)的go依賴包。那么現(xiàn)在就開始解決第一個(gè)問題,go依賴包。
解決go依賴包最直接的方法就一個(gè)一個(gè)去github或者其他地方去下載到本地,但是這樣做很麻煩,docker依賴的go語言包很多,然后依賴包可能又依賴其他包。這里有一個(gè)簡單實(shí)用的辦法,也是go語言管理項(xiàng)目的方便之處。通過go get命令來自動(dòng)下載,例如發(fā)現(xiàn)報(bào)錯(cuò)的是docker某一個(gè)目錄下的依賴包,那么可以如下執(zhí)行:
go get -v ./src/github.com/docker/docker/...
這條命令執(zhí)行以后整個(gè)docker目錄下源文件依賴的包都會(huì)被自動(dòng)下載。如果發(fā)現(xiàn)其他目錄下源文件也報(bào)同樣的錯(cuò)誤,可以按照次方法解決。不過這里需要強(qiáng)調(diào)一點(diǎn),這些下載都是會(huì)下載最新的包,如果編譯老的docker肯定會(huì)出問題,如果編譯最新的docker代碼肯定不會(huì)有問題,因?yàn)楣俜降木幾g是這種方式。
上面執(zhí)行的命令都是建立在go語言環(huán)境建立成功的基礎(chǔ)上,我安裝的go遇到是1.3.3版本的,采用源碼方式安裝。安裝在/export/servers/go下面,然后所有的go語言工程源碼目錄放在/export/servers/gopath。然后配置環(huán)境變量在用戶的根目錄下的.bashrc文件里面如下:
export GOPATH=/export/servers/gopath
export GOROOT=/export/servers/go
export GOARCH=amd64
export GOOS=linux
然后docker的代碼目錄如下:/export/servers/gopath/src/github.com/docker/docker。這樣才能在gopath下面進(jìn)行依賴包的下載。通過上面的方法把所有依賴包下載完以后就可以進(jìn)行編譯了。
在繼續(xù)編譯的過程中還會(huì)遇到缺少c語言依賴包缺少的問題,主要有三個(gè),(1)sqlite3;(2)device-mapper;(3)btrfs.
第一個(gè)sqlite3可以使用如下命令安裝依賴:yum install sqlite-devel.x86_64
第二個(gè)在官方的dockerfile文件里面有解決方案,執(zhí)行如下命令:
git clone --no-checkout /usr/local/lvm2 cd /usr/local/lvm2 git checkout -q v2_02_103
cd /usr/local/lvm2 ./configure --enable-static_link make device-mapper make install_device-mapper
第三個(gè)btrfs使用如下安裝依賴: yum install btrfs-progs。
這些依賴都解決了就繼續(xù)編譯,這個(gè)時(shí)候可能會(huì)出現(xiàn)ld連接錯(cuò)誤,提示找不到庫。因?yàn)閐ocker編譯的方式完全是static,所以所有依賴的庫必須還要有相應(yīng)的靜態(tài)庫(.a),而不是動(dòng)態(tài)庫(.so)。剛才通過yum install sqlite-devel.x86_64安裝了sqlite3的依賴,但是最后發(fā)現(xiàn)里面沒有靜態(tài)庫,所以編譯ld的時(shí)候出錯(cuò)了。我的解決辦法就是重新到sqlite3的官方網(wǎng)站下載了源碼包,然后編譯安裝即可。
編譯完成以后,就會(huì)在docker源碼目錄下的bundles/1.3.1/binary/目錄有如下文件:
docker docker-1.3.1 docker-1.3.1.md5 docker-1.3.1.sha256
docker-1.3.1這個(gè)文件就是我們需要的二進(jìn)制文件了,docker是一個(gè)軟連接到docker-1.3.1的文件。
到此就成功完成編譯了,以后修改了代碼重新支持編譯腳步即可:
./hack/make.sh binary
Docker私有倉庫Registry的搭建驗(yàn)證
1. 關(guān)于Registry
官方的Docker hub是一個(gè)用于管理公共鏡像的好地方,我們可以在上面找到我們想要的鏡像,也可以把我們自己的鏡像推送上去。但是,有時(shí)候,我們的使用場景需要我們擁有一個(gè)私有的鏡像倉庫用于管理我們自己的鏡像。這個(gè)可以通過開源軟件Registry來達(dá)成目的。
Registry在github上有兩份代碼:老代碼庫和新代碼庫。老代碼是采用python編寫的,存在pull和push的性能問題,出到0.9.1版本之后就標(biāo)志為deprecated,不再繼續(xù)開發(fā)。從2.0版本開始就到在新代碼庫進(jìn)行開發(fā),新代碼庫是采用go語言編寫,修改了鏡像id的生成算法、registry上鏡像的保存結(jié)構(gòu),大大優(yōu)化了pull和push鏡像的效率。
官方在Docker hub上提供了registry的鏡像(詳情),我們可以直接使用該registry鏡像來構(gòu)建一個(gè)容器,搭建我們自己的私有倉庫服務(wù)。Tag為latest的registry鏡像是0.9.1版本的,我們直接采用2.1.1版本。
2. Registry的部署
運(yùn)行下面命令獲取registry鏡像,
$ sudo docker pull registry:2.1.1
然后啟動(dòng)一個(gè)容器,
$ sudo docker run -d -v /opt/registry:/var/lib/registry -p 5000:5000 --restart=always --name registry registry:2.1.1
Registry服務(wù)默認(rèn)會(huì)將上傳的鏡像保存在容器的/var/lib/registry,我們將主機(jī)的/opt/registry目錄掛載到該目錄,即可實(shí)現(xiàn)將鏡像保存到主機(jī)的/opt/registry目錄了。
運(yùn)行docker ps看一下容器情況,
lienhua34@lienhua34-Compaq-Presario-CQ35-Notebook-PC ~ $ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f3766397a458 registry:2.1.1 "/bin/registry /etc/d" 46 seconds ago Up 45 seconds 0.0.0.0:5000-5000/tcp registry
說明我們已經(jīng)啟動(dòng)了registry服務(wù),打開瀏覽器輸入,出現(xiàn)下面情況說明registry運(yùn)行正常,
3. 驗(yàn)證
現(xiàn)在我們通過將鏡像push到registry來驗(yàn)證一下。
我的機(jī)器上有個(gè)hello-world的鏡像,我們要通過docker tag將該鏡像標(biāo)志為要推送到私有倉庫,
$ sudo docker tag hello-world 127.0.0.1:5000/hello-world
然后查看以下本地的鏡像,
lienhua34@lienhua34-Compaq-Presario-CQ35-Notebook-PC ~ $ sudo docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
registry 2.1.1 b91f745cd233 5 days ago 220.1 MB
ubuntu 14.04 a5a467fddcb8 6 days ago 187.9 MB
hello-world latest 975b84d108f1 2 weeks ago 960 B
127.0.0.1:5000/hello-world latest 975b84d108f1 2 weeks ago 960 B
接下來,我們運(yùn)行docker push將hello-world鏡像push到我們的私有倉庫中,
lienhua34@lienhua34-Compaq-Presario-CQ35-Notebook-PC ~ $ sudo docker push 127.0.0.1:5000/hello-world
The push refers to a repository [127.0.0.1:5000/hello-world] (len: 1)
975b84d108f1: Image successfully pushed
3f12c794407e: Image successfully pushed
latest: digest: sha256:1c7adb1ac65df0bebb40cd4a84533f787148b102684b74cb27a1982967008e4b size: 2744
現(xiàn)在我們可以查看我們本地/opt/registry目錄下已經(jīng)有了剛推送上來的hello-world。我們也在瀏覽器中輸入,如下圖所示,
現(xiàn)在我們可以先將我們本地的127.0.0.1:5000/hello-world和hello-world先刪除掉,
$ sudo docker rmi hello-world
$ sudo docker rmi 127.0.0.1:5000/hello-world
然后使用docker pull從我們的私有倉庫中獲取hello-world鏡像,
lienhua34@lienhua34-Compaq-Presario-CQ35-Notebook-PC ~ $ sudo docker pull 127.0.0.1:5000/hello-world
Using default tag: latest
latest: Pulling from hello-world
b901d36b6f2f: Pull complete
0a6ba66e537a: Pull complete
Digest: sha256:1c7adb1ac65df0bebb40cd4a84533f787148b102684b74cb27a1982967008e4b
Status: Downloaded newer image for 127.0.0.1:5000/hello-world:latest
lienhua34@lienhua34-Compaq-Presario-CQ35-Notebook-PC ~ $ sudo docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
registry 2.1.1 b91f745cd233 5 days ago 220.1 MB
ubuntu 14.04 a5a467fddcb8 6 days ago 187.9 MB
127.0.0.1:5000/hello-world latest 0a6ba66e537a 2 weeks ago 960 B
4. 可能問題
可能會(huì)出現(xiàn)無法push鏡像到私有倉庫的問題。這是因?yàn)槲覀儐?dòng)的registry服務(wù)不是安全可信賴的。這是我們需要修改docker的配置文件/etc/default/docker,添加下面的內(nèi)容,
DOCKER_OPTS="--insecure-registry xxx.xxx.xxx.xxx:5000"
然后重啟docker后臺(tái)進(jìn)程,
$ sudo service docker restart
這是再push即可。
1.安裝git
因?yàn)間olang是通過git來管理遠(yuǎn)程包的,所以我們首先要安裝git
git安裝比較簡單,直接下一步即可(在Windows Explorer integration選項(xiàng)中將“Git Bash here”和“Git GUI here”打?qū)?,需要了解具體安裝的可以看這里。
2.安裝Golang
1) 首先到選擇適合你系統(tǒng)的安裝包
2)我這里選擇的是:go1.4.2.windows-amd64.msi,下載完成安裝到指定目錄即可。我這里是(E:\Go)。
3)安裝完成后環(huán)境變量已經(jīng)自動(dòng)設(shè)置好了,可以呼出cmd命令行輸入命令查看
go env
可以看到,已經(jīng)出現(xiàn)go命令了。如果你的不能出現(xiàn),那可能是環(huán)境變量設(shè)置的問題。
進(jìn)入我的電腦-高級(jí)設(shè)置-環(huán)境變量查看下,GOROOT變量是否存在,以及Path變量中是否也設(shè)置了GOROOT。沒有的話,新增一個(gè)GOROOT變量,路徑則輸入你剛剛安裝完成后Go的根目錄,如我的是:E:\Go\。然后編輯Path變量,在最后面新增";%GOROOT%bin"。
4)go命令依賴一個(gè)環(huán)境變量:GOPATH,這不是Go的安裝目錄,而是你的工作(工程)目錄(你的代碼都會(huì)在該目錄下)。GOPATH可以有多個(gè),windows以分號(hào)(;)進(jìn)行區(qū)分,Linux系統(tǒng)是冒號(hào)(:),當(dāng)有多個(gè)GOPATH時(shí),默認(rèn)會(huì)將go get的內(nèi)容放在第一個(gè)目錄下。這里我們新建一個(gè)GOPATH變量,以我的為例:F:\mygo。
3.安裝Sublime Text3
注意:sublime是收費(fèi)軟件,不注冊(cè)也可以正常使用,只是保存次數(shù)達(dá)到一定的數(shù)量的時(shí)候會(huì)提示購買;忽略后可以正常使用。
這里需要安裝一個(gè)sublime的pakcage control功能,用于接下來安裝sublime插件。
1)在打開軟件后,按下快捷鍵 Ctrl+`,(`這個(gè)符號(hào)為英文半角模式下,按下 Tab 鍵上方、數(shù)字鍵1左邊的那個(gè)按鍵),此時(shí)會(huì)打開一個(gè)命令窗口,復(fù)制并輸入以下內(nèi)容,最后回車:
import urllib.request,os,hashlib; h = 'eb2297e1a458f27d836c04bb0cbaf282' + 'd0e7a3098092775ccb37ca9d6b2e4b7d'; pf = 'Package Control.sublime-package'; ipp = sublime.installed_packages_path(); urllib.request.install_opener( urllib.request.build_opener( urllib.request.ProxyHandler()) ); by = urllib.request.urlopen( '' + pf.replace(' ', '%20')).read(); dh = hashlib.sha256(by).hexdigest(); print('Error validating download (got %s instead of %s), please try manual install' % (dh, h)) if dh != h else open(os.path.join( ipp, pf), 'wb' ).write(by)
2)重啟sublime之后,你就可以發(fā)現(xiàn)在 Preferences 這個(gè)菜單下出現(xiàn)了菜單項(xiàng) Package Control,如圖:
4. 安裝GoSublime插件
1)在sublime中,按住快捷鍵 shift + ctrl + p,在彈出框中輸入install package,如圖:
2)回車,會(huì)出現(xiàn)如下圖(可能需要稍微等待下,可以看sublime最下面的狀態(tài)):
3)輸入gosublime,回車(可能需要稍微等待下,可以看sublime最下面的狀態(tài)),如圖:
4)gosublime安裝完成后,Preferences - package settings - GoSublime - Settings - Uesrs需要配置下GOPATH,GOROOT,如圖:
5)在打開的窗口中輸入以下內(nèi)容,路徑請(qǐng)自行替換,ctrl+s保存。
{
"env": {
"GOPATH": "F:/mygo",
"GOROOT": "E:/Go"
}
}
6)重啟sublime,在GOPATH中的src新建一個(gè)hello.go文件,可以看到代碼自動(dòng)補(bǔ)全已經(jīng)出來了,:)
至此,sublime text3 + golang 安裝完成。