新的一年,如果我們對(duì)信息技術(shù)領(lǐng)域有所留意的話,就會(huì)發(fā)現(xiàn)“containers”
和
“Docker”
成為了熱詞。在每個(gè)地方,我們都會(huì)將開發(fā)好的軟件打包放入
Docker容器
,到處使用容器。從小型創(chuàng)業(yè)企業(yè)到大型微服務(wù)平臺(tái);從CI
(
Corporate Identity
)平臺(tái)到樹莓派的研發(fā);從數(shù)據(jù)庫(kù)管理系統(tǒng)到
……
你說什么?確定在產(chǎn)品級(jí)的項(xiàng)目中要將數(shù)據(jù)庫(kù)放到容器內(nèi)嗎?真的假的!遺憾之處在于這就是事實(shí)。我見過很多快速成長(zhǎng)的項(xiàng)目將持久化的數(shù)據(jù)放到容器內(nèi)。不僅如此,在同一臺(tái)主機(jī)上還部署了計(jì)算服務(wù)!不幸中的萬幸是有識(shí)者不會(huì)這樣做,但很多新手都是這么干的。
下面我要拋出自己的觀點(diǎn),回答“
為什么
”
不要這樣做。注意,所談?wù)摰囊磺卸蓟诋?dāng)前,即
2017
年
01
月
29
日當(dāng)前的狀況。我們也看到過一些項(xiàng)目,研究如何在
Docker
中安全地管理數(shù)據(jù)庫(kù)。但是,目前數(shù)據(jù)庫(kù)容器化完全是不合理的。
下面,我來逐一闡述其中的原因!共有7
大理由:
1.?dāng)?shù)據(jù)不安全
從“Banned from DBA”
這部分開始,
Docker in Production: A History of Failure
這篇文章中關(guān)于Docker
的觀點(diǎn)完全正確。即使是把
Docker
的
volume
創(chuàng)建在了數(shù)據(jù)原有的目錄,也不能說就有了什么保障。沒錯(cuò),
Docker
的
volume
被設(shè)計(jì)成與聯(lián)合文件系統(tǒng)(
Unions FS
)鏡像層一起,提供持久化存儲(chǔ)功能。但這并不意味著能得到什么保障。
目前Docker
的存儲(chǔ)機(jī)制仍然是不可靠的。一旦數(shù)據(jù)庫(kù)未正確關(guān)閉而引發(fā)容器崩潰,數(shù)據(jù)就亂了,就會(huì)將服務(wù)最重要的部分丟失掉。
2.特定的資源需求
我看到過運(yùn)行在同一主機(jī)的DBMS
容器作為服務(wù)層容器。但這些服務(wù)層的容器與硬件需求并不兼容。
數(shù)據(jù)庫(kù),特別是關(guān)系型數(shù)據(jù)庫(kù),都需要額外的資源。這包括內(nèi)存、磁盤I/O
等。通常我們把數(shù)據(jù)庫(kù)引擎專門用來避免資源并發(fā)的情況出現(xiàn)。將數(shù)據(jù)庫(kù)放到容器內(nèi),會(huì)是一種浪費(fèi)項(xiàng)目經(jīng)費(fèi)的行為。為啥呢?因?yàn)檫@種做法是將許多額外的資源放到了一個(gè)單一的實(shí)例,這會(huì)導(dǎo)致無法控制的局面。在云平臺(tái)中,如果運(yùn)行實(shí)例需要
34G
的內(nèi)存資源,那我們就要?jiǎng)?chuàng)建
64G
的內(nèi)存空間。而實(shí)際上很多這些資源是用不上的。
如何去解決這樣的問題呢?我們可以把這些層分開,然后綁定固定資源的實(shí)例。橫向擴(kuò)展總是優(yōu)于縱向擴(kuò)展,基本就是這樣的。
3. 網(wǎng)絡(luò)問題
要理解Docker
的網(wǎng)絡(luò)部分,就必須對(duì)網(wǎng)絡(luò)虛擬化有深刻的認(rèn)識(shí)。并準(zhǔn)備好處理意料之外的情況發(fā)生。還可能被環(huán)境所迫在沒有幫助的情況下修復(fù)
bug
,或者為了徹底修復(fù)而使用額外的工具。
我們知道,數(shù)據(jù)庫(kù)為了更高的負(fù)載需要特定且持續(xù)的吞吐量,還知道容器是hypervisor
和虛擬主機(jī)之后更獨(dú)立的一層。還有網(wǎng)絡(luò)對(duì)數(shù)據(jù)的復(fù)制來說也至關(guān)重要。復(fù)制需要
7x24
小時(shí)不間斷的網(wǎng)絡(luò)連接。當(dāng)然,還有
Docker
自身存在的網(wǎng)絡(luò)問題,自從
Docker 1.9
以后還未解決的問題。
將上面這些問題匯總起來,我們可以斷定,數(shù)據(jù)庫(kù)容器是不容易被管理的。如果再加上網(wǎng)絡(luò),就會(huì)變得非常困難。盡管你是頂尖的工程師,從不知道什么叫“
困難
”
和
“
不可能
”
。但是解決
Docker
的網(wǎng)絡(luò)問題你要花費(fèi)多長(zhǎng)時(shí)間?而將數(shù)據(jù)庫(kù)放到特定的環(huán)境,抓緊時(shí)間聚精會(huì)神去做真正重要的事情不是更好嗎?
4. 運(yùn)行環(huán)境的狀態(tài)屬性
使用Docker
的時(shí)候,我們時(shí)常遇到
“
無狀態(tài)
”
這個(gè)熱詞。順便提一下,你知道現(xiàn)在的熱詞都有哪些嗎?別告訴我還是
“DevOps”
!
在Docker
中將無狀態(tài)的服務(wù)打包是件很酷的事情,把這些服務(wù)放到一起,不再關(guān)注單點(diǎn)的失敗。那數(shù)據(jù)庫(kù)呢?把數(shù)據(jù)庫(kù)放到相同的環(huán)境中,這樣就變成了有狀態(tài)的。我們將應(yīng)用可能失敗的可能性加大了。下次應(yīng)用實(shí)例或應(yīng)用程序本身崩潰的時(shí)候,很可能就要觸及整個(gè)數(shù)據(jù)庫(kù)的工作流程了。
5. 與Docker的主要功能特性不相匹配
就算我對(duì)Docker
一無所知,還是學(xué)校里一位無足輕重的系統(tǒng)管理員,并不關(guān)心商業(yè)價(jià)值和創(chuàng)新。但我們考慮容器中的數(shù)據(jù)庫(kù),必須要評(píng)估其價(jià)值和收益。
Docker
的實(shí)質(zhì)是什么,我們來看看官方的說法:
Docker
是為開發(fā)人員和系統(tǒng)管理人員開發(fā)、裝載和運(yùn)行分布式應(yīng)用程序的開放平臺(tái)。由
Docker Engine
和
Docker Hub
兩個(gè)部分組成,
Docker Engine
是輕量級(jí)的實(shí)時(shí)運(yùn)行的打包工具,
Docker Hub
為應(yīng)用程序的共享和工作流的自動(dòng)化提供云服務(wù)。
Docker
能夠快速裝配組件狀態(tài)的應(yīng)用程序,并消除開發(fā),測(cè)試和產(chǎn)品環(huán)境之間的差異。因此,
IT
人員無須作任何修改,就可以更加快捷地在筆記本、數(shù)據(jù)中心虛擬機(jī)和任何云端裝載并運(yùn)行同樣的應(yīng)用程序。
根據(jù)上述說法,我們就可以輕松地對(duì)Docker
的價(jià)值給出定義:
·
易于安裝軟件;
·
易于重復(fù)部署(持續(xù)集成);
·
易于橫向展(此條來源于實(shí)踐);
·
易于保持各個(gè)環(huán)境的平等地位。
接下來我們考慮一下,這些功能特性如何與數(shù)據(jù)庫(kù)相匹配。易于安裝數(shù)據(jù)庫(kù)?在運(yùn)行時(shí)與數(shù)據(jù)庫(kù)有什么特別不同之處嗎?
docker run -d mongod:3.4
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.
com:80 --recv 0C49F3730359A14518585931BC711F9BA15703C6
echo"deb [ arch=amd64,arm64 ] http://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.4 multiverse" | sudo tee /etc/apt/sources.
list.d/mongodb-org-3.4.
list
sudo apt-get
update && sudo apt-get install -
y mongodb-org
如果拿MongoDB
集群舉例,那么集群的配置管理(
Configuration Management
)系統(tǒng)會(huì)是什么情況呢?配置管理系統(tǒng)被設(shè)計(jì)成執(zhí)行一條命令就可以完成例行的程序。就拿
MongoDB
的安裝來說,
Ansible
模塊可以用在十幾個(gè)實(shí)例上。無論怎么樣,開發(fā)自己喜歡的配置管理系統(tǒng)就可以。我們可以了解到,這并不像火箭科學(xué)那樣,并不能帶來太多的價(jià)值。
易于重復(fù)部署?為了升級(jí)將數(shù)據(jù)庫(kù)升級(jí)到下一個(gè)版本而重新部署數(shù)據(jù)庫(kù)的頻度有多大?即使集群存在適用性(usability
)的問題,但數(shù)據(jù)庫(kù)升級(jí)不屬于此類問題,而屬于工程問題。思考一下,我們的應(yīng)用程序如何與新版的數(shù)據(jù)庫(kù)引擎協(xié)同工作,數(shù)據(jù)庫(kù)引擎發(fā)生變化時(shí)會(huì)產(chǎn)生哪些破壞性的影響,這才是更有價(jià)值的思考。而
Docker
是無法解決這些問題的。
易于水平擴(kuò)展?我們是否要在很多不同實(shí)例之間共享數(shù)據(jù)目錄?難道不怕直接發(fā)生數(shù)據(jù)并發(fā)和可能發(fā)生的數(shù)據(jù)崩潰?不是在特定的數(shù)據(jù)環(huán)境下部署多個(gè)實(shí)例更安全嗎?還有最后去完成主從服務(wù)的復(fù)制。
易于保持各環(huán)境的平等地位?數(shù)據(jù)庫(kù)實(shí)例環(huán)境發(fā)生變化的頻度有多大?我們每天都升級(jí)操作系統(tǒng)嗎?也許數(shù)據(jù)庫(kù)的版本或依賴軟件就像類庫(kù)和模塊一樣的形式存在呢?與工程團(tuán)隊(duì)保持一致豈不是更容易嗎?
我們就當(dāng)這些說法都成立。但是是否存在這種可能性,“
蹩腳
”
的工程師不遵守規(guī)則,堅(jiān)持要使用不同版本的數(shù)據(jù)庫(kù)進(jìn)行開發(fā)?或者
“
出色
”
的工程師遵守規(guī)則但難于理解使用什么?我想對(duì)于上述后兩個(gè)問題是這樣。
Docker
并不是解決環(huán)境平等地位問題的有效解決方案。
至此,與數(shù)據(jù)庫(kù)容器化相關(guān)的所有功能特性都被梳理了一遍。
6. 數(shù)據(jù)庫(kù)層特有的隔離狀態(tài)極為重要
實(shí)際上,我在上述第二條和第三條的理由中已經(jīng)表明了這一觀點(diǎn)。但我把它單獨(dú)作為一個(gè)主題是因?yàn)橄朐俅沃厣暌槐?。被隔離的層級(jí)越多,我們獲取資源就越容易??梢垣@得如此多的收益而不限于特定的環(huán)境并不是個(gè)問題。但是在Docker
中,這些功能特性存在于無狀態(tài)的服務(wù)中,而不適用于數(shù)據(jù)庫(kù)。
在數(shù)據(jù)庫(kù)當(dāng)中并沒有看到任何具有隔離屬性的功能特性。因此,我們又何必將數(shù)據(jù)庫(kù)放到容器中呢?
7. 與云平臺(tái)不兼容
我們當(dāng)中的大多數(shù)人已經(jīng)開始使用云平臺(tái)做項(xiàng)目了。云平臺(tái)可以對(duì)虛擬機(jī)進(jìn)行編排,實(shí)現(xiàn)彈性資源調(diào)度。例如,在夜間或周末無人值守的時(shí)候,為什么需要測(cè)試(testing
)環(huán)境和上先前(
staging
)的環(huán)境?我們能夠啟動(dòng)另一個(gè)有著相同配置和服務(wù)啟動(dòng)進(jìn)程的實(shí)例時(shí),為什么還會(huì)擔(dān)心目前正常運(yùn)行的實(shí)例?
這就是云平臺(tái)主要的功能特性,也是我們向云服務(wù)商付費(fèi)的原因。當(dāng)把實(shí)例放到數(shù)據(jù)庫(kù)容器當(dāng)中后,云平臺(tái)的這個(gè)功能特性就不存在了。由于數(shù)據(jù)不匹配,放到容器當(dāng)中的實(shí)例與原有的實(shí)例不兼容。因此,我們會(huì)限制于只使用單個(gè)的物理機(jī),也不會(huì)存在虛擬機(jī)編排的事情。數(shù)據(jù)庫(kù)最好使用非容器化的環(huán)境。虛擬機(jī)的編排和自動(dòng)擴(kuò)展只放在計(jì)算服務(wù)層去完成。
所有數(shù)據(jù)庫(kù)都存在同樣的問題嗎?
并不是所有的數(shù)據(jù)庫(kù)都存在同樣的問題。這些問題只存在于數(shù)據(jù)需要持久化的情況下。并且還要與特定資源需求相關(guān)的數(shù)據(jù)庫(kù)才存在這樣的問題。
如果拿Redis
來做緩存或者會(huì)話數(shù)據(jù)的存儲(chǔ),就不存在這樣的問題。由于這些數(shù)據(jù)不需要存儲(chǔ)在硬盤上,因而也就不存在數(shù)據(jù)丟失的風(fēng)險(xiǎn)。但如果我們拿
Redis
用作持久化的數(shù)據(jù)存儲(chǔ),那就最好將數(shù)據(jù)庫(kù)放在容器之外。即使我們不斷獲得了
RDB
快照文件,在不斷快速變化的計(jì)算集群中找到快照也是一件復(fù)雜的事情。
我們也可以談?wù)勅萜髦械?/span>ES
(
ElasticSearch
)搜索引擎。在
ES
中,可能只存儲(chǔ)索引,并從持久化的數(shù)據(jù)源中不斷重復(fù)構(gòu)建索引。別忘了我們對(duì)特定資源的需求!默認(rèn)情況下,
ES
需要占用
2~3GB
內(nèi)存空間。內(nèi)存是非持久化的,用作
Java
垃圾回收階段。我們能夠確定
ES
就是解決特定資源限制最好的容器嗎?根據(jù)硬件的不同情況安排為
ES
組織不同的實(shí)例不是更好嘛?
本地的開發(fā)環(huán)境就不用擔(dān)心了。在本地開發(fā)環(huán)境中將數(shù)據(jù)庫(kù)放到容器中會(huì)節(jié)省很多時(shí)間和力氣。在產(chǎn)品環(huán)境中也是一樣。要知道OS X
或
Windows
系統(tǒng)下原生的
PostgreSQL
都不會(huì)百分百地與
Linux
版本兼容。所以構(gòu)建起容器代替在主機(jī)系統(tǒng)上直接部署可以彌補(bǔ)這點(diǎn)不足。
結(jié)論
與Docker
相關(guān)的大肆宣傳終將落幕,但這并不意味著人們會(huì)停止使用容器虛擬化技術(shù)。而是意味著人們開始正確地使用容器,并將其使用價(jià)值放在首位。
幾天前,我觀看了有關(guān)Ruby
架構(gòu)的精彩對(duì)話,并從中指出無關(guān)
Ruby
本身而與技術(shù)炒作周期相關(guān)的看法。通過這個(gè)炒作周期我們看到
Docker
正處在第二階段,也就是膨脹預(yù)期的頂峰,已經(jīng)很久了。在最后階段我們會(huì)看到這種情況會(huì)趨于正?;?。我覺得我們要認(rèn)真負(fù)責(zé)地對(duì)待這樣的過程,甚至有必要加速該過程的發(fā)展。
來源:CSDN