上篇文章引入了Docker的基本原理和操做,本節文章主要介紹如何製做Docker鏡像和發佈。java
Docker鏡像的本質是一系列文件的集合,這些文件依次疊加,造成了最後的鏡像文件,相似於下圖所示的結構,linux
從底層往上,依次是文件系統層,操做系統層,專有鏡像層,讀寫層。nginx
啓動文件層:Docker啓動時的用到的文件系統,啓動完成後會自動脫離,用戶不會與這一層直接打交道。docker
操做系統層:這一層主要是操做系統相關的一些文件,根據發行版本的不一樣,可能有CentsOS、Ubuntu等等。文件包含dev,/proc,/bin,/etc 等目錄, 是一個最小化的操做系統,不少工具都沒有提供,包括vi、wget、curl等。注意這一層不包含linux內核,只是可在任何知足要求的linux內核上運行。shell
專有鏡像層:通常各大軟件都會基於上面兩層製做專有的鏡像,好比nginx、tomcat等,都有專門的官方鏡像,能夠直接在docker hub上下載。ubuntu
讀寫層:這是咱們製做本身的鏡像時須要操做的層,是一個動態的運行環境,在後續鏡像製做中的好比ENV, Volume,cmd等操做最終落實到此運行環境中。centos
製做鏡像的實質就是修改讀寫層。當須要修改鏡像內的某個文件時,只對處於最上方的讀寫層進行了變更,不復寫下層已有文件系統的內容,已有文件在只讀層中的原始版本仍然存在,但會被讀寫層中的新版本文件所隱藏,當 docker commit 這個修改過的容器文件系統爲一個新的鏡像時,保存的內容僅爲最上層讀寫文件系統中被更新過的文件。tomcat
能夠經過history命令查看鏡像層,bash
製做鏡像有兩種通用的方法,第一種是直接經過配置好的Container來生成鏡像;另一種是經過Dockerfile的方式,基於已有的鏡像來生成新的鏡像,這種方法更爲經常使用。網絡
這裏以製做nginx的鏡像爲例,介紹整個製做流程。
1)下載基礎鏡像,這裏以Ubuntu做爲基礎鏡像。因爲本地沒有鏡像能夠先利用docker search
獲取官方鏡像的名稱,而後docker pull
將鏡像下載到本地。
2)以交互方式啓動鏡像,方便在容器中安裝軟件。-it
表示交互方式,/bin/bash
爲指定啓動的終端。下圖能夠看到已經成功進入到容器內部了。
docker run -it ubuntu:latest /bin/bash
複製代碼
3)如今按照Nginx正常的安裝流程安裝便可,因爲Ubuntu鏡像只是一個最小化的系統,可能你須要經過apt-get install
來安裝一些須要的軟件。
4)退出容器,使用commit指令生成新的鏡像。
注意退出容器的時候,也有兩種方法,一般直接exit就能夠,可是這樣容器也會關閉。若是不想關閉容器,只是退出終端,可使用Ctrl+P+Q快捷鍵,此時退出後,容器依然在後臺運行。
直接運行docker commit
同時指定容器id或者name,以及鏡像名就能夠了,新的鏡像製做完成了。
docker commit e0c618df0979 ubuntu-nginx
複製代碼
接下來能夠經過正常的方式啓動鏡像了。
上面介紹了手動進入容器內部,製做Docker鏡像的方式,通常比較繁瑣。一般咱們會使用Dockerfile的方式製做鏡像,這種方式下咱們須要編寫Dockerfile文件。
Dockerfile是一個文本格式的配置文件,用戶可使用Dockerfile快速建立自定義鏡像。
下面是一個簡單的Dockerfile文件,先將編譯生成的jar文件複製到容器,而後聲明容器暴露的端口,最後指定在啓動容器時須要運行的指令。
FROM openjdk:8
ADD ["target/bazaar-1.0.0.jar", "bazaar.jar"]
EXPOSE 1234
ENTRYPOINT ["java", "-jar", "/bazaar.jar"]
複製代碼
Dockerfile中經常使用的指令集有:
比較複雜的是CMD與ENTRYPOINT的對比,二者均可以運行指令,可是稍有不一樣。
(1) CMD單獨使用
FROM debian:wheezy
CMD ["/bin/ping", "localhost"]
複製代碼
啓動後不指定任何參數,將會ping localhost,
$ docker run -it test
PING localhost (127.0.0.1): 48 data bytes
56 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.076 ms
56 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.087 ms
56 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.090 ms
^C--- localhost ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.076/0.084/0.090/0.000 ms
複製代碼
可是若是啓動容器的同時帶有新的指令,則原有的CMD會被新的指令覆蓋,
docker run -it test bash
root@e8bb7249b843:/#
複製代碼
(2)CMD和ENTRYPOINT同時使用
CMD一般用做傳遞參數給ENTRYPOINT,以下例子所示:
FROM debian:wheezy
ENTRYPOINT ["/bin/ping"]
CMD ["localhost"]
複製代碼
直接運行鏡像並不指定任何參數,將會一直ping localhost
$ docker run -it test
PING localhost (127.0.0.1): 48 data bytes
56 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.096 ms
56 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.088 ms
56 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.088 ms
^C--- localhost ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.088/0.091/0.096/0.000 ms
複製代碼
若是直接運行的同時,指定一個參數,將會ping對應的參數,此時CMD被覆蓋。
$ docker run -it test google.com
PING google.com (173.194.45.70): 48 data bytes
56 bytes from 173.194.45.70: icmp_seq=0 ttl=55 time=32.583 ms
56 bytes from 173.194.45.70: icmp_seq=2 ttl=55 time=30.327 ms
56 bytes from 173.194.45.70: icmp_seq=4 ttl=55 time=46.379 ms
^C--- google.com ping statistics ---
5 packets transmitted, 3 packets received, 40% packet loss
round-trip min/avg/max/stddev = 30.327/36.430/46.379/7.095 ms
複製代碼
若是你想要製做的容器更加通用一些,能夠在Dockerfile中使用
CMD ["/path/dedicated_command"]
,這樣你能夠在運行容器的同時,根據需求來覆蓋已有的指令。
上面介紹了Dockerfile中經常使用的指令,通常咱們寫好Dockerfile以後,直接進入到Dockerfile所在的目錄,運行docker build便可,Docker會根據Dockerfile中指定的步驟來生成咱們的鏡像。
$ docker build -t your_image_name .
複製代碼
以上就是製做鏡像的全部流程,接下來介紹鏡像的發佈。
鏡像發佈有兩種選擇,能夠直接push到官方的docker hub,你只須要註冊一個docker帳號便可;也能夠本身在本地建立私有倉庫,將鏡像push這裏。
打開 hub.docker.com/ 註冊好帳戶後,記住好本身的帳戶名,待會須要將本地的鏡像打tag帶上用戶名,而後進行push。
首先使用以下的指令就給本地鏡像打tag,
docker tag myImage:v1 your_user_name/myImage:v1
複製代碼
接下來直接push就行,會自動push到官方倉庫,注意可能會須要docker login
一下,這裏直接輸入用戶名密碼便可。
docker push your_user_name/myImage:v1
複製代碼
這樣官方倉庫就有你的Image了, 之後直接docker pull就好了。
(1) 首先下載registry鏡像:docker pull registry.
(2) 接着在5000端口啓動,docker run -d --name reg -p 5000:5000 registry.
(3) 配置http傳輸,私服默認只能使用https,須要配置開放http.
以centos上的配置爲例,
注意圖中的ip根據實際registry的ip來進行設置,能夠經過docker inspect reg來找到。
配置完畢重啓下docker服務
systemctl daemon-reload
systemctl restart docker
複製代碼
以上就完成了私有倉庫的建立。
接下來直接push Image到倉庫便可,流程和push到官方倉庫相似,只是打tag的用戶名改爲私有倉庫的地址。
(1)打tag
docker tag hello-world http://192.168.244.7:5000/hello-world
複製代碼
(2)push鏡像
docker push 192.168.244.7:5000/hello-world
複製代碼
(3)查詢鏡像:
(4)查詢鏡像版本:
以上就是鏡像製做和發佈的所有內容,下節會介紹實際部署中,docker-compose的使用以及docker的網絡通訊。
參考連接: