原文地址:http://blog.jboost.cn/docker-6.html
容器是Docker中的另一核心概念,在Docker中,應用的運行都是在容器內進行的,容器則基於鏡像創建。前面已對Docker鏡像做了基本介紹,本文對Docker容器管理的相關內容做一個梳理。
1. 啟動容器
啟動容器的命令格式如下
docker run [OPTIONS] IMAGE-NAME [COMMAND] [ARG...]
其中OPTIONS部分可指定容器運行的一些可選項,常用選項包括:
- -d 將容器以后台進程(daemon)的形式運行
- -p 指定容器內應用暴露端口與主機端口的映射,如 -p 8080:80 表示將容器內80端口映射到主機的8080端口(主機端口在前,容器端口在后)
- -v 指定容器與主機的掛載目錄映射,如 -v /var/log:/log 表示將容器的/log目錄掛載到主機的/var/log目錄(同樣主機目錄在前,容器目錄在后),后續對容器的/log寫操作實際作用於主機的/var/log目錄
- -e 為容器設置環境變量
- -t 為容器啟動一個偽終端(pseudo-tty)
- -i 讓容器的標准輸入保持打開,一般與 -t 配合使用,讓容器啟動后就打開一個可交互的命令行界面
- -w 指定容器的工作目錄
COMMAND [ARG..] 部分就是容器需要運行的應用進程啟動命令與參數,如果鏡像中有通過 CMD, 或 ENTRYPOINT 指定了容器啟動程序,則可省略。另外可通過 –name 指定容器的名稱,以及 –restart 來指定重啟策略,–restart有三種取值,代表容器支持的三種不同的重啟策略
取值 | 描述 |
---|---|
always | 除非被docker stop 命令明確停止,否則一直嘗試重啟處於停止態的容器;如果Docker重啟,也會自動啟動容器 |
unless-stopped | 與always的區別是,停止態的容器不在Docker重啟的時候被重啟 |
on-failed | 在容器退出時返回值不為0的時候,重啟容器;如果Docker重啟,容器也會被啟動,不管之前是否處於停止狀態 |
以啟動一個mysql數據庫服務為例
docker run -d -p 3306:3306 --name mysql \ -v /home/devuser/apps/mysql/conf/my.cnf:/etc/mysql/conf.d/my.cnf \ -v /home/devuser/apps/mysql/logs:/var/log/mysql \ -v /home/devuser/apps/mysql/data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=Passw0rd --restart=always mysql:5.7
上述命令啟動了一個mysql容器服務,-d 表示以后台進程運行,執行命令后只返回一個容器ID,不會輸出任何其它信息;-p 將容器暴露的端口3306映射到宿主機的3306端口,外部主機就可以通過宿主機IP與3306端口來訪問mysql服務; –name 指定了容器名稱為mysql; -v 將mysql的配置文件路徑、日志路徑、數據存儲路徑映射到了宿主機對應的路徑目錄;-e 設置了一個環節變量指定mysql root賬號的密碼;–restart 指定容器在異常退出時,包括Docker重啟時,自動啟動容器。
我們前面有提過,當我們執行CLI命令時,實際上是客戶端(Docker Client)通過發送請求到Docker后台進程(Docker Daemon),由Docker后台進程來執行的,那么當我們執行上述docker run
命令的時候,Docker后台進程具體都干了些啥呢?一般來說,包括如下幾個操作步驟
- 檢測本地是否存在指定的鏡像,如果不存在,就從公共倉庫下載
- 利用鏡像創建一個容器,並啟動它
- 分配一個文件系統,並在只讀的鏡像層上面掛載一層可讀寫層(容器存儲層)
- 從宿主機配置的網橋接口中橋接一個虛擬接口到容器中去
- 從地址池配置一個 ip 地址給容器
- 執行用戶指定的應用程序
- 執行應用程序完畢后容器被終止
2. 管理已有容器
一般對已有容器的管理包括如下幾個操作:
- 查看運行中的容器
docker ps
或docker container ls
- 查看所有容器
docker ps -a
或docker container ls -a
- 停止運行
docker stop xxx
- 開始停止狀態的容器
docker start xxx
- 重啟運行狀態的容器
docker restart xxx
- 刪除停止狀態的容器
docker rm xxx
- 強制刪除容器(包括運行狀態中)
docker rm -f xxx
- 刪除所有停止狀態的容器
docker container prune
其中xxx既可以是容器ID(短ID即可,只要與其它區分開來),也可以是容器名稱。docker rm
之前必須要先docker stop
將容器置為停止狀態,而docker rm -f
可以強制刪除運行狀態的容器,其背后是通過Linux/POSIX信號來實現的,docker rm -f
命令直接發出SIGKILL
信號,不會給容器內運行進程任何緩沖的時間,立即終止,而docker stop
命令卻是先發送SIGTERM
信號,通知容器進程結束,會為進程預留一個清理並優雅停止的機會,如果一段時間后進程還沒有終止,那么就會發送SIGKILL
信號,來終止進程的運行。
我們也可以像鏡像操作中一樣,組合使用命令來更方便地操作,如強制刪除所有容器(慎用)
docker rm -f $(docker ps -aq)
3. 進入容器
容器在運行時指定 -d 選項時, 是以后台進程的形式運行的,如果我們需要進入容器查看或操作,可以通過docker exec
命令,docker exec
命令的格式如下
docker exec [OPTIONS] container-id COMMAND
OPTIONS常用的一般是 -t, -i,意義跟在docker run
選項中一樣 —— 為容器啟動一個偽終端(pseudo-tty),並保持標准輸入打開,從而可以像Linux命令行一樣進行交互, COMMAND一般為 bash
。
另外還有一個命令是docker attach xxx
,其中xxx是容器ID,但推薦使用docker exec
,因為docker attach
中當執行exit
退出容器時,容器也會隨之終止,但docker exec
則不會。
如果不進入容器,也可以通過docker logs xxx
,xxx是容器ID,來查看容器的輸出信息。
4. 導入導出容器
可以使用docker export
命令將一個容器的快照進行導出,如
docker export xxx > mycontainer.tar
其中xxx是容器ID,可以通過docker ps -a
查看,上述命令將容器的當前快照導出到了本地文件。
docker import
命令則可以將一個容器快照文件導入為鏡像,如
cat mycontainer.tar | docker import - test/myimage:v1.0
也可以通過URL來導入,如
docker import http://test.com/testimage.tgz test/myimage2:v1.0
由此可見,我們獲取鏡像又多了一個來源——從已有容器快照文件導入。
5. 總結
本文對容器的一些基本操作進行了介紹,需要注意的是如之前所說,容器應以無狀態的形式運行,所有產生的數據應該通過掛載數據卷的方式寫入宿主機文件目錄,避免容器銷毀時造成數據丟失;盡量使用docker stop
+ docker rm
的方式來替代docker rm -f
,使容器內運行程序“優雅”地退出。有時候可能遇到這樣的場景,容器創建運行后,我們需要對運行的一些參數進行更新或添加,這時候該怎么操作。后文會對該場景進行介紹,歡迎關注。
我的個人博客地址:http://blog.jboost.cn
我的微信公眾號:jboost-ksxy (一個不只有技術干貨的公眾號,歡迎關注,及時獲取更新內容)
———————————————————————————————————————————————————————————————