1 前言 相信不少人聽過這麼一句話: 人類的本質是復讀機。 在軟體開發領域也一樣,我們總是想尋找更好地方式複製優秀的邏輯或系統。最核心的方法是抽取通用邏輯和組件,把差異化的東西介面化或配置化,達到復用的效果。如Java的Build Once, Run Everywhere,還有Spring的強大的抽 ...
1 前言
相信不少人聽過這麼一句話:
人類的本質是復讀機。
在軟體開發領域也一樣,我們總是想尋找更好地方式複製優秀的邏輯或系統。最核心的方法是抽取通用邏輯和組件,把差異化的東西介面化或配置化,達到復用的效果。如Java
的Build Once, Run Everywhere
,還有Spring
的強大的抽象能力。這是應用層面的復用,Docker
則在系統層面作文章,讓我們可以快速複製一個系統(如CentOS)或一個服務(如Kafka)。
2 Docker的便利與優勢
利用Docker
,我們可以很快的使用別人已經建立好的鏡像來發佈一個完整的系統或某個組件。它至少提供了以下便利:
- 提供一致的運行環境。從同一個鏡像文件創建容器,應用運行環境相同,保持開發環境、測試環境和生產環境的一致。這能減少許多因環境差異和配置差異帶來的問題。測試提了Bug,開發再也不能第一時間回:是你環境沒配好吧?是你不會用吧?
- 彈性的系統。因
Docker
可快速啟動/停止,使系統能根據請求量/數據量動態的改變運行的服務數量,以提供伸縮可變的系統服務。 - 微服務開發。容器可以非常輕量級,而且可快速動態啟停,非常適用於微服務架構。一臺物理機器也能運行多個容器,不一定需要物理集群。
複製一個系統,我們可以通過增加一臺物理機,或者通過虛擬機技術運行多個系統,現在有了Docker
,還可以通過它來啟動一個系統。與其它方式相比,Docker
有以下優勢:
-
啟動速度快,秒級的啟動速度;
-
性能好,近似物理機的性能,不會有過多資源損失和性能浪費;
-
體量小,鏡像可以做得更小(MB級),不像虛擬機的幾GB;
-
跨平臺,能在Linux/Unix/Mac/Windows系統下運行;
-
利於CI/CD,有成熟的技術實踐;
-
社區活躍,有大公司背書,應用廣泛,鏡像資源豐富。
3 Docker核心概念
3.1 鏡像Image
說起鏡像,不由想起當年拿著U盤搗鼓各種系統的日子。那時會找各種系統的iso文件
,下載速度還特別慢,幾GB的文件呢。那些iso文件
,就是鏡像文件。但這些鏡像文件是相對於物理機系統或虛擬機技術而言的,而不是Docker
的鏡像文件。
對於Docker
而言,鏡像會被統一管理,在本地有特定的地方存放鏡像,不同的系統位置不一樣。一般而言,是無須自己管理鏡像文件的,Docker
會有效地管理和組織。列出所有鏡像命令如下:
docker images
或docker image ls
Docker
由鏡像啟動容器,就像通過iso文件
安裝啟動系統一樣。鏡像是通用的,因此也是可以共用的。一般我們可以通過復用別人做好的優秀鏡像來提高開發效率。我們只需要在別人鏡像的基礎上做定製開發即可。例如我們可拉取一個帶JDK
的Linux
鏡像,然後把自己的Java應用添加上去,形成自己新的鏡像。
為了提高復用率與速度,我們將鏡像分層,如下圖所示:
如鏡像B是基於鏡像A打包而成的,則鏡像B比鏡像A多一層。鏡像B包含了鏡像A的所有層級。這樣做的好處是,不用管理一個大的鏡像,而管理層級變化。假如本機已經下載了鏡像E,則本機已經有(A, B, C, E),當需要拉取F的時候,不再需要拉取(A, B)了。這利用了Docker
的緩存技術,另外,在構建新鏡像時,同樣也使用了緩存。
標簽Tag是鏡像的重要概念,一般用於標記版本號,對於同一個鏡像源名,可以有多個標簽,如redis:5.0.8
、redis:latest
,5.0.8
和latest
都是標簽名,預設使用latest
。
3.2 容器Container
有了鏡像後,就可以創建容器了。啟動一個容器,就像啟動一個進程一樣快速,可以通過docker run
命令啟動,如下:
$ docker run hello-world
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
容器提供了軟體硬體環境,會消耗物理機資源,同時它還具有狀態,相互隔離。可以從一個鏡像啟動多個不同的容器,如從Ubuntu
鏡像啟動多個Ubuntu
系統。可以通過命令docker ps
查看當前運行的容器,已經停止的容器不會顯示出來。當容器停止時,容器文件並不會消失,可以通過docker ps -a
查看所有容器。
可以簡單理解鏡像與容器的關係:
鏡像是容器的模板,是沒運行沒狀態的文件,啟動容器需要鏡像。容器是運行著的、帶狀態的相互隔離的服務。可以由一個鏡像啟動多個容器,也可以從一個容器創建一個鏡像,但這並不說明兩者是可逆的相互轉換。
3.3 倉庫Repository
倉庫很容易理解,就是存放鏡像的地方。既然鏡像是通用的,可以共用,那就需要一個共用的地方,倉庫承擔著這樣一個責任。這跟maven
、npm
等是同樣的道理。最大、最常用的倉庫當然是官方倉庫Docker Hub
,但國內訪問速度也相當感人,可以通過使用國內倉庫解決這個問題,如使用阿裡的倉庫。這跟GitHub
、maven
也是何其相似。
我們可以從倉庫拉取別人的鏡像,也可以把自己構建的鏡像推送到倉庫上。
4 總結
本次主要講解一下Docker
的概念,實踐與命令以後再一一道來。
歡迎訪問南瓜慢說 www.pkslow.com獲取更多精彩文章!
歡迎關註微信公眾號<南瓜慢說>,將持續為你更新...
多讀書,多分享;多寫作,多整理。