国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

深入 Docker:容器和鏡像

zqhxuyuan / 3003人閱讀

摘要:容器對鏡像文件的所有操作均是在虛擬出的改動層上進行的。建議使用版本標簽標記鏡像,并推送特定版本標簽的鏡像和標簽的鏡像。手動刪除的容器不能恢復。

  

在本專欄往期的 Flux7 系列教程 里,我們已經簡單地探討了 Docker 的基本操作。而在那篇教程中,我們一直是簡單地將容器當成是“正在運行的鏡像”,并沒有深入地區分鏡像和容器到底是什么、有什么區別。因此本次翻譯 深入 Docker:容器和鏡像 這篇文章,通過一些實例向大家介紹 Docker 容器和鏡像的具體區別。

Docker 是一個非常有趣的項目。它自己宣稱可以減輕部署服務器的難度,當然我相信里面有炒作的成分。但是實際使用后,我覺得 Docker 的表現還是可圈可點的。本篇文章將會從頭開始進行操作鏡像,同時試圖通過實例和文檔來解答實際操作 Docker 中遇到的問題。

本文僅僅是試圖使用深入講解 Docker 鏡像和容器的基礎知識,而不是像 了解 Docker:一種更好的虛擬化方式 一樣試圖總結出 Docker 的所有操作方法。

如果你打算按照本文操作的話,那么你首先有臺安裝好 Docker 的 Linux 主機。使用 Docker Machine 安裝 Docker 很簡單,但是同時我也推薦使用 Digital Ocean 中已經安裝好 Docker 的云主機直接操作。本篇文章所使用的 Docker 版本為 1.6.0,同時文中所有的命令都需要 root 權限。

技巧

同樣,譯者在正文開始提供一個操作 Docker 的小知識。下文中也會多次使用到這一點。

Docker 會為所有已經運行(包括已經停止)的容器隨機分配一個唯一的名字和一個唯一的 ID,docker 命令可以識別 ID,也可以識別這個名字。

如圖所示,第一行的容器的 ID 是 43de70a54ec1,名字是 admiring_ardinghelli
想刪除第一行對應的容器,我們只需要 docker rm 43de70a54ec1,或者簡寫成 docker rm 43de,或者 docker rm admiring_ardinghelli

容器去哪兒了?

剛開始使用 Docker 的用戶會發現,運行完一個容器,再次運行這個容器,原來的容器內的內容已經消失了,例如:

現在我們使用 -i(交互式)和 -t(臨時終端)參數運行一個容器,然后輸入一些交互命令:

shell(HOST) # docker run -it ubuntu /bin/bash
(CONTAINER) root@1f608dc4e5b4:/# echo hello docker > /message.txt
(CONTAINER) root@1f608dc4e5b4:/# cat /message.txt
hello docker
(CONTAINER) root@1f608dc4e5b4:/# exit

在上面那個容器內,我們創建了 /message.txt 文件,現在我們嘗試重新讀取這個文件:

shell(HOST) # docker run -it ubuntu cat /message.txt
cat: /message.txt: No such file or directory

剛剛我們明明新建了這個文件,現在怎么沒了?
同時,運行 docker ps 列出容器,剛剛那個 1f608dc4e5b4 容器到哪里去了?

好吧,那么我們用 docker ps -a 命令列出所有容器,然后仔細觀察一下:

(HOST) # docker ps -a
CONTAINER ID        IMAGE                 COMMAND              CREATED             STATUS                      PORTS               NAMES
b3d8c3ef31a0        ubuntu:latest         "cat /message.txt"   33 minutes ago      Exited (1) 33 minutes ago                       admiring_lalande
1f608dc4e5b4        ubuntu:latest         "/bin/bash"          34 minutes ago      Exited (0) 15 minutes ago                       insane_wright

現在大家應該可以發現問題了:居然有兩個不同的容器,一個執行了 /bin/bash,一個執行了 cat /message.txt

在本專欄以往的文章中,多次提到:Docker 使用一個叫做 UnionFS 的層級文件系統進行鏡像操作。容器對鏡像文件的所有操作均是在虛擬出的“改動層”上進行的。當然對容器而言,UnionFS 和普通的文件系統并無差別,也無法看到任何“改動層”。

每次運行 docker run 命令的時候,Docker 都會指定新建容器,并且為容器自己的改動層。所以我們兩次都運行了 ubuntu 鏡像,那么我們也將會有兩個新的、不同的容器,每個容器也都會有自己獨立的的“改動層”。因此,在第一個容器內創建的 /message.txt 文件在第二個容器內是無法訪問的。當然,要是能互相訪問,那我們就得為 Docker 的安全性擔心了。

容器到底去哪兒了?
  

剛剛的問題是:“容器去哪兒了?”
現在的問題是:“容器到底去哪兒了?我需要里面的 message.txt 文件,怎么才能取出來?”

已經停止的容器中的數據并不會消失,而是被存儲在相應的“改動層”中。我們可以通過 docker ps -a 進行查找容器。在這個例子中,我們要找的容器便是執行了 /bin/bash 命令的容器,ID是 1f608dc4e5b4,名稱是 insane_wright

對比起 ID,容器的名稱更加易讀。因此在本篇文章后面的例子中,我都將用名稱來進行操作和識別容器。當然,你也可以在 docker run 的時候用 --name 參數指定容器的名稱。

那么現在我們現在運行上面例子中已經停止的 insane_wright 容器:

(HOST) # docker start -ai insane_wright
(CONTAINER) root@1f608dc4e5b4:/# cat /message.txt
hello docker
(CONTAINER) root@1f608dc4e5b4:/# exit

使用 -a 參數將容器的輸出導出到終端,同時使用 -i 參數進行交互式的操作。這條命令可以讓我們繼續運行容器 insane_wright,現在你應該能看得到我們剛剛創建的 /message.txt 文件了。

容器能不能提取出來?
  

現在我們已經運行了自己的容器,容器內也有獨立的數據,我們也知道如何獲取容器內的數據,那么問題來了:我們能不能把這個狀態下的容器給保存起來?

本專欄前面的文章提到過得益于 UnionFS,對于 Docker 來說,其實容器和鏡像的差別并不大。容器可以認為是已經運行過的或正在運行的鏡像,只不過是鏡像上面添加了幾個改動層。當然,大部分鏡像也是如此。例如某些 mysql 鏡像,便僅僅是在官方 ubuntu 鏡像的基礎上增加了一個 mysql 改動層。

對于上面例子中的容器,我們可以用下面這條命令將其打包成鏡像:

(HOST) $ docker commit -a "Jordan Bach" -m "saved my message" insane_wright jbgo/message:v0.0.1
1c9195e4c24c894a274f857a60b46fb828ee70ff0e78d18017dfb79c5bf68409

本條命令將容器 insange_wright 的改動層的屬性變為“只讀”,并且指定存儲為 jbgo/message 鏡像。鏡像基于原 ubuntu 鏡像,增加了一個改動層,標簽為 v0.0.1。標簽可以為任意,當然一般用來記錄版本信息。

當然,如果你打算自己嘗試的話,記得將我的名字 jbgo 替換為你自己在 Docker Hub 上的用戶名。即便你沒有 Docker Hub 賬戶,也要養成給鏡像做簽名的習慣。

可以用如下命令檢查當前的鏡像:

(HOST) # docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
jbgo/message        v0.0.1              1c9195e4c24c        18 seconds ago      188.3 MB
ubuntu              latest              b7cf8f0d9e82        4 days ago          188.3 MB

現在我們有兩個鏡像了:一個是原有的 ubuntu 鏡像,鏡像是我們在剛開始進行 docker run 的時候自動從 Docker Hub 上面下載下來的;另一個便是我們剛剛保存的,有一個 /message.txt 文件的鏡像。

不信?
那我運行給你看。

(HOST) # docker run -it jbgo/message:v0.0.1 cat /message.txt
hello docker

這里我們并沒有運行剛剛的 insane_wright 容器,而是運行了我們剛剛保存的鏡像。
我們確實把剛剛的容器保存為一個新的鏡像了。

還不信?
那我檢查給你看。

(HOST) # docker ps -a
CONTAINER ID        IMAGE                 COMMAND              CREATED             STATUS                      PORTS               NAMES
01bd4c098203        jbgo/message:v0.0.1   "cat /message.txt"   10 seconds ago      Exited (0) 9 seconds ago                        hopeful_lovelace
b3d8c3ef31a0        ubuntu:latest         "cat /message.txt"   33 minutes ago      Exited (1) 33 minutes ago                       admiring_lalande
1f608dc4e5b4        ubuntu:latest         "/bin/bash"          34 minutes ago      Exited (0) 15 minutes ago                       insane_wright

容器運行記錄里面多了一個叫做 hopeful_lovelace 的容器,是運行 jdgo/message:v0.0.1 鏡像而創建的這個容器。

如何備份鏡像?
  

上面我們創建了帶有一個 /message.txt 文件的鏡像,也用它運行了容器,那么如果 Docker 宿主機崩潰了或者文件消失了怎么辦?如何保證我們創建的鏡像在系統崩潰后仍然不丟失?

我們需要 Docker Registry,可以存儲和下載鏡像的地方。Docker Hub 官方提供了 Docker Hub Registry 讓我們來存儲鏡像,當然我們也可以自己搭建 Docker Registry。本篇文章將會使用 Docker Hub Registry,如果你想按照本文中繼續操作的話,記得將我的名字 jbgo 換成你自己在 Docker Hub 上的用戶名。

使用如下操作將鏡像上傳到 Docker Registry 上:

(HOST) # docker push jbgo/message
The push refers to a repository [jbgo/message] (len: 1)
1c9195e4c24c: Image push failed

Please login prior to push:
Username: jbgo
Password:
Email: jordanbach@gmail.com
WARNING: login credentials saved in /root/.dockercfg.
Login Succeeded
The push refers to a repository [jbgo/message] (len: 1)
1c9195e4c24c: Image already exists
b7cf8f0d9e82: Image successfully pushed
2c014f14d3d9: Image successfully pushed
a62a42e77c9c: Image successfully pushed
706766fe1019: Image successfully pushed
Digest: sha256:b2a98b19e06a4df91150f8a2cd47a6e440cbc13b39f1fc235d46f97f631ad117

因為我是第一次在本機執行 docker push 操作,所以 Docker Registry 需要驗證我的身份。

本次上傳的鏡像被保存在這里。
你可以使用 docker pull jbgo/message 來下載我的鏡像。

當然,如果你按照上面的來操作的話,可能會出現一點小問題:

(HOST) # docker pull jbgo/message
Pulling repository jbgo/message
FATA[0007] Tag latest not found in repository jbgo/message

下面我來解釋一下到底出了什么問題:
當你使用 docker push jbgo/message 命令的時候,默認上傳標簽為 latest 的鏡像。如果沒有便會報錯。你可以采用如下命令解決: docker tag jbgo/message:v0.0.1 jbgo/message:latest
這次再嘗試推送:

(HOST) # docker push jbgo/message:latest
The push refers to a repository [jbgo/message] (len: 1)
1c9195e4c24c: Image already exists
b7cf8f0d9e82: Image already exists
2c014f14d3d9: Image already exists
a62a42e77c9c: Image already exists
706766fe1019: Image already exists
Digest: sha256:cc2fbbb2029c6402cea639b2454da08ef05672da81176ae97f57d4f51be19fc3

這次上傳會快得多,因為服務器上已經有了這個鏡像,我們上傳的僅僅是相同鏡像的不同標簽而已。

你不信?
那我驗證給你看:

(HOST) # docker pull jbgo/message
latest: Pulling from jbgo/message
1c9195e4c24c: Already exists
706766fe1019: Already exists
a62a42e77c9c: Already exists
2c014f14d3d9: Already exists
b7cf8f0d9e82: Already exists
Digest: sha256:cc2fbbb2029c6402cea639b2454da08ef05672da81176ae97f57d4f51be19fc3
Status: Downloaded newer image for jbgo/message:latest

當然,別臺服務器一樣可以使用這個命令下載我的鏡像。

當然,也可以使用如下命令上傳特定標簽的鏡像:docker push jbgo/message:v0.0.1
建議使用版本標簽標記鏡像,并推送特定版本標簽的鏡像和 latest 標簽的鏡像

使用完畢的容器如何處理?

上面只是介紹了容器如何理解容器和鏡像,如果有很多歷史容器被保存在硬盤上,想要釋放掉這些空間,我們應該怎么做?

使用如下命令刪除多個容器:

(HOST) # docker rm hopeful_lovelace insane_wright admiring_lalande
hopeful_lovelace
insane_wright
admiring_lalande

現在再檢查一下還有沒有這些容器:

(HOST) # docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

我們運行的所有容器和所有的歷史容器都會被保存在硬盤上,除非你手動 docker rm 它們。手動刪除的容器不能恢復。

為什么上傳了不止一個鏡像?

有心人注意到,剛剛我們第一次上傳 jbgo/message 鏡像的時候,Docker 上傳了不止一個鏡像。

(HOST) # docker push jbgo/message:v0.0.1
...
1c9195e4c24c: Image already exists
b7cf8f0d9e82: Image successfully pushed
2c014f14d3d9: Image successfully pushed
a62a42e77c9c: Image successfully pushed
706766fe1019: Image successfully pushed

到底發生了什么?

首先使用 docker history 檢查一下鏡像改動歷史:

(HOST) # docker history jbgo/message:v0.0.1
IMAGE               CREATED             CREATED BY                                      SIZE
1c9195e4c24c        33 minutes ago      /bin/bash                                       108 B
b7cf8f0d9e82        4 days ago          /bin/sh -c #(nop) CMD ["/bin/bash"]             0 B
2c014f14d3d9        4 days ago          /bin/sh -c sed -i "s/^#s*(deb.*universe)$/   1.895 kB
a62a42e77c9c        4 days ago          /bin/sh -c echo "#!/bin/sh" > /usr/sbin/polic   194.5 kB
706766fe1019        4 days ago          /bin/sh -c #(nop) ADD file:777fad733fc954c0c1   188.1 MB

會發現,其實我們創建了不止一個鏡像,也就是有不止一個改動層。
使用 docker inspect 命令仔細觀察第一個鏡像(第一層)進行過的改動:

(HOST) # docker inspect 1c9195e4c24c
[{
    "Architecture": "amd64",
    "Author": "Jordan Bach",
    "Comment": "saved my message",
    "Config": {

這個肯定就是我們的 /message.txt 改動層了,那么其他的那么多是什么?

jbgo/message 是基于 ubuntu 鏡像的,我們來檢查一下 ubuntu 鏡像的改動歷史:

(HOST) # docker history ubuntu
IMAGE               CREATED             CREATED BY                                      SIZE
b7cf8f0d9e82        4 days ago          /bin/sh -c #(nop) CMD ["/bin/bash"]             0 B
2c014f14d3d9        4 days ago          /bin/sh -c sed -i "s/^#s*(deb.*universe)$/   1.895 kB
a62a42e77c9c        4 days ago          /bin/sh -c echo "#!/bin/sh" > /usr/sbin/polic   194.5 kB
706766fe1019        4 days ago          /bin/sh -c #(nop) ADD file:777fad733fc954c0c1   188.1 MB

那么這樣一切就很明確了:那些是 ubuntu 鏡像的改動歷史。為了確保本地和上傳到 Docker Hub 的鏡像一致,我們上傳到 Docker Hub 中的鏡像便是包含著五層改動層的新鏡像。

 如何刪除鏡像?

前面提到過,我們刪除容器,那么我們本機上仍然保存著鏡像,如何刪掉它們?

(HOST) # docker rmi jbgo/message
Error response from daemon: Conflict, cannot delete 1c9195e4c24c because the container 2ea39e64a130 is using it, use -f to force
FATA[0000] Error: failed to remove one or more images

提示出錯了,根據錯誤信息可以看出,還有容器在用這一個鏡像。

但是我們沒有正在運行著的容器啊,到底哪兒出錯了?

檢查所有容器,發現容器 2ea39e64a130

(HOST) # docker ps -a
CONTAINER ID        IMAGE                 COMMAND              CREATED             STATUS                     PORTS               NAMES
2ea39e64a130        jbgo/message:latest   "cat /message.txt"   2 minutes ago       Exited (0) 2 minutes ago                       lonely_jones

當然,這是 Docker 的機制:如果你仍然有容器的歷史記錄,那么為了確保你能再次啟動這個容器,這些鏡像是不能刪除的。

首先刪除掉這個容器:docker rm lonely_jones

然后刪除鏡像:

(HOST) # docker rmi jbgo/message
Untagged: jbgo/message:latest
Deleted: 1c9195e4c24c894a274f857a60b46fb828ee70ff0e78d18017dfb79c5bf68409
Deleted: b7cf8f0d9e82c9d96bd7afd22c600bfdb86b8d66c50d29164e5ad2fb02f7187b
Deleted: 2c014f14d3d95811df672ddae2af376f9557f6b8f5623e3e3f8c5ca3f6ff42e6
Deleted: a62a42e77c9c3626118dc411092d23cf658220261acdafe21a7589a8eeba627e
Deleted: 706766fe101906a1a6628173c2677173a5f8c6c469075083f3cf3a8f5e5eb367

這次我們可以很輕松地刪除掉 jbgo/message 鏡像了。
確認一下:

(HOST) # docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
確實沒了。
后記

本篇文章介紹了容器和鏡像的操作實例,當然 Docker 還有更多新奇的功能和只是等待大家去發現。
本專欄仍在繼續組織翻譯更多的系列文章,希望大家多多關注。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/7914.html

相關文章

  • 深入 Docker容器鏡像

    摘要:容器對鏡像文件的所有操作均是在虛擬出的改動層上進行的。建議使用版本標簽標記鏡像,并推送特定版本標簽的鏡像和標簽的鏡像。手動刪除的容器不能恢復。 在本專欄往期的 Flux7 系列教程 里,我們已經簡單地探討了 Docker 的基本操作。而在那篇教程中,我們一直是簡單地將容器當成是正在運行的鏡像,并沒有深入地區分鏡像和容器到底是什么、有什么區別。因此本次翻譯 深入 Docker:容器...

    paulquei 評論0 收藏0
  • Flux7 Docker 系列教程(一):Docker 簡介

    摘要:本系列教程翻譯自,系列共有九篇,本文譯自第一篇。,一種新的容器化技術,因為輕量級和便攜化而受到廣泛關注。本篇文章是系列教程的第一篇。鏡像只讀的容器模板,簡言之就是系統鏡像文件。首先,向發出請求創建一個鏡像并且指定容器內要運行的命令。 本系列教程翻譯自 Flux7 Docker Tutorial Series,系列共有九篇,本文譯自第一篇 Part 1: An Introduction。...

    zhaofeihao 評論0 收藏0
  • Flux7 Docker 系列教程(一):Docker 簡介

    摘要:本系列教程翻譯自,系列共有九篇,本文譯自第一篇。,一種新的容器化技術,因為輕量級和便攜化而受到廣泛關注。本篇文章是系列教程的第一篇。鏡像只讀的容器模板,簡言之就是系統鏡像文件。首先,向發出請求創建一個鏡像并且指定容器內要運行的命令。 本系列教程翻譯自 Flux7 Docker Tutorial Series,系列共有九篇,本文譯自第一篇 Part 1: An Introduction。...

    yacheng 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<