獲取鏡像:
docker pull [選項] [Docker Registry地址]<倉庫名>:<標籤>
Docker Registry地址: 地址的格式一般是 <域名/IP>[:端口號] 。默認地址是 Docker Hub。
倉庫名:如之前所說,這裏的倉庫名是兩段式名稱,既<用戶名>/<軟件名> 。 對於 Docker Hub,如果不給出用戶名,則默認爲library,也就是官方鏡像。
例如:
docker pull redis
默認是拉取最新版本的ubuntu鏡像,也可以用TAG來拉取指定版本的鏡像,例如:
docker pull redis:3.2
查看本地鏡像
docker images dockerREPOSITORY TAG IMAGE ID CREATED SIZE redis 3.2 e97b1f10d81a 4 weeks ago 99.7MB ubuntu latest 452a96d81c30 5 weeks ago 79.6MB
第一個字段是指鏡像來自於哪個倉庫,
TAG:標籤信息,通常用版本來定義
IMAGE ID:鏡像唯一ID號
CREATED:鏡像創建時間
SIZE:鏡像大小
搜索鏡像:默認是從官方的源中搜索鏡像信息
docker search TERM
例如:
~ docker search mysql dockerNAME DESCRIPTION STARS OFFICIAL AUTOMATED mysql MySQL is a widely used, open-source relation… 6327 [OK] mariadb MariaDB is a community-developed fork of MyS… 1987 [OK] mysql/mysql-server Optimized MySQL Server Docker images. Create… 453 [OK] percona Percona Server is a fork of the MySQL relati… 342 [OK] zabbix/zabbix-server-mysql Zabbix Server with MySQL database support 99 [OK] hypriot/rpi-mysql RPi-compatible Docker Image with Mysql 85 centurylink/mysql Image containing mysql. Optimized to be link… 60 [OK] zabbix/zabbix-web-nginx-mysql Zabbix frontend based on Nginx web-server wi… 52 [OK] 1and1internet/ubuntu-16-nginx-php-phpmyadmin-mysql-5 ubuntu-16-nginx-php-phpmyadmin-mysql-5 35 [OK] tutum/mysql Base docker image to run a MySQL database se… 32 centos/mysql-57-centos7 MySQL 5.7 SQL database server 28 mysql/mysql-cluster Experimental MySQL Cluster Docker images. Cr… 25 schickling/mysql-backup-s3 Backup MySQL to S3 (supports periodic backup… 19 [OK] bitnami/mysql Bitnami MySQL Docker Image 15 [OK] linuxserver/mysql A Mysql container, brought to you by LinuxSe… 14 zabbix/zabbix-proxy-mysql Zabbix proxy with MySQL database support 13 [OK] centos/mysql-56-centos7 MySQL 5.6 SQL database server 8 openshift/mysql-55-centos7 DEPRECATED: A Centos7 based MySQL v5.5 image… 6 circleci/mysql MySQL is a widely used, open-source relation… 5 dsteinkopf/backup-all-mysql backup all DBs in a mysql server 3 [OK] mysql/mysql-router MySQL Router provides transparent routing be… 2 openzipkin/zipkin-mysql Mirror of https://quay.io/repository/openzip… 1 cloudposse/mysql Improved `mysql` service with support for `m… 0 [OK] ansibleplaybookbundle/mysql-apb An APB which deploys RHSCL MySQL 0 [OK] cloudfoundry/cf-mysql-ci Image used in CI of cf-mysql-release 0
星級越高,排名越靠前,official字段爲OK的,表示爲官方鏡像。
刪除鏡像:
docker rmi IMAGE [IMAGE...]
參數:
-f:強制刪除鏡像,一般不建議這麼做。
使用Tag刪除鏡像
刪除一個或者多個鏡像。IMAGE可以爲鏡像Tag或者鏡像ID。例如
# docker rmi myip:v2 Untagged: myip:v2 Deleted: sha256:1faed945e9b83ac507736931bc5560dd560ac320f82a844d3bd8f864625c54c4
注意:當同一個鏡像有多個標籤時,docker rmi只會刪除該鏡像標籤中的多個標籤而已。並不影響鏡像文件。當鏡像只剩下一個標籤時,此時刪除鏡像會徹底刪除鏡像。
使用鏡像ID刪除鏡像:
當使用鏡像ID刪除鏡像時,會先嚐試刪除所有指向該鏡像的標籤,然後刪除該鏡像文件本身
但是,當鏡像創建的容器存在時,需要先刪除容器才能刪除鏡像,否則報錯。
# docker rmi myip Error response from daemon: conflict: unable to remove repository reference "myip" (must force) - container 2990105ab563 is using its referenced image b84408411f93
使用docker ps -a查看所有容器
# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6306512c14f0 ubuntu:latest "bash" 3 hours ago Exited (0) 3 hours ago loving_engelbart cab48a8a6d10 myip "bash" 3 hours ago Exited (0) 3 hours ago vibrant_bohr 0262d2bc48b4 myip "-i" 3 hours ago Created inspiring_brattain 2990105ab563 myip "curl -s http://ip.cn" 3 hours ago Exited (0) 3 hours ago xenodochial_lamport
使用docker rm 刪除容器
#docker rm 0262d2bc48b4 2990105ab563 cab48a8a6d10 0262d2bc48b4 2990105ab563
刪除鏡像:
# docker rmi myip Untagged: myip:latest Deleted: sha256:b84408411f933b1603328fc584a98b1c847d74a10908ae79adedb4c88cb83f35 Deleted: sha256:a45349740712b04c4b87f75bb9ee998cdff10f309f88f52771a295bd0185cbb4 Deleted: sha256:43d1aec07e38576af5b4eb906c0e62c389cf6bad63d50ed22db5faa985fa9f4f Deleted: sha256:0eb9547c59e758021c6ec4e519574ef615d89c6711333f06a80b957760ec5c8e Deleted: sha256:db2a6ad5636f2fb7f392af22fc561d808da37d5e47b97cebe0a568f740fed138
存出和載入鏡像:
存出鏡像:
docker save -o image_name IMAGE:TAG
用戶可以使用docker save將本地的鏡像存出,然後分享給他人,例如:
# docker save -o ubuntu_14.04.tar ubuntu:14.04 [root@OPS01-LINTEST02 ~]# ls ubuntu_14.04.tar
載入鏡像:
docker load --inpput image_name 或者 docker load < image_name
上傳鏡像:
用戶可以使用docker push命令上傳鏡像,默認是上傳到官方Dock Hub倉庫(需要註冊賬號)。
例如:用戶user上傳本地的test:latest的鏡像使用以下命令
docker push user/test:latest
使用鏡像啓動一個容器:
docker run -it --rm ubuntu bash
-it:這是兩個參數,
-i:交互式操作,-t:表示這是個終端
--rm:容器退出後隨即將其刪除,默認情況下,退出的容器不會隨即刪除,除非手動docker rm,我們這裏只是隨便 執行個命令,看看結果,不需要排障和保留結果,因此使用 --rm 可以避免 浪費空間。
查看本機上存在的容器:
docker ps -a dockerCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3b00082711a9 ubuntu "/bin/bash" 21 hours ago Exited (255) 20 hours ago nostalgic_minsky 969a66036c68 ubuntu "/bin/bash" 21 hours ago Exited (127) 21 hours ago epic_banach
虛懸鏡像:
<none> <none> 00285df0df87 5 d ays ago 342 MB
上面的鏡像列表中,還可以看到一個特殊的鏡像,這個鏡像既沒有倉庫名,也沒有標籤,均爲 <none>,
這類鏡像叫做虛懸鏡像
這個鏡像原本是有鏡像名和標籤的,原來爲 ,隨着官方鏡像維護,發 布了新版本後,重新 時, 這個鏡像名被 轉移到了新下載的鏡像身上,而舊的鏡像上的這個名稱則被取消,從而成爲了
<none> 。除了 docker pull 可能導致這種情況, docker build 也同樣可 以導致這種現象。由於新舊鏡像同名,舊鏡像名稱被取消,從而出現倉庫名、標籤 均爲 <none> 的鏡像。這類無標籤鏡像也被稱爲 虛懸鏡像(dangling image) ,可 以用下面的命令專門顯示這類鏡像
docker images -f dangling=true REPOSITORY TAG IMAGE ID CREATED SIZE <none> <none> 00285df0df87 5 days ago 342 MB
一般來說,虛懸鏡像已經失去了存在的價值,是可以隨意刪除的,可以用下面的命令刪除。
$ docker rmi $(docker images -q -f dangling=true)
列出包括中間層在內的所有鏡像:
docker images -a
列出部分(指定)鏡像:
docker iamges ubuntu
過濾鏡像:--filter 或 -f
例如:查看nginx之後建立的鏡像
# docker images -f since=nginx REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu 14.04 578c3e61a98c 6 days ago 223MB
查看nginx之前建立的鏡像
# docker images -f before=nginx:latest REPOSITORY TAG IMAGE ID CREATED SIZE centos 7 49f7960eb7e4 7 days ago 200MB centos latest 49f7960eb7e4 7 days ago 200MB centos 6 70b5d81549ec 2 months ago 195MB
定製表格的輸出格式,這是使用了GO的語法:https://gohugo.io/templates/introduction/
# docker images --format "{{.ID}}: {{.Repository}}" 578c3e61a98c: ubuntu cd5239a0906a: nginx 49f7960eb7e4: centos 49f7960eb7e4: centos 70b5d81549ec: centos
以表格等距顯示
# docker images --format "table {{.ID}}\t{{.Repository}}\t{{.Tag}}" IMAGE ID REPOSITORY TAG 578c3e61a98c ubuntu 14.04 cd5239a0906a nginx latest 49f7960eb7e4 centos 7 49f7960eb7e4 centos latest 70b5d81549ec centos 6
利用commit理解鏡像構成
我們用nginx鏡像啓動一個webserver
docker run --name webserver -d -p 80:80 nginx
run=create容器 + start容器
這條命令會用nginx容器啓動一個容器,名字爲webserver,並映射了80端口,我們可以通過訪問http://localhost來訪問這個站點,
假設我們不喜歡這個頁面要改成我們定製的頁面,執行下面的命令,
docker exec -it webserver bash
我們以交互式終端方式進入 webserver 容器,並執行了 bash 命令,也就是獲 得一個可操作的 Shell。
然後修改了nginx的index頁面,並退出
#echo '<h1>Hello, Docker!</h1>' >/usr/share/nginx/html/index.
#exit
再次訪問nginx的站點
我們修改了容器的文件,也就是改動了容器的存儲層。我們可以通過 docker diff 命令看到具體的改動。
# docker diff webserver C /run A /run/nginx.pid C /usr C /usr/share C /usr/share/nginx C /usr/share/nginx/html C /usr/share/nginx/html/index.html C /var C /var/cache C /var/cache/nginx A /var/cache/nginx/client_temp A /var/cache/nginx/fastcgi_temp A /var/cache/nginx/proxy_temp A /var/cache/nginx/scgi_temp A /var/cache/nginx/uwsgi_temp C /root A /root/.bash_history
當我們運行一個容器的時候(如果不使用卷的話),我們做的任何文件修 改都會被記錄於容器存儲層裏。
而 Docker 提供了一個 docker commit 命令,可以將容器的存儲層保存下來成爲鏡像。
換句話說,就是在原有鏡像的基礎上,再疊加上容器的存儲層,並構成新的鏡像。
以後我們運行這個新鏡像的時候,就會擁有原有容器最後的文件變化。
docker commit 的語法格式爲:
docker commit [選項] <容器ID或容器名> [<倉庫名>[:<標籤>]]
參數:
-a, --author="":指定作者
-m, --message="": 記錄修改的內容
-c, --change=[ ]:提交的時候執行Dockfile指令,包括 CMD | ENTRYPOINT | ENV | EXPOSE | LABLE | ONBUILD | USER | VOLUME | WORKDIR等
-p, --pause=true:提交時暫停容器運行
這裏我們使用下面的命令來保存鏡像
# docker commit --author "cpzeng <[email protected]>" --message "修改了index頁面" webserver nginx:v2 sha256:f270f6bb87140e2d9b84566b75d1b45443d9a7b3aba981ec414f24f38cdae7fb
查看nginx鏡像
# docker images nginx REPOSITORY TAG IMAGE ID CREATED SIZE nginx v2 f270f6bb8714 About a minute ago 109MB nginx latest cd5239a0906a 6 days ago 109MB
使用docker history 查看修改歷史,可以看到新增了我們修改的這一層,驗證了docker是分層存儲的說法
# docker history nginx:v2 IMAGE CREATED CREATED BY SIZE COMMENT f270f6bb8714 2 minutes ago nginx -g daemon off; 97B 修改了index頁面 cd5239a0906a 6 days ago /bin/sh -c #(nop) CMD ["nginx" "-g" "daemon… 0B <missing> 6 days ago /bin/sh -c #(nop) STOPSIGNAL [SIGTERM] 0B <missing> 6 days ago /bin/sh -c #(nop) EXPOSE 80/tcp 0B <missing> 6 days ago /bin/sh -c ln -sf /dev/stdout /var/log/nginx… 0B <missing> 6 days ago /bin/sh -c set -x && apt-get update && apt… 53.7MB <missing> 6 days ago /bin/sh -c #(nop) ENV NJS_VERSION=1.15.0.0.… 0B <missing> 6 days ago /bin/sh -c #(nop) ENV NGINX_VERSION=1.15.0-… 0B <missing> 6 weeks ago /bin/sh -c #(nop) LABEL maintainer=NGINX Do… 0B <missing> 6 weeks ago /bin/sh -c #(nop) CMD ["bash"] 0B <missing> 6 weeks ago /bin/sh -c #(nop) ADD file:ec5be7eec56a74975… 55.3MB
慎用docker commit
使用 docker commit 命令雖然可以比較直觀的幫助理解鏡像分層存儲的概念, 但是實際環境中並不會這樣使用。
首先,如果仔細觀察之前的docker diff webserver的結果,你會發現除了真正想要修改的/usr/share/nginx/html/index.html文件外,由於命令的執行,還有很多文件被改動或添加了。這還僅僅是最簡單的操作,如果是安裝軟件包、編譯構建,那會有大量的無關內容被添加進來,如果不小心清理,將會導致鏡 像極爲臃腫。
此外,使用 docker commit 意味着所有對鏡像的操作都是黑箱操作,生成的鏡像也被稱爲黑箱鏡像,換句話說,就是除了製作鏡像的人知道執行過什麼命令,怎麼生成的鏡像,別人根本無從得知。而且,即使是這個製作鏡像的人,過一段時間 後也無法記清具體在操作的。雖然 docker diff 或許可以告訴得到一些線索, 但是遠遠不到可以確保生成一致鏡像的地步。這種黑箱鏡像的維護工作是非常痛苦 的。
而且,回顧之前提及的鏡像所使用的分層存儲的概念,除當前層外,之前的每一層 都是不會發生改變的,換句話說,任何修改的結果僅僅是在當前層進行標記、添 加、修改,而不會改動上一層。如果使用 docker commit 製作鏡像,以及後期 修改的話,每一次修改都會讓鏡像更加臃腫一次,所刪除的上一層的東西並不會丟 失,會一直如影隨形的跟着這個鏡像,即使根本無法訪問到TM。這會讓鏡像更加臃 腫。
docker commit 命令除了學習之外,還有一些特殊的應用場合,比如被***後保 存現場等。但是,不要使用 docker commit 定製鏡像,定製行爲應該使用Dockerfile 來完成。
使用dockerfile定製鏡像
從剛纔的 docker commit 的學習中,我們可以瞭解到,鏡像的定製實際上就是 定製每一層所添加的配置、文件。如果我們可以把每一層修改、安裝、構建、操作 的命令都寫入一個腳本,用這個腳本來構建、定製鏡像,那麼之前提及的無法重複 的問題、鏡像構建透明性的問題、體積的問題就都會解決。這個腳本就是 Dockerfile。
Dockerfile 是一個文本文件,其內包含了一條條的指令(Instruction),每一條指令 構建一層,因此每一條指令的內容,就是描述該層應當如何構建。
還以之前定製 nginx 鏡像爲例,這次我們使用 Dockerfile 來定製。 在一個空白目錄中,建立一個文本文件,並命名爲 Dockerfile
#mkdir mynginx
# cd mynginx/
# vim Dockerfile
其內容爲
FROM nginx RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
FROM:指定基礎鏡像,FROM爲必備指令,並且必須爲第一條指令
除了選擇現有鏡像爲基礎鏡像外,Docker 還存在一個特殊的鏡像,名爲 scratch 。這個鏡像是虛擬的概念,並不實際存在,它表示一個空白的鏡像。
RUN:該指令用來執行命令行命令,是常用的指令之一。格式:
shell格式:RUN <command>
例如:
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
exec格式:RUN ["可執行文件", "參數1", "參數2"]
注意:每一個RUN都會在原有的鏡像基礎上新建立一層,所以不要每一個命令使用一個RUN,因爲這會產生非常臃腫、非常多層的鏡像,不僅僅增加了構建時間,而且容易出錯。
nion FS 是有最大層數限制的,比如 AUFS,曾經是最大不得超過 42 層,現在是 不得超過 127 層。
多個命令的dockerfile可以這樣寫
這裏爲了格式化還進行了換行。Dockerfile 支持 Shell 類的行尾添加 \ 的 命令換行方式,以及行首 # 進行註釋的格式。
良好的格式,比如換行、縮進、注 釋等,會讓維護、排障更爲容易,這是一個比較好的習慣。此外,還可以看到這一組命令的最後添加了清理工作的命令,刪除了爲了編譯構建 所需要的軟件,清理了所有下載、展開的文件,
並且還清理了 apt 緩存文件。這是很重要的一步,我們之前說過,鏡像是多層存儲,每一層的東西並不會在下一層 被刪除,會一直跟隨着鏡像。因此鏡像構建時,一定要確保每一層只添加真正需要 添加的東西,任何無關的東西都應該清理掉
構建之前的nginx鏡像
[root@OPS01-LINTEST02 mynginx]# pwd /root/mynginx [root@OPS01-LINTEST02 mynginx]# ls Dockerfile # docker build -t nginx:v3 . Sending build context to Docker daemon 2.048kB Step 1/2 : FROM nginx ---> cd5239a0906a Step 2/2 : RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html ---> Running in 2d5502331097 Removing intermediate container 2d5502331097 ---> ea06a30dbec1 Successfully built ea06a30dbec1 Successfully tagged nginx:v3
可以看到,先啓動一個容器,然後執行命令,完成後刪除了容器,可以看到目前有以下鏡像
# docker images nginx REPOSITORY TAG IMAGE ID CREATED SIZE nginx v3 ea06a30dbec1 2 minutes ago 109MB nginx v2 f270f6bb8714 42 minutes ago 109MB nginx latest cd5239a0906a 6 days ago 109MB
docker構建上下文
上面的命令
docker build -t nginx:v3 .
這個點表示當前目錄,而dockerfile就在當前目錄。這個點其實是在指定上下文路徑。
注意:如果把當前目錄當成上下文路徑,則寫一個點,如果不是當前目錄,在使用完整路徑或者相對路徑代替,但這個路徑一定不能少
還可以使用完整路徑這樣寫:
docker build -t nginx:v7 -f /root/mynginx/test /root/mynginx
/root/mynginx 是指上下文路徑, /root/mynginx/test是指dockerfile的文件名
下面是官網的例子
$ docker build -f Dockerfile.debug .
This will use a file called Dockerfile.debug
for the build instructions instead of Dockerfile
.
$ curl example.com/remote/Dockerfile | docker build -f - .
The above command will use the current directory as the build context and read a Dockerfile from stdin.
$ docker build -f dockerfiles/Dockerfile.debug -t myapp_debug .$ docker build -f dockerfiles/Dockerfile.prod -t myapp_prod .
The above commands will build the current build context (as specified by the .
) twice, once using a debug version of a Dockerfile
and once using a production version.
$ cd /home/me/myapp/some/dir/really/deep$ docker build -f /home/me/myapp/dockerfiles/debug /home/me/myapp$ docker build -f ../../../../dockerfiles/debug /home/me/myapp
These two docker build
commands do the exact same thing. They both use the contents of the debug
file instead of looking for a Dockerfile
and will use /home/me/myapp
as the root of the build context. Note that debug
is in the directory structure of the build context, regardless of how you refer to it on the command line.
官網參考連接:https://docs.docker.com/engine/reference/commandline/build/#specify-a-dockerfile--f