1. 鏡像是什么?
2. Docker鏡像的特點
3. 容器和鏡像的轉換----Docker鏡像的 Commit操作
一. 鏡像是什么?
鏡像是一種輕量級, 可執行的獨立軟件包, 用來打包軟件運行環境和基於運行環境開發的軟件, 它包含運行某個軟件所需的所有內容, 包括代碼, 運行時, 庫, 環境變量和配置文件.
1. UnionFS: 聯合文件系統
UnionFs聯合文件系統: Union文件系統(UnionFS) 是一種分層, 輕量級並且高性能的文件系統, 它支持對文件系統的修改作為一次提交來一層層的疊加, 同時可以將不同目錄掛載到同一個虛擬文件系統下. Union文件系統是Docker鏡像的基礎, 鏡像可以通過分層來進行集成, 基於基礎鏡像(沒有父鏡像), 可以制作各種具體的應用鏡像.
特性: 一次同時加載多個文件系統, 但從外面看起來, 只能看到一個文件系統, 聯合加載會把各層文件系統疊加起來, 這樣最終的文件系統會包含所有底層的文件和目錄
2. Docker: 鏡像加速原理
docker鏡像實際上是由一層一層的文件系統組成, 這種層級就是聯合文件系統UnionFS,
bootfs(boot file system) 主要包含bootloader和kernel, bootloader主要是引導加載kernel, Linux剛啟動時會加載bootfs文件系統, 在Docker鏡像的最底層是bootfs, 這一層與我們典型的Linux/Unix系統是一樣的, 包含boot加載器和內核, 當boot加載完成之后整個內核就都在內存中了, 此時內存的使用權已有bootfs轉交給內核, 此時系統也會卸載bootfs.
rootfs(root file system), 在bootfs之上, 包含的就是典型Linux系統中的/dev, /proc, /bin, /etc等標准目錄和文件, rootfs就是各種不同的操作系統發行版, 比如Ubuntu, centos等.
平時,我們安裝進虛擬機的centOS都是好幾個G, 為什么docker里才200M?
對於一個精簡的OS, rootfs可以很小, 只需要包括最基本的命令, 工具和程序庫就可以了, 因為底層直接用Host的kernel, 自己只需提供rootfs就可以了. 由此可見,對於不同發行版本的Linux, bootfs基本是一致的, rootfs會有差別, 因此不同的發行版可以共用bootfs
這里就說明了docker為什么小而快, 就是因為他和主機功能內核.
以docker pull為例, 在下載的過程中可以看到docker鏡像是一層一層的下載.
3. 分層的鏡像
我們來看看最終下載的鏡像
發現一個問題, tomcat鏡像的大小是647M, 而centos鏡像是237M, 我們都知道centos 操作系統的鏡像怎么也要幾個G, 這里只有二百多M, 這是什么原因就不說了,上面已經解釋了. 那為什么tomcat鏡像要比centos的鏡像大呢? 原因是tomcat不是一個單獨的鏡像, 它包含了運行環境. 我們上面說了, 鏡像就像一層一層的洋蔥皮. tomcat要運行在操作系統上, 操作系統要安裝jdk,然后才能啟動tomcat. 我們來模擬這個場景
也就是說, tomcat鏡像里面, 不僅僅是有tomcat鏡像包, 它還包含了tomcat的運行環境. 所以, 可以看到tomcat下載的時候, 他會下載很多其他的鏡像. 這就是鏡像的分層
4. 為什么Docker鏡像要采用分層結構呢?
最大的好處就是---共享資源
比如: 有多個鏡像都從base鏡像構建二來, 那么宿主機只需要在磁盤上保存一份base鏡像, 同時內存中也只需要加載這一份base鏡像, 就可以為所有的容器服務了, 而且鏡像的每一層都可以被共享.
二. Docker鏡像的特點
docker鏡像都是只讀的, 一個新的可寫層被加載到鏡像的頂部, 這一層通常被稱為"容器層", "容器層"之下的都被稱為"鏡像層".
三. 容器和鏡像的轉換----Docker鏡像的Commit操作
鏡像運行, 生成容器, 容器運行生成鏡像
容器, 一定是工作在前台的守護進程****
什么意思呢? 如果docker認為當前沒有工作在前台的守護進程, 那么他會任務起來就白啟了. 那他就會自動退出
也就是說, 我們必須至少有一個運行在前台的守護進程
docker commit提交容器副本使之稱為一個新的鏡像
docker commit -m= "提交的信息描述" -a="作者" 容器Id 要創建的目標鏡像名:版本號
1. 案例1:
先來看看如果沒有后台啟動的進程, 程序是否會退出
docker run --name test docker.io/centos
剛剛啟動的容器, 果然退出了. 之前就不知道為什么啟動不起來. 原因就是, 這里沒有前台運行的守護進程. 所以, 一啟動, 就退出了
讓docker 容器在前台啟動守護進程的方法有很多. 比如 -it /bin/bash, 比如在dockerfile中添加前台運行守護進程等
docker run -it --name test docker.io/centos
比如: 加一個-it進入到客戶端.
2. 案例2:
下面我們來模擬運行tomcat
docker images tomcat
然后啟動tomcat容器
docker run -it -p 8080:8080 docker.io/tomcat
-p: 做了一個端口映射, 將本機的8080端口映射到docker 容器
這時候容器啟動了, 我們看看啟動的日志消息
我們看到這里啟動tomcat和我們平時啟動tomcat看到的日志是一樣的
我們可以從瀏覽器中訪問到: 輸入的是虛擬機的網址 192.168.198.133:8080, 可以看到tomcat的啟動頁面
接下來我們刪除tomcat訪問的文檔
進入到tomcat容器
docker exec -it 05169ce5172a /bin/bash
查看tomcat的文檔
刪除掉doc目錄
然后制作一個新的tomcat鏡像, 沒有docs文檔的tomcat
輸入命令
docker commit -m="沒有docs的tomcat" -a="lxl" 容器ID lxl/tomcat02
docker commit -m="沒有docs的tomcat" -a="lxl" 05169ce5172a lxl/tomcat02
commit命令在實戰項目中會比較有用, 這里了解一下.