天天看點

Docker 入門之鏡像&容器下面介紹一下容器

先介紹一下鏡像

1.從docker  registry 擷取鏡像

docker pull [選項] [Docker Registry 位址[:端口号]/]倉庫名[:标簽]
           
  • Docker 鏡像倉庫位址:位址的格式一般是 

    <域名/IP>[:端口号]

    。預設位址是 Docker Hub。
  • 倉庫名:如之前所說,這裡的倉庫名是兩段式名稱,即 

    <使用者名>/<軟體名>

    。對于 Docker Hub,如果不給出使用者名,則預設為 

    library

    ,也就是官方鏡像。

不指定tag會pull latest版

Docker 入門之鏡像&amp;容器下面介紹一下容器

從下載下傳過程中可以看到我們之前提及的分層存儲的概念,鏡像是由多層存儲所構成。下載下傳也是一層層的去下載下傳,并非單一檔案。下載下傳過程中給出了每一層的 ID 的前 12 位。并且下載下傳結束後,給出該鏡像完整的 

sha256

 的摘要,以確定下載下傳一緻性。

想運作容器docker  run  ubuntu:18.04 就行。但是最好加一些參數

docker run -it --rm ubuntu:18.04 bash       進去 cat /etc/os-release 查ubuntu的參數  exit 退出互動式bash

docker  run就是運作容器的指令,這裡簡要的說明一下上面用到的參數。

  • -it

    :這是兩個參數,一個是 

    -i

    :互動式操作,一個是 

    -t

     終端。我們這裡打算進入 

    bash

     執行一些指令并檢視傳回結果,是以我們需要互動式終端。
  • --rm

    :這個參數是說容器退出後随之将其删除。預設情況下,為了排障需求,退出的容器并不會立即删除,除非手動 

    docker rm

    。我們這裡隻是随便執行個指令,看看結果,不需要排障和保留結果,是以使用 

    --rm

     可以避免浪費空間。
  • ubuntu:18.04

    :這是指用 

    ubuntu:18.04

     鏡像為基礎來啟動容器。
  • bash

    :放在鏡像名後的是 指令,這裡我們希望有個互動式 Shell,是以用的是 

    bash

進入容器後,我們可以在 Shell 下操作,執行任何所需的指令。這裡,我們執行了 

cat /etc/os-release

,這是 Linux 常用的檢視目前系統版本的指令,從傳回的結果可以看到容器内是 

Ubuntu 18.04.1 LTS

 系統。

最後我們通過 

exit

 退出了這個容器。

2.擷取鏡像清單

docker images 或者  docker  image  ls

Docker 入門之鏡像&amp;容器下面介紹一下容器

在docker  hub中看到的 鏡像要比在這小,是因為  docker hub 中是壓縮檔案,在docker pull的過程中為了節省流量。

而 pull 下來後是解壓縮占用本地磁盤。

你可以通過 docker  system  df  指令來便捷的檢視鏡像、容器、資料卷所占用的空間。

Docker 入門之鏡像&amp;容器下面介紹一下容器

3.虛懸鏡像

鏡像既沒有倉庫名,也沒有标簽,均為 

<none>

。即是懸空鏡像,沒啥用,删了就好:

<none>               <none>              00285df0df87        5 days ago          342 MB
           

這個鏡像原本是有鏡像名和标簽的,原來為 

mongo:3.2

,随着官方鏡像維護,釋出了新版本後,重新 

docker pull mongo:3.2

 時,

mongo:3.2

 這個鏡像名被轉移到了新下載下傳的鏡像身上,而舊的鏡像上的這個名稱則被取消,進而成為了 

<none>

。除了 

docker pull

 可能導緻這種情況,

docker build

 也同樣可以導緻這種現象。由于新舊鏡像同名,舊鏡像名稱被取消,進而出現倉庫名、标簽均為 

<none>

 的鏡像。這類無标簽鏡像也被稱為 虛懸鏡像(dangling image) ,可以用下面的指令專門顯示這類鏡像:

$ docker image ls -f dangling=true
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
<none>              <none>              00285df0df87        5 days ago          342 MB
           

一般來說,虛懸鏡像已經失去了存在的價值,是可以随意删除的,可以用下面的指令删除。

$ docker image prune
           
Docker 入門之鏡像&amp;容器下面介紹一下容器

4.搜尋查詢鏡像

查鏡像時 可以在docker  images 後面加鏡像:tag 過濾搜尋。

Docker 入門之鏡像&amp;容器下面介紹一下容器

還可以加 -f 參數 相當于 --filter    我加了幾個鏡像來做測試。

Docker 入門之鏡像&amp;容器下面介紹一下容器

-f 所配合的 since   before 參數會根據建立時間過濾。之前之後。

如果鏡像建立時指定了label  也可以通過 -f  label=xxx過濾。其實這種 -f 過濾意義不大。感覺docker images ubuntu這麼查找就很好用了。-f 在過濾鏡像批量删除時就很好用。

docker images -f since=ubuntu:latest -q              docker images  ubuntu  -q 

-q 參數會列出所有的鏡像id  這樣就可以批量操作了  比如  rmi 

 5.删除鏡像

删除鏡像的指令如下

docker image rm [選項] <鏡像1> [<鏡像2> ...]
           

可以結合第4條 過濾着删除。

docker image rm hello-world:latest    此時要是該鏡像有容器存在,會警告你。  删掉容器,再删鏡像就行了。

Docker 入門之鏡像&amp;容器下面介紹一下容器

docker  rmi imageID  也是可以的 也遵循上面這個删 container 

删除鏡像容器的話  憑借 ID 删應該就夠了。或者通過 指定的鏡像Tag

docker images  --digests  查出  sha256     指定[email protected]... 删除也行    如下這麼配合過濾參數删除也可以。

注意   $()這個裡面引用表達式    docker  image  rm  $(docker images  -q  ubuntu)

docker  rmi  $(docker  images -q  ubuntu) 一樣的。

當我們使用上面指令删除鏡像的時候,實際上是在要求删除某個标簽的鏡像。是以首先需要做的是将滿足我們要求的所有鏡像标簽都取消,這就是我們看到的 

Untagged

 的資訊。因為一個鏡像可以對應多個标簽,是以當我們删除了所指定的标簽後,可能還有别的标簽指向了這個鏡像,如果是這種情況,那麼 

Delete

 行為就不會發生。是以并非所有的 

docker image rm

 都會産生删除鏡像的行為,有可能僅僅是取消了某個标簽而已。

6.利用 commit 了解鏡像構成

我們先起一個NGINX   nginx 就是一個web伺服器。 例如  lnmp 這種web開發模式。使用的就是php-fpm結合nginx實作反向代理和負載均衡。 nginx代理了伺服器。

docker  run  --name webserver  -d  -p 80:80  nginx   

container 的names 命名為 webserver   -p暴露主控端端口與虛拟端口(即容器端口)的映射關系。 

這樣就起了一個names 為 webserver 的容器。容器啟動了,我們就可以在浏覽器通路了。 輸入 主控端的ip 就可以通路了。

此處需要注意一下。關于docker 盡量不要使用localhost 和127.0.0.1  使用真實ip會帶來更多便利減少更多警告。

如果你想改啥東西,就 docker exec  -it  containerName  bash  進入容器内部改。

docker  exec  -it  webserver  bash  進入nginx起的 容器修改你要改的東西,然後exit 就好。

比如  我把nginx的展示頁面改成 hello  zhangyong  然後就會立即生效。stop  start 是證明容器重新開機後修改還是成立的。

Docker 入門之鏡像&amp;容器下面介紹一下容器

至于浏覽器的頁面就不展示了。

然後exit  退出到ubuntu系統中docker  diff  webserver  diff 看一下剛才的操作給webserver這個容器帶來的改變。

但是我就改了箭頭指的那個檔案,帶來了這麼多改變、

Docker 入門之鏡像&amp;容器下面介紹一下容器

經過上述操作,docker  commit  可以将這個容器再釋出成一個鏡像,即将存儲層打成鏡像的一層來釋出。但是我們需要注意這個問題,改了一點就帶來這麼多的變化,那麼這個容器再釋出勢必會更加臃腫。不但多了些占磁盤的資料,主要是還将本次修改變成了黑盒。建立鏡像通過dockerFile 鏡像裡面加了什麼一看就知道,但是這麼修改釋出之後變化了什麼隻有釋出者知道。将很難進行維護。

docker commit [選項] <容器ID或容器名> [<倉庫名>[:<标簽>]]
           

 docker commit --author "zhangyong"  webserver nginx:v8   将webserver 釋出成nginx:v8版本。

docker run --name webserver2 -d -p 81:80 nginx:v8  起一個v8版本的容器叫 webserver2 并指定映射到主控端81端口

Docker 入門之鏡像&amp;容器下面介紹一下容器

docker  exec -it webserver2 bash   進去再改一改然後浏覽器對比一下。

接下來通過docker  history  image:tag 來對比一下nginx這兩個版本鏡像的差別。可以看到多了一層。

Docker 入門之鏡像&amp;容器下面介紹一下容器

可以看到我對index.html頁面代碼改的更少了,反而這一層多打了475B 

下面介紹一下容器

1.容器啟動

先寫一下Dockerfile 

FROM ubuntu

docker  build -t ubuntu:v1 .    -t指定鏡像:tag   .  上下文路徑。

第一種啟動方式:docker run -it --rm --name ubuntu1 ubuntu:v1   

-t

 選項讓Docker配置設定一個僞終端(pseudo-tty)并綁定到容器的标準輸入上, 

-i

 則讓容器的标準輸入保持打開。

--rm 運作完删掉這個容器。  --name 指定容器名稱  最後指定鏡像:tag

當利用 

docker run

 來建立容器時,Docker 在背景運作的标準操作包括:

  • 檢查本地是否存在指定的鏡像,不存在就從公有倉庫下載下傳
  • 利用鏡像建立并啟動一個容器
  • 配置設定一個檔案系統,并在隻讀的鏡像層外面挂載一層可讀寫層
  • 從宿主主機配置的網橋接口中橋接一個虛拟接口到容器中去
  • 從位址池配置一個 ip 位址給容器
  • 執行使用者指定的應用程式
  • 執行完畢後容器被終止

第二種啟動方式:docker  start  container

docker start  ubuntu1

docker  ps 查運作中的容器

docker  ps  -a 查所有容器。注:主程序退出的容器你docker  start  container  啟動是會立即退出的。

2.容器守護态運作

docker  run  -d  ubuntu:v1  

-d 參數就是背景運作。保證你echo 輸出出來的東西不會阻塞在指令行。

docker   logs   container  查echo 控制台輸出的日志。

3.終止容器  

docker  stop   container   注:所有container的位置都可以寫容器名稱或者id

docker  restart  container  重新開機容器。

4.進入容器

有兩種能進入容器的方法,隻需記一種就好了。

docker  attach  這種方式進容器,exit退出會将容器stop關掉  docker attach  container  

docker  exec   這種方式進入容器,exit不會關閉容器。選這種。 docker exec -it container bash

docker  exec  -it  ubuntu  bash   注意exec必須得兩個參數。  正确的玩法就是我寫的這個。哈哈哈。

5.導入||導出容器

目前感覺這個用處不大。因為傳遞的都是鏡像,導出它幹啥。

docker  export  container  >  file.tar 

cat  file.tar  |  docker  import  -  test:v1.0  導入成鏡像。

6.删除容器

docker  rm container 删除鏡像。

docker  rm  $(docker ps -a -q) 你也可以這麼玩。按照一個指令作為參數删除所有的。

當然删除的前提是這個容器得是stop的。

docker  container  prune  删除所有停止的容器。這個指令特别爽。

參考:https://yeasy.gitbooks.io/docker_practice/content/