1. 程式人生 > >docker入門——管理容器

docker入門——管理容器

ons 網絡配置 aps address deb gif ror 鏡像 tail命令

除了交互式的容器(interactive container),我們也可以創建長期運行的容器。守護式容器(daemonized container)沒有交互式會話,非常適合運行應用程序和服務。大多數時候我們都需要以守護式來運行我們的容器。

創建守護式容器

# docker run --name daemon_dave -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"
64b5c862a23cb5b15e489fbd51dab5cfc958ca447db936732abb0f01ca2282b0
  • -d 參數,docker會將容器放到後臺運行,並返回容器ID

我們還在容器要運行的命令裏使用了一個while循環,該循環會一直打印hello world,直到容器或其進程停止運行。通過組合使用上面的這些參數,可以發現docker run命令並沒有像上一個容器一樣將主機的控制臺附著到新的shell會話上,而是僅僅返回了一個容器ID而已,我們還是在宿主機的命令行之中。通過docker ps 命令可以看到一個正在運行的容器。

# docker ps
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS              PORTS               NAMES
64b5c862a23c        ubuntu              "/bin/sh -c ‘while t   19 minutes ago      Up 19 minutes                           daemon_dave

同時我們也可以通過docker logs命令來獲取容器的日誌,探究該容器內部都在幹什麽。

# docker logs daemon_dave
hello world
hello world
hello world
...

通過 -f 參數可以跟蹤守護式容器的日誌,功能類似與tail -f命令,通過Ctrl+c退出日誌跟蹤。

# docker logs -f daemon_dave 
hello world
hello world
hello world
...

通過--tail 10 可以獲取日誌最後10行的內容,另外也可以通過--tail 0 -f 命令來跟蹤某個容器的最新日誌而不必讀取整個日誌文件。

技術分享
# docker logs --tail 10 daemon_dave 
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world


# docker logs --tail 0 -f daemon_dave 
hello world
hello world
hello world
hello world
hello world
--tail命令

為了讓調試更簡單,我們還可以使用-t標誌為每條日誌項加上時間戳,同樣通過Ctrl+c退出日誌跟蹤。

# docker logs --tail 0 -ft daemon_dave 
2017-05-11T08:16:11.088410871Z hello world
2017-05-11T08:16:12.090729257Z hello world
2017-05-11T08:16:13.093541541Z hello world

查看容器內的進程:

除了容器的日誌,我們也可以查看容器內部運行的進程。通過docker top我們可以看到容器內所有的進程:

# docker top daemon_dave
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                9691                1339                0                   15:45               ?                   00:00:00            /bin/sh -c while true; do echo hello world; sleep 1; done
root                12526               9691                0                   16:29               ?                   00:00:00            sleep 1

在容器內部運行進程:

我們可以通過docker exec命令在容器內部額外啟動新進程。可以在容器內運行的進程有兩種類型:後臺任務和交互式任務。後臺任務在容器內運行且沒有交互需求,而交互式任務則保持在前臺運行。對於需要在容器內部打開Shell的任務,交互式任務是很實用的。下面先看一個後臺任務的例子:

# docker exec -d daemon_dave touch /etc/new_config_file

這裏-d表示需要運行一個後臺進程,-d標誌之後,指定的是要在內部執行這個命令的容器的名字以及要執行的命令。上面例子中的命令在daemon_dave容器內創建了一個空文件,文件名為/etc/new_config_file。通過docker exec後臺命令,我們可以在正在運行的容器中進行維護、監控以及管理任務。

我們也可以在daemon_dave容器中啟動一個諸如打開shell的交互式任務:

# docker exec -t -i daemon_dave /bin/bash
[email protected]:/# ls -l /etc/new_config_file 
-rw-r--r-- 1 root root 0 May 11 08:39 /etc/new_config_file

和運行交互容器時一樣,這裏的-t 和 -i 標誌為我們執行的進程創建了TTY並捕捉STDIN。這條命令會在daemon_dave容器內創建一個新的bash會話,有了這個會話,我們就可以在該容器中運行其他命令了。這裏我們找到了之前我們通過後臺任務創建的文件。

停止守護式容器:

## 只需要執行docker stop + 容器名 命令,就可以停止守護式容器
# docker stop daemon_dave
daemon_dave

## 當然我們也可以通過docker stop + 容器ID 來停止守護式容器

自動重啟容器:

如果由於某種錯誤而導致容器停止運行,我們可以通過--restart標誌,讓Docker自動重啟該容器。--restart標誌會檢查容器的退出代碼,並據此來決定是否要重啟容器。默認的行為是Docker不會重啟容器。

# docker run --restart=always --name daemon_dave_restart -d ubuntu /bin/sh -c "while true; do echo hello world;sleep 1; done"
0e6bf4b02e2593605821dc53c0daea7ec3d899e844bd56902f1c0a548c85ea68

這裏--restart標誌被設置為always。無論容器的退出代碼是什麽,Docker都會自動重啟該容器。除了always,我們還可以將這個標誌設為on-failure,這樣,只有當容器的退出代碼為非0值的時候,才會自動重啟。另外,on-failure還接受一個可選的重啟次數參數

--restart=on-failure:5

這樣,當容器退出代碼為非0時,Docker會嘗試自動重啟該容器,最多重啟5次。

深入容器

除了通過docker ps命令獲取容器的信息,我們還可以使用docker inspect來獲取更多的容器信息

# docker inspect daemon_dave
[
{
    "Id": "4e01f78301baf396cc1870a880dd09414117c9a5a30eed59dfbfcebdd2baf768",
    "Created": "2017-05-11T09:05:49.882890923Z",
    "Path": "/bin/sh",
    "Args": [
        "-c",
        "while true; do echo hello world; sleep 1; done"
    ],
    "State": {
        "Running": true,
        "Paused": false,
        "Restarting": false,
        "OOMKilled": false,
        "Dead": false,
        "Pid": 14828,
        "ExitCode": 0,
...

docker inspect命令會對容器進行詳細的檢查,然後返回其配置信息,包括名稱、命令、網絡配置以及很多有用的數據。

我們也可以用-f或者--format標誌來選定查看結果

## 這條命令會返回容器的運行狀態
# docker inspect --format=‘{{ .State.Running }}‘ daemon_dave
true

## 我們還可以通過它來獲取容器的IP地址等
# docker inspect --format=‘{{ .NetworkSettings.IPAddress }}‘ daemon_dave
172.17.0.9

## 我們也可以同時指定多個容器,並顯示每個容器的輸出結果
# docker inspect --format=‘{{ .Name }} {{ .State.Running }}‘ daemon_dave SetName
/daemon_dave true
/SetName false

除了查看容器,我們還可以通過瀏覽/var/lib/docker目錄來深入了解Docker的工作原理。該目錄存放著Docker鏡像、容器以及容器的配置。所有的容器都保存在/var/lib/docker/containers目錄下。

刪除容器:

如果容器不再使用,我們可以使用docker rm命令來刪除它們

# docker rm daemon_dave
Error response from daemon: Cannot destroy container daemon_dave: Conflict, You cannot remove a running container. Stop the container before attempting removal or use -f
Error: failed to remove containers: [daemon_dave]

## 需要註意的是,運行中的容器是無法直接刪除的!必須先通過docker stop或docker kill命令停止容器,才能將其刪除
# docker stop daemon_dave
daemon_dave

# docker rm daemon_dave
daemon_dave

# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                         PORTS               NAMES
78679e02be1c        ubuntu              "/bin/bash"         4 hours ago         Exited (0) About an hour ago                       SetName             
f4d39b81dd5d        ubuntu              "/bin/bash"         4 hours ago         Exited (0) 4 hours ago                             clever_noyce

目前,還沒有辦法一次刪除所有容器,不過可以通過docker rm `docker ps -a -q`刪除所有容器。docker ps -a 會列出現有的全部容器,而-q標誌則是表示只需要返回容器的ID而不返回容器的其他信息,並傳遞給了docker rm命令,從而達到刪除所有容器的目的。

docker入門——管理容器