Docker入門筆記
序
現在,Docker應用的應該比較廣泛了,雖然在專案中已經全面應用了,但我對這個東西理解還停留在很粗淺的層面,所以這周抽晚上的時間看了下這本書《第一本Docker書-修訂版》。從書評上,這本書確然是比較初級的,但對我而言,正合適。我的看法是,如果不是真正遇到了非常特殊的問題,需要深入理解Docker內部的原理,止步於會用也並非不可,畢竟Docker完成的功能並非那麼複雜。
筆記
安裝
為什麼說這本書非常初級,那是因為它連這裡的安裝都寫的非常多——當然,這並非是我的目的。通過安裝,我們可以瞭解到,Docker是一種C/S架構,守護程序通過socket接收來自客戶端的命令。
命令列
由於Docker的流行,讓大家接納了容器的概念,但Docker其實只是對系統提供的隔離技術進行封裝,抽象成了容器。本質上還是系統提供的虛擬化技術。這些東西,這本書並沒有涉及到,有本書叫做《Docker容器與容器雲》 講的相對深刻。這本書甚至可以教你實現一個極簡化容器。
其實剛開始接觸Docker的時候,對映象和容器的關係總會有些迷惑,熟悉了可能並不覺得這是個問題。我的理解是,映象等價於硬碟上的可執行檔案,容器就是這個可執行檔案經過載入變成了執行的程序,而Docker根據映象建立容器的過程可類比OS載入這個可執行檔案的過程。
Docker提供了一系列的命令來操作映象和容器,比如建立、檢視、刪除等等。這些東西可以檢視docker的命令列文件 。
映象
在具體使用時,構建自己的映象應該是必不可少的。Docker使用Dockerfile來指定如何建立一個映象。Dockerfile在我的理解中類似構建可執行程式的Makefile,同樣都是列出來構建步驟。
一個映象包含了很多層次,每次Dockerfile中的命令提交就會形成一個新的映象,直至整個構建檔案的所有命令提交才會形成最終的映象,如果在構建的過程中出現異常,得到的是一個部分成功映象,也可以以此來建立一個容器。
映象構建成功後,Docker會為其分配一個映象ID,可以藉由這個ID來管理映象。
所以,構建容器最重要的東西就是寫一個Dockerfile,這裡面的東西也很多,可以檢視docker的Dockerfile參考文件 。
當我看這一章的時候,對CMD和ENTRYPOINT的使用有點小不解,從作用上它們都是用來指定容器啟動時的執行命令。所以兩者有共同的地方,如都可以用exec方式(用[]來包含命令)或者shell方式(直接跟命令)來執行。但肯定有不同的地方(不然就不會有兩個命令了),CMD很容易在容器啟動的時候被過載,但ENTRYPOINT就不容易(當然也有方法),所以CMD通常用來指定預設引數,而ENTRYPOINT用來指定具體的命令,這樣當ENTRYPOINT沒有指定特殊的引數時,Docker會將CMD中的引數的當作預設值傳遞到ENTRYPOINT中設定的命令。所以,兩者可以共存,而且兩者必然要有一個,哪怕是空的也可以。但兩者都不支援多個,如果有多個,後者會覆蓋前者的內容。
當映象構建完成之後,可以將其push到某個registry中,公共的registry類似Docker Hub,當然也可以構建自己的私有倉庫。這裡可以類比為程式碼寫完之後將其上傳到github。
例項
這本書中用幾個例子講解了如何在現實中使用Docker,分了幾種場景,測試用、執行具體的服務。用的比較多應該是後者,而且更多是以容器叢集的方式使用。所以Docker容器之間的聯網方式就很關鍵。
Docker提供了多種聯網方式,但比較有意義的可能就是Docker Network方式。
在安裝Docker時,會在宿主機上建立一個新的網路介面,docker0。每個Docker容器都會在這個介面上分配一個IP地址。它是一個虛擬的乙太網橋,用於連線本地宿主網路和容器。Docker每建立一個容器就會在docker0上建立一個虛擬介面,其中一端作為容器的eth0介面,另一端統一命名為vethecxxx一類的名字。所以,這有點類似於網線的兩端直連。當所有的Docker容器都連到這個虛擬的docker0介面上時,它們共同形成了一個子網。
至此,容器就可以通過docker0這個外部虛擬閘道器跟宿主機通訊,完成Docker容器的聯網問題——內部容器之間的聯網以及對外的網際網路訪問。
使用docker network create xxx可以建立一個類似docker0的虛擬網路,當有了這個網路後,基於Docker容器的叢集才能運作。而這才是容器真正的應用之處。書中舉了一個Node程式棧的例子,跟很多場景的使用方式已然差不太多了。
我對這裡的聯網理解還是比較淺薄的,後續如果有更多的需要再進一步研究吧。
編排
一個真實的專案中,容器是非常多的,所以管理這些容器,包括啟動、重啟、發現容器提供的服務等等是一件很複雜的問題。解決這一類問題的方式稱之為容器的編排。
比較常見的可能是,docker compose。所以,這個並不屬於Docker容器的基本內容,只是一種輔助工具——簡單說,沒有它容器也是可以正常執行的。
但是,有了它會更加的方便管理複雜的容器叢集及其之間的關係。
docker compose使用docker-compose.yaml檔案來管理這些容器。該檔案定義了有哪些容器,以及容器的屬性。對了,這裡還有一點忘了在上面提及,就是容器的卷。這是又一個比較重要的東西,因為映象一般都是穩定的,類似於程式本身,但資料並不穩定,而且在容器執行過程中,資料會隨時的產生或者消費,這就不能將其放到映象中。所以就有了卷這個概念,用於為容器提供一個可變資料的儲存空間。
一般在compose配置檔案中,容器的屬性類似這樣:
container-name: image: xxxxx command: xxxxx ports: - "xxx:xxx" volumes: - x:xxxx
當然不可能這麼簡單,可以參考這裡的compose參考文件 。
其他
書裡面還提及了其他內容,比如Docker API以及其他編排工具,但我覺得對於我目前的狀態並沒有太大的意義,所以沒有細看。現在看書越來越功利了!
總結
我覺得,docker可以看做是虛擬化技術的一次普及,讓之前大家少用的虛擬化變得更加的平民化,但本質上並沒有太多的新內容。