文章目錄
- 一、什么是容器?
- 二、為什么需要容器
- 三、容器的生命周期
- 容器狀態
- 容器OOM
- 容器異常退出
- 容器異常退出
- 容器暫停
- 四、容器命令
- 命令清單
- 詳細介紹
- 五、容器操作案例
- 容器的狀態遷移
- 容器批量操作
- 容器交互模式
- attached 模式
- detached 模式
- interactive 模式
- 容器 與 宿主機 文件拷貝
- 容器 自動刪除 與 自動重啟
- 容器環境變量設置
- 查看容器的詳細信息
- 容器鏡像的導入導出
- 鏡像的資源查看
- 鏡像的日志查看
- 容器的資源查看
- 六、綜合實戰
- Mysql 容器化安裝
- Redis 容器化安裝
- Redis 出現的原因
- Redis 是什么
- Redis 的應用場景
- C++ 容器制作
- 容器資源更新
一、什么是容器?
首先,我們了解了鏡像,容器可以被視為鏡像的實際運行實例。鏡像本身是一個靜態且只讀的文件,而容器則在此基礎上附加了一個可寫的文件層,這使得容器能夠運行需要的進程。簡單來說,容器是運行著實際應用進程的實體。
容器有五種基本狀態:創建、運行、停止、暫停和刪除。
容器本質上是主機上一個運行的進程,但它通過獨立的命名空間隔離和資源限制與主機進程區分開來。在容器內部,無法直接訪問主機上的進程、環境變量或網絡等信息,這也是容器與直接在主機上運行的進程之間的關鍵區別。
容器是基于鏡像創建的可執行實例,且可以獨立存在。一個鏡像可以啟動多個容器實例。容器化環境的運行實質上是在容器內創建一個文件系統的讀寫副本,也就是說,為鏡像添加了一層新的容器層,這一層允許對鏡像副本進行修改。
鏡像和容器的關系就像:一個類實例化出多個對象,而這幾個對象的差別卻很大;
當然,容器的差別主要體現在它們的運行時狀態上(比如不同容器內的文件更改、配置或進程等)
二、為什么需要容器
我們知道,鏡像是靜態的文件,其自身并不能提供服務,類似一個Windows、Linux的光驅,需要在主機上才能運行;
同理,真正的應用環境在容器中運行。
下面再簡單列舉一下 為什么需要容器:
-
輕量級虛擬化:容器比傳統虛擬機更輕便,占用資源少,啟動更快。
-
環境隔離:每個容器都提供獨立的運行環境,避免應用之間的環境沖突。
-
一致的開發、測試和生產環境:容器保證在不同環境中應用的運行一致性,解決“在我電腦上能跑”的問題。
-
高效的資源利用:容器共享宿主操作系統的內核,減少資源浪費,相比虛擬機能運行更多實例。
-
快速啟動和部署:容器啟動速度快,通常在幾秒鐘內即可啟動,適用于快速部署和動態伸縮。
-
簡化運維管理:容器化應用易于管理、遷移和擴展,便于自動化部署和持續集成。
三、容器的生命周期
容器狀態
類比進程的生命周期,容器的生命周期一樣與其運行狀態相關,容器有以下五種運行狀態:
- created:初建狀態
- running:運行狀態
- stopped:停止狀態
- paused:暫停狀態
- deleted:刪除狀態
各生命周期之間的轉換關系如圖所示:
我們可以通過下面命令,對容器進行操作并將容器轉為不同的狀態:
-
docker create
創建容器后,不立即啟動運行,容器進入初建狀態。 -
docker run
創建容器,并立即啟動運行,進入運行狀態。 -
docker start
容器轉為運行狀態。 -
docker stop
容器將轉入停止狀態。 -
docker kill
容器在故障(死機)時執行kill
(斷電),容器轉入停止狀態。
這種操作容易丟失數據,除非必要,否則不建議使用。 -
docker restart
重啟容器,容器轉入運行狀態。 -
docker pause
容器進入暫停狀態。 -
docker unpause
取消暫停狀態,容器進入運行狀態。 -
docker rm
刪除容器,容器轉入刪除狀態。 -
容器異常終止
-
killed by out-of-memory
(因內存不足被終止)
宿主機內存被耗盡,也被稱為 OOM(Out Of Memory)。
解決方案:非計劃終止時,需要殺死最吃內存的容器。 -
container process exited
(異常終止)
當容器異常終止后,會出現Should restart?
選項。
可選擇以下操作:-
yes
需要重啟,容器執行start
命令,轉為運行狀態。 -
no
不需要重啟,容器轉為停止狀態。
-
-
容器OOM
OOM 即 Out of Memory(內存不足),即計算機或系統在運行時,嘗試分配更多內存給進程,但系統的物理內存或虛擬內存已經用盡,無法再分配給該進程或其他進程,從而導致該進程被操作系統終止或掛起。
- 如果容器中的應用耗盡了主機系統分配給容器的內存限額,就會觸發 OOM 事件。
- 比如在容器中部署了一個 web 服務。假設主機分配給該容器的內存上限為 1G,當腳本申請的內存大于 1G 時,容器就會觸發 OOM 事件。而在這種情況下,此容器將會被強制關閉。
- 需要注意的是,關閉容器的并非是 Docker Daemon,而是宿主機操作系統。因為容器本質是一組運行在宿主機操作系統中的進程,宿主機操作系統通過 cgroups 對這組進程設定資源上限,當這些進程申請的資源到達上限時,觸發的是宿主機操作系統的內核 OOM 事件。
- 如果用戶不想關閉該容器,可以通關
--oom-kill-disable
來禁用OOM-Killer
。- 使用此參數時,仍需注意,如果使用
-m
設置了此容器內存上限,當容器達到內存資源上限時,主機不會關閉容器,也不會繼續向此容器繼續分配資源,此時容器將處于 掛起(hung) 狀態。
- 使用此參數時,仍需注意,如果使用
- 如果用戶使用了
--oom-kill-disable
,但未使用-m
來設定上限,此時容器將盡可能多的使用主機內存資源。(主機內存有多大,它就將用多大)
容器異常退出
容器異常退出
每個 Docker 容器內部都運行一個 Init 進程,容器內的其他進程都是由 Init 進程派生出來的子進程。容器的生命周期實際上與 Init 進程的運行狀態密切相關。如果一個子進程發生異常退出,它的父進程也會隨之退出,最終導致 Init 進程退出,從而使整個容器停止運行。
當 Init 進程退出時,容器會自動停止。此時,Docker 無法判斷進程退出是正常還是異常。當容器停止時,Docker Daemon 會嘗試將容器從“已停止”狀態恢復到“運行中”狀態。但只有在容器啟用了 --restart
參數時,Docker Daemon 才會嘗試重啟容器,否則容器將保持在停止狀態。
容器暫停
當 Docker 暫停容器時,容器的 CPU 資源會被“剝奪”,但其他資源,如內存 (Memory) 和網絡 (Network) 資源,仍然保持不變。失去 CPU 資源的進程將不會被主機的內核調度,從而使該容器處于“凍結”狀態。
四、容器命令
命令清單
下面是 Docker
容器的相關命令:
命令 | 別名 | 功能 | 備注 |
---|---|---|---|
docker create | docker container create | 創建容器 | |
docker run | docker container run | 運行容器 | 必須掌握 |
docker attach | docker container attach | 連接到正在運行中的容器 | |
docker commit | docker container commit | 將鏡像提交為容器 | 必須掌握 |
docker cp | docker container cp | 在容器和宿主機之間拷貝 | 必須掌握 |
docker diff | docker container diff | 檢查容器里文件結構的更改 | |
docker exec | docker container exec | 在運行的容器中執行命令 | 必須掌握 |
docker export | docker container export | 將容器導出為 tar | |
docker inspect | docker container inspect | 查看容器詳細信息 | 必須掌握 |
docker kill | docker container kill | 殺死容器 | 必須掌握 |
docker logs | docker container logs | 查看日志 | 必須掌握 |
docker ps | docker container ls , docker container list , docker container ps | 查看正在運行的進程 | 必須掌握 |
docker pause | docker container pause | 暫停進程 | |
docker port | docker container port | 查看容器的端口映射 | |
docker container prune | 刪除停止的容器 | ||
docker rename | docker container rename | 重命名容器 | |
docker restart | docker container restart | 重啟容器 | 必須掌握 |
docker rm | docker container rm , docker container remove | 刪除容器 | 必須掌握 |
docker start | docker container start | 啟動容器 | 必須掌握 |
docker stats | docker container stats | 查看資源占用信息 | 必須掌握 |
docker stop | docker container stop | 停止容器 | 必須掌握 |
docker top | docker container top | 查看某個容器的資源占用 | 必須掌握 |
docker unpause | docker container unpause | 繼續運行容器 | |
docker update | docker container update | 更新容器配置 | |
docker wait | docker container wait | 阻止一個或多個容器停止 |
詳細介紹
-
docker create
- 功能: 創建一個新的容器但不啟動它
- 語法:
docker create [OPTIONS] IMAGE [COMMAND] [ARG...]
- 別名:
docker container create
- 關鍵參數:
-i
: 以交互模式運行容器,通常與-t
同時使用-P
: 隨機端口映射-p
: 指定端口映射,格式:主機端口:容器端口
-t
: 為容器重新分配一個偽輸入終端,通常與-i
同時使用--name="nginx-lb"
: 為容器指定名稱-h "mars"
: 指定容器的 hostname-e username="ritchie"
: 設置環境變量--cpuset-cpus="0-2"
: 綁定容器到指定 CPU 運行-m
: 設置容器使用的最大內存--network="bridge"
: 指定容器的網絡連接類型--link=[]
: 添加鏈接到另一個容器--volume , -v
: 綁定一個卷--rm
: 容器退出時自動刪除--restart
: 自動重啟容器
- 樣例:
docker create --name mynginx nginx:latest
-
docker run
- 功能: 創建一個新的容器并運行一個命令
- 語法:
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
- 別名:
docker container run
- 關鍵參數:
-d
: 后臺運行容器,并返回容器 ID-i
: 以交互模式運行容器,通常與-t
同時使用-P
: 隨機端口映射-p
: 指定端口映射,格式:主機端口:容器端口
-t
: 為容器重新分配一個偽輸入終端,通常與-i
同時使用--name="nginx-lb"
: 為容器指定名稱-h "mars"
: 指定容器的 hostname-e username="ritchie"
: 設置環境變量--cpuset-cpus="0-2"
: 綁定容器到指定 CPU 運行-m
: 設置容器使用的最大內存--network="bridge"
: 指定容器的網絡連接類型--link=[]
: 添加鏈接到另一個容器--volume , -v
: 綁定一個卷--rm
: 容器退出時自動刪除--restart
: 自動重啟容器
- 樣例:
docker run --name mynginx -d nginx:latest docker run -p 80:80 -v /data:/data -d nginx:latest
-
docker ps
- 功能: 列出容器
- 語法:
docker ps [OPTIONS]
- 別名:
docker container ls
,docker container list
,docker container ps
- 關鍵參數:
-a
: 顯示所有容器,包括未運行的-f
: 根據條件過濾顯示--format
: 指定返回值的模板文件,如json
或table
-l
: 顯示最新的容器-n
: 列出最近創建的 N 個容器--no-trunc
: 不截斷輸出-q
: 靜默模式,只顯示容器編號-s
: 顯示容器總的文件大小
- 樣例:
docker ps -a
-
docker logs
- 功能: 查看容器日志
- 語法:
docker logs [OPTIONS] CONTAINER
- 別名:
docker container logs
- 關鍵參數:
-f ,--follow
: 跟蹤日志輸出--since
: 顯示某個開始時間的所有日志-t, --timestamps
: 顯示時間戳-n, --tail
: 僅列出最新 N 條容器日志
- 樣例:
docker logs -f mynginx docker logs --since="2016-07-01" --tail=10 mynginx
-
docker attach
- 功能: 連接到正在運行中的容器
- 語法:
docker attach [OPTIONS] CONTAINER
- 別名:
docker container attach
- 關鍵參數:
--sig-proxy
: 是否將所有信號代理,默認是true
- 樣例:
docker attach mynginx docker attach --sig-proxy=false mynginx
-
docker exec
- 功能: 在容器中執行命令
- 語法:
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
- 別名:
docker container exec
- 關鍵參數:
-d
: 分離模式,在后臺運行-i
: 即使沒有附加也保持 STDIN 打開-t
: 分配一個偽終端-e
: 設置環境變量-u, --user
: 指定用戶<name|uid>[:<group|gid>]
-w, --workdir
: 指定工作目錄
- 樣例:
docker exec -it mynginx echo "Hello bit" docker exec -it mynginx bash
-
docker start
- 功能: 啟動停止的容器
- 語法:
docker start [OPTIONS] CONTAINER [CONTAINER...]
- 別名:
docker container start
- 樣例:
docker start mynginx
-
docker stop
- 功能: 停止運行中的容器
- 語法:
docker stop [OPTIONS] CONTAINER [CONTAINER...]
- 別名:
docker container stop
- 關鍵參數:
-s
: 發送的信號
- 樣例:
docker stop mynginx
-
docker restart
- 功能: 重啟容器
- 語法:
docker restart [OPTIONS] CONTAINER [CONTAINER...]
- 別名:
docker container restart
- 關鍵參數:
-s
: 發送信號
- 樣例:
docker restart mynginx
-
docker kill
- 功能: 強制退出容器
- 語法:
docker kill [OPTIONS] CONTAINER [CONTAINER...]
- 別名:
docker container kill
- 關鍵參數:
-s
: 發送的信號
- 注意事項:
docker kill
發送的是SIGKILL
信號,而docker stop
發送的是SIGTERM
信號 - 樣例:
docker kill mynginx
-
docker top
- 功能: 查看容器中運行的進程信息,支持
ps
命令參數 - 語法:
docker top CONTAINER [ps OPTIONS]
- 別名:
docker container top
- 樣例:
docker top mynginx
- 功能: 查看容器中運行的進程信息,支持
-
docker stats
- 功能: 顯示容器資源的使用情況,包括 CPU、內存、網絡 I/O 等
- 語法:
docker stats [OPTIONS] [CONTAINER...]
- 別名:
docker container stats
- 關鍵參數:
--no-stream
: 不刷新
- 樣例:
docker stats --no-stream docker stats mynginx
-
docker container inspect
- 功能: 查看容器詳細信息
- 語法:
docker container inspect [OPTIONS] CONTAINER [CONTAINER...]
- 關鍵參數:
-f
: 指定返回值的模板文件,如table
、json
-s
: 顯示總的文件大小
- 注意事項:
docker inspect
會自動檢查是鏡像還是容器,然后顯示詳細信息
- 樣例:
docker container inspect mynginx
-
docker port
- 功能: 用于列出指定容器的端口映射,或者查找將
PRIVATE_PORT
NAT 到面向公眾的端口 - 語法:
docker port CONTAINER [PRIVATE_PORT[/PROTO]]
- 別名:
docker container port
- 樣例:
docker port mynginx
- 功能: 用于列出指定容器的端口映射,或者查找將
-
docker cp
- 功能: 在容器和宿主機之間拷貝文件
- 語法:
docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|- docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
- 別名:
docker container cp
- 樣例:
# 將主機 /www/ 目錄拷貝到容器 mynginx 的 /www 目錄下 docker cp /www/ mynginx:/www/ # 將容器 /www/ 目錄拷貝到主機的 /wwwbak 目錄下 docker cp mynginx:/www/ /wwwbak/
-
docker diff
- 功能: 檢查容器里文件結構的更改
- 語法:
docker diff CONTAINER
- 樣例:
docker diff mynginx
-
docker commit
- 功能: 從容器創建一個新的鏡像
- 語法:
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
- 參數:
-a
: 提交的鏡像作者-c
: 使用 Dockerfile 指令來創建鏡像,可以修改啟動指令-m
: 提交時的說明文字-p
: 在 commit 時,將容器暫停
- 樣例:
docker commit c3f279d17e0a maxhou/mynginx:v01
-
docker pause
- 功能: 暫停容器中所有的進程
- 語法:
docker pause CONTAINER [CONTAINER...]
- 別名:
docker container pause
- 樣例:
docker pause mynginx
-
docker unpause
- 功能: 恢復容器中所有的進程
- 語法:
docker unpause CONTAINER [CONTAINER...]
- 別名:
docker container unpause
- 樣例:
docker unpause mynginx
-
docker rm
- 功能: 刪除停止的容器
- 語法:
docker rm [OPTIONS] CONTAINER [CONTAINER...]
- 別名:
docker container rm
- 關鍵參數:
-f
: 通過SIGKILL
信號強制刪除一個運行中的容器
- 樣例:
# 刪除 mynginx 容器 docker stop mynginx docker rm mynginx # 刪除所有停止的容器 docker rm $(docker ps -a -q)
-
docker export
- 功能: 導出容器內容為 tar 文件
- 語法:
docker export [OPTIONS] CONTAINER
- 別名:
docker container export
- 關鍵參數:
-o
: 寫入到文件
- 樣例:
# 導出 nginx 為 tar 文件 docker export -o mynginx202203.tar mynginx
-
docker wait
- 功能: 阻塞運行直到容器停止,然后打印出它的退出代碼
- 語法:
docker wait CONTAINER [CONTAINER...]
- 別名:
docker container wait
- 樣例:
docker wait mynginx
-
docker rename
- 功能: 重命名容器
- 語法:
docker rename CONTAINER NEW_NAME
- 別名:
docker container rename
- 樣例:
docker rename mynginx myweb
-
docker container prune
- 功能: 刪除所有停止的容器
- 語法:
docker container prune [OPTIONS]
- 關鍵參數:
-f
,--force
: 不提示是否進行確認
- 樣例:
docker container prune
-
docker update
- 功能: 更新容器配置
- 語法:
docker update [OPTIONS] CONTAINER [CONTAINER...]
- 別名:
docker container update
- 關鍵參數:
--cpus
: 設置 CPU 數量--cpuset-cpus
: 使用哪些 CPU--memory
: 設置內存限制--memory-swap
: 設置交換內存--cpu-period
: 用來指定容器對 CPU 的使用要在多長時間內做一次重新分配--cpu-quota
: 用來指定在這個周期內,最多可以有多少時間用來跑這個容器
- 樣例:
# 更新內存 docker update -m 400m myweb
五、容器操作案例
容器的狀態遷移
下面演示一下容器的基本的狀態改變操作:
- 通過
docker create
命令進行容器的創建:
ubuntu@VM-8-2-ubuntu:~$ docker create --name mynginx -p 8080:80 nginx:1.24.0
4c269e3619d4b40a22d94ef031edab6abaf06059020d3e520f92b0d62bff55ee
- 通過
docker ps
命令可以查看創建的容器:
ubuntu@VM-8-2-ubuntu:~$ docker ps -a | grep mynginx
23400afbdb50 nginx:1.24.0 "/docker-entrypoint.…" About a minute ago Created mynginx
- 隨后啟動容器:
ubuntu@VM-8-2-ubuntu:~$ docker start mynginx
mynginx
ubuntu@VM-8-2-ubuntu:~$ docker ps -a | grep mynginx
4c269e3619d4 nginx:1.24.0 "/docker-entrypoint.…" About a minute ago Up About a minute 0.0.0.0:8080->80/tcp, [::]:8080->80/tcp mynginx
- 通過
docker stop
停止容器:
ubuntu@VM-8-2-ubuntu:~$ docker stop mynginx
mynginx
ubuntu@VM-8-2-ubuntu:~$ docker ps -a | grep mynginx
4c269e3619d4 nginx:1.24.0 "/docker-entrypoint.…" 2 minutes ago Exited (0) 3 seconds ago mynginx
- 再次啟動容器后 kill 容器:
ubuntu@VM-8-2-ubuntu:~$ docker start mynginx
mynginx
ubuntu@VM-8-2-ubuntu:~$ docker kill mynginx
mynginx
ubuntu@VM-8-2-ubuntu:~$ docker ps -a | grep mynginx
4c269e3619d4 nginx:1.24.0 "/docker-entrypoint.…" 4 minutes ago Exited (137) 3 seconds ago mynginx
- 啟動容器后暫停容器:
ubuntu@VM-8-2-ubuntu:~$ docker start mynginx
mynginx
ubuntu@VM-8-2-ubuntu:~$ docker pause mynginx
mynginx
ubuntu@VM-8-2-ubuntu:~$ docker ps -a | grep mynginx
4c269e3619d4 nginx:1.24.0 "/docker-entrypoint.…" 4 minutes ago Up 7 seconds (Paused) 0.0.0.0:8080->80/tcp, [::]:8080->80/tcp mynginx
- 恢復容器:
ubuntu@VM-8-2-ubuntu:~$ docker unpause mynginx
mynginx
ubuntu@VM-8-2-ubuntu:~$ docker ps -a | grep mynginx
4c269e3619d4 nginx:1.24.0 "/docker-entrypoint.…" 5 minutes ago Up 38 seconds 0.0.0.0:8080->80/tcp, [::]:8080->80/tcp mynginx
- 重啟容器,可以觀察到啟動時間變快了:
ubuntu@VM-8-2-ubuntu:~$ docker ps -a | grep mynginx
4c269e3619d4 nginx:1.24.0 "/docker-entrypoint.…" 9 minutes ago Up 5 seconds 0.0.0.0:8080->80/tcp, [::]:8080->80/tcp mynginx
ubuntu@VM-8-2-ubuntu:~$ docker restart mynginx
mynginx
ubuntu@VM-8-2-ubuntu:~$ docker ps -a | grep mynginx
4c269e3619d4 nginx:1.24.0 "/docker-entrypoint.…" 10 minutes ago Up 2 seconds 0.0.0.0:8080->80/tcp, [::]:8080->80/tcp mynginx
- 通過
docker rm
可以刪除容器:
ubuntu@VM-8-2-ubuntu:~$ docker stop mynginx
mynginx
ubuntu@VM-8-2-ubuntu:~$ docker rm mynginx
mynginx
容器批量操作
命令 | 解釋 |
---|---|
docker container ls -qf name=xxx | 根據容器名稱過濾,返回與名稱匹配的容器 ID。 |
docker container ls -f status=running | 根據容器狀態過濾,顯示所有正在運行的容器。 |
docker container ls -aq | 靜默模式,列出所有容器的容器 ID(包括運行中和停止的容器)。 |
docker container ls -f ancestor=xxx | 根據鏡像名稱過濾,顯示所有使用指定鏡像(如 xxx )的容器。 |
docker container ls -f ancestor=xxx | 根據鏡像 ID 過濾,顯示所有使用指定鏡像 ID(如 xxx )的容器。 |
參數:
-q
:只返回容器的 ID,不顯示其他信息。-a
:包括所有容器(包括停止的容器)。-f
/--filter
:允許根據不同的條件進行過濾,條件如狀態、鏡像等。
我們可以利用上面的批量選擇,執行一些對容器的批量操作,比如想要批量刪除容器:
# 根據容器狀態進行刪除
docker container rm $(docker container ls -q --filter status=exited)
# 刪除所有容器
docker container rm $(docker container ls -aq)
類比這種方式,我們可以對容器進行各種批量操作,下面是相關的刪除操作:
操作描述 | 命令 |
---|---|
根據容器狀態刪除已退出容器 | docker container rm $(docker container ls -q --filter status=exited) |
刪除所有容器(包括運行中的和已停止的) | docker container rm $(docker container ls -aq) |
刪除所有已停止的容器 | docker container rm $(docker container ls -aq --filter "status=exited") |
刪除所有懸掛的容器(未運行的容器) | docker container prune -f |
停止并刪除所有容器 | docker stop $(docker ps -q) && docker rm $(docker ps -aq) |
刪除指定名稱的容器 | docker container rm <container_name> <container_name> |
容器交互模式
attached 模式
對于下面的命令:
# 通過 nginx 鏡像創建一個容器, 映射 80 端口
[wqy@vm~]$ docker container run -p 80:80 nginx
-p 80:80
表示端口映射,第一個端口表示映射到宿主機的端口,第二個端口表示映射到 Docker 容器的端口。- 通過這種方式運行的容器,就是attached模式,容器在前臺運行。
- 訪問服務器網址的時候,每訪問一次,命令窗口就會打印一次日志,Docker 容器日志會實時展現到窗口并占用此端口
attached
模式僅適用于容器和程序的調試階段- 而在linux服務器下,通過Ctrl+C信號就可以停止docker服務,實在不太方便(穩定),為了更加穩定,一般可以選用
detached
模式(后文介紹)
detached 模式
在 docker container run -p 80:80 nginx
命令基礎上加 -d
/ --detach
選項表示 detached 模式
docker container run -p -d 80:80 nginx
對于 detached
模式:
- 在后臺運行,啟動后只顯示容器 ID,并且可以輸入任何命令
- 關掉窗口后依然繼續運行,停止和刪除容器都需要使用 shell 命令,減少誤操作的可能
- 一般更建議使用該模式
- 我們可以通過
docker container attach <name>
將detached模式下的容器轉為attached
interactive 模式
當我們創建好一個容器之后, 可能需要去容器內部獲取信息或執行命令,就需要進入到交互式模式。
例如創建一個 Ubuntu 容器后,需要到系統里輸入各種 Shell 命令和系統進行交互,就需要先進入交互式模式。
docker container run -it nginx sh
上面的命令用于啟動一個 nginx 容器,并在其中運行 sh(shell)命令,進入容器的交互式終端(Shell)。
我們可以在Shell中執行下面的命令:
bin boot dev docker-entrypoint.d docker-entrypoint.sh
etc home lib lib64 media mnt opt proc root run
sbin srv sys tmp usr var
-i:保持容器運行。通常與 -t 同時使用,加入 it 這兩個參數后,容器創建后自動進入容器中,退出容器后,容器自動關閉
-t
:為容器重新分配一個偽輸入終端,通常與 -i 同時使用
針對一個已經運行的容器里進入到交互模式
對于一個已經運行的容器,我們可以通過下面的命令,將其轉為交互式模式:
docker container exec -it <name> sh
同時可以通過 exit
退出交互式模式。
容器 與 宿主機 文件拷貝
一般我們可以通過 以下方法 實現 容器 與 宿主機間的文件拷貝:
docker cp
命令- Docker 網絡
- 掛載卷(Volume)
- 使用共享文件夾
下面分別進行簡單舉例:
1, 使用 docker cp
命令
docker cp
命令可以在宿主機與容器之間直接拷貝文件或目錄。
- 從宿主機拷貝文件到容器
docker cp /path/on/host <container_id>:/path/in/container# 示例
docker cp /home/user/data.txt my_container:/root/data.txt
# 將宿主機上的 `/home/user/data.txt` 文件拷貝到容器 `my_container` 的 `/root/data.txt` 路徑。
-
/path/on/host
:宿主機上的文件或目錄路徑。 -
<container_id>
:容器的 ID 或名稱。 -
/path/in/container
:容器內目標路徑。 -
從容器拷貝文件到宿主機
docker cp <container_id>:/path/in/container /path/on/host‘# 示例
docker cp my_container:/root/data.txt /home/user/data.txt
# 將容器 my_container 中 /root/data.txt 文件拷貝到宿主機的 /home/user/data.txt 路徑。
<container_id>
:容器的 ID 或名稱。/path/in/container
:容器內的文件或目錄路徑。/path/on/host
:宿主機上的目標路徑。
- 使用掛載卷(Volume)
卷是 Docker 提供的一種持久化數據的方法。通過掛載卷,可以讓容器與宿主機共享文件和目錄。
使用命令行創建卷并掛載
我們可以在啟動容器時通過 -v
或 --mount
選項掛載一個宿主機目錄到容器的某個路徑,這樣容器和宿主機就可以共享該目錄的文件。
docker run -v /path/on/host:/path/in/container <image_name>
/path/on/host
:宿主機上的目錄。/path/in/container
:容器內的目錄路徑。
- 使用共享目錄(Bind Mount)
與卷類似**,綁定掛載(Bind Mount)允許容器直接訪問宿主機上的指定目錄。通過綁定宿主機和容器的文件路徑,可以讓文件互通。**
docker run --mount type=bind,source=/path/on/host,target=/path/in/container <image_name>
source=/path/on/host
:宿主機目錄路徑。target=/path/in/container
:容器內目錄路徑。
- 使用 Docker 網絡(適用于容器間通信)
如果容器之間需要共享文件,可以通過 Docker 網絡讓容器直接訪問宿主機或其他容器的服務。在這種場景下,文件傳輸可能通過網絡協議(如 FTP、HTTP、NFS)進行。
例如:
- 通過 NFS 或 Samba 等協議共享文件。
- 在宿主機上運行 FTP 服務,然后在容器內訪問宿主機的 FTP 服務。
容器 自動刪除 與 自動重啟
- 容器的自動刪除
容器自動刪除是指當容器停止運行時,Docker 會自動刪除容器以釋放資源。這個功能通常用于短期任務或一次性任務的容器,以避免殘留停止的容器。
我們可以在啟動容器時 通過 -rm 參數設置容器的自動刪除
docker run --rm ubuntu
- 容器自動重啟
docker run --restart always <image_name>
這個指令保證容器在任何情況下停止后都能自動重啟。
容器環境變量設置
在 Docker 中,環境變量可以在容器運行時傳遞給容器內部的應用或服務,下面會介紹一些設置環境變量的方法:
1. 使用 -e
或 --env
選項設置環境變量
當你使用 docker run
命令啟動容器時,可以使用 -e
或 --env
選項來設置環境變量。每個 -e
或 --env
選項后跟一個 KEY=VALUE
對。
示例:
docker run --rm -e MY_VAR=value ubuntu printenv MY_VAR
-e MY_VAR=value
:設置容器內的環境變量MY_VAR
的值為value
。printenv MY_VAR
:容器內執行printenv MY_VAR
命令,輸出環境變量MY_VAR
的值。
這個命令執行后會輸出value
2. 使用 --env-file
選項從文件加載環境變量
如果有多個環境變量需要設置,可以將它們存儲在一個文件中,并使用 --env-file
選項來加載這些環境變量。
- 環境變量文件示例(
.env
文件):
MY_VAR=value
ANOTHER_VAR=another_value
- 命令:
docker run --rm --env-file .env ubuntu printenv MY_VAR
--env-file .env
:從.env
文件加載環境變量并傳遞給容器。printenv MY_VAR
:容器內執行printenv MY_VAR
,輸出MY_VAR
的值。
3. 使用 docker exec
修改正在運行容器的環境變量
如果容器已經在運行,并且你想修改它的環境變量,可以通過 docker exec
命令進入容器并在容器內修改環境變量。
示例:
docker exec -it <container_id> bash
進入容器后,可以使用 export
命令來設置環境變量:
export MY_VAR=value
此時,MY_VAR
的值會被修改為 value
,但是這種修改只會在當前的 shell 會話中有效。如果你退出容器,環境變量會丟失。
4. 使用 --env
設置多個環境變量
我們也可以在同一 docker run
命令中設置多個環境變量。
- 示例:
docker run --rm -e VAR1=value1 -e VAR2=value2 ubuntu bash -c 'echo $VAR1 $VAR2'
- 這會同時設置
VAR1
和VAR2
兩個環境變量,并輸出它們的值。
查看容器的詳細信息
- 查看容器的基本信息:
docker ps
和docker inspect
a. docker ps
:查看正在運行的容器(-a 查看所有容器)
docker ps
命令用于列出當前正在運行的容器,并顯示其基本信息,比如容器 ID、名稱、鏡像、狀態、端口映射等。
docker ps
輸出示例:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d8f9b711b8fa ubuntu "bash" 2 minutes ago Up 2 minutes my_container
b. docker inspect
:查看容器的詳細信息
docker inspect
命令提供容器的詳細信息,包括其配置、網絡設置、掛載卷等。你可以通過容器 ID 或容器名稱來指定需要查看的容器。
docker inspect <container_id_or_name>
輸出示例:
[{"Id": "d8f9b711b8fa...","Created": "2024-12-28T08:24:35.275285626Z","Path": "bash","Args": [],"State": {"Status": "running","Running": true,"Paused": false,"Restarting": false,"OOMKilled": false,"Dead": false,"Pid": 1234,"ExitCode": 0,"Error": "","StartedAt": "2024-12-28T08:24:37.607128397Z","FinishedAt": "2024-12-28T08:24:37.607128397Z"},"Image": "sha256:...","ResolvConfPath": "/var/lib/docker/containers/d8f9b711b8fa/resolv.conf","Mounts": [],"Config": {"Hostname": "d8f9b711b8fa","Env": ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"]},"NetworkSettings": {"Networks": {"bridge": {"IPAddress": "172.17.0.2","MacAddress": "02:42:ac:11:00:02"}}}}
]
這個 JSON 格式的輸出包含了容器的所有信息,比如:
- Id:容器 ID
- Created:容器創建時間
- State:容器的狀態(是否運行、退出代碼等)
- Config:容器的配置(如環境變量、命令等)
- NetworkSettings:容器的網絡配置(IP 地址、網絡類型等)
- Mounts:掛載的卷和文件系統
- 查看容器的資源使用情況:
docker stats
docker stats
命令可以查看容器的實時資源使用情況,如 CPU、內存、網絡 I/O 等。
docker stats
輸出示例:
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
d8f9b711b8fa my_container 0.02% 10.5MiB / 1.95GiB 0.53% 1.2kB / 0B 1.5MB / 0B 2
我們也可以指定查看某個容器的資源使用情況:
docker stats <container_id_or_name>
- 查看容器的日志:
docker logs
通過 docker logs
命令,你可以查看容器的標準輸出和標準錯誤輸出日志。
加上 -f
參數 可以查看容器日志的實時輸出。
docker logs <container_id_or_name>
- 查看容器的網絡信息:
docker network inspect
如果想查看容器的網絡配置,可以使用 docker network inspect
命令。首先可以使用 docker network ls
查看當前可用的網絡。
docker network ls
然后,通過 docker network inspect
來查看某個網絡的詳細信息,其中也包括與該網絡連接的容器信息。
docker network inspect <network_name_or_id>
- 查看容器的環境變量:
docker exec
和printenv
你可以通過 docker exec
進入容器并使用 printenv
命令查看容器內的所有環境變量:
docker exec -it <container_id_or_name> printenv
如果你只關心某個特定的環境變量,可以通過 grep
過濾:
docker exec -it <container_id_or_name> printenv | grep MY_VAR
- 查看容器內的進程:
docker top
docker top
命令可以顯示容器內的進程信息,類似于 Linux 上的 top
命令。
docker top <container_id_or_name>
它會顯示容器內部正在運行的進程列表,包括 PID、進程名、內存使用情況等。
- 查看容器的文件系統:
docker diff
docker diff
命令可以列出容器文件系統中的變化,顯示自容器啟動以來做出的文件修改(增加、刪除、修改)。
docker diff <container_id_or_name>
- 查看容器的掛載卷:
docker inspect
容器的掛載卷信息也可以通過 docker inspect
獲取,具體是在輸出的 Mounts
部分。
docker inspect <container_id_or_name> | grep Mounts -A 10
容器鏡像的導入導出
下面分別列出容器與鏡像的導入導出命令:
操作 | 命令格式 | 示例 | 解釋 |
---|---|---|---|
導出容器 | docker export <container_id> > <filename>.tar | docker export my_container > backup.tar | 將容器的文件系統導出為 .tar 格式的文件,不包括鏡像和容器的元數據。 |
導入容器 | docker import <filename>.tar <image_name>:<tag> | docker import backup.tar my_image:latest | 從 .tar 文件中導入容器的文件系統并創建一個新的鏡像。 |
導出鏡像 | docker save -o <filename>.tar <image_name>:<tag> | docker save -o my_image.tar my_image:latest | 將 Docker 鏡像導出為 .tar 文件,可以在其他主機上通過 docker load 導入使用。 |
導入鏡像 | docker load -i <filename>.tar | docker load -i my_image.tar | 從 .tar 文件中加載鏡像,并將其添加到本地 Docker 鏡像列表中。 |
鏡像的資源查看
這里直接列舉相關的docker 資源查看命令:
命令 | 說明 |
---|---|
docker images 或 docker image ls | 列出所有本地鏡像及其信息 (名稱、標簽、大小等) |
docker inspect <image_name> | 查看鏡像的詳細元數據 |
docker history <image_name> | 查看鏡像的歷史層信息及構建過程 |
docker system df | 查看 Docker 系統的磁盤使用情況(鏡像、容器、卷) |
docker image inspect <image_name> | 查看鏡像的詳細層次結構信息 |
鏡像的日志查看
下面的表格介紹了 使用 docker logs 查看日志的方式:
操作 | 命令格式 | 示例 | 說明 |
---|---|---|---|
查看容器日志 | docker logs <container_id_or_name> | docker logs my_container | 顯示指定容器的標準輸出和標準錯誤輸出。 |
實時查看容器日志 | docker logs -f <container_id_or_name> | docker logs -f my_container | 實時查看容器日志,類似 tail -f ,會持續顯示新產生的日志條目。 |
查看容器日志的特定時間范圍(自某時間點起) | docker logs --since "<time>" <container_id_or_name> | docker logs --since "2024-12-01T00:00:00" my_container | 查看自某個時間點以來的日志。時間可以是相對時間(如 10m 表示過去 10 分鐘)。 |
查看容器日志的特定時間范圍(直到某時間點) | docker logs --until "<time>" <container_id_or_name> | docker logs --until "2024-12-01T00:00:00" my_container | 查看直到某個時間點的日志。 |
查看容器日志的最新部分 | docker logs --tail <number> <container_id_or_name> | docker logs --tail 100 my_container | 查看容器日志的最后 N 行,幫助你快速查看最新的日志條目。 |
查看容器日志并顯示時間戳 | docker logs -t <container_id_or_name> | docker logs -t my_container | 在每條日志前添加時間戳,幫助你了解日志產生的時間。 |
實時查看日志并顯示時間戳 | docker logs -ft <container_id_or_name> | docker logs -ft my_container | 實時查看容器日志,并且每條日志會帶有時間戳。 |
查看容器日志并實時跟蹤最新部分 | docker logs -f --tail <number> <container_id_or_name> | docker logs -f --tail 50 my_container | 查看容器的最后 N 行日志,并且實時跟蹤新的日志更新。 |
參數部分:
-f
:實時查看日志輸出,類似于 Linux 命令tail -f
。--since
和--until
:用于指定時間范圍,--since
是自某個時間點以來,--until
是直到某個時間點。--tail
:僅查看日志的最后 N 行。-t
:在日志行前加上時間戳,便于查看日志發生的時間。
容器的資源查看
下面簡單介紹一些命令:監控和查看容器的資源消耗,如 CPU、內存、磁盤等:
操作描述 | 命令 |
---|---|
查看所有容器的實時資源使用情況 | docker stats |
查看單個容器的實時資源使用情況 | docker stats <container_name_or_id> |
查看容器的詳細信息(包括資源限制等) | docker inspect <container_name_or_id> |
查看容器的內存限制 | docker inspect --format '{{.HostConfig.Memory}}' <container_name_or_id> |
查看容器的 CPU 配額 | docker inspect --format '{{.HostConfig.CpuShares}}' <container_name_or_id> |
查看容器的日志 | docker logs <container_name_or_id> |
查看容器的文件系統使用情況 | docker system df |
六、綜合實戰
Mysql 容器化安裝
1進入docker hub 官網,查找 mysql 的鏡像,可以看到很多版本,這里選擇一個使用人數相對較多的:
圖片圖片圖片
通過 docker pull
拉取鏡像
ubuntu@VM-8-2-ubuntu:~$ docker pull mysql:5.7
5.7: Pulling from library/mysql
20e4dcae4c69: Pull complete
1c56c3d4ce74: Pull complete
e9f03a1c24ce: Pull complete
68c3898c2015: Pull complete
6b95a940e7b6: Pull complete
90986bb8de6e: Pull complete
ae71319cb779: Pull complete
ffc89e9dfd88: Pull complete
43d05e938198: Pull complete
064b2d298fba: Pull complete
df9a4d85569b: Pull complete
Digest: sha256:4bc6bc963e6d8443453676cae56536f4b8156d78bae03c0145cbe47c2aad73bb
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7
MySQL 的默認端口是 3306,且有密碼。根據官網的啟動用例:
docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
解釋一下部分字段:
-
--name some-mysql
:為新啟動的容器指定一個名字,這里容器的名字是some-mysql
。 -
-e MYSQL_ROOT_PASSWORD=my-secret-pw
:使用-e
參數設置環境變量。這個環境變量MYSQL_ROOT_PASSWORD
用來設置 MySQL 數據庫的 root 用戶密碼。這里密碼設置為my-secret-pw
。 -
-d
:指示 Docker 在后臺運行容器,并返回容器 ID。容器不會綁定到終端。
執行下面的命令:
ubuntu@VM-8-2-ubuntu:~$ docker run --name mysql -e MYSQL_ROOT_PASSWORD=123456 -p 8200:3306 -d mysql:5.7
4a542dd7bfe0a8be6d47fb2cbd6d9f165596d56b07463eb8d6a702a92c577d00
此時進入容器,可以發現mysql可以正常登錄:
ubuntu@VM-8-2-ubuntu:~$ docker exec -it mysql bash
bash-4.2# mysql -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.44 MySQL Community Server (GPL)Copyright (c) 2000, 2023, Oracle and/or its affiliates.Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
通過下面的代碼釋放空間:
docker stop mysql
docker rm mysql
Redis 容器化安裝
Redis 出現的原因
在 Web 應用發展的初期,關系型數據庫受到了廣泛的關注和應用。這是因為當時的 Web 站點訪問量和并發不高,交互也較少。隨著訪問量的提升,使用關系型數據庫的 Web 站點逐漸開始在性能上遇到瓶頸,而瓶頸的主要原因通常是在磁盤的 I/O 上。隨著互聯網技術的進一步發展,各類應用層層疊加,導致如今在云計算、大數據盛行的時代,對性能有了更高的要求,主要體現在以下幾個方面:
- 低延遲的讀寫速度:快速響應的應用能顯著提升用戶的滿意度。
- 支撐海量數據和流量:例如,搜索引擎等大型應用需要處理 PB 級別的數據,并能應對百萬級的并發流量。
為了解決這些問題,NoSQL 數據庫應運而生,它具備高性能、可擴展性強和高可用等優點,廣泛受到開發人員和系統管理員的青睞。
Redis 是什么
Redis(全稱:Remote Dictionary Server,中文名為遠程字典服務器)是目前最受歡迎的 NoSQL 數據庫之一。它使用 ANSI C 編寫,是一個開源、基于內存、支持多種數據結構的鍵值對存儲數據庫,具備如下特性:
- 基于內存運行,性能高效:由于數據存儲在內存中,讀寫速度非常快。
- 支持分布式,具備理論上的無限擴展性:可以橫向擴展,支持大規模分布式系統。
- 鍵值存儲系統:數據以鍵值對形式存儲,簡單而高效。
- 開源且使用 ANSI C 編寫:遵循 BSD 協議,并支持多種編程語言的 API。
- 支持持久化:可以將數據持久化到磁盤,也可以僅作為內存存儲使用。
Redis 的應用場景
幾乎所有的大型互聯網公司都在使用 Redis。Redis 提供了多種數據類型,如 String 類型、哈希類型、列表類型、集合類型、順序集合類型,這些數據結構能夠支持多種應用場景。以下是 Redis 常見的應用場景:
- 緩存系統:尤其適用于“熱點”數據(即頻繁讀取、少量寫入的數據),能大幅提高系統響應速度。
- 計數器:適用于需要實時計數的場景,如訪問量統計、投票系統等。
- 消息隊列系統:通過 Redis 的 List 和 Pub/Sub 功能,構建高效的消息隊列。
- 實時排行榜:Redis 的有序集合(Sorted Set)能高效地支持實時排行榜的需求。
- 社交網絡:如用戶關注、評論、點贊等社交互動操作,可以通過 Redis 高效處理。
Redis 的高性能和靈活性使其成為許多 Web 應用中不可或缺的組件,尤其是在需要快速響應和處理海量數據時,Redis 的優勢尤為明顯。
C++ 容器制作
-
首先通過
docker pull ubuntu:22.04
拉取鏡像 -
啟動容器:
ubuntu@VM-8-2-ubuntu:~$ docker run --name mygcc -it ubuntu:22.04 bash
- 更新apt包并安裝gcc/vim:
apt update
apt install gcc vim -y
- 編輯代碼:
root@8f8244b7f41d:/# mkdir src
root@8f8244b7f41d:/# cd src
root@8f8244b7f41d:/src# vim demo.c
- 執行代碼:
root@8f8244b7f41d:/src# gcc demo.c -o demo
root@8f8244b7f41d:/src# ./demo
hello docker
- 此時退出容器
root@8f8244b7f41d:/src# exit
exit
ubuntu@VM-8-2-ubuntu:~$
可以看出容器已經退出,如果想再次運行通過restart恢復即可。
容器資源更新
- 首先運行一個 nginx 容器
ubuntu@VM-8-2-ubuntu:~$ docker run -d --name mynginx1 -p 8080:80 nginx:1.24.0
88c1f95c0066a3658ccee40a9207b5f44ff970a4e815ad8b05297b5875316f6f
- 通過 docker top 查看容器中的進程, 添加 aux 查看內存和CPU信息
ubuntu@VM-8-2-ubuntu:~$ docker top mynginx1 aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 2378550 0.1 0.3 8932 5760 ? Ss 20:00 0:00 nginx: master process nginx -g daemon off;
message+ 2378598 0.0 0.1 9320 2772 ? S 20:00 0:00 nginx: worker process
message+ 2378599 0.0 0.1 9320 2772 ? S 20:00 0:00 nginx: worker process
- 通過 docker stat 查看資源的動態變化:
ubuntu@VM-8-2-ubuntu:~$ docker top mynginx1 aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 2378550 0.1 0.3 8932 5760 ? Ss 20:00 0:00 nginx: master process nginx -g daemon off;
message+ 2378598 0.0 0.1 9320 2772 ? S 20:00 0:00 nginx: worker process
message+ 2378599 0.0 0.1 9320 2772 ? S 20:00 0:00 nginx: worker process
- 通過 docker update 更新容器的最大內存
ubuntu@VM-8-2-ubuntu:~$ docker update -m 300m --memory-swap 600m mynginx1
mynginx1
- 再次執行 docker stat 查詢容器狀態,可以看到最大內存被限制為 300mb
ubuntu@VM-8-2-ubuntu:~$ docker update -m 300m --memory-swap 600m mynginx1
mynginx1
- 停止容器并釋放資源:
docker stop <id>
docker rm <id>