開篇
提起Docker,有很多人第一印象會認為它就是一個虛擬化容器,所以大家特別容易陷入到一種誤區,就是覺得Docker只是在Linux作業系統之上又增加了一層,就跟OS上跑了一個VMWare一樣,Docker一定變得又慢又復雜,還不如原生安裝的服務看起來舒服,
實際上這是誤區,Docker管理的各種服務,都是作業系統原生的行程,并不是一個虛擬化產物,它的正確定義是應用容器引擎,
那怎么去理解這個應用容器引擎呢?就要說說Docker的核心原理了——其中主要機制之一,通過Linux的namespace機制實作了資源隔離,這個資源隔離就包括了:
- UTS,對主機名和域名的隔離
- IPC,對信號量、訊息佇列和共享記憶體的隔離
- PID,對行程編號的隔離
- Network,對網路設備、網路協議堆疊、網路埠對隔離
- Mount,對掛載點(檔案系統)的隔離
- User,對用戶和用戶組的隔離,
這些隔離機制都是Linux內核的namespace機制實作,也是Docker容器設計的精髓,
就好像原來是一個300平米的大house,就住著一家人,臥室、廚房、衛生間這一家人獨享,可是房子太大完全可以住三個家庭,不僅能公攤一部分費用,還能為主家帶來額外的收益,那么就要對這個大house重新進行規劃設計,滿足三個家庭的需要,制定一些生活制度,有些資源是可以共享的,但關鍵資源就必須隔離開,保護隱私嘛!其實大家說到底還是在一個大房子內平等的生活,
用了這個比喻其實就是告訴大家,你就把Docker理解為一個房子多個家庭的規劃安排包租婆,Docker管理了很多的容器服務,容器服務就是在宿主機上跑著的,例如MySQL、Nginx、微服務等等都是容器服務,大家都是在一個OS上平等的運行著,只不過進了自己房間,你對別人房間的情況就一無所知了,那么這不僅保護了各個服務之間不會產生對資源爭用,而且還能根據預先入戶的協議,分配好CPU、記憶體、磁盤的容量,這樣大家住在一起也是明明白白的,誰也不能沾了誰的便宜,當然了對外的網路埠還是需要各家分配不同的,
有了這個本事,你就能在有限的云資源上跑很多服務啦!我自己做的公司網站跑在阿里云的ECS CentOS7,就跑了三個Docker容器:Nginx、MySQL、Wordpress,我才給分配了512M記憶體,夠摳門吧,但是運行地妥妥的,只是物理記憶體是在太小,有時候重啟服務,OS報記憶體資源就不夠了,必須把Docker也重啟,清空一下記憶體就好了,
我給當時老東家的兩個互聯網平臺產品用了三臺ECS性能不錯的服務器,4核,16G記憶體,足足跑了50多個微服務和其他基礎服務,真的是把資源榨得是干干凈凈,關鍵還有服務日志隔離、環境變數隔離、全域配置隔離等待,好處實在太多了,關鍵對我們產品在互聯網架構上的Devops提供了良好的基礎支撐,我可以在一臺虛擬機上跑兩套微服務,一套生產、一套測驗,測驗好的微服務升級版本號,變成新的生產微服務,老的微服務進入過渡替換期,詳見:構建互聯網醫療平臺的Devops應用架構
問題集錦
1. Docker必須聯網嗎?
連接互聯網不是必要的,可以內部搭建Docker Registry服務,我曾經就是在阿里云的多臺機器的其中一臺做了Registry服務,然后讓其他機器通過內網的5000埠訪問就可以了,記得給每臺服務器的docker服務都配置一下都不走SSL,
我們也只有遠程發布才讓自己的開發客戶端,訪問Nginx的HTTP SSL埠,反向代理到Registry倉庫,那么就需要在服務端裝一個Docker版的nginx,因為公網盡量走HTTPS,如下圖所示:
關于內網怎么裝Docker的問題,你需要先找一個能上網的機器,通過docker hub做好你自己的Docker images,最好會dockfile怎么做,這是個腳本技術,主要有一些本地化和引數優化需要再做一下Docker images,然后Docker push到內網私有register服務倉庫就可以了,其他內網機器只要Docker pull命令,就可以使用你制作的Docker images了,
windows系統下開發,就下載安裝windows的Docker desktop使用和mac版本一樣,
2. Docker里面的程式如何實作熱更新?
用Dockerfile構建一個鏡像,并生成了一個容器來運行程式,現在程式代碼發生了變更,想要實作熱更新如何實作呢?
一般Docker更新的方式,都是pull下來新的images,然后重啟容器,當然也有一些討巧的辦法,通過對Docker內的發布程式目錄鏡像到本地目錄,那么每次只上傳程式包,更新服務器本地目錄之后再進行Docker重啟,這種方式免去了Docker體量太大,上傳慢的問題,
但是這些都需要重啟容器,不算真正意義上的熱更新,在線業務系統往往允許的抖動時長會很嚴苛,而且即便是Docker鏡像在測驗環境都已經測驗的沒有問題了,放到生產服務器上也不能沒有經過驗證就直接替換,若是web系統,我建議用api網關+docker-compose+多版本運行的方式來實作熱更新,而且這也會使得升級抖動的影響降到最低,如下圖所示:T 為測驗,P為生產,v1、v2就是docker-compose的多版本發布,通過API網關重定向微服務新版本跳轉,實作最小升級抖動,
具體意思我簡要說一下,就是讓docker-compose作為你的應用發布的整體,這樣無論是微服務也好,單體應用也好,就都統一作為一個單元部署管理了!
然后對需要更新的新版本程式,發布出新版本的docker-compose,QA驗證無誤后,再由api網關實作動態切換,Docker熱更新的大體思路就是這樣,
3. Docker掛載資料卷的時候映射檔案會出現不同步?
學習Docker的時候發現 映射redis.conf 會出現這種情況 難道一定要先從容器中拷貝一份再運行yml嗎
Docker映射組態檔的時候,一定是先要有這個檔案,記住,而不是等其內部會創建這個檔案,否則它只會創建出目錄,
因此Docker映射檔案不存在就走映射目錄了,
所以第一種方式:是組態檔已經存在,也就是自己上傳到服務器自定義配置目錄,然后Docker直接映射過去,這時候映射檔案或者映射目錄一個道理,
第二種方式:配置目錄映射到自定義目錄,容器運行程序腳本自動化寫入,那么配置目錄的各項檔案就需要在容器初始化程序中,由腳本對鏡像內的打包組態檔完成寫入,
其實我做過一個Redis的優化過的生產級的Docker,走的是第一種方式,需要你自己上傳一下配置,可以看看我的gitee源代碼倉庫,gitee倉庫也就做了這一個面向Redis中文化、性能調參過的dockerfile以及組態檔,·在gitee中搜索“讀位元組” 有個我寫得不錯的單機版Redis Dockerfile檔案,里面對性能做過優化,大家可以用來學習,
結束語
總之在目前Kubernetes如日中天的時代,我們有時候要冷靜思考一下,到底我們有必要搞得那么復雜嗎?難道Docker還不夠用嗎?如果配合上Portainer這種在線免費的Docker管理工具,能讓你的云上服務群管理的很好,
但是有一點是有門檻的,那就是玩Docker一定要不斷歷練自己的Linux能力,包括腳本撰寫能力,因為有些Docker Images并不能按照你的實際環境滿足你的使用需求,需要自建Dockerfile,我就在以前的工程中配合Maven撰寫了自己的Dockerfile和Shell腳本,微服務從打包到發布,一氣呵成,而且可以靈活去選擇哪個微服務進行更新,這就真的需要深刻的去理解Linux了,
這些都并不是說會用Docker就夠了,實際上面對更復雜的K8s,熟悉Linux這個問題一樣是繞不過去的,因此還是關鍵的那一步,容器時代,用好容器引擎是從簡單的Docker開始,并且在搞定程式之外歷練自己的Linux功力,你的技術將提升得更快!
可以閱讀另一篇關于分布式和大資料技術的詳細文章:
“大資料殺熟”到呼叫的是什么演算法模型,如何監管?
前往讀位元組創作中心——了解”讀位元組“更多創作內容

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/286003.html
標籤:架構設計
