一、Docker鏡像
Docker鏡像是啓動Docker容器的一個非常重要的組件。Docker各組件之間的關係如圖:
Docker鏡像含有啓動容器所需要的文件系統及其內容,因此Docker鏡像用於創建並啓動容器。並且Docker鏡像是採用分層構建,聯合掛載的機制實現的。那什麼是分層構建,聯合掛載呢?如圖:
在分層構建機制中,最底層爲bootfs,用於系統引導的文件系統,包括bootloader和kernel,容器啓動完成後會被卸載以節省內存資源。在bootfs之上的是rootfs,這裏就是docker容器的根文件系統,要指出的是在docker中,由內核掛載爲“只讀模式”,而後通過“聯合掛載”額外掛載一個可寫層。
例如我們需要做一個httpd的Docker鏡像,通常是在一個最小的Linux系統之上利用分層構建技術再新建一個層用來構建httpd服務。所有的寫操作都只能在writable層實現。
二、Overlayfs和Aufs
要實現分層構建需要特殊的文件系統來支持,最早是使用Aufs,但現在Docker中默認的是使用Overlayfs。
三、Docker Registry
啓動容器時,Docker daemon會試圖從本地獲取相關的鏡像;本地鏡像不存在時,其將從Registry中下載該鏡像並保存到本地,在不指定Registry時會默認指向dockerhub。Docker Registry分類:Sponsor Registry、Mirror Registry、Vendor Registry、Private Registry。
Registry是由repository和index組成。repository可分爲頂層倉庫和用戶倉庫,用戶倉庫的格式爲“用戶名/倉庫名”。鏡像的開發與維護:
四、基於容器的Docker鏡像製作示例
下面舉一個簡單的小例子:在busybox鏡像的基礎上製作一個網頁鏡像,每次啓動運行這個鏡像時,這個網頁頁面都會自動存在並運行。
1.啓動一個最小系統,如busybox,創建一個頁面:
]# docker run --name box1 -it busybox / # ls bin dev etc home proc root sys tmp usr var / # mkdir -p /data/html / # vi /data/html/index.html <h1>Hello Docker.</h1>
2.保證容器處於運行狀態,使用docker commit命令製作:
~]# docker commit -h Flag shorthand -h has been deprecated, please use --help Usage: docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]] Create a new image from a container's changes 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) #容器運行時還在不停的生成新文件,爲了完整性,可以使用這一選項。
~]# docker commit -p box1
sha256:15cb8525323f4287b2977b4f0d4809421aaab194b39985ad8f3cd32b9a721bc9
~]# docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE <none> <none> 15cb8525323f 38 seconds ago 1.2MB busybox latest 3a093384ac30 2 weeks ago 1.2MB
<none>就是剛纔製作的的鏡像,因爲沒有指定Repository名和Tag所以顯示爲<none>。爲了使用便利,也可以用 docker tag 打上標籤和Repository名:
~]# docker tag 15cb8525323f ready/httpd:v0.1 ~]# docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE ready/httpd v0.1 15cb8525323f 6 minutes ago 1.2MB busybox latest 3a093384ac30 2 weeks ago 1.2MB
啓動鏡像,可以看到文件都在:
~]# docker run --name new1 -it ready/httpd:v0.1 / # ls data/html/index.html data/html/index.html / #
3.查看docker容器啓動時默認運行的程序
用 docker inspect 命令可以查看容器啓動時默認運行的程序:
~]# docker inspect new1 ...略去... "Cmd": [ "sh" #說明啓動時默認運行的是shell
]
...略去...
~]# docker inspect nginx:1.14-alpine
"Cmd": [ "nginx", "-g", "daemon off;" #nginx必須運行在前臺,不然就代表啓動即停止 ]
用 docker commit 修改容器啓動時默認運行的程序:
~]# docker commit -a "Ready" -c 'CMD ["/bin/httpd","-f","-h","/data/html"]' -p new1 ready/httpd:v0.2
sha256:d2eee7f29cc73a7bd64487752133772be8dd69fbf6c2f0db92ff07e33bc8c5ee
-a :是指明作者,-c :是修改默認配置,上面的示例只是修改了CMD的參數。
啓動新鏡像,現在默認運行的不是shell了,所以不使用-it選項:
~]# docker container run --name new2 ready/httpd:v0.2
再啓一個終端,用curl命令就可以直接訪問這個容器的頁面了:
~]# curl 172.17.0.2 <h1>Hello Docker.</h1>
4.做好容器後就能根據需要push到容器倉庫中了
可以根據實際情況push到docker hub或者阿里雲的容器倉庫,或者其他的倉庫。
雖然這個容器中的httpd服務和網頁都已經搭建好了,但只有容器的宿主機和同一宿主機上的其他容器能夠訪問這個頁面,這是因爲容器的網卡是鏈接在宿主機上的虛擬網卡上的,如果要外部能訪問容器的網頁,需要打開宿主機Linux的核心轉發功能。