Docker 的鏡像與容器

Docker 是基於 linux 內核的 cgroup 和 namespace 等實現的進程隔離技術,是操做系統層面的虛擬化技術。因爲進程在宿主機上被分割成獨立的空間,就像一個獨立的容器將這些進程與外界隔離開來,所以被稱爲容器。linux

Docker 容器與傳統的虛擬化技術最大的區別在於,傳統的虛擬化技術是在宿主機器上虛擬出一套硬件後,在其上面運行完整的操做系統,而後在該系統上運行用戶進程,屬於硬件層面的虛擬化技術。而 docker 是操做系統層面的虛擬化技術,不須要虛擬化硬件,同一宿主機器上的全部容器共享宿主機的硬件和操做系統內核,只是在用戶態隔離進程的運行環境和存儲空間,所以對於上層用戶而言一個容器就好像是一臺獨立的主機。下圖是 docker 官網上的一張對比圖,左邊描述的是 docker 容器技術,右邊描述的是傳統的虛擬機技術。redis

docker與虛擬機的區別

這個區別使得 docker 相比與傳統的虛擬化技術要輕量的多,啓動一個虛擬機須要佔用幾 G 到幾十 G 的磁盤空間,須要的時間也是幾分鐘到十幾分鐘不等,而啓動一個容器只通常只要幾十 M 到上百 M,啓動的速度更是能夠在秒級時間內完成。docker

Docker 中有三個最重要的概念:鏡像、容器和倉庫。弄懂這三個概念就可使用基本的容器了。首先你能夠將容器想象成是一臺 linux 主機,在這個主機中會啓動須要的進程,好比一個 redis 的容器就會啓動一個 redis 的服務器。而啓動一個容器須要鏡像,相似於安裝一個 linux 系統須要安裝包,你能夠想象鏡像就是容器的安裝包。最後倉庫就是存放鏡像的地方,方便的是從這個倉庫下載鏡像只須要一個命令就能搞定,就像 apt-get 安裝軟件那樣方便。json

使用鏡像

有了鏡像才能生成容器,所以咱們先來了解鏡像。ubuntu

下載鏡像——docker pull

下載鏡像使用 docker pull 命令來實現,該命令格式以下:bash

docker pull [OPTIONS] NAME[:TAG|@DIGEST]
複製代碼
  • 能夠經過 docker pull --help 查詢幫助信息
  • OPTIONS 中 -a 選項表示拉取全部標籤的鏡像,-q 選項表示靜默下載,不打印輸出信息到屏幕
  • NAME 由倉庫名/鏡像名:標籤名的格式組成,倉庫名沒有則從默認倉庫 library 拉取,也就是官方鏡像,鏡像名必須有,標籤名沒有則默認拉取 latest 標籤的鏡像。同一個鏡像名的鏡像能夠有多個標籤,通常每更新一個版本就新增一個標籤,latest 標籤就是最新的鏡像。

好比能夠這樣下載標籤爲 18.04 的 ubuntu 鏡像:服務器

$ docker pull ubuntu:18.04
18.04: Pulling from library/ubuntu
bf5d46315322: Pull complete
9f13e0ac480c: Pull complete
e8988b5b3097: Pull complete
40af181810e7: Pull complete
e6f7c7e5c03e: Pull complete
Digest: sha256:147913621d9cdea08853f6ba9116c2e27a3ceffecf3b492983ae97c3d643fbbe
Status: Downloaded newer image for ubuntu:18.04
複製代碼

列出鏡像——docker image ls

docker image ls 命令能夠列出系統中已經下載了的全部鏡像。docker 中不少命令與 linux 的命令類似,所以在使用的時候能夠類比,docker 中有諸如 rm、ls、ps等命令。將瞭解更多的命令一樣能夠經過 docker image --help 來查看幫助信息。ui

$ docker image ls         
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
zookeeper           latest              e41846a619f5        17 hours ago        224MB
ubuntu              18.04               cf0f3ca922e0        3 days ago          64.2MB
ubuntu              latest              cf0f3ca922e0        3 days ago          64.2MB
redis               latest              f7302e4ab3a8        2 months ago        98.2MB
hello-world         latest              fce289e99eb9        9 months ago        1.84kB
複製代碼

列表分別包含了倉庫名標籤鏡像ID建立時間鏡像大小docker image ls命令展現的是一個完整鏡像的大小,可是因爲鏡像是分層存儲的,不一樣的鏡像若是使用了相同的層,這個層只會存儲一份數據,全部鏡像公用,所以鏡像實際佔用的空間大小要比顯示的小。this

刪除鏡像——docker image rm

docker image rm 命令能夠刪除鏡像,通常配合docker image ls命令來使用。docker image rm命令的使用格式是:spa

docker image rm [OPTIONS] IMAGE [IMAGE...]
複製代碼
  • 使用 docker image rm --help 能夠查看幫助信息
  • OPTIONS: --force/-f 強制刪除
  • 鏡像能夠是鏡像名,或者鏡像名加標籤,或者鏡像的ID

好比能夠這樣刪除標籤爲 latest 的 ubuntu 鏡像:

$ docker image rm ubuntu:latest
Untagged: ubuntu:18.04
Untagged: ubuntu@sha256:a7b8b7b33e44b123d7f997bd4d3d0a59fafc63e203d17efedf09ff3f6f516152
Deleted: sha256:cf0f3ca922e08045795f67138b394c7287fbc0f4842ee39244a1a1aaca8c5e1c
Deleted: sha256:c808877c0adcf4ff8dcd2917c5c517dcfc76e9e8a035728fd8f0eae195d11908
Deleted: sha256:cdf75cc6b4d28e72a9931be2a88c6c421ad03cbf984b099916a74f107e6708ff
Deleted: sha256:b9997ded97a1c277d55be0d803cf76ee6e7b2e8235d610de0020a7c84c837b93
Deleted: sha256:a090697502b8d19fbc83afb24d8fb59b01e48bf87763a00ca55cfff42423ad36
複製代碼

Untagged 和 Deleted 在執行 docker image rm 時,出現了兩種狀況,Untagged 和 Deleted。由於同一個鏡像(不僅是同名,而是真正意義上的同一個)能夠對應多個標籤,當執行 rm 命令時先移除這個指定的標籤,只有當移除的標籤是最後一個標籤的時候纔會同時刪除這個鏡像。除此以外,由於鏡像是分層存儲的,要刪除的鏡像多是別的鏡像的基礎層,若是刪除了這個鏡像也會致使依賴方出現問題。所以,若是有別的鏡像依賴這個鏡像,那麼這是這個鏡像也不會被刪除。另外,若是有其餘容器依賴於這個鏡像,那麼也不能刪除這個鏡像,由於刪除這個鏡像必然會致使容器出現故障。

操做容器

運行容器——docker run

運行容器有兩種方式,一種是新建一個容器並啓動,另外一種是啓動一個已終止的容器。

docker run 命令用來新建一個容器並啓動,該命令的使用格式是:

docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
複製代碼

好比下面這個命令會經過 ubuntu 鏡像建立並運行一個容器,而後執行 /bin/bash 命令。

$ docker run -it ubuntu /bin/bash
複製代碼

其中常見的命令選項有:

  • -i 選項是讓容器標準輸入打開,就能夠接受鍵盤輸入了
  • -t 選項是讓docker分配一個僞終端,綁定到標準輸入上。經過這個僞終端就能夠像操做一臺 linux 機器來操做這個容器了。
  • --name <容器名稱> 選項爲容器指定一個名稱
  • -d 選項讓容器在後臺運行,什麼是後臺運行,下文有說明
  • -rm 選項是讓容器終止時自動銷燬

用這個命令啓動一個容器後,就能夠像操做一臺普通的 ubuntu 機器同樣,操做這個容器了。能夠嘗試在這個容器中執行一些 linux 命令。

root@e7cd5bc73508:/# ps
  PID TTY          TIME CMD
    1 pts/0    00:00:00 bash
   10 pts/0    00:00:00 ps

root@e7cd5bc73508:/# ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
複製代碼

須要注意的是,對於這種以交互模式啓動的容器,當終止交互後,容器就退出了。

docker container start 能夠啓動一個終止的容器,該命令的使用格式是:

docker container start [OPTIONS] CONTAINER [CONTAINER...]
複製代碼

要啓動一個容器,須要知道容器的ID來做爲docker container start的參數,接下來介紹如何查看容器。

查詢容器狀態——docker container ls

docker container ls 列出全部正在運行的容器

docker container ls -a 列出全部的容器,包括已經終止的容器

列出的容器信息包括:

  • 容器ID(CONTAINER ID),這是容器的惟一標識,操做容器相關的命令都須要帶上這個標識
  • 依賴的鏡像名稱(IMAGE)
  • 執行的命令(COMMAND)
  • 建立的時間(CREATED)
  • 容器的狀態(STATUS),UP 是運行狀態,Exited 是終止狀態
  • 暴露的端口(PORTS)
  • 容器的名稱(NAMES),能夠在啓動容器的時候經過 --name 選項指定容器的名稱,若是沒有指定,系統會生成一個默認名稱

終止容器——docker container stop

docker container stop 命令用來終止一個正在運行的容器

終止的容器能夠經過 docker container start 命令啓動,docker container restart 命令會先終止容器,而後再啓動容器。

守護態運行

大多數時候須要容器在後臺運行,不須要將輸出結果打印到宿主主機上。此時,能夠經過 -d 參數來實現。

不使用 -d 選項啓動下面這個容器,表現以下:

$ docker run ubuntu /bin/bash -c "while true; do echo hello world; sleep 1; done"
hello world
hello world
hello world
hello world
hello world
複製代碼

使用 -d 選項啓動這個容器,表現以下:

$ docker run -d ubuntu /bin/bash -c "while true; do echo hello world; sleep 1; done"
574ee145e9ca501639a233601efe9574a356a8d7bdef461d240b2212b6aeaf77
複製代碼

在宿主的終端只輸出了該容器的 ID。若是須要查看容器的輸出可使用 docker container logs 命令。本文在說容器的這些命令時都省略了最後一個參數容器 ID,這個讀者在使用的時候須要自行加上,查詢容器 ID 的方法前面已經介紹過了。若是想要持續獲取容器的輸出可使用 docker container logs -f 命令。

進入容器

使用 -d 參數啓動容器後,容器在後臺運行,若是須要進入容器可使用 docker attach 命令或 docker exec 命令。建議使用 docker exec 命令,緣由在下面進行說明。

docker attach

$ docker run -it -d ubuntu
2b10efdeaa9f0f24f0060bf636cc8f1bae9598f5e0176b498447a7b63ea10d06

$ docker container ls
CONTAINER ID    IMAGE     COMMAND       CREATED             STATUS              PORTS          NAMES
2b10efdeaa9f    ubuntu    "/bin/bash"   13 seconds ago      Up 11 seconds                      cocky_golick

$ docker attach 2b10efdeaa9f
root@2b10efdeaa9f:/# 
複製代碼

使用 attach 命令,若是從這個終端退出後,這個容器也會被終止,這就是不推薦使用 attach 命令的緣由。

docker exec

$ docker run -it -d ubuntu
61299a9b910b029f9a8667131a45aff92fbc35633e4f86c8fcfb72e6362c5115

$ docker container ls
CONTAINER ID        IMAGE      COMMAND         CREATED             STATUS          PORTS           NAMES
61299a9b910b        ubuntu     "/bin/bash"     6 seconds ago       Up 5 seconds                    friendly_hawking

$ docker exec -it 61299a9b910b /bin/bash
複製代碼

使用 exec 命令,能夠生成新的僞終端與容器進行交互,所以退出時不會致使容器退出。

刪除容器

docker container rm 命令能夠刪除一個容器,若是要刪除一個正在運行的容器可使用docker container rm -f

若是要清除全部終止的容器可使用 docker container prune 命令。

訪問倉庫

  • docker login 登陸到docker hub倉庫
  • docker logout 退出登陸
  • docker search <關鍵詞> 搜索鏡像
  • docker pull 從倉庫下載鏡像
  • docker push 將本地倉庫推送到遠程倉庫

下面演示一下這些命令的使用:

$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one. Username: xxx Password: xxx WARNING! Your password will be stored unencrypted in /root/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded $ docker pull hello-world # 爲鏡像 hello-world 生成一個新的標籤,並且指定倉庫爲本身倉庫的用戶名 $ docker tag hello-world:latest oscarwin/hello-world:3.0 # 將鏡像推送到遠程倉庫,那麼就能夠在 docker hub 裏看到本身推送的這個鏡像了 $ docker push oscarwin/hello-world 複製代碼
相關文章
相關標籤/搜索