docker學習-docker容器運行

docker run是啓動容器的方法,能夠用三種指定的方式指定容器啓動時執行的命令。
(1)CMD指令
(2)ENTRYPOINT指令
(3)在docker run中命令行中指定
可是docker run並不能長期保持running狀態,咱們常常須要進入到容器中去作一些工做,好比查看日誌、調試、啓動其餘進程等。有兩種進入容器的方式:attach和exec。linux

docker attach

首先啓動一個容器,保持後臺長期運行docker

docker run -d ubuntu /bin/bash -c "while true; do sleep 1; echo i_am_a_container;done

首先檢查容器的ID數據庫

docker ps -a

docker學習-docker容器運行

CONTAINER ID就是容器的編號,其實就是容器ID前12個字符,又叫短ID
IMAGE就是base IMAGE
NAMES是容器的名稱,在啓動容器的時候能夠經過 --name參數顯式的爲容器命名。ubuntu

經過docker attach能夠attach到容器啓動命令的終端。bash

docker attach 1e5cc7e3b22b

docker學習-docker容器運行
經過短ID attach到了容器的啓動命令終端,以後看到的是echo每秒輸出一次打印信息
能夠經過ctl+p,而後ctl+q退出attach終端網絡

docker exec

經過docker exec進入相同的容器ide

docker exec -it 1e5cc7e3b22b bash

docker學習-docker容器運行
說明
一、-it 以交互的形式打開終端,執行bash
二、能夠像普通linux同樣執行命令,顯示了容器啓動的進程
三、退出容器工具

docker exec命令格式以下:學習

docker exec -it <container> bash |sh

attach vs exec

二者的主要區別以下:
一、attch直接進入容器啓動命令的終端,不會啓動新的進程
二、exec則是在容器中打開新的終端,並且能夠啓動新進程
三、若是想直接在終端中查看啓動命令的輸出,用attach,其餘狀況用exec測試

運行容器的最佳實踐

按用途容器大體能夠分爲兩類:服務類容器和工具的容器
前者以daemon的形式運行,對外提供服務,好比Web Server、數據庫等。經過-d 之後臺的方式啓動這類容器是很是合適的,若是要排查問題,能夠經過exec -it進入容器
後者容器一般能給咱們提供一個臨時的工做環境,一般以run -it方式進行

工具類容器多使用基礎鏡像,例如busybox,debian,ubuntu等

總結以下:

(1)當CMD,Entypoint和docker run命令行指定的命令運行結束時,容器中止
(2)經過-d參數在後臺啓動容器
(3)經過exec -it能夠進入容器並執行命令

容器生命週期

stop/start/restart容器

docker stop:中止運行中的容器,容器在docker host中其實就是一個進程,該命令本質上是像該進程發送一個SIGTERM信號,也可經過docker kill命令快速中止容器

docker start: 對於中止的容器。能夠經過該命令進行啓動,會保留容器的第一次啓動時的參數

docker restart :重啓容器

pause/unpause容器

docker pause:讓容器暫停,如須要對容器的文件系統打快照
unpause:處於pause狀態的容器不會佔用CPU資源,直到經過dokcer unpause恢復運行

刪除容器

docker rm:使用docker一段時間後,host上可能會有大量已經退出的容器,這些容器依然會佔用host的文件系統資源,可使用docker rm進行刪除
若是但願一次刪除多個容器,則可使用以下命令

docker rm -v $(docker ps -aq -f status=exited)

容器的狀態機制

整個容器的生命週期狀態機制,以下所示:
docker學習-docker容器運行

資源限制

一個docker host上會運行若干容器,每一個容器都須要cpu,內存和IO資源。Docker提供了相似的機制避免某個容器因佔用太多資源而影響到其餘容器或者整個HOST的資源

內存限額

與操做系統相似,容器可以使用的內存包括兩個部分:物理內存和swap。Docker經過下面的兩組參數來控制容器內存的使用量
(1)-m或 --memory:設置內存的使用限制
(2)--memory-swap:設置內存+swap的使用限制
例如:
docker run -m 200M --memory-swap=300M ubuntu
含義時容許該容器最多使用200M的內存和300MB的 swap。默認狀況下,上面兩組參數爲-l,即對容器內存和swap的使用沒有限制

測試使用progrium/stress鏡像,該鏡像能夠用於對容器執行壓力測試

docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 280M

說明:
一、--vm1:啓動1個內存工做線程
二、--vm-bytes 280M,每一個線程分配280MB內存
docker學習-docker容器運行
過程:
1分配280M內存
2釋放280M內存
3再分配280M內存
4再釋放
5 一致持續循環

cpu限制

默認設置下,全部的容器能夠平等的使用hostCPU資源,並且沒有限制
docker能夠經過-c或者--cpu-shares設置容器使用cpu的權重,若是不指定,默認值1024
與內存限額不一樣,經過-c設置的cpu share並非cpu資源的絕對數量,而是一個相對的權重值。某個容器最終能分配的到的CPU資源取決於它的cpu share總和和比例,換句話說經過cpu share能夠設置容器使用CPU的優先級

docker run --name "container_A" -c 1024 ubuntu && docker run --name "container_B" -c 512 ubuntu

container_A的cpu share 1024,是containerB的兩倍,當兩個容器都須要CPU資源時,前者能夠獲得的cpu是後者的兩倍

須要特別注意的是,這種按權重分配CPU的只會發生在CPU資源緊張的狀況下。若是containerA處於空閒狀態,這時爲了充分利用CPU資源,containrB也能夠分配到所有可用的cpu

Block IO帶寬限制

Block IO是另外一種能夠限制容器資源,它是指磁盤的讀寫,docker能夠經過設置權重,限制bsp和iops的方式控制容器讀寫磁盤的帶寬。

IO權重
默認狀況下,全部的容器能平等的讀寫磁盤,能夠經過設置 --blkio-weight 參數來改變容器的block IO的優先級
--blkio-weight與--cpu-share相似,設置的是相對權重,默認爲500

docker run -it --name container_A --blkio-weight 600 ubuntu && docker run --it --name container_B --blkio-weight 300 ubuntu

經過命令行設定,containerA的讀寫磁盤帶寬是containerB的兩倍

限制bps和iops

bsp是byte per second ,每秒讀寫的數據量
iops是ip per second,每秒IO的次數

能夠經過如下參數控制容器的bsp和 iops
--device-read-bps,限制讀某個設備的 bps。
--device-write-bps,限制寫某個設備的 bps。
--device-read-iops,限制讀某個設備的 iops。
--device-write-iops,限制寫某個設備的 iops。

cgroup和namespace

cgropu和namespace是實現容器底層的最重要的兩種技術。cgroup實現資源限制,namespace實現資源的隔離

cgroup

cgroup 全稱 Control Group。Linux 操做系統經過 cgroup 能夠設置進程使用 CPU、內存 和 IO 資源的限額。前面咱們看到的--cpu-shares、-m、--device-write-bps 實際上就是在配置 cgroup。
能夠在/sys/fs/cgroup中找到

docker run -it --cpu-shares 512 progrium/stress -c 1

記錄容器ID。在 /sys/fs/cgrouXXXpu/docker 目錄中,Linux 會爲每一個容器建立一個 cgroup 目錄,以容器長ID 命名:
docker學習-docker容器運行
目錄中包含全部與 cpu 相關的 cgroup 配置,文件 cpu.shares 保存的就是 --cpu-shares 的配置,值爲 512。
一樣的,/sys/fs/cgroup/memory/docker 和 /sys/fs/cgroup/blkio/docker 中保存的是內存以及 Block IO 的 cgroup 配置

namespace

在每一個容器中,咱們均可以看到文件系統,網卡等資源,這些資源看上去是容器本身的。拿網卡來講,每一個容器都會認爲本身有一塊獨立的網卡,即便 host 上只有一塊物理網卡。這種方式很是好,它使得容器更像一個獨立的計算機。

Linux 實現這種方式的技術是 namespace。namespace 管理着 host 中全局惟一的資源,並可讓每一個容器都以爲只有本身在使用它。換句話說,namespace 實現了容器間資源的隔離。
Linux 使用了六種 namespace,分別對應六種資源:Mount、UTS、I*、PID、Network 和 User。

Mount namespace
Mount namespace 讓容器看上去擁有整個文件系統。

容器有本身的 / 目錄,能夠執行 mount 和 umount 命令。固然咱們知道這些操做只在當前容器中生效,不會影響到 host 和其餘容器。
UTS namespace
簡單的說,UTS namespace 讓容器有本身的 hostname。 默認狀況下,容器的 hostname 是它的短ID,能夠經過 -h 或 --hostname 參數設置。

I P C namespace
IPC namespace 讓容器擁有本身的共享內存和信號量(semaphore)來實現進程間通訊,而不會與 host 和其餘容器的 IPC 混在一塊兒。

PID namespace
可以使容器可以擁有本身的PID
Network namespace
Network namespace 讓容器擁有本身獨立的網卡、IP、路由等資源。咱們會在後面網絡章節詳細討論。

User namespace
User namespace 讓容器可以管理本身的用戶,host 不能看到容器中建立的用戶。

經常使用命令

如下是容器的經常使用操做命令create 建立容器 run 運行容器 pause 暫停容器 unpause 取消暫停繼續運行容器 stop 發送 SIGTERM 中止容器 kill 發送 SIGKILL 快速中止容器 start 啓動容器 restart 重啓容器 attach attach 到容器啓動進程的終端 exec 在容器中啓動新進程,一般使用 "-it" 參數 logs 顯示容器啓動進程的控制檯輸出,用 "-f" 持續打印 rm 從磁盤中刪除容器

相關文章
相關標籤/搜索