Docker 入门系列(3)- Docker 容器(创建、启动、终止、进入、删除、导入、导出容器、容器和镜像转化)
Docker 容器
簡單來說,容器是鏡像的一個運行實例。所不同的是,鏡像是靜態的只讀文件,而容器帶有運行時需要的可寫文件層。
如果認為虛擬機是模擬運行的一整套操作系統(包括內核、應用運行態環境和其他系統環境)和跑在上面的應用,那么 Docker 容器就是獨立運行的一個 (或一組)應用,以及它們必需的運行環境。
1. 創建容器
docker create
使用 docker create 命令新建一個容器,新建的容器處于停止狀態,可以使用 docker start 命令來啟動它。
wohu@iZm5egn5zptnov4j3oxh4fZ:~/docker$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
33197473a278 hello-world "/hello" 6 days ago Exited (0) 6 days ago frosty_galileo
wohu@iZm5egn5zptnov4j3oxh4fZ:~/docker$ docker create -it ubuntu:16.04
1f51e44dab220bfffb73bbd27cd7fe08ecf1109d368094329efb1818c32477f3
wohu@iZm5egn5zptnov4j3oxh4fZ:~/docker$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1f51e44dab22 ubuntu:16.04 "/bin/bash" 9 seconds ago Created confident_wu
33197473a278 hello-world "/hello" 6 days ago Exited (0) 6 days ago frosty_galileo
wohu@iZm5egn5zptnov4j3oxh4fZ:~/docker$ docker start 1f
1f
wohu@iZm5egn5zptnov4j3oxh4fZ:~/docker$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1f51e44dab22 ubuntu:16.04 "/bin/bash" 40 seconds ago Up 2 seconds confident_wu
33197473a278 hello-world "/hello" 6 days ago Exited (0) 6 days ago frosty_galileo
2. 新建并啟動容器
docker run
除了創建容器后通過 start 命令來啟動,也可以直接新建并啟動容器。所需要的命令主要為docker run,等價于先執行 docker create 命令,再執行 docker start 命令。
wohu@iZm5egn5zptnov4j3oxh4fZ:~/docker$ docker run ubuntu:16.04 /bin/echo "hello world"
hello world
wohu@iZm5egn5zptnov4j3oxh4fZ:~/docker$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c6813fb16675 ubuntu:16.04 "/bin/echo 'hello wo…" About a minute ago Exited (0) About a minute ago determined_blackwell
1f51e44dab22 ubuntu:16.04 "/bin/bash" 6 minutes ago Up 5 minutes confident_wu
33197473a278 hello-world "/hello" 6 days ago Exited (0) 6 days ago frosty_galileo
wohu@iZm5egn5zptnov4j3oxh4fZ:~/docker$
當利用 docker run 來創建并啟動容器時,Docker 在后臺運行的標準操作包括:
- 檢查本地是否存在指定的鏡像,不存在就從公有倉庫下載
- 利用鏡像創建一個容器,并啟動該容器
- 分配一個文件系統給容器,并在只讀的鏡像層外面掛載一層可讀寫層
- 從宿主主機配置的網橋接口中橋接一個虛擬接口到容器中
- 從網橋的地址池配置一個 IP 地址給容器
- 執行用戶指定的應用程序
- 執行完畢后容器被自動終止
下面的命令啟動一個 bash 終端,允許用戶進行交互:
wohu@iZm5egn5zptnov4j3oxh4fZ:~/docker$ docker run -ti ubuntu:16.04 /bin/bash
root@acb806366cf1:/# pwd
/
root@acb806366cf1:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@acb806366cf1:/# exit
exit
wohu@iZm5egn5zptnov4j3oxh4fZ:~/docker$
- -t 選項讓 Docker 分配一個偽終端 (pseudo-tty) 并綁定到容器的標準輸入上
- -i 則讓容器的標準輸入保持打開
輸入 exit 命令可以退出當前的容器
運行一個容器,使用 docker run 命令即可。 另 docker run -參數 含義:
docker run --name container-name -d image-name
--name:為容器起一個名稱;-d:detached,執行完這句命令后,控制臺將不會阻塞,可以繼續輸入命令操作,不會阻塞,也就是啟動守護式容器,如果執行docker run --name mycentos -it centos會進入啟動容器的命令控制臺,也就是啟動交互式容器;-i:以交互方式運行容器,通常與-t搭配使用;-t:為容器重新分配一個偽輸入終端,通常與-i搭配使用;-P:隨機端口映射;-p:指定端口映射,后面會有端口映射詳細講解;image-name:要運行的鏡像名稱;
守護態運行
需要讓 Docker 容器在后臺以守護態 (Daemonized) 形式運行。此時,可以通過添加 -d 參數來實現。獲取容器的輸出信息,可以通過 docker logs命令。
wohu@iZm5egn5zptnov4j3oxh4fZ:~/docker$ docker run -d ubuntu:16.04 /bin/echo "this is test output"
89860f528c9a9c4c552ee23837a7254ffcace89a9abf30a1d83e72947341d396
wohu@iZm5egn5zptnov4j3oxh4fZ:~/docker$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
89860f528c9a ubuntu:16.04 "/bin/echo 'this is …" 6 seconds ago Exited (0) 4 seconds ago admiring_driscoll
acb806366cf1 ubuntu:16.04 "/bin/bash" 9 minutes ago Exited (0) 9 minutes ago gifted_bartik
c6813fb16675 ubuntu:16.04 "/bin/echo 'hello wo…" 26 minutes ago Exited (0) 26 minutes ago determined_blackwell
1f51e44dab22 ubuntu:16.04 "/bin/bash" 31 minutes ago Up 31 minutes confident_wu
33197473a278 hello-world "/hello" 6 days ago Exited (0) 6 days ago frosty_galileowohu@iZm5egn5zptnov4j3oxh4fZ:~/docker$ docker logs 89
this is test output
wohu@iZm5egn5zptnov4j3oxh4fZ:~/docker$
3. 終止容器
可以使用 docker stop 來終止一個運行中的容器。該命令的格式為
docker stop [-t|--time[=10]] CONTAINER...
首先向容器發送 SIGTERM 信號,等待一段超時時間 (默認為 10秒) 后,再發送 SIGKILL 信號來終止容器
docker kill 命令會直接發送 SIGKILL 信號來強行終止容器。
此外,當 Docker 容器中指定的應用終結時,容器也會自動終止。例如對于上一節中只啟動了一個終端的容器,用戶通過 exit 命令或 Ctrl+d 來退出終端時,所創建的容器立刻終止,處于 stopped 狀態。
wohu@iZm5egn5zptnov4j3oxh4fZ:~/docker$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
89860f528c9a ubuntu:16.04 "/bin/echo 'this is …" 5 minutes ago Exited (0) 5 minutes ago admiring_driscoll
acb806366cf1 ubuntu:16.04 "/bin/bash" 14 minutes ago Exited (0) 14 minutes ago gifted_bartik
c6813fb16675 ubuntu:16.04 "/bin/echo 'hello wo…" 31 minutes ago Exited (0) 31 minutes ago determined_blackwell
1f51e44dab22 ubuntu:16.04 "/bin/bash" 36 minutes ago Up 36 minutes confident_wu
33197473a278 hello-world "/hello" 6 days ago Exited (0) 6 days ago frosty_galileo
wohu@iZm5egn5zptnov4j3oxh4fZ:~/docker$ docker stop 1f
1f
wohu@iZm5egn5zptnov4j3oxh4fZ:~/docker$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
89860f528c9a ubuntu:16.04 "/bin/echo 'this is …" 6 minutes ago Exited (0) 6 minutes ago admiring_driscoll
acb806366cf1 ubuntu:16.04 "/bin/bash" 15 minutes ago Exited (0) 15 minutes ago gifted_bartik
c6813fb16675 ubuntu:16.04 "/bin/echo 'hello wo…" 32 minutes ago Exited (0) 32 minutes ago determined_blackwell
1f51e44dab22 ubuntu:16.04 "/bin/bash" 37 minutes ago Exited (0) 3 seconds ago confident_wu
33197473a278 hello-world "/hello" 6 days ago Exited (0) 6 days ago frosty_galileo
wohu@iZm5egn5zptnov4j3oxh4fZ:~/docker$
處于終止狀態的容器,可以通過 docker start 命令來重新啟動,docker restart 命令會將一個運行態的容器先終止,然后再重新啟動它。
4. 進入容器
docker exec
在使用 -d 參數時,容器啟動后會進入后臺,用戶無法看到容器中的信息,也無法進行操作。使用 docker exec 命令,可以在容器內直接執行任意命令。
wohu@iZm5egn5zptnov4j3oxh4fZ:~/docker$ docker start ac
ac
wohu@iZm5egn5zptnov4j3oxh4fZ:~/docker$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
89860f528c9a ubuntu:16.04 "/bin/echo 'this is …" 13 minutes ago Exited (0) About a minute ago admiring_driscoll
acb806366cf1 ubuntu:16.04 "/bin/bash" 22 minutes ago Up 3 seconds gifted_bartik
c6813fb16675 ubuntu:16.04 "/bin/echo 'hello wo…" 40 minutes ago Exited (0) 40 minutes ago determined_blackwell
1f51e44dab22 ubuntu:16.04 "/bin/bash" 45 minutes ago Exited (0) 7 minutes ago confident_wu
33197473a278 hello-world "/hello" 6 days ago Exited (0) 6 days ago frosty_galileo
wohu@iZm5egn5zptnov4j3oxh4fZ:~/docker$ docker exec -ti ac /bin/bash
root@acb806366cf1:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@acb806366cf1:/# exit
exit
wohu@iZm5egn5zptnov4j3oxh4fZ:~/docker$
5. 刪除容器
docker rm -f|--force[-v|--volumes]CONTAINER[CONTAINER…]
使用 docker rm 命令來刪除處于終止或退出狀態的容器,主要支持的選項包括:
- -f,–force=false:是否強行終止并刪除一個運行中的容器
- -l,–link=false:刪除容器的連接,但保留容器
- -v,–volumes=false:刪除容器掛載的數據卷
默認情況下,docker rm 命令只能刪除處于終止或退出狀態的容器,并不能刪除還處于運行狀態的容器。
如果要直接刪除一個運行中的容器,可以添加 - f 參數。Docker 會先發送 SIGKILL 信號給容器,終止其中的應用,之后強行刪除。
wohu@iZm5egn5zptnov4j3oxh4fZ:~/docker$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
89860f528c9a ubuntu:16.04 "/bin/echo 'this is …" 19 minutes ago Exited (0) 7 minutes ago admiring_driscoll
acb806366cf1 ubuntu:16.04 "/bin/bash" 28 minutes ago Up 5 minutes gifted_bartik
c6813fb16675 ubuntu:16.04 "/bin/echo 'hello wo…" 45 minutes ago Exited (0) 45 minutes ago determined_blackwell
1f51e44dab22 ubuntu:16.04 "/bin/bash" About an hour ago Exited (0) 13 minutes ago confident_wu
33197473a278 hello-world "/hello" 6 days ago Exited (0) 6 days ago frosty_galileo
wohu@iZm5egn5zptnov4j3oxh4fZ:~/docker$ docker rm ac
Error response from daemon: You cannot remove a running container acb806366cf1e0374c5fd3eeac2e1d0a227fe88ae3b30006e0c6c0e2f1800348. Stop the container before attempting removal or force remove
wohu@iZm5egn5zptnov4j3oxh4fZ:~/docker$ docker rm -f ac
ac
wohu@iZm5egn5zptnov4j3oxh4fZ:~/docker$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
89860f528c9a ubuntu:16.04 "/bin/echo 'this is …" 20 minutes ago Exited (0) 7 minutes ago admiring_driscoll
c6813fb16675 ubuntu:16.04 "/bin/echo 'hello wo…" About an hour ago Exited (0) About an hour ago determined_blackwell
1f51e44dab22 ubuntu:16.04 "/bin/bash" About an hour ago Exited (0) 14 minutes ago confident_wu
33197473a278 hello-world "/hello" 6 days ago Exited (0) 6 days ago frosty_galileo
wohu@iZm5egn5zptnov4j3oxh4fZ:~/docker$
6. 導出容器
docker export[-o|-- output[=""]]CONTAINER
導出容器是指導出一個已經創建的容器到一個文件,不管此時這個容器是否處于運行狀態,可以使用 docker export 命令,其中,可以通過 - o 選項來指定導出的 tar 文件名,也可以直接通過重定向來實現。
wohu@iZm5egn5zptnov4j3oxh4fZ:~/docker$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
89860f528c9a ubuntu:16.04 "/bin/echo 'this is …" 20 minutes ago Exited (0) 7 minutes ago admiring_driscoll
c6813fb16675 ubuntu:16.04 "/bin/echo 'hello wo…" About an hour ago Exited (0) About an hour ago determined_blackwell
1f51e44dab22 ubuntu:16.04 "/bin/bash" About an hour ago Exited (0) 14 minutes ago confident_wu
33197473a278 hello-world "/hello" 6 days ago Exited (0) 6 days ago frosty_galileo
wohu@iZm5egn5zptnov4j3oxh4fZ:~/docker$ docker export -o 111.tar 89
wohu@iZm5egn5zptnov4j3oxh4fZ:~/docker$ docker export 89 > 222.tar
wohu@iZm5egn5zptnov4j3oxh4fZ:~/docker$ ls
111.tar 222.tar ubuntu.tar
wohu@iZm5egn5zptnov4j3oxh4fZ:~/docker$
之后,可將導出的 tar 文件傳輸到其他機器上,然后再通過導入命令導入到系統中,從而實現容器的遷移。
7. 導入容器
導出的文件又可以使用 docker import 命令導入變成鏡像。
wohu@iZm5egn5zptnov4j3oxh4fZ:~/docker$ ls
111.tar 222.tar ubuntu.tar
wohu@iZm5egn5zptnov4j3oxh4fZ:~/docker$ cat 222.tar | docker import - 222_import:v1.0
sha256:78ca641fd62347d9017eed3f1dbf5f1d5df05349b52c557f0b048ae444150421
wohu@iZm5egn5zptnov4j3oxh4fZ:~/docker$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
222_import v1.0 78ca641fd623 19 seconds ago 85.9MB
test_image latest 1cd880207b3e 3 days ago 116MB
ubuntu 16.04 a51debf7e1eb 2 weeks ago 116MB
hello-world latest 4ab4c602aa5e 3 months ago 1.84kB
wohu@iZm5egn5zptnov4j3oxh4fZ:~/docker$
實際上,既可以使用 docker load 命令來導入鏡像存儲文件到本地鏡像庫,也可以使用 docker import 命令來導入一個容器快照到本地鏡像庫。
docker load適用于鏡像docker import適用于容器
這兩者的區別在于容器快照文件將丟棄所有的歷史記錄和元數據信息 (即僅保存容器當時的快照狀態),而鏡像存儲文件將保存完整記錄,體積也更大。此外,從容器快照文件導入時可以重新指定標簽等元數據信息。
8. 容器的生命周期
9. docker kill 和 docker stop 區別
在上面關于docker容器生命周期管理中stop 和 kill 都是關閉容器,但是其中的kill是怎么實現強制殺死運行中的容器的呢?
這里需要說明下關linux下關于終止進程的信號:SIGTERM 和 SIGKILL
SIGKILL信號:無條件終止進程信號。進程接收到該信號會立即終止,不進行清理和暫存工作。該信號不能被忽略、處理和阻塞,它向系統管理員提供了可以殺死任何進程的方法。
SIGTERM信號:程序終結信號,可以由kill命令產生。與SIGKILL不同的是,SIGTERM信號可以被阻塞和終止,以便程序在退出前可以保存工作或清理臨時文件等。
docker stop 會先發出SIGTERM信號給進程,告訴進程即將會被關閉。在-t指定的等待時間過了之后,將會立即發出SIGKILL信號,直接關閉容器。
docker kill 直接發出SIGKILL信號關閉容器。但也可以通過-s參數修改發出的信號。
docker restart 中同樣可以設置 -t 等待時間,當等待時間過后會立刻發送SIGKILL信號,直接關閉容器。
因此會發現在docker stop的等待過程中,如果終止docker stop的執行,容器最終沒有被關閉。而docker kill幾乎是立刻發生,無法撤銷。
10. 容器和鏡像轉換關系
11. 查看容器內部細節
可用通過如下命令 docker insepct 查看容器內部細節,返回為 json:
docker insepct container-id
12. 容器和宿主機互相拷貝文件
- 宿主機拷貝文件到容器:
docker cp 文件 container-id:目標文件/文件夾
示例:
docker cp /tmp/test.txt 7f237caad43b:/tmp
將宿主機 /tmp/test.txt 文件拷貝到容器 7f237caad43b中 /tmp 目錄中。
- 從容器拷貝文件到宿主機:
docker cp container-id:目標文件/文件夾 宿主機目標文件/文件夾
示例:
docker cp 7f237caad43b:/tmp/log.log /tmp
將容器 7f237caad43b 中 /tmp/log.log 拷貝到宿主機 /tmp 目錄下。
13. 查看容器日志
查看容器實時運行的日志
docker logs -f -t --tail=行數 容器ID或容器名
查看容器從某個時刻開始的日志
docker logs -f -t --since="2018-11-28" --tail=10 容器ID或容器名
總結
以上是生活随笔為你收集整理的Docker 入门系列(3)- Docker 容器(创建、启动、终止、进入、删除、导入、导出容器、容器和镜像转化)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Docker 入门系列(2)- Dock
- 下一篇: Docker 入门系列(4)- Dock