一、Docker網絡
1.docker網絡實現(xiàn)原理
Docker使用Linux橋接,在宿主機虛擬一個Docker容器網橋(docker0),Docker啟動一個容器時會根據(jù)Docker網橋的網段分配給容器一個IP地址,稱為Container-IP,同時Docker網橋是每個容器的默認網關。因為在同一宿主機內的容器都接入同一個網橋,這樣容器之間就能夠通過容器的 Container-IP 直接通信。
?2.docker的網絡模式
docker初始狀態(tài)下有三種默認的網絡模式 ,bridg(橋接),host(主機),none(無網絡設置)
使用docker run創(chuàng)建Docker容器時,可以用 --net 或 --network 選項指定容器的網絡模式
●host模式:使用 --net=host 指定。
●none模式:使用 --net=none 指定。
●container模式:使用 --net=container:NAME_or_ID 指定。
●bridge模式:使用 --net=bridge 指定,默認設置,可省略。?
1)host模式
相當于Vmware中的橋接模式,與宿主機在同一個網絡中,但沒有獨立IP地址。
Docker使用了Linux的Namespaces技術來進行資源隔離,如PID Namespace隔離進程,Mount Namespace隔離文件系統(tǒng),Network Namespace隔離網絡等。
一個Network Namespace提供了一份獨立的網絡環(huán)境,包括網卡、路由、iptable規(guī)則等都與其他的Network Namespace隔離。 一個Docker容器一般會分配一個獨立的Network Namespace。
但如果啟動容器的時候使用host模式,那么這個容器將不會獲得一個獨立的Network Namespace, 而是和宿主機共用一個Network Namespace。容器將不會虛擬出自己的網卡、配置自己的IP等,而是使用宿主機的IP和端口。
容器和宿主機共享網絡命名空間,容器和宿主機使用同一個IP、端口范圍(容器和宿主機不可以使用相同的端口)等網絡資源
#創(chuàng)建容器test1,指定網絡模式為 host
#容器和宿主機共享網絡命名空間,但沒有獨立IP地址。使用宿主機的IP,和宿主機共享端口范圍。
docker run -d --name test1 --net=host nginx
?
#訪問宿主機的ip和80端口,則可以訪問到tt1的nginx服務
curl http://192.168.190.10:80
2)container模式
?在理解了host模式后,這個模式也就好理解了。這個模式指定新創(chuàng)建的容器和已經存在的一個容器共享一個Network Namespace,而不是和宿主機共享。 新創(chuàng)建的容器不會創(chuàng)建自己的網卡,配置自己的IP,而是和一個指定的容器共享IP、端口范圍等。同樣,兩個容器除了網絡方面,其他的如文件系統(tǒng)、進程列表等還是隔離的。兩個容器的進程可以通過lo網卡設備通信。
與指定容器共享網絡命名空間,兩個容器使用同一個IP、端口范圍(兩個容器不可以使用相同的端口)等網絡資源
?
基于鏡像centos:7 創(chuàng)建一個名為web1的容器
docker run -itd --name web1 centos:7 /bin/bash
查看容器web1的pid號
docker inspect -f '{{.State.Pid}}' web1
ls -l /proc/web1的pid/ns
創(chuàng)建web2容器,使用container網絡模式,和web2共享網絡命名空間
docker run -itd --name web2 --net=container:web1 centos:7 bash
查看web2容器的pid
docker inspect -f '{{.State.Pid}}' web2
ls -l /proc/web2的pid/ns/
可以看到web2和web1共享同一個網絡命名空間
?3)none模式
使用none模式,Docker容器擁有自己的Network Namespace,但是,并不為Docker容器進行任何網絡配置。 也就是說,這個Docker容器沒有網卡、IP、路由等信息。這種網絡模式下容器只有l(wèi)o回環(huán)網絡,沒有其他網卡。這種類型的網絡沒有辦法聯(lián)網,封閉的網絡能很好的保證容器的安全性。
?每個容器都有獨立的網絡命名空間,但是容器沒有eth0網卡、IP、端口等,只有l(wèi)o網卡
4)?bridge模式
bridge模式是docker的默認網絡模式,不用--net參數(shù),就是bridge模式。
相當于Vmware中的 nat 模式,容器使用獨立network Namespace,并連接到docker0虛擬網卡。通過docker0網橋以及iptables nat表配置與宿主機通信,此模式會為每一個容器分配Network Namespace、設置IP等,并將一個主機上的 Docker 容器連接到一個虛擬網橋上。?? ?
(1)當Docker進程啟動時,會在主機上創(chuàng)建一個名為docker0的虛擬網橋,此主機上啟動的Docker容器會連接到這個虛擬網橋上。虛擬網橋的工作方式和物理交換機類似,這樣主機上的所有容器就通過交換機連在了一個二層網絡中。
(2)從docker0子網中分配一個IP給容器使用,并設置docker0的IP地址為容器的默認網關。在主機上創(chuàng)建一對虛擬網卡veth pair設備。 veth設備總是成對出現(xiàn)的,它們組成了一個數(shù)據(jù)的通道,數(shù)據(jù)從一個設備進入,就會從另一個設備出來。因此,veth設備常用來連接兩個網絡設備。
(3)Docker將 veth pair 設備的一端放在新創(chuàng)建的容器中,并命名為 eth0(容器的網卡),另一端放在主機中, 以 veth* 這樣類似的名字命名, 并將這個網絡設備加入到 docker0 網橋中??梢酝ㄟ^ brctl show 命令查看。
(4)使用 docker run -p 時,docker實際是在iptables做了DNAT規(guī)則,實現(xiàn)端口轉發(fā)功能。可以使用iptables -t nat -vnL 查看。
docker默認得網絡模式。每個容器都有獨立的網絡命名空間(net namespace),每個容器有獨立的IP、端口范圍(每個容器可以使用相同的端口)、路由、iptables規(guī)則等
[root@localhost~] # docker run -id --name c1 centos:7
7e58036ebc1761ded7734f9b5b2024bb67a803c13443a3938cdadb59e552e6d2
[root@localhost~] # docker run -id --name c2 centos:7
6071236a94a7d0f9afc5e28bbbc747e57fe0378837ecc374997d83809eeaa540
[root@localhost~] # docker run -id --name c3 centos:7
c15001d3341396783760106481eec514ac7f57451ff5457a04cd6eea848e0094
[root@localhost~] # brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.0242ffc896ea no veth16145e4
veth18d626e
vethc8f7bb8
virbr0 8000.525400d2ee29 yes virbr0-nic
[root@localhost~] # docker run -id --name c4 -p 8080:80 centos:7
e28bff2010dd7801f0efa416f2f263a1d1cc597fc6569bc09d80e75f01608741
[root@localhost~] # docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e28bff2010dd centos:7 "/bin/bash" 7 seconds ago Up 6 seconds 0.0.0.0:8080->80/tcp, :::8080->80/tcp c4
c15001d33413 centos:7 "/bin/bash" 27 seconds ago Up 27 seconds c3
6071236a94a7 centos:7 "/bin/bash" 37 seconds ago Up 36 seconds c2
7e58036ebc17 centos:7 "/bin/bash" 45 seconds ago Up 45 seconds c1
?5)自定義網絡
未創(chuàng)建自定義網絡時,創(chuàng)建指定IP容器的測試
指定容器IP的方式:?
注意:創(chuàng)建指定IP的容器也需要基于docker網卡的IP網段?
docker run -id --name a1 --ip 172.17.0.33 nginx
ping 172.17.0.33
docker run -id --name a2 --network bridge --ip 172.17.44 nginx
?創(chuàng)建自定義docker網絡
docker network create --subnet=172.33.0.0/16 --opt "com.docker.network.bridge.name"="docker1" mynetwork
?再次創(chuàng)建指定IP的容器:
docker run -id --net=mynetwork --ip 172.33.0.33 --name a3 centos:7
ping 172.33.0.33
刪除自定義網絡:
如果想要刪除自定義的網絡,可以使用 docker network rm 網絡模式名稱 進行刪除,例如docker network rm mynetwork。
?刪除網絡模式前,需要先確保使用該網絡模式創(chuàng)建的容器已退出(即已停止)。如果容器仍在運行,則該網絡無法刪除。
二、 Docker容器的資源控制
Docker 通過 Cgroup 來控制容器使用的資源配額,包括 CPU、內存、磁盤三大方面, 基本覆蓋了常見的資源配額和使用量控制。
Cgroup 是 ControlGroups 的縮寫,是 Linux 內核提供的一種可以限制、記錄、隔離進程組所使用的物理資源(如 CPU、內存、磁盤 IO 等等) 的機制,被 LXC、docker 等很多項目用于實現(xiàn)進程資源控制。Cgroup 本身是提供將進程進行分組化管理的功能和接口的基礎結構,I/O 或內存的分配控制等具體的資源管理是通過該功能來實現(xiàn)的。
- 資源限制:可以對任務使用的資源總額進行限制。
- 優(yōu)先級分配:通過分配的cpu時間片數(shù)量以及磁盤IO帶寬大小,實際上相當于控制了任務運行優(yōu)先級。
- 資源統(tǒng)計:可以統(tǒng)計系統(tǒng)的資源使用量,如cpu時長,內存用量等。
- 任務控制: cgroup可以對任務 執(zhí)行掛起、恢復等操作。
?1.docker占用宿主機cpu的限制
Linux通過CFS(Completely Fair Scheduler,完全公平調度器)來調度各個進程對CPU的使用。CFS默認的調度周期是100ms。
我們可以設置每個容器進程的調度周期,以及在這個周期內各個容器最多能使用多少 CPU 時間。
使用 --cpu-period 即可設置調度周期,使用 --cpu-quota 即可設置在每個周期內容器能使用的CPU時間。兩者可以配合使用。
CFS 周期的有效范圍是 1ms~1s,對應的 --cpu-period 的數(shù)值范圍是 1000~1000000。
而容器的 CPU 配額必須不小于 1ms,即 --cpu-quota 的值必須 >= 1000。
?
cpu.cfs_period_us:cpu分配的周期(微秒,所以文件名中用 us 表示),默認為100000。
cpu.cfs_quota_us:表示該cgroups限制占用的時間(微秒),默認為-1,表示不限制。 如果設為50000,表示占用50000/100000=50%的CPU。
1) 進行CPU壓力測試
進行CPU壓力測試
docker exec -it ee97db7bbc0e /bin/bash
vi /cpu.sh
#!/bin/bash
i=0
while true
do
let i++
done
chmod +x /cpu.sh
./cpu.sh
top 可以看到這個腳本占了很多的cpu資源
設置50%的比例分配CPU使用時間上限
docker run -itd --name test6 --cpu-quota 50000 centos:7 /bin/bash #可以重新創(chuàng)建一個容器并設置限額
或者
cd /sys/fs/cgroup/cpu/docker/ee97db7bbc0e5c21133c0ec6ed4ae249607c170cd48cc409313b0cd798183c99
echo 50000 > cpu.cfs_quota_us
docker exec -it ee97db7bbc0e /bin/bash
./cpu.sh
top #可以看到cpu占用率接近50%,cgroups對cpu的控制起了效果
在多核情況下,如果允許容器進程完全占用兩個 CPU, 則可以將 cpu-period 設置為 100000( 即 0.1 秒), cpu-quota設置為 200000(0.2 秒)。
?2)設置CPU資源占用比(設置多個容器時才有效)
Docker 通過 --cpu-shares 指定 CPU 份額,默認值為1024,值為1024的倍數(shù)。
#創(chuàng)建兩個容器為 c1 和 c2,若只有這兩個容器,設置容器的權重,使得c1和c2的CPU資源占比為1/3和2/3。
docker run -itd --name c1 --cpu-shares 512 centos:7
docker run -itd --name c2 --cpu-shares 1024 centos:7
#分別進入容器,進行壓力測試
yum install -y epel-release
yum install -y stress
stress -c 4 #產生四個進程,每個進程都反復不停的計算隨機數(shù)的平方根
#查看容器運行狀態(tài)(動態(tài)更新)
docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
1f5745917472 c2 66.50% 5.5MiB / 976.3MiB 0.56% 20.4MB / 265kB 115MB / 14.2MB 4
ca3a9c360230 c1 32.68% 2.625MiB / 976.3MiB 0.27% 20.4MB / 325kB 191MB / 12.7MB 4
可以看到在 CPU 進行時間片分配的時候,容器 c2 比容器 c1 多一倍的機會獲得 CPU 的時間片。
但分配的結果取決于當時主機和其他容器的運行狀態(tài), 實際上也無法保證容器 c1 一定能獲得 CPU 時間片。比如容器 c1 的進程一直是空閑的,那么容器 c2 是可以獲取比容器 c1 更多的 CPU 時間片的。極端情況下,例如主機上只運行了一個容器,即使它的 CPU 份額只有 50,它也可以獨占整個主機的 CPU 資源。
Cgroups 只在容器分配的資源緊缺時,即在需要對容器使用的資源進行限制時,才會生效。因此,無法單純根據(jù)某個容器的 CPU 份額來確定有多少 CPU 資源分配給它,資源分配結果取決于同時運行的其他容器的 CPU 分配和容器中進程運行情況。
?3)設置容器綁定指定的CPU
先分配虛擬機4個CPU核數(shù)
docker run -itd --name test7 --cpuset-cpus 1,3 centos:7 /bin/bash
進入容器,進行壓力測試
yum install -y epel-release
yum install stress -y
stress -c 4
退出容器,執(zhí)行 top 命令再按 1 查看CPU使用情況。
?2.對內存使用限制
//-m(--memory=) 選項用于限制容器可以使用的最大內存
docker run -itd --name test8 -m 512m centos:7 /bin/bash
docker stats
//限制可用的 swap 大小, --memory-swap
強調一下,--memory-swap 是必須要與 --memory 一起使用的。
正常情況下,--memory-swap 的值包含容器可用內存和可用 swap。
所以 -m 300m --memory-swap=1g 的含義為:容器可以使用 300M 的物理內存,并且可以使用 700M(1G - 300)的 swap。
如果 --memory-swap 設置為 0 或者 不設置,則容器可以使用的 swap 大小為 -m 值的兩倍。
如果 --memory-swap 的值和 -m 值相同,則容器不能使用 swap。
如果 --memory-swap 值為 -1,它表示容器程序使用的內存受限,而可以使用的 swap 空間使用不受限制(宿主機有多少 swap 容器就可以使用多少)。
?3.對磁盤IO配額控制(blkio)的限制
--device-read-bps:限制某個設備上的讀速度bps(數(shù)據(jù)量),單位可以是kb、mb(M)或者gb。
例:docker run -itd --name test9 --device-read-bps /dev/sda:1M centos:7 /bin/bash
--device-write-bps : 限制某個設備上的寫速度bps(數(shù)據(jù)量),單位可以是kb、mb(M)或者gb。
例:docker run -itd --name test10 --device-write-bps /dev/sda:1mb centos:7 /bin/bash
--device-read-iops :限制讀某個設備的iops(次數(shù))
--device-write-iops :限制寫入某個設備的iops(次數(shù))
創(chuàng)建容器,并限制寫速度
docker run -it --name test10 --device-write-bps /dev/sda:1mb centos:7 /bin/bash
通過dd來驗證寫速度
dd if=/dev/zero of=test.out bs=1M count=10 oflag=direct 添加oflag參數(shù)以規(guī)避掉文件系統(tǒng)cache
10+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 10.0033 s, 1.0 MB/s
默認情況容器的寫速度
[root@localhost~] # docker run -id --name e1 centos:7
fc47a2e5778fd4616b78f7e243cba135c5631afaf294e6d382a0d859a1ba956d
[root@localhost~] # docker exec -it e1 bash
[root@fc47a2e5778f /]# dd if=/dev/zero of=/opt/test.txt bs=10M count=5 oflag=direct
5+0 records in
5+0 records out
52428800 bytes (52 MB) copied, 0.0413864 s, 1.3 GB/s
[root@fc47a2e5778f /]#
?4.清理docker占用的磁盤空間
docker system prune -a 可用于清理磁盤,刪除關閉的容器、無用的數(shù)據(jù)卷和網絡
docker system prune -a #可以用于清理磁盤,刪除關閉的容器、無用的數(shù)據(jù)卷和網絡
文章來源:http://www.zghlxwxcb.cn/news/detail-601942.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-601942.html
到了這里,關于【云原生】Docker網絡及Cgroup資源控制的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!