一、Docker 網(wǎng)絡(luò)
1、Docker 網(wǎng)絡(luò)實(shí)現(xiàn)原理
-
Docker使用Linux橋接,在宿主機(jī)虛擬一個(gè)Docker容器網(wǎng)橋(docker0),Docker啟動(dòng)一個(gè)容器時(shí)會(huì)根據(jù)Docker網(wǎng)橋的網(wǎng)段分配給容器一個(gè)IP地址,稱為Container-IP,同時(shí)Docker網(wǎng)橋是每個(gè)容器的默認(rèn)網(wǎng)關(guān)。因?yàn)樵谕凰拗鳈C(jī)內(nèi)的容器都接入同一個(gè)網(wǎng)橋,這樣容器之間就能夠通過容器的 Container-IP 直接通信。
-
Docker網(wǎng)橋是宿主機(jī)虛擬出來的,并不是真實(shí)存在的網(wǎng)絡(luò)設(shè)備,外部網(wǎng)絡(luò)是無法尋址到的,這也意味著外部網(wǎng)絡(luò)無法直接通過 Container-IP 訪問到容器。如果容器希望外部訪問能夠訪問到,可以通過映射容器端口到宿主主機(jī)(端口映射),即 docker run 創(chuàng)建容器時(shí)候通過 -p 或 -P 參數(shù)來啟用端口,訪問容器的時(shí)候就通過 [宿主機(jī)IP]:[容器端口]訪問容器。
docker run -d --name test1 -P nginx #隨機(jī)映射端口(從32768開始)
docker run -d --name test2 -p 43000:80 nginx #指定映射端口
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
61a08c55a980 nginx:1.12 "nginx -g 'daemon of…" 6 seconds ago Up 5 seconds 0.0.0.0:9912->80/tcp, :::9912->80/tcp xc2
62b5078266fa nginx:1.12 "nginx -g 'daemon of…" About a minute ago Up About a minute 0.0.0.0:32768->80/tcp, :::32 xc1
瀏覽器訪問:http://192.168.92.13:9912 、http://192.168.2.13:32768
#查看容器的輸出和日志信息
docker logs 容器的ID/名稱
2、Docker 的網(wǎng)絡(luò)模式:
- Host:容器將不會(huì)虛擬出自己的網(wǎng)卡,配置自己的IP等,而是使用宿主機(jī)的IP和端口。
- Container:創(chuàng)建的容器不會(huì)創(chuàng)建自己的網(wǎng)卡,配置自己的IP,而是和一個(gè)指定的容器共享IP、端口范圍。
- None:該模式關(guān)閉了容器的網(wǎng)絡(luò)功能。
- Bridge:默認(rèn)為該模式,此模式會(huì)為每一個(gè)容器分配、設(shè)置IP等,并將容器連接到一個(gè)docker0虛擬網(wǎng)橋,通過docker0網(wǎng)橋以及iptables nat 表配置與宿主機(jī)通信。
安裝Docker時(shí),它會(huì)自動(dòng)創(chuàng)建三個(gè)網(wǎng)絡(luò),bridge(創(chuàng)建容器默認(rèn)連接到此網(wǎng)絡(luò))、 none 、host
docker network ls 或 docker network list #查看docker網(wǎng)絡(luò)列表
NETWORK ID NAME DRIVER SCOPE
ff5c8f10de12 bridge bridge local
c348364a519d host host local
3eb7a0b88d4f none null local
#使用docker run創(chuàng)建Docker容器時(shí),可以用 --net 或 --network 選項(xiàng)指定容器的網(wǎng)絡(luò)模式
●host模式:使用 --net=host 指定。
●none模式:使用 --net=none 指定。
●container模式:使用 --net=container:NAME_or_ID 指定。
●bridge模式:使用 --net=bridge 指定,默認(rèn)設(shè)置,可省略。
網(wǎng)絡(luò)模式詳解:
1.host模式
- 相當(dāng)于Vmware中的橋接模式,與宿主機(jī)在同一個(gè)網(wǎng)絡(luò)中,但沒有獨(dú)立IP地址。
- Docker使用了Linux的Namespaces技術(shù)來進(jìn)行資源隔離,如PID Namespace隔離進(jìn)程,Mount Namespace隔離文件系統(tǒng),Network Namespace隔離網(wǎng)絡(luò)等。
- 一個(gè)Network Namespace提供了一份獨(dú)立的網(wǎng)絡(luò)環(huán)境,包括網(wǎng)卡、路由、iptable規(guī)則等都與其他的Network Namespace隔離。 一個(gè)Docker容器一般會(huì)分配一個(gè)獨(dú)立的Network Namespace。 但如果啟動(dòng)容器的時(shí)候使用host模式,那么這個(gè)容器將不會(huì)獲得一個(gè)獨(dú)立的Network Namespace, 而是和宿主機(jī)共用一個(gè)Network Namespace。容器將不會(huì)虛擬出自己的網(wǎng)卡、配置自己的IP等,而是使用宿主機(jī)的IP和端口。
2.container模式
- 在理解了host模式后,這個(gè)模式也就好理解了。這個(gè)模式指定新創(chuàng)建的容器和已經(jīng)存在的一個(gè)容器共享一個(gè)Network Namespace,而不是和宿主機(jī)共享。 新創(chuàng)建的容器不會(huì)創(chuàng)建自己的網(wǎng)卡,配置自己的IP,而是和一個(gè)指定的容器共享IP、端口范圍等。同樣,兩個(gè)容器除了網(wǎng)絡(luò)方面,其他的如文件系統(tǒng)、進(jìn)程列表等還是隔離的。兩個(gè)容器的進(jìn)程可以通過lo網(wǎng)卡設(shè)備通信。
docker run -itd --name xc3 centos:7 /bin/bash #--name 選項(xiàng)可以給容器創(chuàng)建一個(gè)自定義名稱
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
db47fc5d33ac centos:7 "/bin/bash" 4 minutes ago Up 4 minutes xc3
docker inspect -f '{{.State.Pid}}' xc3 #查看容器進(jìn)程號(hào)
6758
ls -l /proc/25495/ns #查看容器的進(jìn)程、網(wǎng)絡(luò)、文件系統(tǒng)等命名空間編號(hào)
lrwxrwxrwx. 1 root root 0 7月 20 18:17 ipc -> ipc:[4026532561]
lrwxrwxrwx. 1 root root 0 7月 20 18:17 mnt -> mnt:[4026532559]
lrwxrwxrwx. 1 root root 0 7月 20 18:16 net -> net:[4026532565]
lrwxrwxrwx. 1 root root 0 7月 20 18:17 pid -> pid:[4026532562]
lrwxrwxrwx. 1 root root 0 7月 20 18:17 user -> user:[4026531837]
lrwxrwxrwx. 1 root root 0 7月 20 18:17 uts -> uts:[4026532560]
docker run -itd --name xc4 --net=container:db47fc5d33ac centos:7 /bin/bash
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
25538fed6111 centos:7 "/bin/bash" 16 seconds ago Up 15 seconds xc4
db47fc5d33ac centos:7 "/bin/bash" 4 minutes ago Up 4 minutes xc3
docker inspect -f '{{.State.Pid}}' xc4
7146
ls -l /proc/27123/ns #查看可以發(fā)現(xiàn)兩個(gè)容器的 net namespace 編號(hào)相同
lrwxrwxrwx. 1 root root 0 7月 20 18:22 ipc -> ipc:[4026532661]
lrwxrwxrwx. 1 root root 0 7月 20 18:22 mnt -> mnt:[4026532659]
lrwxrwxrwx. 1 root root 0 7月 20 18:22 net -> net:[4026532565]
lrwxrwxrwx. 1 root root 0 7月 20 18:22 pid -> pid:[4026532672]
lrwxrwxrwx. 1 root root 0 7月 20 18:22 user -> user:[4026531837]
lrwxrwxrwx. 1 root root 0 7月 20 18:22 uts -> uts:[4026532660]
3.none模式
- 使用none模式,Docker容器擁有自己的Network Namespace,但是,并不為Docker容器進(jìn)行任何網(wǎng)絡(luò)配置。 也就是說,這個(gè)Docker容器沒有網(wǎng)卡、IP、路由等信息。這種網(wǎng)絡(luò)模式下容器只有l(wèi)o回環(huán)網(wǎng)絡(luò),沒有其他網(wǎng)卡。這種類型的網(wǎng)絡(luò)沒有辦法聯(lián)網(wǎng),封閉的網(wǎng)絡(luò)能很好的保證容器的安全性。
4.bridge模式
-
bridge模式是docker的默認(rèn)網(wǎng)絡(luò)模式,不用–net參數(shù),就是bridge模式。
-
相當(dāng)于Vmware中的 nat 模式,容器使用獨(dú)立network Namespace,并連接到docker0虛擬網(wǎng)卡。通過docker0網(wǎng)橋以及iptables nat表配置與宿主機(jī)通信,此模式會(huì)為每一個(gè)容器分配Network Namespace、設(shè)置IP等,并將一個(gè)主機(jī)上的 Docker 容器連接到一個(gè)虛擬網(wǎng)橋上。
-
(1)當(dāng)Docker進(jìn)程啟動(dòng)時(shí),會(huì)在主機(jī)上創(chuàng)建一個(gè)名為docker0的虛擬網(wǎng)橋,此主機(jī)上啟動(dòng)的Docker容器會(huì)連接到這個(gè)虛擬網(wǎng)橋上。虛擬網(wǎng)橋的工作方式和物理交換機(jī)類似,這樣主機(jī)上的所有容器就通過交換機(jī)連在了一個(gè)二層網(wǎng)絡(luò)中。
-
(2)從docker0子網(wǎng)中分配一個(gè)IP給容器使用,并設(shè)置docker0的IP地址為容器的默認(rèn)網(wǎng)關(guān)。在主機(jī)上創(chuàng)建一對(duì)虛擬網(wǎng)卡veth pair設(shè)備。 veth設(shè)備總是成對(duì)出現(xiàn)的,它們組成了一個(gè)數(shù)據(jù)的通道,數(shù)據(jù)從一個(gè)設(shè)備進(jìn)入,就會(huì)從另一個(gè)設(shè)備出來。因此,veth設(shè)備常用來連接兩個(gè)網(wǎng)絡(luò)設(shè)備。
-
(3)Docker將 veth pair 設(shè)備的一端放在新創(chuàng)建的容器中,并命名為 eth0(容器的網(wǎng)卡),另一端放在主機(jī)中, 以 veth* 這樣類似的名字命名, 并將這個(gè)網(wǎng)絡(luò)設(shè)備加入到 docker0 網(wǎng)橋中。可以通過 brctl show 命令查看。
-
(4)使用 docker run -p 時(shí),docker實(shí)際是在iptables做了DNAT規(guī)則,實(shí)現(xiàn)端口轉(zhuǎn)發(fā)功能??梢允褂胕ptables -t nat -vnL 查看。
5.自定義網(wǎng)絡(luò)
#直接使用bridge模式,是無法支持指定IP運(yùn)行docker的,例如執(zhí)行以下命令就會(huì)報(bào)錯(cuò)
docker run -itd --name test3 --network bridge --ip 172.17.0.10 centos:7 /bin/bash
//創(chuàng)建自定義網(wǎng)絡(luò)
#可以先自定義網(wǎng)絡(luò),再使用指定IP運(yùn)行docker
docker network create --subnet=172.18.0.0/16 --opt "com.docker.network.bridge.name"="docker1" mynetwork
#docker1 為執(zhí)行 ifconfig -a 命令時(shí),顯示的網(wǎng)卡名,如果不使用 --opt 參數(shù)指定此名稱,那你在使用 ifconfig -a 命令查看網(wǎng)絡(luò)信息時(shí),看到的是類似 br-110eb56a0b22 這樣的名字,這顯然不怎么好記。
#mynetwork 為執(zhí)行 docker network list 命令時(shí),顯示的bridge網(wǎng)絡(luò)模式名稱。
docker run -itd --name zj1 --net mynetwork --ip 172.18.0.10 centos:7 /bin/bash
二、資源控制
- Docker 通過 Cgroup 來控制容器使用的資源配額,包括== CPU、內(nèi)存、磁盤三大方面==, 基本覆蓋了常見的資源配額和使用量控制。
- Cgroup 是 ControlGroups 的縮寫,是 Linux 內(nèi)核提供的一種可以限制、記錄、隔離進(jìn)程組所使用的物理資源(如 CPU、內(nèi)存、磁盤 IO 等等) 的機(jī)制,被 LXC、docker 等很多項(xiàng)目用于實(shí)現(xiàn)進(jìn)程資源控制。Cgroup 本身是提供將進(jìn)程進(jìn)行分組化管理的功能和接口的基礎(chǔ)結(jié)構(gòu),I/O 或內(nèi)存的分配控制等具體的資源管理是通過該功能來實(shí)現(xiàn)的。
1.CPU 資源控制
(1)設(shè)置CPU使用率上限
-
Linux通過CFS(Completely Fair Scheduler,完全公平調(diào)度器)來調(diào)度各個(gè)進(jìn)程對(duì)CPU的使用。CFS默認(rèn)的調(diào)度周期是100ms。
-
我們可以設(shè)置每個(gè)容器進(jìn)程的調(diào)度周期,以及在這個(gè)周期內(nèi)各個(gè)容器最多能使用多少 CPU 時(shí)間。
-
使用 --cpu-period 即可設(shè)置調(diào)度周期,使用 --cpu-quota 即可設(shè)置在每個(gè)周期內(nèi)容器能使用的CPU時(shí)間。兩者可以配合使用。
-
CFS 周期的有效范圍是 1ms~1s,對(duì)應(yīng)的 –cpu-period 的數(shù)值范圍是 1000~1000000。
-
而容器的 CPU 配額必須不小于 1ms,即 --cpu-quota 的值必須 >= 1000。
docker run -itd --name zj2 centos:7 /bin/bash
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c2288c10656f centos:7 "/bin/bash" 6 seconds ago Up 6 seconds zj2
cd /sys/fs/cgroup/cpu/docker/3ed82355f81151c4568aaa6e7bc60ba6984201c119125360924bf7dfd6eaa42b/
cat cpu.cfs_quota_us
-1
cat cpu.cfs_period_us
100000
#cpu.cfs_period_us:cpu分配的周期(微秒,所以文件名中用 us 表示),默認(rèn)為100000。
#cpu.cfs_quota_us:表示該cgroups限制占用的時(shí)間(微秒),默認(rèn)為-1,表示不限制。 如果設(shè)為50000,表示占用50000/100000=50%的CPU。
#進(jìn)行CPU壓力測試
docker exec -it 3ed82355f811 /bin/bash
yum install -y epel-release
yum install -y stress
top #可以看到這個(gè)腳本占了很多的cpu資源
#設(shè)置50%的比例分配CPU使用時(shí)間上限
docker run -itd --name test6 --cpu-quota 50000 centos:7 /bin/bash #可以重新創(chuàng)建一個(gè)容器并設(shè)置限額
或者
cd /sys/fs/cgroup/cpu/docker/3ed82355f81151c4568aaa6e7bc60ba6984201c119125360924bf7dfd6eaa42b/
echo 50000 > cpu.cfs_quota_us
docker exec -it 3ed82355f811 /bin/bash
./cpu.sh
top #可以看到cpu占用率接近50%,cgroups對(duì)cpu的控制起了效果
#在多核情況下,如果允許容器進(jìn)程完全占用兩個(gè) CPU, 則可以將 cpu-period 設(shè)置為 100000( 即 0.1 秒), cpu-quota設(shè)置為 200000(0.2 秒)。
(2)設(shè)置CPU資源占用比(設(shè)置多個(gè)容器時(shí)才有效)
- Docker 通過 --cpu-shares 指定 CPU 份額,默認(rèn)值為1024,值為1024的倍數(shù)。
#創(chuàng)建兩個(gè)容器為 c1 和 c2,若只有這兩個(gè)容器,設(shè)置容器的權(quán)重,使得c1和c2的CPU資源占比為1/3和2/3。
docker run -itd --name c1 --cpu-shares 512 centos:7 bash
docker run -itd --name c2 --cpu-shares 1024 centos:7 bash
#分別進(jìn)入容器,進(jìn)行壓力測試
yum install -y epel-release
yum install -y stress
stress -c 4 #產(chǎn)生四個(gè)進(jìn)程,每個(gè)進(jìn)程都反復(fù)不停的計(jì)算隨機(jī)數(shù)的平方根
#查看容器運(yùn)行狀態(tài)(動(dòng)態(tài)更新)
docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
552ffcd46ff2 c2 268.01% 228.5MiB / 3.843GiB 5.81% 38.8MB / 500kB 283kB / 24.9MB 2
2268181ce6ad c1 132.62% 243.8MiB / 3.843GiB 6.20% 38.8MB / 513kB 58.1MB / 25.3MB 2
-
可以看到在 CPU 進(jìn)行時(shí)間片分配的時(shí)候,容器 c2 比容器 c1 多一倍的機(jī)會(huì)獲得 CPU 的時(shí)間片。
-
但分配的結(jié)果取決于當(dāng)時(shí)主機(jī)和其他容器的運(yùn)行狀態(tài),實(shí)際上也無法保證容器 c1 一定能獲得 CPU 時(shí)間片。比如容器 c1 的進(jìn)程一直是空閑的,那么容器 c2 是可以獲取比容器 c1 更多的 CPU 時(shí)間片的。極端情況下,例如主機(jī)上只運(yùn)行了一個(gè)容器,即使它的 CPU 份額只有50,它也可以獨(dú)占整個(gè)主機(jī)的 CPU 資源。
-
Cgroups 只在容器分配的資源緊缺時(shí),即在需要對(duì)容器使用的資源進(jìn)行限制時(shí),才會(huì)生效。因此,無法單純根據(jù)某個(gè)容器的 CPU 份額來確定有多少 CPU 資源分配給它,資源分配結(jié)果取決于同時(shí)運(yùn)行的其他容器的 CPU 分配和容器中進(jìn)程運(yùn)行情況。
(3)設(shè)置容器綁定指定的CPU
#先分配虛擬機(jī)4個(gè)CPU核數(shù)
docker run -itd --name xc1 --cpuset-cpus 1,3 centos:7 /bin/bash
#進(jìn)入容器,進(jìn)行壓力測試
yum install -y epel-release
yum install stress -y
stress -c 4
#退出容器,執(zhí)行 top 命令再按 1 查看CPU使用情況。
2.對(duì)內(nèi)存使用的限制
//-m(--memory=) 選項(xiàng)用于限制容器可以使用的最大內(nèi)存
docker run -itd --name xc2 -m 512m centos:7 /bin/bash
docker stats
//限制可用的 swap 大小, --memory-swap 強(qiáng)調(diào)一下,–memory-swap 是必須要與 --memory
一起使用的。正常情況下,–memory-swap 的值包含容器可用內(nèi)存和可用 swap。 所以 -m 300m --memory-swap=1g
的含義為:容器可以使用 300M 的物理內(nèi)存,并且可以使用 700M(1G - 300)的 swap。如果 --memory-swap 設(shè)置為 0 或者 不設(shè)置,則容器可以使用的 swap 大小為 -m 值的兩倍。 如果
–memory-swap 的值和 -m 值相同,則容器不能使用 swap。 如果 --memory-swap 值為 -1,它表示容器程序使用的內(nèi)存受限,而可以使用的 swap 空間使用不受限制(宿主機(jī)有多少 swap 容器就可以使用多少)。文章來源:http://www.zghlxwxcb.cn/news/detail-606448.html
3.對(duì)磁盤IO配額控制(blkio)的限制
--device-read-bps:限制某個(gè)設(shè)備上的讀速度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 : 限制某個(gè)設(shè)備上的寫速度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 :限制讀某個(gè)設(shè)備的iops(次數(shù))
--device-write-iops :限制寫入某個(gè)設(shè)備的iops(次數(shù))
#創(chuàng)建容器,并限制寫速度
docker run -it --name test10 --device-write-bps /dev/sda:1mb centos:7 /bin/bash
#通過dd來驗(yàn)證寫速度
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.0025 s, 1.0 MB/s
#清理docker占用的磁盤空間
docker system prune -a #可以用于清理磁盤,刪除關(guān)閉的容器、無用的數(shù)據(jù)卷和網(wǎng)絡(luò)
文章來源地址http://www.zghlxwxcb.cn/news/detail-606448.html
到了這里,關(guān)于Docker 網(wǎng)絡(luò)、資源控制的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!