首頁 > 軟體

聊聊Docker中容器的建立與啟停問題

2022-06-06 22:00:20

1. 映象和容器

看待映象和容器的一種方式是將它們類比成程式與程序。一個程序可以視為一個被執行的應用程式,同樣,一個Docker容器可以視為一個執行中的Docker映象。

標題Docker映象與容器

如果大家熟悉物件導向原理,看待映象和容器的另一種方法是將映象看作類而將容器看作物件。物件是類的具體範例,同樣,容器是映象的範例。使用者可以從單個映象建立多個容器,就像物件一樣,它們之間全都是相互隔離的。不論使用者在物件內修改了什麼,都不會影響類的定義——它們從根本上就是不同的東西。

2. 新建並啟動容器

首先,我們會檢視Docker是否能正常工作,然後學習基本的Docker的工作流:建立並管理容器。我們將瀏覽容器的典型生命週期:從建立、管理到停止,直到最終刪除。 第一步,檢視docker程式是否存在,功能是否正常:

[root@localhost ~]# sudo docker info
Containers: 1
Images: 8
Storage Driver: aufs
    Root Dir: /var/lib/docker/aufs
    Backing Filesystem: extfs
    Dirs: 10
Execution Driver: native-0.2
Kernel Version: 3.13.0-43-generic
Operating System: Ubuntu 14.04.2 LTS
CPUs: 1
Total Memory: 994 MiB
Name: riemanna
ID: DOIT:XN5S:WNYP:WP7Q:BEUP:EBBL:KGIX:GO3V:NDR7:YW6E:VFXT:FXHM WARNING: No swap limit support

在這裡我們呼叫了docker可執行程式的info命令,該命令會返回所有容器和映象(映象即是Docker用來構建容器的“構建塊”)的數量、Docker使用的執行驅動和儲存驅動(execution and storage driver),以及Docker的基本設定。

Docker是基於使用者端-伺服器構架的。它有一個docker程式,既能作為使用者端,也可以作為伺服器端。作為使用者端時,docker程式向Docker守護行程傳送請求(如請求返回守護行程自身的資訊),然後再對返回的請求結果進行處理。

現在,讓我們嘗試啟動第一個Docker容器。我們可以使用docker run命令建立容器。 docker run命令提供了Docker容器的建立到啟動的功能:

[root@localhost ~]# sudo docker run -i -t ubuntu /bin/bash
Unable to find image 'ubuntu' locally
ubuntu:latest: The image you are pulling has been verified 511136ea3c5a: Pull complete
d497ad3926c8: Pull complete
ccb62158e970: Pull complete
e791be0477f2: Pull complete
3680052c0f5c: Pull complete
22093c35d77b: Pull complete
5506de2b643b: Pull complete
Status: Downloaded newer image for ubuntu:latest
root@fcd78e1a3569:/#
官方檔案列出了完整的Docker命令列表,也可以使用docker help獲取這些命令。此外,還可以使用Docker的man頁(即執行man docker-run)。
[root@localhost ~]# sudo docker run -i -t ubuntu /bin/bash

上述命令中:

上述命令中:

        -t  選項讓Docker分配一個偽終端(pseudo-tty)並繫結到容器的標準輸入上,
        -i  則讓容器的標準輸入保持開啟。
利用docker run來建立並啟動容器時,Docker在後臺執行的標準操作包括:
        ·檢查本地是否存在指定的映象,不存在就從公有倉庫下載;
        ·利用映象建立一個容器,並啟動該容器;
        ·分配一個檔案系統給容器,並在唯讀的映象層外面掛載一層可讀寫層;
        ·從宿主主機設定的網橋介面中橋接一個虛擬介面到容器中;
        ·從網橋的地址池設定一個IP地址給容器;
        ·執行使用者指定的應用程式;
        ·執行完畢後容器被自動終止。

官方檔案上列出了docker run命令的所有標誌,此外還可以用命令docker help run檢視這些標誌。或者,也可以用Docker的man頁(也就是執行man docker-run命令)。

接下來,我們告訴Docker基於什麼映象來建立容器,範例中使用的是ubuntu映象。ubuntu映象是一個常備映象,也可以稱為“基礎”(base)映象,它由Docker公司提供,儲存在Docker HubRegistry上。可以以ubuntu基礎映象(以及類似的fedora、debian、centos等映象)為基礎,在選擇的作業系統上構建自己的映象。到目前為止,我們基於此基礎映象啟動了一個容器,並且沒有對容器增加任何東西。

首先Docker會檢查本地是否存在ubuntu映象,如果本地還沒有該映象的話,那麼Docker就會連線官方維護的Docker Hub Registry,檢視Docker Hub中是否有該映象。Docker一旦找到該映象,就會下載該映象並將其儲存到本地宿主機中。 隨後,Docker在檔案系統內部用這個映象建立了一個新容器。該容器擁有自己的網路、IP地址,以及一個用來和宿主機進行通訊的橋接網路介面。最後,我們告訴Docker在新容器中要執行什麼命令,在本例中我們在容器中執行/bin/bash命令啟動了一個Bash shell。 當容器建立完畢之後,Docker就會執行容器中的/bin/bash命令,這時就可以看到容器內的shell了,如下:

root@f7cbdac22a02:/#

3. 使用第一個容器

現在,我們已經以root使用者登入到了新容器中,容器的ID f7cbdac22a02,乍看起來有些令人迷惑的字串`。這是一個完整的Ubuntu系統,可以用它來做任何事情。下面就來研究一下這個容器。首先,我們可以獲取該容器的主機名,如下:

root@f7cbdac22a02:/# hostname 
f7cbdac22a02

可以看到,容器的主機名就是該容器的ID。再來看看/etc/hosts檔案內容:

root@f7cbdac22a02:/# cat /etc/hosts
172.17.0.4 f7cbdac22a02
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

Docker已在hosts檔案中為該容器的IP地址新增了一條主機設定項。 再來看看容器的網路設定情況,如下:

root@f7cbdac22a02:/# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 1500 qdisc noqueue state
    UNKNOWN group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
899: eth0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast
    state UP group default qlen 1000
link/ether 16:50:3a:b6:f2:cc brd ff:ff:ff:ff:ff:ff
inet 172.17.0.4/16 scope global eth0
inet6 fe80::1450:3aff:feb6:f2cc/64 scope link valid_lft forever preferred_lft forever

可以看到,這裡有lo的環回介面,還有IP為172.17.0.4的標準 eth0網路介面,和普通宿主機是完全一樣的。我們還可以檢視容器中執行的程序,如下:

root@f7cbdac22a02:/# ps -aux
USER PID %CPU %MEM    VSZ RSS TTY    STAT START TIME COMMAND
root    1 0.0 0.0    18156 1936 ?    Ss    May30 0:00 /bin/bash 
root    21 0.0 0.0   15568 1100 ?    R+    02:38 0:00 ps -aux

接下來嘗試安裝一個軟體包:

root@f7cbdac22a02:/# apt-get update && apt-get install vim

通過上述命令,就在容器中安裝了Vim編輯器軟體。 使用者可以繼續在容器中做任何自己想做的事情。當所有工作都結束時,輸入exit,就可以返回到Ubuntu宿主機的命令列提示符了。 但是,容器現在已經停止執行了!只有在指定的/bin/bash命令處於執行狀態的時候,我們的容器也才會相應地處於執行狀態。一旦退出容器,/bin/bash命令也就結束了,這時容器也隨之停止了執行。

但容器仍然是存在的,可以用docker ps -a命令檢視當前系統中容器的列表,如下:

CONTAINER ID IMAGE     COMMAND    CREATED  STATUS PORTS NAMES
1cd57c2cdf7f ubuntu:14.04 "/bin/bash" A minute Exited
    gray_cat

預設情況下,當執行docker ps命令時,只能看到正在執行的容器。如果指定-a標誌的話,那麼docker ps命令會列出所有容器,包括正在執行的和已經停止的。 注意:也可以為docker ps命令指定-l標誌,列出最後一個執行的容器,無論其正在執行還是已經停止。也可以通過--format標誌,進一步控制顯示哪些資訊,以及如何顯示這些資訊

從該命令的輸出結果中我們可以看到關於這個容器的很多有用資訊:ID、用於建立該容器的映象、容器最後執行的命令、建立時間以及容器的退出狀態(在上面的例子中,退出狀態是0,因為容器是通過正常的exit命令退出的)。我們還可以看到,每個容器都有一個名稱。 有3種方式可以唯一指代容器:短UUID(如f7cbdac22a02)、長UUID(如f7cbdac22a02e03c9438c729345e54db9d20cfa2ac1fc3494b6eb60872e74778)或者名稱(如gray_cat)。

4. 容器命名

Docker會為我們建立的每一個容器自動生成一個隨機的名稱。例如,上面我們剛剛建立的容器就被命名為gray_cat。如果想為容器指定一個名稱,而不是使用自動生成的名稱,則可以用--name標誌來實現,如下:

[root@localhost ~]# sudo docker run --name bob_the_container -i -t ubuntu /bin/bash 
root@aa3f365f0f4e:/# exit

上述命令將會建立一個名為bob_the_container的容器。一個合法的容器名稱只能包含以下字元:小寫字母a~z、大寫字母A~Z、數位 0~9、下劃線、圓點、橫線(如果用正規表示式來表示這些符號,就是[a-zA-Z0-9_.-])

在很多Docker命令中,都可以用容器的名稱來替代容器ID,後面我們將會看到。容器名稱有助於分辨容器,當構建容器和應用程式之間的邏輯連線時,容器的名稱也有助於從邏輯上理解連線關係。具體的名稱(如web、db)比容器ID和隨機容器名好記多了。我推薦大家都使用容器名稱,以更加方便地管理容器。 容器的命名必須是唯一的。如果試圖建立兩個名稱相同的容器,則命令將會失敗。如果要使用的容器名稱已經存在,可以先用docker rm命令刪除已有的同名容器後,再來建立新的容器。

5.重啟容器

容器已經停止了,我們可以用下面的命令重新啟動一個已經停止的容器,如下:

[root@localhost ~]# sudo docker start bob_the_container

除了容器名稱,也可以用容器ID來指定容器,

[root@localhost ~]# sudo docker start aa3f365f0f4e

也可以使用docker restart命令來重新啟動一個容器。 這時執行不帶-a標誌的docker ps命令,就應該看到我們的容器已經開始執行了。 類似地,Docker也提供了docker create命令來建立一個容器,但是並不執行它。這讓我們可以在自己的容器工作流中對其進行精準化的控制。

6. 附著到容器上

Docker容器重新啟動的時候,會沿用docker run命令時指定的引數來執行,因此我們的容器重新啟動後會執行一個互動式對談shell。此外,也可以用docker attach命令,重新附著到該容器的對談上,如下:

[root@localhost ~]# sudo docker attach bob_the_container

也可以使用容器ID,重新附著到容器的對談上,如下:

[root@localhost ~]# sudo docker attach aa3f365f0f4e

現在,又重新回到了容器的Bash提示符,如下:

root@aa3f365f0f4e:/_#_

可能需要按下確認鍵才能進入該對談。 如果退出容器的shell,容器會再次停止執行。

容器是直接提供應用服務的元件,也是Docker實現快速啟停和高效服務效能的基礎。 在生產環境中,因為容器自身的輕量級特性,推薦大家使用容器時在一組容器前引入HA(High Availability,高可靠性)機制。例如使用HAProxy工具來代理容器存取,這樣在容器出現故障時,可以快速切換到功能正常的容器。此外,建議通過指定合適的容器重啟策略,來自動重啟退出的容器。

到此這篇關於Docker中容器的建立與啟停的文章就介紹到這了,更多相關docker容器建立內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com