本文章同時發佈於:
大家好,繼上次Week22 — 用Redis來幫Line bot髒沙發設計一次性功能 — 實作篇的文章後,我些人私下來詢問我
Docker
是什麼?為什麼要拿他來起動Redis
,直接安裝Redis
不好嗎?
之類的問題。
所以這次就來介紹Docker
,告訴大家為什麼Docker
會成為一個讓許多人準時下班的好東西XD。
我會用Minecraft
與實際遇到的問題來說明,這樣大家可能會比較有感覺。
小林有一天,想與小昌一起玩Minecraft
,於是到了官網下載了Minecraft Server
的Java
執行檔,運行之後,快樂的與小昌完了數週。
有天小昌問:「欸欸,聽說新版出了,我們把原本舊版的Server
留著,然後新開一個新版的Server
,兩個版本我都要,何樂而不為?」
於是小林再起了一個Server
,於是爆炸了
我們可以看到有關鍵的一行錯誤訊息:
adp$a: /Users/chenyoulin/Downloads/./world/session.lock: already locked (possibly by other Minecraft instance?)
already locked
就是指Minecraft Server
所使用的資源已經被鎖著,不能再給其他程序讀寫了,導致新的Server
開不起來。
為什麼要防止資源被不同程序讀寫呢?
因為要防止
Thread
同時對同比資料做寫入,導致錯誤的結果
比如說上圖,Thread A
與Thread B
同時讀取了17這個數字,Thread A
在加1時,Thread B
並不知道,所以Thread B
還是以17來加1,導致明明A
與B
總共加了兩次,答案卻是18。
Minecraft Server
的already locked
也是要防止這個問題,來避免Server
的資源被功用,不然就有可能發生同時砍一格樹,卻掉出兩格的狀況。(等等這樣好像不錯?)
你可能會說,其實小林把「新版的Minecraft Server
移到別的資料夾就不會共用資源了啊」。
是的,你說的沒錯,但是Server
的世界裡,其實很常出現共用的狀況。
比如說Python2 Server
可能用著Linux
的一個核心模組A,而Python3 Server
又用著此新版的核心模組A+。
那問題來了,現在有台Linux
主機有兩個Server
分別是用Python2 Server
與Python3 Server
所寫,就會碰到以下狀況:
Linux
核心模組A可以正常用Python2 Server
,但Python3 Server
就無法使用。Linux
核心模組A可以正常用Python3 Server
,但Python2 Server
就無法使用。這種狀況很難像Minecraft Server
單純移到別的資料夾那麼簡單,因為這個核心模組A又會與一大堆核心模組B, C, D...相依。
如果你有想到
是否可以用
VM
來解決?就是一台裸機Linux
裡面再灌一個灌Linux
那麼你想對了,透過這個方法我們就跟「移到別的資料夾」一樣,我們把共用的核心模組A複製了一份到VM
裡了。
但...好像不止複製了核心模組A而已。
所以有沒有辦法
只複製我想要的模組至這個「隔離資料夾」,而其他的東西照舊用裸機
Linux
的呢
答案就是Docker
!
傳統的VM透過在裸機系統上安裝Hypervisor
,來再啟動與裸機隔離的系統,這種做法除了原本要替換的模組,其他連整個系統模組也都複製進了此空間。
而Docker
則是在裸機系統上製作名為namespace
的「隔離資料夾」,只把要替換的模組放進此隔離空間,其他模組還是用原本裸機的。
我們可以來數數這兩種做法的系統數量,因為直觀的感受就是越多系統電腦越卡XD。
VM
: 4Docker
: 1所以Docker
在效能上是完勝,Docker
效能消耗極少,因為他沒有Hypervisor
這層監視人員來分配資源,Docker
就像原生的Minecraft Server
一樣跑在裸機Linux
上,但他卻可以把資源隔開。
因為這樣的特色,所以你電腦如果可以啟動10個Server
的效能,那放在Docker
裡面跑也是沒問題的,而且資源可以隔離。
前面說了很多Docker
的優點,現在來說說缺點。
我們將核心模組A放入隔離空間後,可以確保此資源不會被共用,但是如果這個核心模組A把Linux
核心的主程式檔刪掉了呢,那整個Linux
就爆炸了。
因為Docker
本身就只有須要替換的東西放入隔離空間內,所以如果你的需求是「隔離空間完全沒有機會觸碰到裸機的資源」,那就需要VM
,因為核心是VM
自己的,要訪問任何裸機資源也會被Hypervisor
控管。
這可能不太算缺點,因為Docker
本來就是為了Linux
而生。
剛剛前面有提到Docker
會用Linux
的核心模組,所以如果Mac
或是Windows
想用Docker
,那就是要先安裝一個Linux VM
。
當然,Mac
跟Windows
已經將這個Linux VM
在安裝時一同優化至系統中,我們不需要手動安裝他,但是因為Linux VM
我們就沒辦法擁有Docker
幾乎不耗資源的。
所以,如果你是Mac
或是Windows
,那麼Docker
是僅較適合用在「開發上」,如果要用在真正發佈出去的Server
,要使用Linux
系統才能發揮Docker
的好處。
Docker
讓隔離資源變成一個非常不耗效能的事情,以前我們想到要開VM
來隔離Server
,就頭很痛,光是安裝Linux
就要半小時了。或者說要開10個VM
,那幾乎是來燒機的XD。
但現在有了Docker
,我們可以用幾乎與裸機Linux
一模一樣的速度來開啟隔離Server
,效能也幾乎與裸機Linux
相同。
省了這麼多時間,能提早下班回家睡覺,這能不香嗎!
有了這些概念後,接下來我跟大家介紹怎麼實作Docker
的Minecraft Server
。
謝謝你的閱讀,也歡迎分享討論指正~