目錄
一、docker網絡模式:
1、概述
2、docker網絡實現原理:
3、docker的網絡模式:
3.1、bridge模式:
3.2、host模式:
3.3、container模式:
3.4、none模式:
3.5、自定義網絡模式:
4、docker網絡總結:
二、docker的數據管理:
1、數據卷
1.1、容器和宿主機之間進行數據共享:
1.2、容器和容器之間實現數據共享:
三、docker網絡通信
1、容器互聯:
四、docker網絡練習:
五、docker的資源控制:
1、CPU資源控制:
1.1、對容器占用CPU的時間進行限制:
1.2、設置CPU資源占用比(設置多個容器時才有效)
1.3、設置容器綁定指定的CPU
2、限制容器對內存的使用:
3、限制使用swap:
4、磁盤IO配額(了解):
5、清理docker占用的磁盤空間:
一、docker網絡模式:
1、概述
docker的網絡就是基于橋接模式實現的
橋接模式:用于連接兩個不同網絡段的設備,共享通信的一種方式
橋接設備:工作在OSI模型的二層,數據鏈路層,轉發數據幀,基于Mac地址轉發
類似于交換機,只能轉發同一網段,通過泛洪廣播來找目標設備mac地址。學習模式
2、docker網絡實現原理:
橋接模式是一種網絡模式,它在Docker中的工作方式可以分為以下幾個步驟:
1、虛擬網絡創建:當您啟動Docker守護進程時,Docker創建一個虛擬網絡橋(通常稱為Docker0)是一個虛擬的網絡設備,類似于物理網絡設備的交換機
2、分配唯一的ip地址:每次您運行一個容器時,Docker分配一個唯一的IP地址給該容器
這個IP地址是在橋接模式網絡的子網中
3、連接容器到橋接網絡:當容器啟動時,Docker將容器的虛擬網絡接口連接到虛擬網絡橋上。其中一個端點位于容器,而另一個端點位于主機上
4、容器之間的通信:如果有多個容器在相同的橋接網絡上運行,他們可以通過各自的ip地址直接通信。Docker會自動在橋接網絡上設置路由,使得容器可以與外部網絡通信,而外部網絡看到的是主機的IP地址
5、NAT(網絡地址轉換):默認情況下,Docker使用NAT技術,將容器的私有IP地址映射到主機上的公共IP地址。這樣,容器可以與外部通信,而外部網絡看到的是主機的IP地址
問題:docker的網橋是宿主機虛擬出來的,并不是一個真正存在的網絡設備,外部網絡無法尋址找到。外部網絡無法直接訪問docker:0這個虛擬網橋分配給容器的IP地址
Docker網橋是宿主機虛擬出來的,并不是真實存在的網絡設備,外部網絡是無法尋址到的,也就是無法直接訪問容器ip訪問容器
如果容器希望外部訪問能夠訪問到,可以通過映射容器端口到宿主機(端口映射)
即Docker run創建容器時用-p/-P啟用,訪問到的時候就通過宿主ip+容器端口來訪問容器
給容器做端口映射:
-P:創建容器的時候,在宿主機和容器之間做一個端口映射。后不接數字代表隨機分配一個端口給宿主機,容器的端口是不變的
-P32768開始
-P(大寫):隨機制定
-p 80:80(小寫):指定端口
進入容器開啟一下服務
實際上,docker是在宿主機和容器之間做了一個iptables的nat地址轉換。
docker run -itd --name test1 -P nginx:1.22.0 /bin/bash
-p 80:80
前面80是宿主機的端口,后面是容器的端口80
docker run -itd --name test3 -p 80:80 nginx:1.22.0 /bin/bash
做端口映射時,宿主機的端口一定是未被占用
宿主機直接查看容器產生的日志:
docker run -itd --name test11 -p 456:80 nginx
必須是在run的時候不加/bin/bash
docker logs 容器名/容器id 查看全部日志
docker logs -f 容器名/容器id 尾部查看全部,動態查看
docker logs --tail=10 -f 容器名/容器id 尾部10條,動態查看
/bin/bash就是為了讓容器后臺有一個運行程序,保證容器不會退出
-d后臺守護運行,但是時間一長容器自動退出
加/bin/bash就是容器的標準輸出,docker logs日志捕獲的是cmd和entrypoint標準輸出。/bin/bash和捕獲日志會沖突
3、docker的網絡模式:
3.1、bridge模式:
在創建docker時不需要指定網絡類型,默認就是bridge
docker run -itd --name test1 -p 4300:80 nginx:1.22.0
4300是宿主機的端口
80是nginx容器的端口
訪問宿主機的ip+端口就等于訪問nginx容器
使用 docker run -p 時,docker實際是在iptables做了DNAT規則,實現端口轉發功能。
可以使用iptables -t nat -vnL 查看。
?
3.2、host模式:
容器將不會虛擬出自己的網卡,也沒有自己的IP地址。全部使用宿主機的IP地址和端口
host:容器和宿主機共用一個網絡命名空間
創建容器的時候指定網絡模式:--network host
docker run -itd --name test1 --network host nginx:latest bin/bash
公用模式:如果是單個容器運行,可以使用host模式。容器的端口和宿主機端口公用一個,但是有多個容器,訪問不了
3.3、container模式:
container:容器和容器之間共用一個網路命名空間
要想容器都起來必須后接/bin/bash
docker run -itd --name test1 --network host nginx:1.22.0 /bin/bash
創建一個test2和test1使用同一個ip和端口
docker run -itd --name test2 --network=container:test1 nginx:1.22.0?/bin/bash
容器中怎么啟動服務:
cd /usr/bin
nginx 啟動
nginx -s stop 停止
容器共用端口,但是不能同時啟動。想要啟動一個,其他容器必須關閉。
也就是說共用端口,只能使用一個
啟動test1的nginx:
停止test1的nginx
nginx -s stop
3.4、none模式:
docker容器有自己的network-space,但是這個容器沒有任何網絡設置。
這個容器沒有網卡,沒有ip沒有路由,只有lo回環網絡。在none模式下,容器不可以聯網(在工作中是用于容器功能測試用)
不能聯網不能訪問
封閉的網絡能很好的保證容器的安全性。
docker run -itd --name test3 --network none nginx:1.22.0 /bin/bash
3.5、自定義網絡模式:
我們可以給docker創建一個自己定義的網段
docker network ls
NETWORK ID:這個是docker網絡唯一網絡id
NAME:docker網絡的名稱
DRIVER:網絡的驅動程序
SCOPE:
docker run -itd --name test6 --network bridge --ip 172.17.0.10 nginx:latest /bin/bash
在使用默認docker:0網橋時,創建容器是不能指定IP地址的,只能由docker網橋自動分配
除非用戶自定義的網絡才可以給容器自定義IP地址
創建自定義網絡:
可以先自定義網絡,再使用指定IP運行docker
docker network create --subnet=172.18.0.0/16 --opt "com.docker.network.bridge.name"="docker1" mynetwork
--opt "com.docker.network.bridge.name"="docker1":這里可以不加,但是網卡名稱難以識別,系統會給你命名復雜名稱
mynetwork:自定義網絡的名稱
有自定義網段之后,創建容器的時候就可以自定義IP地址了
docker run -itd --name nginx1 --network mynetwork --ip 172.18.0.10 nginx:latest /bin/bash
給容器自定義IP地址為 172.18.0.10
自定義IP地址,一定要先自定義網橋
4、docker網絡總結:
docker的網絡模式:
- bridge橋接模式:也是docker的默認模式,在創建時無需指定
- host模式:容器不會有自己的網絡設備,但是可以和宿主機共享ip和端口
- container模式:容器和容器之間共享ip和端口
- none模式:也沒有自己的網絡設備,也沒有網卡、ip。只有一個本地的回環地址。127.0.0.1。不能夠聯網的。相當于一個飛行模式,只能自己訪問自己。一般用于測試容器的功能
- 自定義網絡模式:創建容器時,默認使用docker0網橋是無法給容器定義IP地址的,自能自動分配,自定義網絡在創建容器時,可以給容器指定IP地址
docker如何在創建容器時指定端口映射:
docker沒有二次配置的機制,只能在創建的時候指定
-P(大寫):隨機指定端口
-p(小寫):自定義指定端口
-p 32768:80 32768是宿主機的端口,后面80是容器的端口
docker容器外部查看日志
docker run -itd --name test11 -p 456:80 nginx
必須是在run的時候不加/bin/bash
docker logs 容器名/容器id 查看全部日志
docker logs -f 容器名/容器id 尾部查看全部,動態查看
docker logs --tail=10 -f 容器名/容器id 尾部10條,動態查看
/bin/bash就是為了讓容器后臺有一個運行程序,保證容器不會退出
-d后臺守護運行,但是時間一長容器自動退出
加/bin/bash就是容器的標準輸出,docker logs日志捕獲的是cmd和entrypoint標準輸出。/bin/bash和捕獲日志會沖突
二、docker的數據管理:
1、數據卷
1.1、容器和宿主機之間進行數據共享:
數據卷:是一個供容器使用的特殊的目錄,在容器中,和宿主機的目錄進行映射,主機和宿主機之間都可以對目錄中的文件進行修改,而且雙方是同步生效。對鏡像也沒有影響。宿主機和容器之間實現數據遷移
MySQL ?33066:3306
宿主機的目錄和容器中的目錄進行掛載(映射關系)
docker run -itd --name test1 -v /opt/test1:/opt/test centos:7 /bin/bash
test1是宿主機目錄
test是容器目錄
docker run -itd --name test2 -v /opt/test2:/opt/test:ro?centos:7 /bin/bash
創建只讀模式,容器里面只能讀
容器里面的目錄的文件只能看
1.2、容器和容器之間實現數據共享:
test1 test2 可以有一個或者多個映射目錄,實現數據互傳,數據同步
數據卷容器:只提供掛載點,讓另一方來收集數據
docker run -itd --name test11 -v /opt/data1 -v /opt/data2 centos:7 /bin/bash
docker run -itd --volumes-from test11 --name test12 centos:7 /bin/bash
test11和test12 實現容器間數據共享
三、docker網絡通信
1、容器互聯:
實現兩個容器之間網絡通信
老版本方法:
第一個容器創建:
docker run -itd -P --name test111 centos:7 /bin/bash
第二個容器
docker run -itd -P --name test222 --link test111:test222 centos:7 /bin/bash
在centos容器中下載net-tools工具可以用Linux命令
yum -y install net-tools
要互ping要做映射
新版本都用network指定:
自定義網絡實現網段互ping
docker run -itd -P --name test112 --network=mynetwork centos:7 /bin/bash
docker run -itd -P --name test113 --network=mynetwork centos:7 /bin/bash
同一網段中不用做映射就可以實現互ping
新版本建議使用
四、docker網絡練習:
1、部署一個MySQL鏡像,創建一個MySQL容器,用navicat實現可以直接訪問容器的MySQL,MySQL宿主機:33066
MySQL容器:3306
2、創建一個數據卷。在宿主機可以看到容器內MySQL的日志文件
創建運行mysql容器,并建立數據卷:
docker run -itd --name mysql1 -v /opt/demo1:/opt/test -p 33066:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7.20
本機MySQL遠程登錄測試:
navicat:
my.cnf配置文件拖出來修改
docker cp mysql1:/etc/mysql/my.cnf /opt
重啟docker容器
docker restart mysql1
五、docker的資源控制:
對容器使用宿主機的資源進行限制
docker使用Linux自導的cgroup進行控制
Control groups,是Linux內核系統提供的一種可以限制,記錄,隔離進程組所使用的物理資源的機制。
docker借助這個機制,來實現資源的控制
cgroup本身是提供將進程進行分組化管理的功能和接口的基礎結構。分配控制的機制來實現資源控制。
其他的資源依然是隔離的
1、CPU資源控制:
Linux通過CFS(completely fair scheduler 完全公平調度器),通過這個調度器來調度各個進程對CPU的使用。CFS的調度周期為100ms。
我們也可以自定義容器的調度周期。以及在這個周期時間之內,各個容器能夠使用CPU的調度時間。
--CPU-period 設置容器調度CPU的周期
--CPU-quota 設置每個周期內,容器可以使用CPU的時間
兩者可以配合使用
cd /sys/fs/cgroup/cpu/docker/09103baf76369ad9f6a77576665c49b384b34d01ed1f09f1c6b091abfae27115
cpu.cfs_period_us: 表示 CFS 調度周期的長度,以微秒為單位。
在每個周期內,容器可以使用指定比例的 CPU 時間。默認情況下,cpu.cfs_period_us 的值是 100000(即 100 毫秒)。
cpu.cfs_quota_us: 表示容器在 cpu.cfs_period_us 周期內能夠使用的 CPU 時間量,同樣以微秒為單位。
它定義了一個相對于周期的配額。如果設置為 -1,表示沒有限制。如果設置為正值,表示在周期內的配額。
例如,如果 cpu.cfs_quota_us 設置為 50000,那么容器在一個周期內最多可以使用 50 毫秒的 CPU 時間。
在 Linux 的 CFS 調度器中,cpu.cfs_period_us 參數定義了一個周期,
而這個周期實際上是用來調度任務(包括容器)的基本時間單位。
然而,具體的一次調度的時間是由調度器決定的,并且這個時間在一般情況下是動態變化的。
CFS的周期的有效范圍:1ms-1s之間。則--cpu-period ?1000-1000000
容器使用CPU的配額時間,必須大于1ms,--cpu-quota的值,必須是>=1000
cpu.cfs_quota_us:調度請求之后,根據配額,內核分配給容器使用CPU的時間
-1
如果配置是-1,那么容器在使用宿主機cpu的時間不做任何限制
cpu.rt_period_us
100000
CFS調度周期的長度,微秒,在每個周期內,容器可以使用指定比例的cpu時間,默認情況下都是100毫秒
CFS調度器,100毫秒就是定義了一個周期,在這個周期之內,調度任務(容器)的基本時間單位。
100毫秒一次調度容器請求cpu的資源。然后內核把cpu的資源分配給容器
查看容器的運行占用宿主機資源的情況
docker stats 容器名/id
查看容器內PID和宿主機的映射關系
docker top 容器名/id
1.1、對容器占用CPU的時間進行限制:
進行CPU壓力測試
docker run -itd --name test1 centos:7 /bin/bash
docker exec -it test1 bash
vim /opt/cpu.sh
#!/bin/bash
i=0
while true
do
let i++
done
chmod +x /cpu.sh
./cpu.sh
top #可以看到這個腳本占了很多的cpu資源
設置50%的比例分配CPU使用時間上限
1、可以重新創建一個容器并設置限額
docker run -itd --name test6 --cpu-quota 50000 centos:7 /bin/bash
2、更改cpu.cfs_quota_us配置文件修改CPU使用時間
cd /sys/fs/cgroup/cpu/docker/3ed82355f81151c4568aaa6e7bc60ba6984201c119125360924bf7dfd6eaa42b/
echo 50000 > cpu.cfs_quota_us
默認是100000微秒,100毫秒對應的就是使用時間100%
改成50000微秒,就是50%
docker exec -it 3ed82355f811 /bin/bash
./cpu.sh
top #可以看到cpu占用率接近50%,cgroups對cpu的控制起了效果
在多核情況下,如果允許容器進程完全占用兩個 CPU,
則可以將 cpu-period 設置為 100000( 即 0.1 秒), cpu-quota設置為 200000(0.2 秒)。
docker top test 查看容器內PID和宿主機的映射關系。
UID ?是用戶名。
PID 是進程在宿主系統上的 PID。
PPID 是進程在容器內部的 PID。
STIME 是進程的啟動時間。
TTY 是終端類型和編號。
TIME 是進程的運行時間。
CMD 是進程的命令
1.2、設置CPU資源占用比(設置多個容器時才有效)
Docker 通過 --cpu-shares 指定 CPU 份額,默認值為1024,值為1024的倍數。
創建兩個容器為 c1 和 c2,若只有這兩個容器,設置容器的權重,使得c1和c2的CPU資源占比為1/3和2/3。
--cpu-shares 指定容器占用CPU的份額。默認權重1024,設置的值只能是1024的倍數。
docker run -itd --name c1 --cpu-shares 512 centos:7
docker run -itd --name c2 --cpu-shares 1024 centos:7
--cpu-shares是給每個容器使用cpu設置了相對的權重,權重高的,可以使用CPU的資源更多,但是,如果只有一個容器在運行,即便設置了權重,但是沒有其他更高的權重來占用資源,權重低的容器依然不受限
分別進入容器,進行壓力測試
yum install -y epel-release
yum install -y stress
#stress 是一個用于模擬系統負載的工具,它可以測試系統在高負載條件下的穩定性。
stress -c 4 #產生四個進程,每個進程都反復不停的計算隨機數的平方根
#查看容器運行狀態(動態更新)
docker stats
可以看到在 CPU 進行時間片分配的時候,容器 c2 比容器 c1 多一倍的機會獲得 CPU 的時間片。
但分配的結果取決于當時主機和其他容器的運行狀態, 實際上也無法保證容器 c1 一定能獲得 CPU 時間片。
比如容器 c1 的進程一直是空閑的,那么容器 c2 是可以獲取比容器 c1 更多的 CPU 時間片的。
極端情況下,例如主機上只運行了一個容器,即使它的 CPU 份額只有 50,它也可以獨占整個主機的 CPU 資源。
Cgroups 只在容器分配的資源緊缺時,即在需要對容器使用的資源進行限制時,才會生效。
因此,無法單純根據某個容器的 CPU 份額來確定有多少 CPU 資源分配給它,
資源分配結果取決于同時運行的其他容器的 CPU 分配和容器中進程運行情況。
1.3、設置容器綁定指定的CPU
#先分配虛擬機4個CPU核數
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
#退出容器,執行 top 命令再按 1 查看CPU使用情況。
總結:對CPU的限制:
容器占用CPU的時間
容器占用CPU的權重比(要多個容器,才有效)
容器占用CPU的內核數(綁定指定的CPU內核給容器使用)
2、限制容器對內存的使用:
-m(--memory=) 選項用于限制容器可以使用的最大內存
docker run -itd --name test8 -m 512m centos:7 /bin/bash
docker stats
如果 --memory-swap 設置為 0 或者 不設置,則容器可以使用的 swap 大小為 -m 值的兩倍。
如果 --memory-swap 的值和 -m 值相同,則容器不能使用 swap。
如果 --memory-swap 值為 -1,它表示容器程序使用的內存受限,
而可以使用的 swap 空間使用不受限制(宿主機有多少 swap 容器就可以使用多少)。
3、限制使用swap:
--memory-swap
docker run -itd --name test -m 512m --memory-swap=1g centos:7 /bin/bash
限制使用swap,必須和限制內存一起使用
--memory-swap 是必須要與 --memory 一起使用的。
設置swap有如下集中情況:
1、-m 512m --memory-swap=1g 那么容器實際上能夠使用的swap空間是1g-512m=512m
2、如果不設置--memory-swap=1g,只有-m 512m,那么使用swap的空間是-m后面值的兩倍也就是1024m
3、如果設置的--memory-swap的值和-m內存限制一樣,容器不能使用swap空間 512-512=0
4、如果-m 512m --memory-swap=-1 設為-1則內存受限還是512m,但是容器使用swap空間不受限制
4、磁盤IO配額(了解):
限制容器在磁盤上的讀速度:
--device-read-bps:
限制某個設備上的讀速度bps(數據量),單位可以是kb、mb(M)或者gb。
例:docker run -itd --name test11 --device-read-bps /dev/sda:1M ?centos:7 /bin/bash
限制容器在磁盤上的寫速度:
--device-write-bps :
限制某個設備上的寫速度bps(數據量),單位可以是kb、mb(M)或者gb。
例:docker run -itd --name test12 --device-write-bps /dev/sda:1mb centos:7 /bin/bash
通過dd來驗證寫速度
dd if=/dev/zero of=test.out bs=1M count=10 oflag=direct
在使用dd獲取空字符集是從文件系統的緩存當中輸入,速度是比較快的,禁用文件系統緩存,直接把數據寫入磁盤,可以更真實的測試設備的行,模擬直接寫入物理設備的情況
限制容器讀取的次數:
docker run -itd --name test --device-read-iops /dev/sda:100 centos:7 /bin/bash
限制讀取操作每秒100次
限制容器寫入的次數:
docker run -itd --name test --device-write-iops /dev/sda:50 centos:7 /bin/bash
限制寫入的操作,每秒50次
5、清理docker占用的磁盤空間:
docker system prune -a
刪除已經停止的容器
刪除所有未被使用的網橋設備(docker1)
刪除所有未被使用的鏡像
刪除創建容器時的緩存,以及無用的數據卷