Docker Image簡單說明:含有啟動容器所需要的內核和檔案系統,
-
采用【分層構建】機制,最底層為bootfs,之上為rootfs
-
bootfs:是引導系統的檔案系統,包含bootloader和kernel,容器啟動完后,宿主機(docker deamon行程所在的機器)的會從記憶體中卸載掉bootfs,以節約資源,
從下圖可以看處來,bootfs層使用了aufs或者btrfs檔案系統,
-
rootfs:位于bootfs之上,表現為docker容器的根檔案系統,從下圖可以看出來,rootfs給我們提供了基本的根檔案系統(/bin, /var, /usr等),
- 傳統模式中,系統啟動時,內核掛載rootfs時會首先將其掛載為只讀模式,完整性自檢完成后將其重新掛載為讀寫模式,
- docker中,rootfs由內核掛載為只讀模式,而后通過【聯合掛載】技術額外掛載一個【可寫】層,
-

docker image layer:
- 下圖深藍色的鏡像都稱為父鏡像(parent image),深藍色最下層是基礎鏡像(Base Image)
- 最上層的淺藍色層為【可讀寫】層,它之下都是【只讀】層,

例子:要在Debian內核上搭建一個apache環境的話:
- 先去找一個純凈的最小的Debian image
- 讓后再在Debian image上面,堆上一個編輯器軟體 image(Emacs,或者vim)
- 然后在Emacs image上再堆上一個apache image
啟動關聯:當要啟動apache image時,必須要先啟動Debian image,再啟動Emacs image,
當某個容器啟動后,產生的臨時檔案,怎么處理?
不是docker的apache 啟動后,產生的臨時檔案一般放在/var下,但是既然是docker了,apache產生的臨時檔案就不可以寫入Debian image的/var目錄下了,理由是,這些深藍色的image層都是只讀的,并且這些深藍色image層也會讓別的軟體共同使用,所以產生的臨時檔案就寫到了淺藍色的apache container層了,
當執行了docker container rm 容器后,保存在apache container層里的臨時檔案也一并被洗掉了,
docker 的【分層構建,聯合掛載】功能,需要由專有的檔案系統支撐,
-
aufs:advanced-multi-layered unification filesystem(高級多層統一檔案系統)
-
被用于實作docker的【聯合掛載】功能,
-
aufs包裝了UnionFS,2006年由日本人Junjiro Okajima開發,但由于UnionFS本身就不好,所以aufs也很臃腫,導致linux本人一直沒有同意把aufs加入到linux的內核里,
-
docker最初使用aufs作為容器檔案系統層,目前也支持,
-
aufs的競爭產品是overlayfs,后者從3.18版本開始被加入到linux內核,
-
docker的分層鏡像,除了aufs,還支持btrfs,vfs,devicemapper等
-
新版本的docker使用的是:overlay2(抽象2級檔案系統,必須建立在某個檔案系統上)
Storage Driver: overlay2 Backing Filesystem: xfs
docker registry:
啟動容器時,docker daemon行程會試圖從本地獲取相關的鏡像,但當本地鏡像不存在時,將從Registry(默認的registry 就是docker hub)中下載該鏡像并保存到本地,
如果啟動容器時,只指定鏡像和tag的話,就默認去找docker hub,除非你指定了registry的ip地址,

-
public docker registry:默認就是docker hub,
-
private docker registry:是自己創建的registry服務,自己創建也不麻煩,可以使用由VMware提供的開源
harbor,來創建自己的registry服務,一般docker hub上的鏡像,比如nginx,拿過來是用不了的,因為配置都不一樣,所以專案上一般都是自己打成鏡像,
-
Sponsor Registry:第三方的Registry,供客戶和docker社區使用
-
Mirror Registry:第三方的registry,比如阿里的Registry
-
Vendor Registry:由發布docker鏡像的供應商提供的Registry,比如redhat給自己作業系統提供的鏡像,
docker registry包含repository和index
- repository:docker鏡像的所有迭代版本組成的鏡像倉庫,一個registry中可以有多個repository,
- repository又分為:
- 頂層倉庫:直接用image:tag來表示,比如,redis:5,
- 用戶倉庫:用戶名/倉庫名來表示,比如,user1/redis:5.
- 每個倉庫可以包含多個tag(標簽),
- repository又分為:
- index
- 維護用戶賬戶,鏡像的校驗以及公共命名空間的資訊,
- 相當于為registry提供了一個完成用戶認證等功能的檢索介面,
實際專案開發時,對docker的運用流程:
開發人員從docker hub上,下載要使用的鏡像,然后再修改它后,放入到自己公司的私有registry上;后來再由運維人員做各種環境的部署,

cloud native(云原生)大致意思:
比如從docker hub上下個redis,redis的組態檔是需要定制的,我總不能因為要改個組態檔,而從新打包個redis鏡像,所以redis組態檔的就不能寫死在redis鏡像里了,而是通過讀取系統的環境變數,來生成組態檔,這樣一來,在啟動redis容器時,就可以把你自己的配置,通過環境變數的方式傳遞給redis鏡像,從而達到修改組態檔的目的,
docker hub功能介紹:
- Image Repository:自己的私有docker image 倉庫,一般用法:從docker hub上拉一個image,然后修改,再推到這里,
- automated builders:自動構建image,當監聽到github上的 dockerfile檔案發生變化后,自動構建image,
- webhooks:是automated builders里的功能之一,當你成功提交image到自己的docker hub后,呼叫這個鉤子,
- organizations:創建一個作業組,
- github and bitbucket intergration:和github,bitbucket集成使用,
如何從docker hub以外的registry上下載image呢?
# docker pull <registry>[:port]/[<namespace>]<name>:<tag>
當從https://quay.io/ 上下載image時,使用下面的命令:
# docker pull quya.io/coreos/flannel::v0.11.0-arm64
這里省略了port,默認的port是443(https協議的埠號),
coreos是用戶倉庫,比如,user1/redis:5.
下載完成后,使用docker image ls查看的結果:發現多了【quay.io】的前綴,說明是從quay.io上下載的image,而不是從docker hub上下載的image,
REPOSITORY TAG IMAGE ID SIZE
quay.io/coreos/flannel v0.11.0-arm64 32ffa9fadfd7 53.5MB
-
namespace用法:
namespace examples organization:組織 redhat/k8s, google/k8s login(user name):用戶名 user1/app, user2/app role:角色 devel/app, test/app, prod/app
制作自己的image的方法:
1,使用dockerfile制作
2,基于容器制作
3,基于docker hub的automated builds功能制作

基于容器制作image
容器啟動后,把發生了變化的內容,打成一個image,
命令用法:
# docker container commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
OPTIONS:
Options:
-a, --author string Author (e.g., "John Hannibal Smith <[email protected]>")
-c, --change list Apply Dockerfile instruction to the created image
-m, --message string Commit message
-p, --pause Pause container during commit (default true)
舉例:先下載一個busybox image,然后在里面添加一個/data/html/index.html檔案,檔案內容:【welcome to busybox!!】執行docker container rm,再執行docker container runbusybox后,發現剛才創建的/data/html/index.html檔案沒有了,所以可以得知,沒有commit的修改再下次啟動后,就沒有了,
創建完/data/html/index.html檔案后,為了防止在commit的程序中某些東西又產生了改動,指定-p選項,告訴docker先把container暫停一下,那么我們先commit(docker container commit -p bb1)一次,不指定repository和tags看看效果,用docker image ls查看,發現多了一行none的一行,
REPOSITORY TAG IMAGE ID SIZE
<none> <none> 1e7b9d544ff6 1.22MB
說明image成功了,但是沒有repository和tag,只有個image id,
下面通過使用docker tag命令把只有image id的image加上repository和tag
# docker tag 1e7b9d544ff6 ys/busybox:local1
執行結果查看(docker image ls):repository和tag都添加上了,
REPOSITORY TAG IMAGE ID SIZE
ys/busybox local1 1e7b9d544ff6 1.22MB
可以再一個tag:docker tag ys/busybox:local1 ys/busybox:local2
結果如下:image id是相同的,所以是同一個image(鏡像),只是tag不同,版本相同,
REPOSITORY TAG IMAGE ID SIZE
ys/busybox local1 1e7b9d544ff6 1.22MB
ys/busybox local2 1e7b9d544ff6 1.22MB
tag命令用法:
# docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
檢查一下commit后的image里是否有/data/html/index.html檔案,先終止container(docker container rm),再run,發現里面有/data/html/index.html檔案,說明commit成功了,
洗掉一個tag看看,tag只是某個image的參考,洗掉掉一個tag,如果還有別tag指向這個同一個image,則image還是不會被洗掉的,tag和linux里的硬鏈接差不多,當然tag的主要作用還是表示同一個image的不同版本,所以一般每個tag對應的image id都是不同的,
到此為止,我們只是在原來的image里添加了一些檔案,如果我想改變image啟動時默認的運行程式呢?這就需要用到-c選項了,
比如我讓image啟動后運行的命令為httpd,注意CMD都是大寫,-f是讓httpd在前臺運行,-h指定html的路徑,
# docker container commit -a "ys <[email protected]>" -c 'CMD ["/bin/httpd","-f","-h","data/html"]' -p bb1 ys/busybox:local3
然后啟動ys/busybox:local3,用 docker inspect bb1查看CMD變成了:
"Cmd": [
"/bin/httpd",
"-f",
"-h",
"data/html"
],
發現IP是172.17.0.2,所以運行curl 172.17.0.2后,在控制臺列印出來的就是【welcome to busybox!!】,
測驗完我們自己打的image沒有問題了,想把這個image傳到registry上的話,怎么辦呢?
比如傳到docker hub上,
-
首先你先申請一個docker hub賬戶,比如docker hub賬戶名是ys,
-
在docker hub上創建一個repository,repository的名字必須和你在本地用docker container commit是指定的名字一樣才行,
-
在終端登錄到docker hub,使用命令
docker login,不指定[SERVER]的話,就是登錄到docker hub,# docker login [OPTIONS] [SERVER] Options: -p, --password string Password --password-stdin Take the password from stdin -u, --username string Username -
用docker image ls,確保你本地的repository的名字和你在docker hub上創建的repository的名字一樣,
-
用
docker image push [OPTIONS] NAME[:TAG],把本地的image,推送到docker hub上,# docker image push ys/busybox:v0.1執行上面的命令后,在你的docker hub上創建的ys里的tags里就有了v0.1了,
如果不指定tag,則把本地所有的tags都推送到docker hub上,
-
退出登錄:
docker logout
比如把制作好的image,上傳到阿里的registry上,
- 首先你先申請一個阿里云賬戶,
- 創建【命名空間】和【倉庫名稱】,
- 點擊創建好的倉庫行最后的【管理】,安裝里面的說明操作就可以了,
需求:在一臺機器A上打了個image,機器B也想用,可以,通過阿里云或者docker hub中轉一下,下載到機器B上,但是這樣比較麻煩,所以需要使用輕量的方法,
-
步驟1:機器A,使用docker save把image壓縮成一個檔案,
Usage: docker image save [OPTIONS] IMAGE [IMAGE...] Save one or more images to a tar archive (streamed to STDOUT by default) Options: -o, --output string Write to a file, instead of STDOUT例子:把本機的redis鏡像保存成test.gz,把這個test.gz發給機器B,
# docker image save -o test.gz redis:5 -
步驟2:機器B,使用docker load把從機器A得到的壓縮后的檔案,存盤成image檔案,
Usage: docker image load [OPTIONS] Load an image from a tar archive or STDIN Options: -i, --input string Read from tar archive file, instead of STDIN -q, --quiet Suppress the load output例子:把機器A傳過來的test.gz,做成image檔案,
# docker image load -i test.gz
c/c++ 學習互助QQ群:877684253

本人微信:xiaoshitou5854
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/102222.html
標籤:其他
上一篇:一文解讀RESTful (轉)
下一篇:排名靠前的博客
