Docker的鏡像
鏡像是容器的運行基礎,容器是鏡像運行後臺的形態
鏡像的概念
鏡像是一個包含程序運行必要依賴環境和代碼的只讀文件,它采用分層的文件系統,將每一次改變以讀寫層的形式增加到原來的只讀文件上
鏡像的系統結構
鏡像的本質是磁盤上一系列文件的集合,創建新的鏡像其實也就是對已有鏡像文件的增刪查改。但鏡像之間並不是孤立,而是存在單向的文件依賴關系,如下圖中,鏡像1的FileA是鏡像2FileA的修改版本,NewFile是新創建的文件,其他文件則全部引自鏡像2
鏡像的寫時復制機制
通過docker run命令創建一個容器時,實際上是在改鏡像上創建一個空的可讀寫文件系統層,可以將這個文件系統當成一個新的臨時鏡像,而命令裏所指定的鏡像稱為父鏡像,父鏡像的內容都是以只讀的方式掛載進來。容器會讀取共享父鏡像的內容。不過一旦需要修改父鏡像文件,便會觸發Docker從父鏡像中復制這個文件到臨時鏡像中來,所有的修改均發生在你的文件系統中,而不會對父鏡像造成任何影響,這就是Docker鏡像的寫時復制機制
本地鏡像的管理
查看
通過docker images查看本機上所有的鏡像
[[email protected] ~]# docker images; REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE import latest e9757477bda9 21 hours ago 190.6 MB imported centos 4ef3250d4123 21 hours ago 190.6 MB centos 6.7 a8b4df3be85c 3 months ago 190.6 MB [[email protected]
對上述代碼結果中各個字段的解釋:
REOOSITORY:倉庫名稱。倉庫名稱用來存放同一類型的鏡像,其名稱由它的創建者指定,如果沒有指定則為<none>
關於倉庫名稱,有一下幾種形式:
- [namespace\centos]:由命令空間和實際的倉庫名稱組成,中國通過\隔開
- [centos]:只有倉庫名,對這種沒有命令空間的倉庫名,可以認為屬於頂級命名空間該空間的倉庫只用於官方的鏡像
- [dl.dockerpool.com:5000\centos:6.7]:指定url路徑的方式,如果該鏡像不是防止在Docker Hub上,而是防止在你自己搭建的或者第三方的Hub上,則使用這種命令方式
- TAG:用於區分同一倉庫中的不同鏡像,如果未指定,默認為latest
- IMAGE ID:每個鏡像都有一個字符串類型、長為64位的HashID,用來全網標識一個鏡像。改字段只展示前面一部分,因為這一部分已經足以在本機唯一標識一個鏡像了
- CREATED:鏡像的創建時間
- VIRTUAL SIZE:鏡像所占用的虛擬大小,改大小包含了所有共享文件的大小
下載
docker run 命令運行一個鏡像時,Dokcer首先會在本機尋找該鏡像是否存在,如果不存在則會在Docker Hub上搜索
同時可以通過search命令搜索符合要求的鏡像
[[email protected] ~]# docker search wordpress NAME DESCRIPTION STARS OFFICIAL AUTOMATED wordpress The WordPress rich content management syst... 1434 [OK] appcontainers/wordpress Centos/Debian Based Customizable Wordpress... 34 [OK] bitnami/wordpress Bitnami Docker Image for WordPress 20 [OK] kaihofstetter/wordpress-cli Installs a configured and ready to use Wor... 12 [OK] centurylink/wordpress Wordpress image with MySQL removed. 12 [OK] trafex/wordpress Wordpress container with Nginx 1.10 & PHP-... 3 [OK] maximiliend/wordpress A enhanced docker image of WordPress with ... 3 [OK] scjalliance/wordpress WordPress with GD and FreeType 2 [OK] dsifford/wordpress A WordPress docker environment that just w... 2 [OK] dsteinkopf/wordpress wordpress clone plus some php extensions 1 [OK] bakudankun/wordpress-ja WordPress Japanese Edition forked from off... 1 [OK] orukami/wordpress Wordpress image based on FPM and nginx. 1 [OK] momonga/wordpress wordpress with mbstring, sendmail 1 [OK] ddaishin/wordpress Wordpress日本語最新版 Xdebug OSX... 1 [OK] indiehosters/wordpress WordPress image for IndieHosters service 0 [OK] derjudge/wordpress 1:1 clone of docker-library/wordpress with... 0 [OK] deardooley/wordpress Production-ready minimal Wordpress images. 0 [OK] cuuats/wordpress Wordpress image for CUUATS websites. 0 [OK] miqueladell/wordpress Just a tailor made Wordpress. 0 [OK] ikoptiev/wordpress Official Wordpress image with max file upl... 0 [OK] rwindegger/wordpress A wordpress php-fpm backend. 0 [OK] jamesits/wordpress Docker image for WordPress/Apache/PHP7, op... 0 [OK] appeine/wordpress Container holding WordPress sources 0 [OK] svendocker/wordpress wordpress + mcrypt and recode 0 [OK] fusengine/wordpress Wordpress with php7 and nginx 0 [OK]
如果命令鏡像的名稱沒有命名空間,說明該鏡像屬於Docker Hub的官方鏡像
OFFICIAL:則表示是否為官方鏡像
如果想要下載可以通過pull命令,但是鏡像名必須是完整的包含命令空間和倉庫名,如果一個倉庫中存在多個鏡像,則需要制定TAG,否則默認的TAG為latest
刪除
對於那種不在需要的鏡像通過rmi命令刪除
如果遇到刪除不掉的情況,一般是鏡像被容器所依賴,所以可以通過-f 參數強制刪除
刪除所有的容器:docker rm $(docker ps –a -q)
創建本地鏡像
使用commit命令創建本地鏡像
先用docker run -t -i centos:6.7創建和運行一個容器,並在home目錄下新建一個文件,寫入:my name is new file 並保存
創建容器的時候記住容器的ID:076c8448ce82
然後退出容器,執行如下命令:
[[email protected] ~]# docker commit -m="Message" --author="zhaofan" 076c8448ce82 zhaofan/test:v1 ad8352f07c0e9183b57c365dfac389e1327eb23be08935e8646f3ac7f31deddb
這個時候查看之前創建的文件,發現文件還在
使用Dockerfile創建鏡像
官方推薦用Dockerfile的方式創建
將需要對鏡像的操作全部寫到一個文件中
使用docker build命令中創建鏡像
Dockerfile文件以行為單位,行首為Dockerfile命令,命令都是大寫,其後緊跟著是命令的參數
下面是一個Dockerfile文件實例:
# Version: 1.0.1 FROM ubuntu:latest MAINTAINER xxh "[email protected]" #設置root用戶為後續命令的執行者 USER root #執行操作 RUN apt-get update RUN apt-get install -y nginx #使用&&拼接命令 RUN touch test.txt && echo "abc" >> abc.txt #對外暴露端口 EXPOSE 80 8080 1038 #添加文件 ADD abc.txt /opt/ #添加文件夾 ADD /webapp /opt/webapp #添加網絡文件 ADD https://www.baidu.com/img/bd_logo1.png /opt/ #設置環境變量 ENV WEBAPP_PORT=9090 #設置工作目錄 WORKDIR /opt/ #設置啟動命令 ENTRYPOINT ["ls"] #設置啟動參數 CMD ["-a", "-l" ] #設置卷 VOLUME ["/data", "/var/www"] #設置子鏡像的觸發操作 ONBUILD ADD . /app/src ONBUILD RUN echo "on build excuted" >> onbuild.txt
FROM:指定待擴展的父級鏡像,除了註釋,在文件的開頭必須是一個FROM指令,接下來的指令便在這個父級鏡像的環境中運行,直到遇到下一個FROM指令。通過添加多個FROM指令,可以在同一個Dockerfile文件中創建多個鏡像
MAINTAINER:用來聲明創建鏡像的作者信息,這個不是必須的
RUN:用來修改鏡像的命令,常用來安裝庫,程序以及配置程序。一條RUN指令執行完畢後,會在當前鏡像上創建一個新的鏡像層,接下來的指令會在新的鏡像上繼續執行,RUN語句有兩種形式:
RUN apt-get update
RUN [ "apt-get", "update" ]
第一種形式是在/bin/bash環境下執行指定命令,第二種是直接調用exec來執行如果想要執行多個命令可以通過&&連接
EXPOSE:用來指明容器內進程對外開放的端口,多個端口之間用空格隔開
運行容器時:
通過參數 -P (大寫)即可將 EXPOSE 裏所指定的端口映射到主機上另外的隨機端口,其他容
器或主機就可以通過映射後的端口與此容器通信。同時,我們也可以通過 -p (小寫)參
數將Dockerfile中 EXPOSE 中沒有列出的端口設置成公開的
ADD :向新鏡像中添加文件,這個文件可以是一個主機文件,也可以是一個網絡文件,也可以是一個文件夾。
ADD 命令的第一個參數用來指定源文件(夾) ,它可以是文件路徑、文件夾的路徑或網絡文件的URL地址。需要特別註意的是,如果是文件路徑或文件夾路徑,它必須是相對Dockerfile所在目錄的相對路徑。如果是一個文件URL,在創建鏡像時,會先下載下來,然後再添加到鏡像裏去。第二個參數是文件需要放置在目標鏡像的位置。如果源文件是主機上zip或者tar形式的壓縮文件,Docker會先解壓縮,然後將文件添加到鏡像的指定位置。如果源文件是一個通過URL指定的網絡壓縮文件,則不會解壓。
VOLUME :該命令會在鏡像裏創建一個指定路徑(文件或文件夾)的掛載點,這個路徑可以來自主機或者其他容器。多個容器可以通過同一個掛載點共享數據,即便其中一個容器已經停止,掛載點也仍然可以訪問,只有當掛載點的容器引用全部消失時,掛載點才會自動刪除。
WORKDIR :為接下來執行的指令指定一個新的工作目錄,這個目錄可以是絕對目錄,也可是相對目錄。根據需要, WORKDIR 可以被多次指定。當啟動一個容器時,最後一條 WORKDIR指令所指的目錄將作為容器運行的當前工作目錄。
ENV :設置容器運行的環境變量。在運行容器的時候,通過 -e 參數可以修改這個環境變量值
CMD :用來設置啟動容器時默認運行的命令
CMD 參數的格式和 RUN 類似:
CMD ls -l -a
CMD [ "ls", "-l", "-a" ]
ENTRYPOINT :與 CMD 類似,它也是用來指定容器啟動時默認運行的命令。
通常情況下,我們會將 CMD 和 ENTRYPOINT 搭配起來使用。 ENTRYPOINT 用於指定需要運行的命令, CMD 用於指定運行命令所需要的參數,示例如下:
ENTRYPOINT [ "ls" ]
CMD [ "-a", "-l" ]
USER :為容器的運行及接下來 RUN 、 CMD 、 ENTRYPOINT 等指令的運行指定用戶或UID。
ONBUILD :觸發器指令。構建鏡像的時候,Docker的鏡像構建器會將所有的 ONBUILD 指令指定的命令保存到鏡像的元數據中,這些命令在當前鏡像的構建過程中並不會執行。只有新的鏡像使用 FROM 指令指定父鏡像為這個鏡像時,便會觸發執行。
通過設置 docker build 命令參數 --no-cache=true ,可以禁用緩存機制
Docker Hub
Docker Hub的網址是https://hub.docker.com
Docker Hub上的鏡像分為兩類。 一類是官方鏡像, 比如 ubuntu 、 nginx 、 redis 、 mysql 、 wordpress等,此類鏡像一般由權威的第三方(比如Canonical、Oracle、Red Hat等極具背景的大公司)進行開發維護,最後還需要Docker官方認證通過。另一類為普通用戶鏡像。
Docker的鏡像