使用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來訪問這個站點,

image.png



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

 docker exec -it webserver bash

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

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

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

再次訪問nginx的站點

image.png





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

image.png

這裏爲了格式化還進行了換行。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 Dockerfileand 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







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章