擷取鏡像:
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