把數(shù)據(jù)庫放入Docker是一個好主意嗎?
對于無狀態(tài)的應(yīng)用服務(wù)而言,容器是一個相當(dāng)完美的開發(fā)運維解決方案。然而對于帶持久狀態(tài)的服務(wù) —— 數(shù)據(jù)庫來說,事情就沒有那么簡單了。生產(chǎn)環(huán)境的數(shù)據(jù)庫是否應(yīng)當(dāng)放入容器中,仍然是一個充滿爭議的問題。
站在開發(fā)者的角度上,我非常喜歡Docker,并相信容器也許是未來軟件開發(fā)部署運維的標準方式。但站在DBA的立場上,我認為就目前而言,將生產(chǎn)環(huán)境數(shù)據(jù)庫放入Docker / K8S 中仍然是一個餿主意。
Docker解決什么問題?
讓我們先來看一看Docker對自己的描述。
圖片
圖片
Docker用于形容自己的詞匯包括:輕量,標準化,可移植,節(jié)約成本,提高效率,自動,集成,高效運維。這些說法并沒有問題,Docker在整體意義上確實讓開發(fā)和運維都變得更容易了。因而可以看到很多公司都熱切地希望將自己的軟件與服務(wù)容器化。但有時候這種熱情會走向另一個極端:將一切軟件服務(wù)都容器化,甚至是生產(chǎn)環(huán)境的數(shù)據(jù)庫。
容器最初是針對無狀態(tài)的應(yīng)用而設(shè)計的,在邏輯上,容器內(nèi)應(yīng)用產(chǎn)生的臨時數(shù)據(jù)也屬于該容器的一部分。用容器創(chuàng)建起一個服務(wù),用完之后銷毀它。這些應(yīng)用本身沒有狀態(tài),狀態(tài)通常保存在容器外部的數(shù)據(jù)庫里,這是經(jīng)典的架構(gòu)與用法,也是容器的設(shè)計哲學(xué)。
但當(dāng)用戶想把數(shù)據(jù)庫本身也放到容器中時,事情就變得不一樣了:數(shù)據(jù)庫是有狀態(tài)的,為了維持這個狀態(tài)不隨容器停止而銷毀,數(shù)據(jù)庫容器需要在容器上打一個洞,與底層操作系統(tǒng)上的數(shù)據(jù)卷相聯(lián)通。這樣的容器,不再是一個能夠隨意創(chuàng)建,銷毀,搬運,轉(zhuǎn)移的對象,而是與底層環(huán)境相綁定的對象。因此,傳統(tǒng)應(yīng)用使用容器的諸多優(yōu)勢,對于數(shù)據(jù)庫容器來說都不復(fù)存在。
可靠性
讓軟件跑起來,和讓軟件可靠地運行是兩回事。數(shù)據(jù)庫是信息系統(tǒng)的核心,在絕大多數(shù)場景下屬于關(guān)鍵(Critical)應(yīng)用,Critical Application可按字面解釋,就是出了問題會要命的應(yīng)用。這與我們的日常經(jīng)驗相符:Word/Excel/PPT這些辦公軟件如果崩了強制重啟即可,沒什么大不了的;但正在編輯的文檔如果丟了、臟了、亂了,那才是真的災(zāi)難。數(shù)據(jù)庫亦然,對于不少公司,特別是互聯(lián)網(wǎng)公司來說,如果數(shù)據(jù)庫被刪了又沒有可用備份,基本上可以宣告關(guān)門大吉了。
可靠性(Reliability)是數(shù)據(jù)庫最重要的屬性。可靠性是系統(tǒng)在困境(adversity)(硬件故障、軟件故障、人為錯誤)中仍可正常工作(正確完成功能,并能達到期望的性能水準)的能力??煽啃砸馕吨蒎e(fault-tolerant)與韌性(resilient),它是一種安全屬性,并不像性能與可維護性那樣的活性屬性直觀可衡量。它只能通過長時間的正常運行來證明,或者某一次故障來否證。很多人往往會在平時忽視安全屬性,而在生病后,車禍后,被搶劫后才追悔莫及。安全生產(chǎn)重于泰山,數(shù)據(jù)庫被刪,被攪亂,被脫庫后再捶胸頓足是沒有意義的。
回頭再看一看Docker對自己的特性描述中,并沒有包含“可靠”這個對于數(shù)據(jù)庫至關(guān)重要的屬性。
可靠性證明與社區(qū)知識
如前所述,可靠性并沒有一個很好的衡量方式。只有通過長時間的正確運行,我們才能對一個系統(tǒng)的可靠性逐漸建立信心。在裸機上部署數(shù)據(jù)庫可謂自古以來的實踐,通過幾十年的持續(xù)工作,它很好地證明了自己的可靠性。Docker雖為DevOps帶來一場革命,但僅僅五年的歷史對于可靠性證明而言仍然是圖樣圖森破。對關(guān)乎身家性命的生產(chǎn)數(shù)據(jù)庫而言還遠遠不夠:因為還沒有足夠的小白鼠去趟雷。
想要提高可靠性,最重要的就是從故障中吸取經(jīng)驗。故障是寶貴的經(jīng)驗財富:它將未知問題變?yōu)橐阎獑栴},是運維知識的表現(xiàn)形式。社區(qū)的故障經(jīng)驗絕大多都基于裸機部署的假設(shè),各式各樣的故障在幾十年里都已經(jīng)被人們踩了個遍。如果你遇到一些問題,大概率是別人已經(jīng)踩過的坑,可以比較方便地處理與解決。同樣的故障如果加上一個“Docker”關(guān)鍵字,能找到的有用信息就要少得多。這也意味著當(dāng)疑難雜癥出現(xiàn)時,成功搶救恢復(fù)數(shù)據(jù)的概率要更低,處理緊急故障所需的時間會更長。
微妙的現(xiàn)實是,如果沒有特殊理由,企業(yè)與個人通常并不愿意分享故障方面的經(jīng)驗。故障有損企業(yè)的聲譽:可能暴露一些敏感信息,或者是企業(yè)與團隊的垃圾程度。另一方面,故障經(jīng)驗幾乎都是真金白銀的損失與學(xué)費換來的,是運維人員的核心價值所在,因此有關(guān)故障方面的公開資料并不多。
額外失效點
開發(fā)關(guān)心Feature,而運維關(guān)注Bug。相比裸機部署而言,將數(shù)據(jù)庫放入Docker中并不能降低硬件故障、軟件錯誤、人為失誤的發(fā)生概率。用裸機會有的硬件故障,用Docker一個也不會少。軟件缺陷主要是應(yīng)用Bug,也不會因為采用容器與否而降低,人為失誤同理。相反,引入Docker會因為引入了額外的組件,額外的復(fù)雜度,額外的失效點,導(dǎo)致系統(tǒng)整體可靠性下降。
舉個最簡單的例子,dockerd守護進程崩了怎么辦,數(shù)據(jù)庫進程就直接歇菜了。盡管這種事情發(fā)生的概率并不高,但它們在裸機上 —— 壓根不會發(fā)生。
此外,一個額外組件引入的失效點可能并不止一個:Docker產(chǎn)生的問題并不僅僅是Docker本身的問題。當(dāng)故障發(fā)生時,可能是單純Docker的問題,或者是Docker與數(shù)據(jù)庫相互作用產(chǎn)生的問題,還可能是Docker與操作系統(tǒng),編排系統(tǒng),虛擬機,網(wǎng)絡(luò),磁盤相互作用產(chǎn)生的問題??梢詤⒁姽俜絇ostgreSQL Docker鏡像的Issue列表:https://github.com/docker-library/postgres/issues?q=。
正如《從降本增笑到降本增效》中所說,智力功率很難在空間上累加 —— 團隊的智力功率往往取決于最資深幾個靈魂人物的水平以及他們的溝通成本。當(dāng)數(shù)據(jù)庫出現(xiàn)問題時需要數(shù)據(jù)庫專家來解決;當(dāng)容器出現(xiàn)問題時需要容器專家來看問題;然而當(dāng)你把數(shù)據(jù)庫放入 Kubernetes 時,單獨的數(shù)據(jù)庫專家和 K8S 專家的智力帶寬是很難疊加的 —— 你需要一個雙料專家才能解決問題。而同時精通這兩者的軟件肯定要比單獨的數(shù)據(jù)庫專家少得多。
此外,彼之蜜糖,吾之砒霜。某些Docker的Feature,在特定的環(huán)境下也可能會變?yōu)锽ug。
隔離性
Docker提供了進程級別的隔離性,通常來說隔離性對應(yīng)用來說是個好屬性。應(yīng)用看不見別的進程,自然也不會有很多相互作用導(dǎo)致的問題,進而提高了系統(tǒng)的可靠性。但隔離性對于數(shù)據(jù)庫而言不一定完全是好事。
一個微妙的真實案例是在同一個數(shù)據(jù)目錄上啟動兩個PostgreSQL實例,或者在宿主機和容器內(nèi)同時啟動了兩個數(shù)據(jù)庫實例。在裸機上第二次啟動嘗試會失敗,因為PostgreSQL能意識到另一個實例的存在而拒絕啟動;但在使用Docker的情況下因其隔離性,第二個實例無法意識到宿主機或其他數(shù)據(jù)庫容器中的另一個實例。如果沒有配置合理的Fencing機制(例如通過宿主機端口互斥,pid文件互斥),兩個運行在同一數(shù)據(jù)目錄上的數(shù)據(jù)庫進程能把數(shù)據(jù)文件攪成一團漿糊。
數(shù)據(jù)庫需不需要隔離性?當(dāng)然需要, 但不是這種隔離性。數(shù)據(jù)庫的性能很重要,因此往往是獨占物理機部署。除了數(shù)據(jù)庫進程和必要的工具,不會有其他應(yīng)用。即使放在容器中,也往往采用獨占綁定物理機的模式運行。因此Docker提供的隔離性對于這種數(shù)據(jù)庫部署方案而言并沒有什么意義;不過對云數(shù)據(jù)庫廠商來說,這倒真是一個實用的Feature,用來搞多租戶超賣妙用無窮。
工具
數(shù)據(jù)庫需要工具來維護,包括各式各樣的運維腳本,部署,備份,歸檔,故障切換,大小版本升級,插件安裝,連接池,性能分析,監(jiān)控,調(diào)優(yōu),巡檢,修復(fù)。這些工具,也大多針對裸機部署而設(shè)計。這些工具與數(shù)據(jù)庫一樣,都需要精心而充分的測試。讓一個東西跑起來,與確信這個東西能持久穩(wěn)定正確的運行,是完全不同的可靠性水準。
一個簡單的例子是插件與包管理,PostgreSQL提供了很多實用的插件,譬如PostGIS。假如想為數(shù)據(jù)庫安裝該插件,在裸機上只要yum install然后create extension postgis兩條命令就可以。但如果是在Docker里,按照Docker的實踐原則,用戶需要在鏡像層次進行這個變更,否則下次容器重啟時這個擴展就沒了。因而需要修改Dockerfile,重新構(gòu)建新鏡像并推送到服務(wù)器上,最后重啟數(shù)據(jù)庫容器,毫無疑問,要麻煩得多。
包管理是操作系統(tǒng)發(fā)行版的核心問題。然而 Docker 攪亂了這一切,例如,許多 PostgreSQL 不再以 RPM/DEB 包的形式發(fā)布二進制,而是以加裝擴展的 Postgres Docker 鏡像分發(fā)。這就會立即產(chǎn)生一個顯著的問題,如果我想同時使用兩種,三種,或者PG生態(tài)的一百多種擴展,那么應(yīng)該如何把這些散碎的鏡像整合到一起呢?相比可靠的操作系統(tǒng)包管理,構(gòu)建Docker鏡像總是需要耗費更多時間與精力才能正常起效。
再比如說監(jiān)控,在傳統(tǒng)的裸機部署模式下,機器的各項指標是數(shù)據(jù)庫指標的重要組成部分。容器中的監(jiān)控與裸機上的監(jiān)控有很多微妙的區(qū)別。不注意可能會掉到坑里。例如,CPU各種模式的時長之和,在裸機上始終會是100%,但這樣的假設(shè)在容器中就不一定總是成立了。再比方說依賴/proc文件系統(tǒng)的監(jiān)控程序可能在容器中獲得與裸機上涵義完全不同的指標。雖然這類問題最終都是可解的(例如把Proc文件系統(tǒng)掛載到容器內(nèi)),但相比簡潔明了的方案,沒人喜歡復(fù)雜丑陋的work around。
類似的問題包括一些故障檢測工具與系統(tǒng)常用命令,雖然理論上可以直接在宿主機上執(zhí)行,但誰能保證容器里的結(jié)果和裸機上的結(jié)果有著相同的涵義?更為棘手的是緊急故障處理時,一些需要臨時安裝使用的工具在容器里沒有,外網(wǎng)不通,如果再走Dockerfile→Image→重啟這種路徑毫無疑問會讓人抓狂。
把Docker當(dāng)成虛擬機來用的話,很多工具大抵上還是可以正常工作的,不過這樣就喪失了使用的Docker的大部分意義,不過是把它當(dāng)成了另一個包管理器用而已。有人覺得Docker通過標準化的部署方式增加了系統(tǒng)的可靠性,因為環(huán)境更為標準化更為可控。這一點不能否認。私以為,標準化的部署方式雖然很不錯,但如果運維管理數(shù)據(jù)庫的人本身了解如何配置數(shù)據(jù)庫環(huán)境,將環(huán)境初始化命令寫在Shell腳本里和寫在Dockerfile里并沒有本質(zhì)上的區(qū)別。
可維護性
軟件的大部分開銷并不在最初的開發(fā)階段,而是在持續(xù)的維護階段,包括修復(fù)漏洞、保持系統(tǒng)正常運行、處理故障、版本升級,償還技術(shù)債、添加新的功能等等??删S護性對于運維人員的工作生活質(zhì)量非常重要。
應(yīng)該說可維護性是Docker最討喜的地方:Infrastructure as code??梢哉J為Docker的最大價值就在于它能夠把軟件的運維經(jīng)驗沉淀成可復(fù)用的代碼,以一種簡便的方式積累起來,而不再是散落在各個角落的install/setup文檔。
在這一點上Docker做的相當(dāng)出色,尤其是對于邏輯經(jīng)常變化的無狀態(tài)應(yīng)用而言。Docker和K8s能讓用戶輕松部署,完成擴容,縮容,發(fā)布,滾動升級等工作,讓Dev也能干Ops的活,讓Ops也能干DBA的活(迫真)。
環(huán)境配置
如果說Docker最大的優(yōu)點是什么,那也許就是環(huán)境配置的標準化了。標準化的環(huán)境有助于交付變更,交流問題,復(fù)現(xiàn)Bug。使用二進制鏡像(本質(zhì)是物化了的Dockerfile安裝腳本)相比執(zhí)行安裝腳本而言更為快捷,管理更方便。一些編譯復(fù)雜,依賴如山的擴展也不用每次都重新構(gòu)建了,這些都是很不錯的特性。
不幸的是,數(shù)據(jù)庫并不像通常的業(yè)務(wù)應(yīng)用一樣來來去去更新頻繁,創(chuàng)建新實例或者交付環(huán)境本身是一個極低頻的操作。同時DBA們通常都會積累下各種安裝配置維護腳本,一鍵配置環(huán)境也并不會比Docker慢多少。因此在環(huán)境配置上Docker的優(yōu)勢就沒有那么顯著了,只能說是 Nice to have。當(dāng)然,在沒有專職DBA時,使用Docker鏡像可能還是要比自己瞎折騰要好一些,因為起碼鏡像中多少沉淀了一些運維經(jīng)驗。
通常來說,數(shù)據(jù)庫初始化之后連續(xù)運行幾個月幾年也并不稀奇。占據(jù)數(shù)據(jù)庫管理工作主要內(nèi)容的并不是創(chuàng)建新實例與交付環(huán)境,主要還是日常運維的部分 —— Day2 Operation。不幸的是,在這一點上Docker并沒有什么優(yōu)勢,反而會產(chǎn)生不少的額外麻煩。
Day2 Operation
Docker確實能極大地簡化無狀態(tài)應(yīng)用的日常維護工作,諸如創(chuàng)建銷毀,版本升級,擴容等,但同樣的結(jié)論能延伸到數(shù)據(jù)庫上嗎?
數(shù)據(jù)庫容器不可能像應(yīng)用容器一樣隨意銷毀創(chuàng)建,重啟遷移。因而Docker并不能對數(shù)據(jù)庫的日常運維的體驗有什么提升,真正有幫助的倒是諸如 ansible 之類的工具。而對于日常運維而言,很多操作都需要通過docker exec的方式將腳本透傳至容器內(nèi)執(zhí)行。底下跑的還是一樣的腳本,只不過用docker-exec來執(zhí)行又額外多了一層包裝,這就有點脫褲子放屁的意味了。
此外,很多命令行工具在和Docker配合使用時都相當(dāng)尷尬。譬如docker exec會將stderr和stdout混在一起,讓很多依賴管道的命令無法正常工作。以PostgreSQL為例,在裸機部署模式下,某些日常ETL任務(wù)可以用一行bash輕松搞定:
psql <src-url> -c 'COPY tbl TO STDOUT' |\
psql <dst-url> -c 'COPY tdb FROM STDIN'
但如果宿主機上沒有合適的客戶端二進制程序,那就只能這樣用Docker容器中的二進制:
docker exec -it srcpg gosu postgres bash -c "psql -c \"COPY tbl TO STDOUT\" 2>/dev/null" |\ docker exec -i dstpg gosu postgres psql -c 'COPY tbl FROM STDIN;'
當(dāng)用戶想為容器里的數(shù)據(jù)庫做一個物理備份時,原本很簡單的一條命令現(xiàn)在需要很多額外的包裝:docker套gosu套bash套pg_basebackup:
docker exec -i postgres_pg_1 gosu postgres bash -c 'pg_basebackup -Xf -Ft -c fast -D - 2>/dev/null' | tar -xC /tmp/backup/basebackup
如果說客戶端應(yīng)用psql|pg_basebackup|pg_dump還可以通過在宿主機上安裝對應(yīng)版本的客戶端工具來繞開這個問題,那么服務(wù)端的應(yīng)用就真的無解了??偛荒茉诓粩嗌壢萜鲀?nèi)數(shù)據(jù)庫軟件的版本時每次都一并把宿主機上的服務(wù)器端二進制版本升級了吧?
另一個Docker喜歡講的例子是軟件版本升級:例如用Docker升級數(shù)據(jù)庫小版本,只要簡單地修改Dockerfile里的版本號,重新構(gòu)建鏡像然后重啟數(shù)據(jù)庫容器就可以了。沒錯,至少對于無狀態(tài)的應(yīng)用來說這是成立的。但當(dāng)需要進行數(shù)據(jù)庫原地大版本升級時問題就來了,用戶還需要同時修改數(shù)據(jù)庫狀態(tài)。在裸機上一行bash命令就可以解決的問題,在Docker下可能就會變成這樣的東西:https://github.com/tianon/docker-postgres-upgrade。
如果數(shù)據(jù)庫容器不能像AppServer一樣隨意地調(diào)度,快速地擴展,也無法在初始配置,日常運維,以及緊急故障處理時相比普通腳本的方式帶來更多便利性,我們又為什么要把生產(chǎn)環(huán)境的數(shù)據(jù)庫塞進容器里呢?
Docker和K8s一個很討喜的地方是很容易進行擴容,至少對于無狀態(tài)的應(yīng)用而言是這樣:一鍵拉起起幾個新容器,隨意調(diào)度到哪個節(jié)點都無所謂。但數(shù)據(jù)庫不一樣,作為一個有狀態(tài)的應(yīng)用,數(shù)據(jù)庫并不能像普通AppServer一樣隨意創(chuàng)建,銷毀,水平擴展。譬如,用戶創(chuàng)建一個新從庫,即使使用容器,也得從主庫上重新拉取基礎(chǔ)備份。生產(chǎn)環(huán)境中動輒幾TB的數(shù)據(jù)庫,創(chuàng)建副本也需要個把鐘頭才能完成,也需要人工介入與檢查,并逐漸放量預(yù)熱緩存才能上線承載流量。相比之下,在同樣的操作系統(tǒng)初始環(huán)境下,運行現(xiàn)成的拉從庫腳本與跑docker run在本質(zhì)上又能有什么區(qū)別 —— 時間都花在拖從庫上了。
使用Docker盛放生產(chǎn)數(shù)據(jù)庫的一個尷尬之處就在于,數(shù)據(jù)庫是有狀態(tài)的,而且為了建立這個狀態(tài)需要額外的工序。通常來說設(shè)置一個新PostgreSQL從庫的流程是,先通過pg_baseback建立本地的數(shù)據(jù)目錄副本,然后再在本地數(shù)據(jù)目錄上啟動postmaster進程。然而容器是和進程綁定的,一旦進程退出容器也隨之停止。因此為了在Docker中擴容一個新從庫:要么需要先后啟動pg_baseback容器拉取數(shù)據(jù)目錄,再在同一個數(shù)據(jù)卷上啟動postgres兩個容器;要么需要在創(chuàng)建容器的過程中就指定定好復(fù)制目標并等待幾個小時的復(fù)制完成;要么在postgres容器中再使用pg_basebackup偷天換日替換數(shù)據(jù)目錄。無論哪一種方案都是既不優(yōu)雅也不簡潔。因為容器的這種進程隔離抽象,對于數(shù)據(jù)庫這種充滿狀態(tài)的多進程,多任務(wù),多實例協(xié)作的應(yīng)用存在抽象泄漏,它很難優(yōu)雅地覆蓋這些場景。當(dāng)然有很多折衷的辦法可以打補丁來解決這類問題,然而其代價就是大量額外復(fù)雜度,最終受傷的還是系統(tǒng)的可維護性。
總的來說,Docker 在某些層面上可以提高系統(tǒng)的可維護性,比如簡化創(chuàng)建新實例的操作,但它引入的新麻煩讓這樣的優(yōu)勢顯得蒼白無力。
性能
性能也是人們經(jīng)常關(guān)注的一個維度。從性能的角度來看,數(shù)據(jù)庫的基本部署原則當(dāng)然是離硬件越近越好,額外的隔離與抽象不利于數(shù)據(jù)庫的性能:越多的隔離意味著越多的開銷,即使只是內(nèi)核棧中的額外拷貝。對于追求性能的場景,一些數(shù)據(jù)庫選擇繞開操作系統(tǒng)的頁面管理機制直接操作磁盤,而一些數(shù)據(jù)庫甚至?xí)褂肍PGA甚至GPU加速查詢處理。
實事求是地講,Docker作為一種輕量化的容器,性能上的折損并不大,通常不會超過 10% 。但毫無疑問的是,將數(shù)據(jù)庫放入Docker只會讓性能變得更差而不是更好。
總結(jié)
容器技術(shù)與編排技術(shù)對于運維而言是非常有價值的東西,它實際上彌補了從軟件到服務(wù)之間的空白,其愿景是將運維的經(jīng)驗與能力代碼化模塊化。容器技術(shù)將成為未來的包管理方式,而編排技術(shù)將進一步發(fā)展為“數(shù)據(jù)中心分布式集群操作系統(tǒng)”,成為一切軟件的底層基礎(chǔ)設(shè)施Runtime。當(dāng)越來越多的坑被踩完后,人們可以放心大膽的把一切應(yīng)用,有狀態(tài)的還是無狀態(tài)的都放到容器中去運行。但現(xiàn)在起碼對于數(shù)據(jù)庫而言,還只是一個美好的愿景與雞肋的選項。
需要再次強調(diào)的是,以上討論僅限于生產(chǎn)環(huán)境數(shù)據(jù)庫。對于開發(fā)測試而言,盡管有基于Vagrant的虛擬機沙箱,但我也支持使用Docker —— 畢竟不是所有的開發(fā)人員都知道怎么配置本地測試數(shù)據(jù)庫環(huán)境,使用Docker交付環(huán)境顯然要比一堆手冊簡單明了得多。對于生產(chǎn)環(huán)境的無狀態(tài)應(yīng)用,甚至一些帶有衍生狀態(tài)的不甚重要衍生數(shù)據(jù)系統(tǒng)(譬如Redis緩存),Docker也是一個不錯的選擇。但對于生產(chǎn)環(huán)境的核心關(guān)系型數(shù)據(jù)庫而言,如果里面的數(shù)據(jù)真的很重要,使用Docker前還是需要三思:這樣做的價值到底在哪里?出了疑難雜癥能Hold住嗎?搞砸了這鍋背得動嗎?
任何技術(shù)決策都是一個利弊權(quán)衡的過程,譬如這里使用Docker的核心權(quán)衡可能就是犧牲可靠性換取可維護性。確實有一些場景,數(shù)據(jù)可靠性并不是那么重要,或者說有其他的考量:譬如對于云計算廠商來說,把數(shù)據(jù)庫放到容器里混部超賣就是一件很好的事情:容器的隔離性,高資源利用率,以及管理上的便利性都與該場景十分契合。這種情況下將數(shù)據(jù)庫放入Docker中,也許對他們而言就是利大于弊的。但對于更多的場景來說,可靠性往往都是優(yōu)先級最高的的屬性,犧牲可靠性換取可維護性通常并不是一個可取的選擇。更何況也很難說運維管理數(shù)據(jù)庫的工作,會因為用了Docker而輕松多少:為了安裝部署一次性的便利而犧牲長久的日常運維可維護性并不是一個好主意。
綜上所述,將生產(chǎn)環(huán)境的數(shù)據(jù)庫放入容器中確實不是一個明智的選擇。