天天看點

使用docker鏡像

擷取鏡像:

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鏡像

假設我們不喜歡這個頁面要改成我們定制的頁面,執行下面的指令,

 docker exec -it webserver bash      

 我們以互動式終端方式進入 webserver 容器,并執行了 bash 指令,也就是獲 得一個可操作的 Shell。

然後修改了nginx的index頁面,并退出

#echo '<h1>Hello, Docker!</h1>' >/usr/share/nginx/html/index.      
#exit      

再次通路nginx的站點

使用docker鏡像

我們修改了容器的檔案,也就是改動了容器的存儲層。我們可以通過 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可以這樣寫

使用docker鏡像

這裡為了格式化還進行了換行。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