需求
FreeBSD是個好東西,因為有ZFS。Docker也是個好東西,因為很爽。
然而之前Docker只支援Linux,所以在其它平臺上都需要搞個Linux虛擬機器才能用,麻煩得很。
當然現在也是一樣,只是官方出了一個docker-machine可以更方便地管理虛擬機器裡的docker。基本用法可以參考這篇《Docker on FreeBSD》
不過為了折騰這個東西,我把家裡的伺服器搞崩潰好多次,最後甚至不得不重灌一遍……前前後後折騰了快一個月。
現在把這個血淚教訓總結成本文。
準備環境
docker-machine依賴虛擬機器環境,這裡以最常用的VirtualBox為例。
我的伺服器上本來就跑著VBox,所以當時就直接拿來用了,結果可恥滴失敗了。
首先是需要系統版本:FreeBSD 11以上才提供了docker-machine,所以必須先把我的10升級一下。升級方法以前說過(見《FreeBSD升級失敗的處理》),這裡從略。
升級完成之後還是不能用,建立新machine的時候各種報錯,比如:
Error creating machine: Error in driver during machine creation: Unable to start the VM: /usr/local/bin/VBoxManage startvm dockerhost --type headless failed:
VBoxManage: error: The VMMR0.r0 module version does not match VBoxVMM.dll/so/dylib. If you just upgraded VirtualBox, please terminate all VMs and make sure th
at neither VBoxNetDHCP nor VBoxNetNAT is running. Then try again. If this error persists, try re-installing VirtualBox. (VERR_VMM_R0_VERSION_MISMATCH)
VBoxManage: error: Details: code NS_ERROR_FAILURE (0x80004005), component ConsoleWrap, interface IConsole
Details: 00:00:00.488143 Power up failed (vrc=VERR_VMM_R0_VERSION_MISMATCH, rc=NS_ERROR_FAILURE (0X80004005))
複製程式碼
看上去是某些驅動或服務沒有正常工作。於是參考VirtualBox文件,把vboxdrv和vboxnet都啟用,然後重啟……恭喜,系統崩潰了……
查了很久也沒查出原因,我甚至另外搞了一臺電腦安裝了FreeBSD11重試,還是一樣的問題。
只要下面任意一個命令執行就崩潰:
service vboxnet onestart
kldload vboxdrv.ko
複製程式碼
搜了很久也沒找到原因,搞了好幾天,直到今天搜到有人說了一句:可能跟系統不完全相容。我靈光一閃——對了,我的VBox是通過pkgng安裝的,有可能不相容。於是果斷換成多年不用的ports:
portsnap fetch
portsnap extra # 或update,如果已經安裝了ports的話
cd /usr/ports/emulators/virtualbox-ose
make config
make
make install clean
複製程式碼
然而仍然沒有那麼順利,因為舊版的還在……
pkg delete virtualbox-ose
複製程式碼
刪除後再編譯,仍然會有一些衝突的依賴包,全部刪除掉改用ports的版本。VBox這東西依賴還是相當多的,斷斷續續編譯了兩天才算完成。最後還編譯安裝了一把virtualbox-ose-kmod
。
為了保險起見,docker-machine
和docker-compose
我也是用ports的版本。
需要注意的是,如果你想用非root使用者操作的話,需要先允許這個使用者操作虛擬機器:
pw groupmod vboxusers -m yourname
複製程式碼
使用者需要重新登入一下,如果用了screen或tmux之類的,也需要新開會話(不是新開視窗)才會生效。
另外,為了充分利用ZFS,建立一個ZFS供machine使用:
zfs create -o mountpoint=/home/yourname/.docker tank/docker
複製程式碼
這樣建立的虛擬機器就會在tank/docker這個ZFS裡了。
docker-machine
重點來了,為了使用docker,先得建立一個machine,這就需要使用前面安裝的docker-machine
了:
docker-machine create --driver virtualbox \
--virtualbox-memory 2048 \
--virtualbox-cpu-count 1 \
--virtualbox-disk-size 204800 \
dockerhost
複製程式碼
上面的命令建立了一個叫做dockerhost
的虛擬機器,記憶體2G,CPU一顆,硬碟200G,並且自動執行起來。
然後就可以對這個machine進行一系列操作了。
docker-machine ls
docker-machine stop dockerhost # 停止虛擬機器
docker-machine start dockerhost # 啟動虛擬機器
docker-machine rm dockerhost # 刪除虛擬機器
複製程式碼
成功建立或啟動一個machine之後,就可以操作docker了,不過操作之前需要設定一下環境:
eval `docker-machine env dockerhost`
複製程式碼
主要是就是設定幾個環境變數給docker使用。
如果使用root使用者,需要注意的是:
root使用者的預設shell是csh,並不支援這個命令,必須使用bash。
其它使用者如果也是用csh,也要注意這一點。
docker
現在終於可以開始使用docker了:
docker images
docker ps
docker run helloworld
複製程式碼
大功告成!
但是還沒完,docker-machine裡的檔案路徑是對映過的,所以現在試試這個是不會成功的:
docker run -it --rm -v /home/yourname:/var/workdir alpine /bin/sh
# cd /var/workdir
# touch test
# exit
> cd /home/yourname
> ls test # 並沒有這個檔案
複製程式碼
因為-v對映的路徑不正確,必須使用在machine裡對映過的路徑。預設的對映路徑是:
share => /home
複製程式碼
所以上面那個測試可以改為:
docker run -it --rm -v /share/yourname:/var/workdir alpine /bin/sh
複製程式碼
這樣再做上面的測試就可以成功了。
當然那個預設對映可以自己在VirtualBox裡修改,或者在建立docker-machine的時候指定。