Docker作为目前最火的轻量级容器技术,有很多令人称道的功能,如Docker的镜像管理。然而,Docker同样有着很多不完善的地方,网络方面就是Docker比较薄弱的部分。因此,我们有必要深入了解Docker的网络知识,以及资源管理。
Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信。
Docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着外部网络无法通过直接Container-IP访问到容器。如果容器希望外部访问能够访问到,可以通过映射容器端口到宿主主机(端口映射),即docker run创建容器时候通过 -p 或 -P 参数来启用,访问容器的时候就通过[宿主机IP]:[容器端口]访问容器。
查看命令
[root@server1 ~]# ifconfig
docker 0 网络
docker 虚拟网关,在docker安装完成之后自动生成的虚拟网卡
loopback(lo) :回环网卡、TCP/IP主机连接性,网卡是否生效,检测本地是否可以通信,自我检测,虚拟化平台网卡
ens33:虚拟机(宿主机)网络网卡
virtual bridge(virdr0): linux自身继承了一个虚拟化功能(kvm架构)
,是原生架构的一个虚拟化平台,安装了一个虚拟化平台之后就会系统就会自动安装虚拟网卡 (示例:安装workstation (虚拟化平台)之后,会在网络适配器中会多出VMnet1 VMnet8 VMnet0)
docker 0 :容器的网关,绑定物理网卡,负责做NAT地址转换、端口映射
docker 0本身也是一种容器
安装Docker时,它会自动创建三个网络,bridge(创建容器默认连接到此网络)、 none 、host
网络模式 | 简介 |
---|---|
Host | 容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。 |
Bridge | 此模式会为每一个容器分配、设置IP等,并将容器连接到一个docker0虚拟网桥,通过docker0网桥以及Iptables nat表配置与宿主机通信。 |
None | 该模式关闭了容器的网络功能。 |
Container | 创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围。 |
自定义网络 | 略 |
这个模式容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口,如果启动容器的时候使用 host 模式,那么这个容器将不会获得一个独立的 Network Namespace,而是和宿主机共用一个 Network Namespace。
这个模式新创建的容器和已经存在的一个容器共享一个 network namespace,而不是和宿主机共享,新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定地容器共享IP、端口范围等。
该模式关闭了容器的网络功能,无法联网,但是封闭的网络能很好的保证容器的安全性,一般是用户对网络有自己特殊的需求,不希望 docker 预设置太多的东西。
此模式会为每一个容器分配、设置IP等,并将容器连接到一个docker0 虚拟网桥,通过 docker0 网桥及 iptables的 nat 表配置与宿主机通信。
虚拟网桥的工作方式和物理交换类似,这样的话,所有的容器就通过交换机连在了一个二层网络中。
创建容器时默认使用的是桥接模式,但是使用bridge不支持为容器指定IP
[root@localhost ~]# docker run -itd --name test1 --network bridge --ip 172.17.0.10 centos:7 /bin/bash
20dc45293929f81013a60391bef2626f581a8d3d4f29b8a87ac8b1f9b585ab2a
docker: Error response from daemon: user specified IP address is supported on user defined networks only. #提示想要为容器指定IP只能在用户自定义的网络中才行
[root@server1 ~]# docker run -itd --name test1 --network bridge centos:7 /bin/bash
#不指定IP可以创建成功
配置自定义固定IP
[root@localhost ~]# docker network create --subnet=172.31.0.0/24 test
#创建自定义网络test
[root@localhost ~]# docker run -itd --name web1 --net test --ip 172.31.0.10 centos:7 /bin/bash
创建一个容器,指定网络为test,指定IP地址172.31.0.10
cat /sys/cgroup/cpu/docker/容器ID/cpu.cfs_quota_us
-1代表此容器可以使用得资源不受限制
cpu 周期:1s为一个周期的定律,参数值一般为100000(CPU衡量单位是秒)
假如需要给此容器分配cpu使用率的20%,则参数需要设置为20000,相当于每个周期分配给这个容器0.2s
cpu 在一个时刻,只能给一个进程占用
创建一个cpu使用率为20%的容器
方法一(未创建容器):
[root@docker ~]# docker run -itd --name test --cpu-quota 20000 centos:7 /bin/bash
b1d69017221cce7d3f4a6a53effc64356f7bb6bba269984ef85927e13db1ecc2
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b1d69017221c centos:7 "/bin/bash" 20 minutes ago Up 20 minutes test
方法二(已创建容器):
[root@docker ~]# echo "20000" > b1d69017221cce7d3f4a6a53effc64356f7bb6bba269984ef85927e13db1ecc2
3、查看该容器的cpu占有率
[root@docker ~]# cd /sys/fs/cgroup/cpu/docker/
[root@docker docker]# ls
b1d69017221cce7d3f4a6a53effc64356f7bb6bba269984ef85927e13db1ecc2 cpuacct.usage cpu.rt_runtime_us
cgroup.clone_children cpuacct.usage_percpu cpu.shares
cgroup.event_control cpu.cfs_period_us cpu.stat
cgroup.procs cpu.cfs_quota_us notify_on_release
cpuacct.stat cpu.rt_period_us tasks
[root@docker docker]# cd b1d69017221cce7d3f4a6a53effc64356f7bb6bba269984ef85927e13db1ecc2/
[root@docker b1d69017221cce7d3f4a6a53effc64356f7bb6bba269984ef85927e13db1ecc2]# cat cpu.cfs_quota_us
20000
4、进入容器,运行一些操作
[root@docker ~]# docker exec -it b1d69017221c /bin/bash
[root@0b1d69017221c /]# yum -y install bc #“bc”是一种计算机程序
Failed to set locale, defaulting to C.UTF-8
CentOS Linux 8 - AppStream 753 kB/s | 6.3 MB 00:08
......
Installed:
bc-1.07.1-5.el8.x86_64
Complete!
[root@b1d69017221c /]# echo "scale=5000;4*a(1)" | bc -l -q #此操作是运行计算圆周率
**验证:**另开一个终端,运行top,查看cpu占比(按“1”显示cpu详细信息)
按比例分配 设置容器权重,此处权重是所有值相加然后看占用百分比
1、创建两个容器,设置容量为512和1024
[root@docker ~]# docker run -itd --name c1 --cpu-shares 512 centos:7 /bin/bash
[root@docker ~]# docker run -itd --name c2 --cpu-shares 1024 centos:7 /bin/bash
2、再开两个终端,进入这两容器中,进行压测
以其中一个为例:
docker exec -it 8183bf4c2fec /bin/bash
yum install epel-release -y #安装压测工具
yum install stress -y
stress -c 4 #使用压测工具模拟产生4个cpu线程
环境:
1、添加cpu核心,有4个内核
2、先清空现有的容器
[root@docker ~]# docker ps -a | awk ‘{print docker rm “$1”}’ | bash
1、创建容器,并指定cpu1,3,使用第2和第4个cpu
[root@docker ~]# docker run -itd --name test1 --cpuset-cpus 1,3 centos:7 /bin/bash
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e53d3e2d5f49 centos:7 "/bin/bash" 5 seconds ago Up 4 seconds test1
2、开一个终端,进入容器,运行压测工具
[root@docker ~]# docker exec -it e53d3e2d5f49 /bin/bash
[root@3e85fc6a8e03 /]# yum install epel-release -y
.....省略部分内容
[root@3e85fc6a8e03 /]# yum install stress -y
.....省略部分内容
[root@e53d3e2d5f49 /]# stress -c 4
创建一个内存限制为666M的容器
[root@docker ~]# docker run -itd --name aaa -m 666m centos:7 /bin/bash
docker的Io限制就是对block的Io进行约束
控制数据量用的较多,其中控制Io次数使用的较少
--device-read-bps :限制读某个设备的bps (数据量,比特率,每秒数据传输速率)
docker run -itd --device-read-bps /dev/sda:30M centos:7 /bin/bash
--device-write-bps:限制写入某 个设备的bps (数据量)
docker run -itd --device-write-bps /dev/sda:30M centos:7 /bin/bash
--device-read-iops限制读某个设备的iops (次数)
--device-write-iops 限制写入某个设备的iops (次数)