數據卷
Docker提供三種方式將數據從宿主機掛載到容器中:
• volumes:Docker管理宿主機文件系統的一部分(/var/lib/docker/volumes)。保存數據的最佳方式。
• bind mounts:將宿主機上的任意位置的文件或者目錄掛載到容器中。
• tmpfs:掛載存儲在主機系統的內存中,而不會寫入主機的文件系統。如果不希望將數據持久存儲在任何位置,可以使用
tmpfs,同時避免寫入容器可寫層提高性能。
volumes:
#創建一個數據卷
[root@node1 ~]# docker volume create nginx-vol
nginx-vol
#查看卷
[root@node1 ~]# docker volume ls
DRIVER VOLUME NAME
local nginx-vol
#查看詳細信息
[root@node1 ~]# docker volume inspect nginx-vol
[
{
"CreatedAt": "2019-10-22T10:24:29-04:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/nginx-vol/_data",
"Name": "nginx-vol",
"Options": {},
"Scope": "local"
}
]
#用卷創建一個容器,如果沒有指定卷,自動創建
docker run -d --name=nginx-01 --mount src=nginx-vol,dst=/usr/share/nginx/html nginx
#刪除數據卷 要先停止容器把容器刪了才能刪除數據卷
[root@node1 ~]# docker volume rm nginx-vol
nginx-vol
#數據卷是被設計用來持久化數據的,它的生命週期獨立於容器,Docker 不會在容器被刪除後自動刪除,
#並且也不存在垃圾回收這樣的機制來處理沒有任何容器引用的數據卷 。
#如果需要在刪除容器的同時移除數據卷。可以在刪除容器 的時候使用 docker rm -v 這個命令。
#無主的數據卷可能會佔據很多空間,要清理請使用以下命令 docker volume prun
bindmounts掛載主機目錄
#如果源文件/目錄沒有存在,不會自動創建,會拋出一個錯誤。
#如果掛載目標在容器中非空目錄,則該目錄現有內容將被隱藏
[root@node1 app]# docker run -itd --name=nginx-02 --mount type=bind,src=/app/wwwroot,dst=/usr/share/nginx/html nginx
容器網路
當 Docker 啓動時,會自動在主機上創建一個 docker0 虛擬網橋,實際上是 Linux 的一個 bridge,可以理解爲一個軟件交換機。它會在掛載到它的網口之間進 行轉發。 同時,Docker 隨機分配一個本地未佔用的私有網段(在 RFC1918 中定義)中的一 個地址給 docker0 接口。比如典型的 172.17.42.1 ,掩碼爲 255.255.0.0 ,此後啓動的容器內的網口也會自動分配一個同一網段 ( 172.17.0.0/16 )的地址。
當創建一個 Docker 容器的時候,同時會創建了一對 veth pair 接口(當數據包 發送到一個接口時,另外一個接口也可以收到相同的數據包)。這對接口一端在容 器內,即 eth0 ;另一端在本地並被掛載到 docker0 網橋,名稱以 veth 開 頭(例如 vethAQI2QT )。通過這種方式,主機可以跟容器通信,容器之間也可 以相互通信。Docker 就創建了在主機和所有容器之間一個虛擬共享網絡。
映射容器端口到宿主主機的實現 默認情況下,容器可以主動訪問到外部網絡的連接,但是外部網絡無法訪問到容 器。容器訪問外部實現容器所有到外部網絡的連接,源地址都會被 NAT 成本地系統的 IP 地址。這是使用 iptables 的源地址僞裝操作實現的。
映射容器端口到宿主主機的實現 默認情況下,容器可以主動訪問到外部網絡的連接,但是外部網絡無法訪問到容器。
容器訪問外部實現
[root@node1 app]# iptables -t nat -nL
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- 172.17.0.0/16 0.0.0.0/0
#其中,上述規則將所有源地址在 172.17.0.0/16 網段,目標地址爲其他網段 (外部網絡)的流量動態僞裝爲
#從系統網卡發出。MASQUERADE 跟傳統SNAT的好處是它能動態從網卡獲取地址。
外部訪問容器實現
#-p 5001:8080 本機5001端口映射到容器8080端口
target prot opt source destination
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:5001 to:172.17.0.2:8080
網絡模式
•bridge
--net=bridge
默認網絡,Docker啓動後創建一個docker0網橋,默認創建的容器也是添加到這個網橋中
•host
--net=host
容器不會獲得一個獨立的networknamespace,而是與宿主機共用一個。這就意味着容器不會有自己的網卡信息,而是使用宿主機的。容器除了網絡,其他都是隔離的。
•none
--net=none
獲取獨立的networknamespace,但不爲容器進行任何網絡配置,需要我們手動配置
•container
--net=container:Name/ID
與指定的容器使用同一個networknamespace,具有同樣的網絡配置信息,兩個容器除了網絡,其他都還是隔離的。
自定義網絡與默認的bridge原理一樣,但自定義網絡具備內部DNS發現,可以通過容器名或者主機名容器之間網絡通信。
#容器要想訪問外部網絡,需要本地系統的轉發支持。在Linux 系統中,檢查轉發是否打開。
[root@node1 app]# sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 0
[root@node1 app]# sysctl -w net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1
#使用 -p hostPort:containerPort 格式本地的 5001 端口映射到容器的8080端 口,
[root@node1 app]# docker run -itd -p 5001:8080 --name=nginx-02 --mount type=bind,src=/app/wwwroot,dst=/usr/share/nginx/html nginx
#查看映射端口配置 使用 docker port 來查看當前映射的端口配置,也可以查看到綁定的地址
[root@node1 app]# docker port 2e1
8080/tcp -> 0.0.0.0:5001
#docker inspect查看容器所有變量
[root@node1 app]# docker inspect 2e1
#-p 標記可以多次使用來綁定多個端口
[root@node1 app]# docker run -d -p 5000:5000 -p 3000:80 training/webapp python app.py