linux雲計算之Docker容器的各種操作,容器各種狀態之間如何轉換,以及實現容器的底層技術


1.容器

本節討論容器的各種操作,容器各種狀態之間如何轉換,以及實現容器的底層技術。

 

容器: 由鏡像運行形成容器

鏡像: 構建,制作鏡像  docker commit

docker run -it centos

docker images

docker ps

 

 

 

 

 

 

 

 

1.啟動容器

docker run 是啟動容器的方法

Dockerfile 中,可用三種方式指定容器啟動時執行的命令

CMD 指令。

ENTRYPOINT指令。

 docker run 命令行中指定。

 

CMD和enterpoint的區別

Dockerfile中,只能有一個ENTRYPOINT指令,如果有多個ENTRYPOINT指令則以最后一個為准。

Dockerfile中,只能有一個CMD指令,如果有多個CMD指令則以最后一個為准。

Dockerfile中,ENTRYPOINT指令或CMD指令,至少必有其一。

 

例如

docker run --name bbox1 busybox pwd容器啟動時執行 pwd,返回的 / 是容器中的當前目錄。 /  根  表示鏡像工作目錄在 / 下面

 

docker ps docker  ps 或 docker container ls 可以查看 Docker host 中當前運行的容器

docker ps -a-a 會顯示所有狀態的容器,  他的狀態為退出exited 一閃而過over

這種“一閃而過”的容器通常不是我們想要的結果,我們希望容器能夠保持 runing 狀態,這樣才能被我們使用。

COMMAD  第三列表示容器啟動時使用的命令

 

 

 

 

 

 

2.讓容器長期運行

因為容器的生命周期依賴於啟動時執行的命令,只要該命令不結束,容器也就不會退出。

例如

docker run busybox  /bin/sh -c "while true ; do sleep 1; done"while 語句讓 bash 不會退出

 

 

 

 

docker ps 打開另一個終端查看容器仍處於運行狀態  缺點:它占用了一個終端

 

 

 

 

 

docker run -d busybox  /bin/sh -c "while true ; do sleep 1; done" -d 后台方式啟動容器。  容器啟動后回到了 docker host 的終端。docker 返回了一串字符,這是容器的 ID。

 

 

 

 

docker ps

 

 

 

 

注意

CONTAINER ID 是容器的 “短ID”,前面啟動容器時返回的是 “長ID”。短ID是ID的前12個字符。

NAMES 字段顯示容器的名字,在啟動容器時可以通過 --name 參數顯示地為容器命名如果不指定,docker 會自動為容器分配名字。

 

通過 “ID”、“短ID” 或者 “名稱 來指定  要操作的容器。

停止一個容器

docker stop 13556b3f36d9 通過 “短ID” 指定了要停止的容器。

 

 

通過 while 啟動的容器雖然能夠保持運行,但實際上沒有干什么有意義的事情。

容器常見的用途是運行后台服務

docker run -d --name "my_httpd" httpd --name 指定了容器的名字

docker ps

docker history httpd

看到容器運行的命令是httpd-foreground,  通過 docker history 可知這個命令是通過 CMD 指定的。

 

3.兩種進入容器的方法   attach 和 exec

1.docker attach    可以 attach 到容器  啟動命令的終端,

 

例如:

docker run -d busybox /bin/sh -c "while true; do sleep 1; echo I_am_in container; done"

docker ps

 

 

 

 

docker attach 7a13aecce97473    通過 “長ID” attach 到了容器的啟動命令終端,之后看到的是echo 每隔一秒打印的信息。

 

 

 

 

注:

可通過 Ctrl+p 然后 Ctrl+q 組合鍵退出 container 終端。

 

2.docker exec      進入相同的容器

docker exec -it 7a13aecce974  /bin/sh

ps -elf

hostname

 

 

 

 

 

注意

-it 以交互模式打開 pseudo-TTY,執行 bash,其結果就是打開了一個 bash 終端。

進入到容器中,容器的 hostname 就是其 “短ID”。

ps -elf 顯示了容器啟動進程while 以及當前的 bash 進程。

 

執行 exit 退出容器,回到 docker host。

docker exec -it <container容器id>  /bash|sh 是執行 exec 最常用的方式。

 

4.attach 和 exec區別

attach 直接進入容器 啟動命令 的終端,不會啟動新的進程。

exec 則是在容器中打開新的終端,並且可以啟動新的進程。

 

直接在終端中查看啟動命令的輸出,用 attach; 其他情況使用 exec。

 

查看日志  查看啟動命令的輸出  使用 docker logs 命令

docker logs -f 容器-f 的作用與 tail -f 類似,能夠持續打印輸出。

 

 

 

 

5.運行容器的分類

用途容器 分為兩類服務類容器   工具類容器。

1. 服務類容器以 daemon 的形式運行對外提供服務。比如 web server,數據庫等。

通過 -d 以后台方式啟動這類容器是非常合適的。

如果要排查問題,可以通過 exec -it 進入容器

 

2. 工具類容器通常給能我們提供一個臨時的工作環境,

通常以 run -it 方式運行,

 

docker run -it busybox

wget www.baidu.com

exit

 

 

 

 

 

注意

運行 busybox,run -it 的作用是在容器啟動后就直接進入。

通過 wget 驗證了在容器中訪問 internet 的能力。

執行 exit 退出終端,同時容器停止。

 

busybox是一個軟件工具箱,里邊集成了linux中幾百個常用的linux命令以及工具。

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

 

6.容器運行小結

容器運行相關的知識點:

CMD 或 Entrypoint 或 docker run 命令行指定的命令運行結束時,容器停止。

通過 -d 參數在后台啟動容器。

通過 exec -it 可進入容器並執行命令。

 

指定容器的三種方法:

ID。

ID。

容器名稱。 可通過 --name 為容器命名。重命名容器可執行docker rename。

 

容器按用途可分為兩類:

服務類的容器

工具類的容器

 

7.容器常用操作 停止 啟動 重啟

stop/start/restart +容器

1.docker stop 可以停止運行的容器

docker ps

docker stop id

docker ps -a

 

 

 

 

容器在 docker host 中實際上是一個進程,docker stop 命令本質上是向該進程發送一個 SIGTERM 信號。

想快速停止容器,可使用 docker kill 命令,其作用是向容器進程發送 SIGKILL 信號。

 

docker kill my_httpd

 

 

2.對於處於停止狀態的容器,可以通過 docker start 重新啟動。

docker start my_httpd

docker ps

 

注意

docker start 會保留容器的第一次啟動時的所有參數。

docker restart 可以重啟容器,其作用就是依次執行 docker stop 和docker start。

 

3.容器可能會因某種錯誤而停止運行。  重啟

對於服務類容器,啟動容器時設置   --restart   重啟  就可以達到這個效果。

 

docker run -d --restart=always httpd

 

--restart=always 意味着無論容器因何種原因退出(包括正常退出),就立即重啟。

該參數的形式還可以是 --restart=on-failure:3,意思是如果啟動進程退出代碼非0,則重啟容器,最多重啟3次。

8.pause/unpause 容器

暫時讓容器暫停工作一段時間,比如要對容器的文件系統打個快照,或者 dcoker host 需要使用 CPU,這時可以執行 docker pause。暫停

docker pause  id

docker ps 處於暫停狀態的容器不會占用 CPU 資源,直到通過 docker unpause 恢復運行。

docker unpause

 

 

 

 

 

 

 

9.刪除容器

docker使用一段時間后,host 會有大量已經退出了的容器。這些容器依然會占用 host 的文件系統資源,

如果確認不會再重啟此類容器,可以通過 docker rm 刪除。

 

docker rm  id

docker rm 一次可以指定多個容器,如果希望批量刪除所有已經退出的容器

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

 

批量刪除

docker ps -aq

docker ps -aq -f status=exited查找狀態為exited的

docker rm `docker ps -aq -f status=exited`刪除

 

 

 

 

注意:docker rm 是刪除容器,而 docker rmi 是刪除鏡像。

10.容器底層技術cgroup案例

一個 docker host 上會運行若干容器,每個容器都需要 CPU、內存和 IO 資源。

對於 KVM,VMware 等虛擬化技術,用戶可以控制分配多少 CPU、內存資源給每個虛擬機。

對於容器Docker 也提供了類似的機制避免某個容器因占用太多資源而影響其他容器乃至整個 host 的性能。

 

容器的底層實現技術
cgroup 和 namespace 是最重要的兩種技術。

cgroup 實現資源限額, namespace 實現資源隔離。

 

 

1.cgroup

cgroup 全稱 Control Group。Linux 操作系統通過 cgroup 可以設置進程使用 CPU、內存 和 IO 資源的限額。    

cgroup 在 /sys/fs/cgroup

 

 

 

 

 

實例  啟動一個容器,設置 --cpu-shares=512

cd sys/fs/cgroup/cpu/docker

cat cpu.shares

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

 

 

 

 

 

該鏡像可用於對容器執行壓力測試。

docker ps查看容器的 ID

 

 

/sys/fs/cgroup/cpu/docker 目錄中Linux 會為每個容器創建一個 cgroup 目錄,以容器長ID 命名:

ls

目錄中包含所有與 cpu 相關的 cgroup 配置,文件 cpu.shares 保存的就是 --cpu-shares 的配置,值為 512。

 

 

默認設置下,所有容器可以平等地使用 host CPU 資源並且沒有限制。

Docker 可以通過 -c 或 --cpu-shares 設置容器使用 CPU 的權重。如果不指定,默認值為 1024。

 

通過 -c 設置的 cpu share 並不是 CPU 資源的絕對數量,而是一個相對的權重值。某個容器最終能分配到的 CPU 資源取決於它的 cpu share 占所有容器 cpu share 總和的比例。

 

通過 cpu share 可以設置容器使用 CPU 的優先級。

 

/sys/fs/cgroup/memory/docker 和 /sys/fs/cgroup/blkio/docker 中保存的是內存以及 Block IO 的 cgroup 配置。

2.Namespace  命名空間

在每個容器中,我們都可以看到文件系統,網卡等資源,這些資源看上去是容器自己的。拿網卡來說,每個容器都會認為自己有一塊獨立的網卡,即使 host 上只有一塊物理網卡。這種方式非常好,它使得容器更像一個獨立的計算機。

Linux 實現這種方式的技術是 namespace。namespace 管理着 host 中全局唯一的資源,並可以讓每個容器都覺得只有自己在使用它。namespace 實現了容器間資源的隔離。

 

Linux 使用了六種 namespace,分別對應六種資源Mount、UTS、IPC、PID、Network 和 User,

1.Mount namespace  底層硬件設備

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

容器有自己的 / 目錄,可以執行 mount 和 umount 命令。當然我們知道這些操作只在當前容器中生效,不會影響到 host 和其他容器。

2.UTS namespace有自己的主機名

簡單的說,UTS(UNIX Time-sharing System) namespace 讓容器有自己的 hostname。 默認情況下,容器的 hostname 是它的短ID,可以通過 -h 或 --hostname 參數設置。

docker run -it --hostname bbox4 busybox

hostname

 

 

 

 

3.IPC namespace 進程間通信的ipc

IPC namespace 讓容器擁有自己的共享內存和信號量(semaphore)來實現進程間通信,而不會與 host 和其他容器的 IPC 混在一起。

4.PID namespace 進程號

容器在 host 中以進程的形式運行 docker ps

 ps axf 可以查看容器進程

所有容器的進程都掛在 container進程下,同時也可以看到容器自己的子進程。

如果我們進入到某個容器,ps 就只能看到自己的進程了

docker exec -it 70a5fe753756 /bin/sh

/ # ps axf

 

 

 

 

 

而且進程的 PID 不同於 host 中對應進程的 PID,容器中 PID=1 的進程當然也不是 host 的 init 進程。也就是說:容器擁有自己獨立的一套 PID,這就是 PID namespace 提供的功能。

5.Network namespace

Network namespace 讓容器擁有自己獨立的網卡、IP、路由等資源。

6.User namespace

User namespace 讓容器能夠管理自己的用戶,host 不能看到容器中創建的用戶。

[root@host2 ~]# docker run -it centos

[root@2e89852f6f0b /]# useradd xuld

[root@2e89852f6f0b /]# [root@host2 ~]# su - xuld

 

 

 

 

在容器中創建了用戶 xuld,但 host 中並不會創建相應的用戶。

7.小結

首先學習了容器的各種操作,以及實現容器的底層技術:cgroup 和 namespace。

容器的常用操作命令:

create      創建容器  

run         運行容器  

pause       暫停容器  

unpause     取消暫停繼續運行容器  

stop        發送 SIGTERM 停止容器  

kill        發送 SIGKILL 快速停止容器  

start       啟動容器  

restart     重啟容器  

attach      attach 到容器啟動進程的終端  

exec        在容器中啟動新進程,通常使用 "-it" 參數  

logs        顯示容器啟動進程的控制台輸出,用 "-f" 持續打印  

rm          從磁盤中刪除容器 -v

 

3.Docker的網絡管理

1.容器的網絡管理

容器的網絡默認與宿主機、與其他容器相互隔離,且容器中可以運行一些網絡應用,比如nginx、web應用、數據庫等,如果需要讓外部也可以訪問這些容器中運行的網絡應用,那么就需要配置網絡來實現。

同樣的,不同需求下,容器與宿主機的通信有不同的業務狀態這時候就需要容器網絡管理以達成管理不同業務下相關的網絡配置

2.Docker中的網絡驅動模式

bridge network(網橋)模式:默認的網絡模式,類似虛擬機的nat模式

host network(主機)模式:容器與宿主機之間的網絡無隔離,即容器直接使用宿主機網絡。

none network模式:容器禁用所有網絡。

overlay network(覆蓋)模式:利用vxlan實現的bridge模式。

macvlan network模式:容器具備MAC地址,使其在外部看來是一台真實的網絡設備。

 

查看網絡  查看橋

docker network ls

 

 

 

 

 

ip a

brctl show

 

 

 

 

 

 

 

 

 

3.常見的網絡 管理命令

docker network ls 查看網絡

 

docker network create [參數] 網絡創建網絡

常用參數:

-d 指定網絡的驅動,不指定默認為bridge

-- subnet 指定子網網段(192.168.0.0/16)

-- ip-range 指定容器的IP范圍

-- gateway 子網的網關

 

 

docker network rm 網絡 [網絡..]刪除網絡

docker network inspect  網絡查看網絡詳情

docker run/create --network 網絡使用網絡

docker network connect/disconnect  網絡 容器網絡連接與斷開

4.常見的網絡模式簡介 none和host和bridge網絡

1.none網絡模式的特點:

容器上沒有網絡,也無需任何網絡設備

如果需要使用網絡,需要用戶自行安裝與配置

 

2.host網絡模式的特點:

容器完全共享宿主機的網絡,網絡沒有隔離。宿主機的網絡就是容器的網絡。

容器、主機上的應用所使用的端口不能重復。

外部可以直接訪問容器,不需要端口映射

容器IP就是宿主機的IP

 

 

 

 

 

3.Bridge 網絡模式

bridge網絡模式的特點:

1.宿主機上需要單獨的bridge網卡,如Docker默認創建的docker0。

2.容器之間、容器與主機之間的網絡通信,是借助為每一個容器生成的一對veth pair虛擬網絡設備對,進行通信的。一個在容器上,另一個在宿主機上。

 

3.每創建一個基於bridge網絡的容器,都會自動在宿主機上創建一個veth虛擬網絡設備。外部無法直接訪問容器。需要建立端口映射才能訪問。

4.容器借由veth虛擬設備通過如Docker0這種bridge網絡設備進行通信。

5.每一容器具有單獨的IP

6.bridge網絡模式下宿主機與容器服務使用的端口可以重復

 

 

 

 

 

 

Docker 安裝時會創建一個 命名為 docker0 的 linux bridge。如果不指定--network,創建的容器默認都會掛到 docker0 上。

brctl show

 

 

 

 

 

 

當前 docker0 上沒有任何其他網絡設備,創建容器看有什么變化。

docker run -it busybox

 

 

 

 

 

 

 

brctl show

 

 

 

 

一個新的網絡接口  veth6f0112被掛到了 docker0 上, veth6f0112就是新創建容器的虛擬網卡。

 

 

容器的網絡配置。

容器有一個網卡 eth0@if60,  為什么不是 veth6f01129 

實際上 eth0@if60 和  veth6f01129 是一對 veth pair。

veth pair 是一種成對出現的特殊網絡設備,可以把它們想象成由一根虛擬網線連接起來的一對網卡,網卡的一頭(eth0@if60)在容器中,另一頭( veth6f01129)掛在網橋 docker0 上,其效果就是將 eth0@if60 也掛在了 docker0 上。

docker run -it busybox

 

 

 

 

 

我們還看到 eth0@if60 已經配置了 IP 172.17.0.2

docker network inspect bridge 看一下 bridge 網絡的配置信息

 

 

 

 

bridge 網絡配置的 subnet 就是 172.17.0.0/16,並且網關是 172.17.0.1。這個網關就是 docker0

ifconfig  docker0

 

 

 

 

 

 

當前容器網絡拓撲結構

容器創建時,docker 會自動從 172.17.0.0/16 中分配一個 IP,這里 16 位的掩碼保證有足夠多的 IP 可以供容器使用。

除了 none, host, bridge 這三個自動創建的網絡,用戶也可以根據業務需要創建 user-defined 網絡。

 

自定義容器網絡

除了 none, hostbridge 這三個自動創建的網絡,用戶也可以根據業務需要創建 user-defined 網絡。

Docker 提供三種 user-defined 網絡驅動:bridge, overlay 和 macvlan。

overlay 和 macvlan 用於創建跨主機的網絡

 

4.創建 bridge 網絡

docker network create --driver bridge my_net

docker network ls

brctl show查看當前 host 的網絡結構變化

 

 

 

 

 

新增了一個網橋 my_net 的短 id

docker network inspect  my_net 查看 my_net 的配置信息

 

 

 

 

這里 172.18.0.0/16 是 Docker 自動分配的 IP 網段

brctl show

 

 

 

 

docker run  -it --network my_net centos

ip a

 

 

 

 

 

 

5.可以自己指定 IP 網段10.24.0.0

只需在創建網段時指定 --subnet 和 --gateway 參數:

docker network create  --driver bridge  --subnet 10.24.23.0/16 --gateway  10.24.0.1 my_net2

docker network ls

brctl show

 

 

 

 

 

 

 

 

 

容器要使用新的網絡,需要在啟動時通過 --network 指定

docker run -it --network my_net2 centos

ip a容器分配到的 IP 為 10.24.0.2

 

 

 

 

 

 

容器的 IP 都是 docker 自動從 subnet 中分配,也可以指定一個靜態 IP    通過--ip指定

 

docker run -it --network my_net2  --ip 10.24.23.100 centos

 

 

 

 

 

 

注意  

只有使用 --subnet 創建的網絡才能指定靜態 IP。

my_net 創建時沒有指定 --subnet,如果指定靜態 IP 報錯如下:

 

 

 

 

 

6.增加網卡   理解容器之間的連通性

docker network ls兩個 busybox 容器都掛在 my_net2 上 能夠互通    

 

 

 

 

異網絡 跨網絡不同的網絡如果加上   路由就可以通信

 

docker run -itd --network my_net2 centos

docker exec  -it 910463badad30 /bin/sh

Ip a

 

 

 

 

 

docker run  -it --network my_net centos

 

 

 

 

 

ip r查看 host 上的路由表

cat /proc/sys/net/ipv4/ip_forward看是否開啟路由轉發

 

 

 

 

 

 

 

 

iptables-save查看防火牆 路由規則

 

 

 

 

注意

iptables DROP 掉了網橋 docker0  br-6bcd98e3c34e  br-1f0b3d7673750之間雙向的流量。

 

 

容器my_net增加了一個網卡 eth1,分配了 my_net 的 IP 10.24.0.3

docker network connect my_net2 621a462438a621a462438 為my _ net 的短id

 

 

 

 

 

my_ net  查看

之前

 

 

 

 

之后

 

 

 

 

 

my_net   ping  my_net2

my _net2的網卡

 

 

 

 

 

 

 

 

 

7.容器訪問外部世界

容器 訪問 外部網絡

1.容器訪問外部世界

2.外部世界訪問容器

 

my_net容器中查看能否上網

ping www.baidu.com

 

 

 

 

注意

這里外網指的是容器網絡以外的網絡環境,並非特指 internet。

 

這里的關鍵就是 NAT   查看 docker host 上的 iptables 規則:

iptables -t nat -S

 

 

 

 

 

NAT 表中,有這么一條規則:

-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE

其含義是:

如果網橋 docker0 收到來自 172.17.0.0/16 網段的外出包,把它交給 MASQUERADE 處理。而 MASQUERADE 的處理方式是將包的源地址替換成 host 的地址發送出去,即做了一次網絡地址轉換(NAT)。

 

 

通過 tcpdump 查看地址是如何轉換的。先查看 docker host 的路由表:

ip r

 

 

 

 

 

默認路由通過 ens33 發出去,所以我們要同時監控 ens33 和 docker0 上的 icmp(ping)數據包。

centos ping baidu.com 時,tcpdump 輸出如下:

 

 

 

 

 

 

docker0 收到 centos  ping 包,源地址為容器 IP 172.17.0.2,這沒問題,交給 MASQUERADE 處理。這時, ens33 上我們看到了變化:

 

 

 

 

ping 包的源地址變成了 ens33  IP 192.168.137.104

 

 

這就是 iptable NAT 規則處理的結果,從而保證數據包能夠到達外網。過程

 

 

 

 

注釋:

1.centos 發送 ping 包:172.17.0.2 > www.baidu.com。

2.docker0 收到包,發現是發送到外網的,交給 NAT 處理。

3.NAT 將源地址換成 ens33  IP:192.168.137.104 > www.baidu.com。

4.ping 包從ens33 發送出去,到達 www.baidu.com。

5.通過 NAT,docker 實現了容器對外網的訪問。

8.外部世界訪問容器

端口映射。

docker 可將容器對外提供服務的端口映射到 host 的某個端口,外網通過該端口訪問容器。容器啟動時通過-p參數映射端口:

 

 

 

 

 

容器啟動后,可通過 docker ps 或者 docker port 查看到 host 映射的端口。

httpd 容器的 80 端口被映射到 host 32770 上,這樣就可通過 <host ip>:<32770> 訪問容器的 web 服務了。

 

 

 

 

 

 

 

 

除了映射動態端口,也可在 -p 中指定映射到 host 某個特定端口,例如可將 80 端口映射到 host 的 8080 端口:

docker run -d -p 8080:80 httpd

curl 192.168.10.10:8080

 

 

 

 

 

 

每一個映射的端口,host 都會啟動一個 docker-proxy 進程來處理訪問容器的流量:

 

 

 

 

 

0.0.0.0:32770->80/tcp 為例分析整個過程:

 

 

 

 

docker-proxy 監聽 host 的 32770 端口。

curl 訪問 10.0.2.15:32770 時,docker-proxy 轉發給容器 172.17.0.2:80。

httpd 容器響應請求並返回結果。

 

overlay網絡模式的特點:

1.overlay網絡模式實現方案有很多種,在Docker自身集成了一種,基於VXLAN隧道技術實現

2.overlay網絡主要用於實現跨主機容器之間的通信

 

macvlan網絡模式的特點:

1.macvlan的主要特點就是通信直接基於mac地址進行轉發

2.在macvlan中宿主機擔任的角色是一台二層交換機Docker會維護一張mac地址表,當宿主機收到數據包時,直接根據mac地址找到對應的容器

3.而在容器內部互相通信的時候,容器直接使用IP互通,所以每個容器對於外面的網絡都是一台真實的網絡設備

 

5.容器數據管理

宿主機要直接訪問容器中的文件,但是由於容器中的文件沒有持久化,且容器沒有使用數據卷,那么當容器刪除后,文件數據也會隨之消失,其他容器也無法直接訪問相互的文件。

1.數據卷的特點

數據卷存在於宿主機的文件系統中,獨立於容器,和容器的生命周期是分離的。

數據卷可以是目錄也可以是文件,容器可以利用數據卷與宿主機進行數據共享,實現了容器間的數據共享和交換。

容器啟動初始化時,如果容器使用的鏡像包含了數據,這些數據會拷貝到數據卷中。

容器對數據卷的修改是實時進行的。

數據卷的變化不會影響鏡像的更新。數據卷是獨立於聯合文件系統,鏡像是基於聯合文件系統。鏡像與數據卷之間不會有相互影響。

鏡像 2. volume

2.Docker數據卷的掛載方式

bind mounts: 將宿主機上的一個文件或目錄掛載到容器上

volumes:由Docker創建和管理。使用Docker volume命令管理

 

1.  bind mounts掛載數據卷

docker run/create -v

-v  宿主機文件或文件夾路徑:容器中的文件或文件夾路徑

掛載一個主機目錄作為數據卷

使用-v標記也可以指定掛載一個本地的已有目錄到容器中去作為數據卷(推薦方式)。

 

例如 docker host 上有目錄 /root/htdocs

[root@host2 htdocs]# vi index.html

<html><body><h1>This is a file in host file system!</h1></body></html>


通過 -v 將其 mount 到 httpd 容器:
[root@host2 ~]# docker run -d -p 80:80 -v ~/htdocs:/usr/local/apache2/htdocs httpd

79984086504f1be3ec1b3e259318ae20a517c6a28a4ec722b5bfd436b822ea31

-v 的格式為 <host path>:<container path>。/usr/local/apache2/htdocs 就是 apache server 存放靜態文件的地方。

由於 /usr/local/apache2/htdocs 已經存在,原有數據會被隱藏起來,取而代之的是 host $HOME/htdocs/ 中的數據,這與 linux mount 命令的行為是一致的。

[root@host2 ~]# curl 127.0.0.1:80

<html><body><h1>This is a file in host file system!</h1></body></html>

curl 顯示當前主頁確實是 $HOME/htdocs/index.html 中的內容。更新一下,看是否能生效:

 

[root@host2 ~]# echo "update index page" >~/htdocs/index.html

[root@host2 ~]# curl 127.0.0.1:80

update index page

host 中的修改確實生效了,bind mount 可以讓 host 與容器共享數據。這在管理上是非常方便的。

這個功能在進行測試的時候十分方便,比如用戶可以將一些程序或數據放到本地目錄中,然后在容器內運行和使用。另外,本地目錄的路徑必須是絕對路徑,如果目錄不存在Docker會自動創建。

 

Docker掛載數據卷的默認權限是讀寫(rw),用戶也可以通過ro指定為只讀:

[root@host2 ~]# docker run -d -p 80:80 -v ~/htdocs:/usr/local/apache2/htdocs:ro httpd

20ae3006a19d1bd5552a612e82d8474223356bff73aacfc6427c9ff88b0c9855

[root@host2 ~]# docker exec -it 20ae bash

root@20ae3006a19d:/usr/local/apache2# echo "do some changes" >htdocs/index.html

bash: htdocs/index.html: Read-only file system

加了:ro之后,容器內對所掛載數據卷內的數據就無法修改了。

 

掛載一個本地主機文件作為數據卷

-v標記也可以從主機掛載單個文件到容器中作為數據卷(不推薦)。

docker run -d -p 801:80 -v ~/htdocs/index.html:/usr/local/apache2/htdocs/new_index.html httpd

3a50a099cb83af27f9084ca4e9030788cba85a24d72f97e7833070e48ca5ff4a

 

curl 127.0.0.1:801

<html><body><h1>It works!</h1></body></html>

[root@host2 ~]# curl 127.0.0.1:801/new_index.html        

update index page

 

使用 bind mount 單個文件的場景是:只需要向容器添加文件,不希望覆蓋整個目錄。在上面的例子中,我們將 html 文件加到 apache 中,同時也保留了容器原有的數據。

6.Docker compose

1.Docker compose介紹

前面我們使用 Docker 的時候,定義 Dockerfile 文件,然后使用 docker build、docker run 等命令操作容器。然而微服務架構的應用系統一般包含若干個微服務,每個微服務一般都會部署多個實例,如果每個微服務都要手動啟停,那么效率之低,維護量之大可想而知

 

Docker Compose是一個能一次性定義和管理多個Docker容器的工具。

Compose中定義和啟動的每一個容器都相當於一個服務(service)

Compose中能定義和啟動多個服務,且它們之間通常具有協同關系

我們通常使用YAML文件來配置我們應用程序的服務

2.安裝Docker compose

使用python pip包安裝

1.安裝pip工具  epel-release

2.執行以下命令:pip install -U docker-compose

 

 

 

 

 

3.檢驗是否安裝成功:docker-compose version

 

 

 

3.Docker Compose文件配置與注意事項

常見的配置項:

version:指定Docker Compose File版本號

services:定義多個服務並配置啟動參數

volumes:聲明或創建在多個服務中共同使用的數據卷對象

networks:定義在多個服務中共同使用的網絡對象

configs:聲明將在本服務中要使用的一些配置文件

secrets:聲明將在本服務中要使用的一些秘鑰、密碼文件

x-***:自定義配置。主要用於復用相同的配置

 

Docker Compose File 的格式要求非常嚴格,一定需要注意的有

配置項的縮進使用空格

注意配置項冒號后要添加空格

編寫完Docker Compose File后可以使用docker-compose config 檢查文件是否出錯

 

 

 

 

 

 官網例子

docker-compose.yml文件是一個YAML文件,它定義了Docker容器在生產環境中的行為。

 

 

 

 

 

 

 

執行docker stack deploy需要給應用命名。這里,它被設置為getstartedlab

 

 

 

 

在使用docker stack deploy命令之前,我們需要先運行:

 

 

 

 

 

 

 

查看service:

 

 

 

 

要查看一個stack的所有任務,可以運行docker stack ps,后面跟着你的app名,如下例所示:

 

 

 

 

如果只列出系統上的所有容器,任務也會顯示出來,不過這並不會被服務過濾

 

 

 

 

可以通過更改docker-compose中的replicas值來擴展(縮小)應用程序。保存更改,並重新運行docker stack deploy命令:

 

 

 

 

 

 

 

查看服務及容器情況:

 

 

 

 

7.簡答& 實驗

簡答題

實現容器的底層技術有哪些?

容器網絡如何實現自定義?

容器與外界通信原理是什么?

容器如何實現數據管理?

Docker compose是做什么用的?

實驗題

1)  編寫docker compose 的yaml文件,實現批量創建多個容器

2)  自定義創建容器網絡,創建容器選擇該網絡,並驗證網絡之間的連通性

3)  實現將本地目錄掛載到容器

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM