docker 是一套 Linux 的 LXC 管理工具.
LXC (Linux Containers) 的概念類似于虛擬機(jī), 但是形式上有區(qū)別. 虛擬機(jī)更像是提供"機(jī)器環(huán)境", 而 LXC 則是提供"運(yùn)行環(huán)境". 單看概念它們的區(qū)別有些微妙, 但是 LXC 的特點(diǎn)就是, 同樣是提供一套完全隔離的操作系統(tǒng)環(huán)境, 它很快, 超級(jí)快.
在使用上, 概念上的區(qū)別就是, 用虛擬機(jī), 可能更多是想, 做一個(gè)電腦, 讓它跑起來, 然后再說讓這臺(tái)電腦干什么事.
而 docker 的使用, 則是做一個(gè)環(huán)境(一組進(jìn)程, 還有虛擬的設(shè)備等), 用環(huán)境來運(yùn)行一個(gè)命令. 環(huán)境-命令 是一體的(一個(gè)容器), 命令一旦執(zhí)行完成, 那么一個(gè)容器實(shí)例的任務(wù)就結(jié)束了. 所以如果我們想讓一個(gè)容器像一臺(tái)電腦那樣, 通常我們給它一個(gè)像 /usr/bin/sshd -D
這樣的命令, 這個(gè)容器像一臺(tái)電腦, 是因?yàn)檫@個(gè)命令一直"沒有執(zhí)行完成"的效果.
虛擬機(jī)的使用, 一個(gè)鏡像就是一個(gè)安裝好的系統(tǒng). 而 docker 中, 鏡像更像是一張安裝光盤(刻盤后不能更改), 容器才是安裝好的系統(tǒng). 這種兩層式結(jié)構(gòu)相較于傳統(tǒng)的"快照"機(jī)制, 要好用得多. (如何從真正的系統(tǒng)安裝 ISO 鏡像得到 docker 鏡像, 我現(xiàn)在也不清楚怎么做)
更具體一些, 使用 docker , 就是在指定的環(huán)境中執(zhí)行一條命令, 比如:
docker run ubuntu:14.04 /bin/bash
意思就是, 在 ubuntu:14.04 這個(gè)環(huán)境中, 執(zhí)行 /bin/bash 這條命令. 當(dāng)然, 這條命令顯然是瞬間就執(zhí)行完了的. 如果和這個(gè)命令立即有交互, 那么需要一些參數(shù):
docker run -t -i ubuntu:14.04 /bin/bash
-t
是分配一個(gè)虛擬終端, -i
是獲取當(dāng)前的輸入. 這樣你可以立即使用一個(gè)終端來和這個(gè)環(huán)境交互了.
雖然終端是正常使用電腦最常用的交互方式, 不過真實(shí)使用 docker 的場(chǎng)景中, 會(huì)這樣用的機(jī)會(huì)不會(huì)很多的. 通常是直接執(zhí)行我們要做的事, 比如運(yùn)行一個(gè)服務(wù), 或者執(zhí)行一系列的計(jì)算.
使用 nc
來作一個(gè)例子:
docker run -t ubuntu:14.04 nc -l 8000
加上 -t
是因?yàn)樾枰粋€(gè)終端來顯示輸出, 否則 nc
的標(biāo)準(zhǔn)輸出就沒地方去了.
docker 安裝之后, 會(huì)自動(dòng)在系統(tǒng)中作一個(gè)網(wǎng)橋配置, run
出來的每個(gè)容器實(shí)例, 都會(huì)分配一個(gè)橋接的 IP 地址. 上面的命令執(zhí)行之后, 已經(jīng)有容器在運(yùn)行了, 并且在其中, nc
正監(jiān)聽著 8000
端口. 我們要接上去試試, 首先需要找到這個(gè)容器實(shí)例的 IP 地址.
先看當(dāng)前運(yùn)行著的實(shí)例列表:
docker ps
你先看到下面的信息:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e1d0c9193025 ubuntu:14.04 nc -l 8000 5 seconds ago Up 4 seconds silly_curie
記下 ID , 不需要全部, 前面幾位就可以了, 然后查看指定容器實(shí)例的細(xì)節(jié):
docker inspect e1d0
會(huì)輸出一串 json 字符串, 里面會(huì)有這樣一節(jié):
"NetworkSettings": { "Bridge": "docker0", "Gateway": "172.17.42.1", "IPAddress": "172.17.0.82", "IPPrefixLen": 16, "PortMapping": null, "Ports": {} },
可以看到, 容器的 IP 是 172.17.0.82
, 上面的網(wǎng)關(guān) IP 172.17.42.1
就是你"實(shí)體機(jī)"的.
在實(shí)體機(jī)使用 telnet
連上去:
telnet 172.17.0.82 8000
現(xiàn)在能看到效果了.
^]
然后 quit
退出, nc
那邊結(jié)束執(zhí)行, 命令執(zhí)行完, 之前的那個(gè)容器實(shí)例也就關(guān)閉了. 你使用 docker ps
看不到. 但是使用:
docker ps -a
就能看到所有的容器實(shí)例. 在這里列出的實(shí)例是真實(shí)存在的, 只是當(dāng)前并沒有運(yùn)行起來而已. 你可以隨時(shí)讓其中的實(shí)例再運(yùn)行起來:
docker start e1d0c9193025
這樣你又可以 telnet
, 只是沒地方看輸出.
回顧上面的過程, 提出兩個(gè)概念, 鏡像 和 容器 .
鏡像 指上面的 ubuntu:14.04
這種, 嗯, 這種環(huán)境, 這種系統(tǒng). 后面會(huì)講如何做一個(gè)自己的 鏡像 .
容器 是在具體的 鏡像 上 run
具體的命令, 得到的一個(gè)"綁定狀態(tài)". run
命令執(zhí)行時(shí)的一些參數(shù)(比如和實(shí)體機(jī)的端口映射), 也是"狀態(tài)"的一部分, run
過之后就不能更改了.
它們的關(guān)系, 有些像編程語言中的 類 和 實(shí)例 . run
時(shí)的命令就像是類實(shí)例化時(shí)的參數(shù). 后面會(huì)提到, 你可以刪除 容器 , 也可以刪除 鏡像 . 當(dāng)你想刪除 鏡像 , 但是使用它的 容器 還存在時(shí), 你會(huì)得到操作失敗的提示.
類 有繼承關(guān)系, 得利于 AUFS 這些的層級(jí)文件系統(tǒng), 鏡像 的構(gòu)建也是這種層層封裝的結(jié)果.
更多建議: