目录
2.5 自定义网络(user-defined network)
3.1.4 查看容器信息(包含配置、环境、网关、挂载、cmd等信息)
3.6 配置 user-defined network 模式(自定义网络)
Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的 Container-IP 直接通信
Docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着外部网络无法直接通过 Container-IP 访问到容器。如果容器希望外部访问能够访问到,可以通过映射容器端口到宿主主机(端口映射),即 docker run 创建容器时候通过 -p 或 -P 参数来启用,访问容器的时候就通过[宿主机IP]:[容器端口]访问容器
端口映射:
在启动容器的时候,如果不指定对应的端口,在容器外是无法通过网络来访问容器内的服务
端口映射机制将容器内的服务提供给外部网络访问,实质上就是将宿主机的端口映射到容器中,使得外部网络访问宿主机的端口便可访问容器内的服务
- docker run -d --name test1 -P nginx #随机映射端口(从32768开始)
- docker run -d --name test2 -p 9999:80 nginx #指定映射端口
-
- docker ps -a #查看当前所有的容器
浏览器访问:http://172.16.12.12:32768 和 http://172.16.12.12:9999
- #查看容器的输出和日志信息
- 格式:docker logs 容器的ID/名称
- 如:docker logs test1
- #使用 docker run -p 时,docker实际是在iptables做了DNAT规则,实现端口转发功能
- iptables -t nat -vnL
Docker 提供了多种网络模式,用于在容器间和容器与外部网络之间建立通信。这些网络模式可以根据实际需求选择,下面是一些常见的 Docker 网络模式
优点:
① 性能优势:由于容器与宿主机共享网络栈,因此在host网络模式下,容器之间的通信不需要经过网络地址转换(NAT),可以提高网络性能
② 简化网络配置:使用host网络模式可以简化网络配置,容器可以直接访问宿主机上的所有网络服务,无需进行端口映射
③ 高吞吐量:由于容器直接使用宿主机的网络接口,可以获得更高的网络吞吐量,适用于对网络性能要求较高的场景
缺点:
① 安全性:由于容器与宿主机共享网络栈,容器之间的隔离性降低,可能会增加一定的安全风险,特别是在多租户环境中
② 端口冲突:在host网络模式下,容器与宿主机共享相同的网络接口,可能会导致端口冲突,需要谨慎管理端口使用
③ 不适用于多主机环境:host网络模式适用于单个主机上的容器,不适用于跨主机通信的场景
优点:
① 容器之间共享同一个网络命名空间,可以直接进行网络通信,无需通过网络层进行路由,提高了网络通信的效率
② 可以方便地实现容器之间的私有网络,适用于需要高度互联的容器组
③ 可以更好地控制容器之间的通信,增强了网络安全性
缺点:
① 容器之间共享网络命名空间,可能会导致网络隔离性不足,容器之间的通信可能会相互影响
② 不适合需要完全隔离的场景,因为容器共享网络命名空间,可能会导致安全性问题
③ 可能会增加网络配置和管理的复杂性,特别是在大规模部署时
优点:
① 提供了最高级别的隔离性,适用于一些需要完全隔离的场景,如测试隔离性等。
② 可以防止容器与外部网络发生意外的通信,增强了安全性。
缺点:
① 容器无法与外部网络通信,除非手动配置网络连接或使用其他通信方式,这可能增加了管理和配置的复杂性。
② 不适合一般应用场景,因为容器无法访问外部资源,如互联网或其他容器服务。
优点:
① 桥接网络模式是默认的网络模式,易于使用和管理。
② 提供了一定程度的网络隔离,容器之间默认无法直接通信,增强了安全性。
③ 允许容器使用NAT(网络地址转换)来访问外部网络,同时也支持端口映射,方便从外部访问容器内的服务。
缺点:
① 需要进行端口映射才能从外部访问容器内的服务,可能会增加管理复杂性。
② 容器之间的通信需要通过桥接网络,可能会影响性能,尤其在大规模部署时。
创建自定义的网络模式来满足特定的网络需求。自定义网络模式可以帮助您更好地管理容器之间的通信和隔离
优点:
① 隔离性:自定义网络模式可以帮助实现容器之间的隔离,使它们可以在独立的网络环境中运行
② 灵活性:通过自定义网络模式,您可以根据应用程序需求定制网络配置,实现更灵活的网络管理
③ 安全性:自定义网络模式可以帮助您更好地控制容器之间的通信,提高网络安全性
④ 性能:自定义网络模式可以优化容器之间的通信性能,减少不必要的网络开销
缺点:
① 需要用户自行创建和配置网络,可能增加管理复杂性
使用docker run创建Docker容器时,可以用 --net 或 --network 选项指定容器的网络模式
host模式 | --net=host | 容器和宿主机共享Network namespace |
container模式 | --net=container:NAME_or_ID | 多个容器共享一个Network namespace |
none模式 | --net=none | 容器有独立的Network namespace,但并没有对其进行任何网络设置,如分配veth pair 和网桥连接,配置IP等。 |
bridge模式 | --net=bridge | 默认为该模式,可省略 |
安装Docker时,它会自动创建三个网络,bridge(创建容器默认连接到此网络)、 none 、host
- #查看docker网络列表
- docker network ls 或 docker network list
- 格式:docker ps --filter "network=网络模式" 或者 docker network ls|grep 网络模式
- #如:docker ps --filter "network=bridge" #搜索bridge模式的容器
- #如:docker network ls|grep bridge
docker inspect -f '{{.State.Pid}}' 容器ID/容器名称 #查看指定容器的进程号
docker inspect 容器ID/容器名
brctl show
- #创建名为nginx01的容器网络模式为host
- docker run -d --name nginx01 --network host nginx:latest
docker inspect nginx01 #查看容器详细信息,包括配置、环境、网络模式等信息
- #查看host模式的容器
- docker ps --filter "network=host"
- docker inspect -f '{{.State.Pid}}' nginx01 #查看指定容器的进程号
- lsof -i:80 #查看80端口是否被host模式的nginx01容器的进程占用
浏览器访问:172.16.12.10,查看是否能访问nginx
(1)先创建一个bridge模式的容器
docker run -itd --name centos01 centos:7 /bin/bash
- #搜索bridge模式的容器,是否有centos01
- docker ps --filter "network=bridge"
- #查看容器进程号
- docker inspect -f '{{.State.Pid}}' centos01
-
- #查看容器的进程、网络、文件系统等命名空间编号
- ls -l /proc/9684/ns
(2)创建 container 模式的容器centos02,共享centos01容器的网卡
docker run -itd --name centos02 --net=container:centos01 centos:7 /bin/bash
- #查看centos02容器的网络模式是否是container
- docker inspect centos02 | grep NetworkMode
- #查看容器进程号
- docker inspect -f '{{.State.Pid}}' centos02
-
- #查看容器的进程、网络、文件系统等命名空间编号
- ls -l /proc/9967/ns
观察可以发现两个容器的 net namespace 编号相同
- #创建网络模式为 none 的centos03容器
- docker run -itd --name centos03 --network=none centos:7 /bin/bash
- #查看centos03容器的网络模式是否是node
- docker inspect centos03
- #搜索网络模式为none的容器
- docker ps --filter "network=none"
bridge模式是docker的默认网络模式,不用--net参数,就是bridge模式
- #创建网络模式为 bridge(默认模式) 的centos04容器,不用--net参数指定
- docker run -itd --name centos04 centos:7 /bin/bash
- #查看centos04容器的网络模式是否是bridge
- docker inspect centos04
- #搜索网络模式为bridge的容器
- docker ps --filter "network=bridge"
- #直接使用bridge模式,是无法支持指定IP运行docker的,例如执行以下命令就会报错
- docker run -itd --name centos05 --network bridge --ip 172.17.0.100 centos:7 /bin/bash
(1)创建自定义网络
- #可以先自定义网络,再使用指定IP运行docker
- docker network create --subnet=172.20.0.0/16 --opt "com.docker.network.bridge.name"="docker1" mynetwork
-
- #docker1 为执行 ifconfig -a 命令时,显示的网卡名,如果不使用 --opt 参数指定此名称,那你在使用 ifconfig -a 命令查看网络信息时,看到的是类似 br-110eb56a0b22 这样的名字,这显然不怎么好记
- #mynetwork 为执行 docker network list 命令时,显示的bridge网络模式名称
brctl show #查看网桥信息
(2) 使用指定IP创建并运行docker
docker run -itd --name centos05 --net mynetwork --ip 172.20.0.100 centos:7 /bin/bash
- #查看centos05容器的IP是否是我们设置的172.20.0.100
- docker inspect centos05
Control Groups (cgroups):
cgroups,是一个非常强大的linux内核工具,他不仅可以限制被 namespace 隔离起来的资源, 还可以为资源设置权重、计算使用量、操控进程启停等等。 所以 cgroups(Control groups)实现了对资源的配额和度量
cgroups有四大功能:
- #创建并运行一个centos06容器
- docker run -itd --name centos06 centos:7 /bin/bash
-
- #切换到指定 Docker 容器的 CPU 控制组目录
- cd /sys/fs/cgroup/cpu/docker/a4a05d1b6b69644fec398777baa35daeb82606c4cc540d65be0d3e2259737f27/
- #/sys/fs/cgroup/cpu/docker/: 这是 Docker 容器的 CPU 控制组目录所在的路径。控制组是 Linux 内核提供的一种机制,用于对进程组进行资源控制和管理
Docker 容器的 CPU 控制组目录 | 说明 |
---|---|
cgroup.clone_children | 用于控制是否允许子 cgroup 继承父 cgroup 的配置。如果设置为 1,则子 cgroup 将继承父 cgroup 的配置;如果设置为 0,则子 cgroup 将不继承父 cgroup 的配置 |
cgroup.procs | 列出了当前在该 cgroup 中运行的进程(任务)的 PID。可以通过向这个文件写入 PID,将进程移动到该 cgroup 中 |
cpuacct.usage | 包含了容器在 CPU 上消耗的总时间,以纳秒为单位。可以用来监视容器在 CPU 上的实际使用情况 |
cpu.cfs_period_us | 用于设置 CPU CFS(Completely Fair Scheduler)周期的长度,单位是微秒。决定了任务在一个周期内能够使用的 CPU 时间 |
cpu.rt_period_us | 用于设置实时调度任务的周期长度,单位是微秒。用于限制实时任务在一个周期内的执行时间 |
cpu.shares | 用于设置容器相对于其他容器的 CPU 分配权重。通过调整这个值,可以影响容器在 CPU 分配上的优先级 |
notify_on_release: | 用于控制当 cgroup 中的最后一个任务退出时是否通知。如果设置为 1,则当 cgroup 中的最后一个任务退出时会收到通知;如果设置为 0,则不会收到通知 |
cgroup.event_control | 用于控制 cgroup 事件的通知。可以用来注册和取消事件通知 |
cpuacct.stat | 包含了有关 CPU 账户的统计信息,例如用户态和内核态的 CPU 时间消耗 |
cpuacct.usage_percpu | 包含了每个 CPU 核心上容器消耗的 CPU 时间,以纳秒为单位。可以用来查看每个 CPU 核心上的 CPU 使用情况 |
cpu.cfs_quota_us | 用于设置容器在一个周期内能够使用的 CPU 时间配额,单位是微秒。超过这个配额的部分将被限制 |
cpu.rt_runtime_us | 用于设置实时调度任务的运行时间配额,单位是微秒。用于限制实时任务的运行时间 |
cpu.stat | 包含了有关 CPU 使用情况的统计信息,例如 CPU 时间消耗、时间片的使用情况等 |
tasks | 列出了当前在该 cgroup 中运行的进程(任务)的 PID。可以通过向这个文件写入 PID,将进程移动到该 cgroup 中 |
- #查看容器在一个周期内能够使用的 CPU 时间配额
- cat cpu.cfs_quota_us
- #默认值 -1,表示该容器没有被限制在一个周期内可以使用的 CPU 时间配额
- #如果设为50000,表示占用50000/100000=50%的CPU
-
- #查看CPU CFS 调度器的周期长度,单位也是微秒(us)
- cat cpu.cfs_period_us
- #CPU CFS 调度器的周期长度为100毫秒。在一个周期内,容器的进程可以使用的 CPU 时间总量受限于这个周期的长度
(1)设置50%的比例分配CPU使用时间上限
- echo 50000 > cpu.cfs_quota_us
- cat cpu.cfs_quota_us
(2)进入到容器中,进行CPU压力测试
- #进入到centos06的容器内
- docker exec -it centos06 /bin/bash
-
- #编写压力测试的循环脚本
- vi cpu.sh
- #!/bin/bash
- i=0
- while true
- do
- let i++
- done
-
- #添加执行权限,并执行脚本
- chmod +x cpu.sh
- source cpu.sh
(3)查看CPU占用资源
top #查看这个压力测试的循环脚本占了50%左右的CPU资源
docker stats #查看容器占用的系统资源信息
注:
如果不对 cpu.cfs_quota_us 进行限制,则默认值为-1的情况下,进行压力测试,CPU资源使用率接近100%
- 总结:
- 设置设置50%的比例分配CPU使用时间上限的方法
-
- 方法一:创建并运行容器时指定分配CPU使用时间的比例进行限额
- docker run -itd --name test --cpu-quota 50000 centos:7 /bin/bash
-
- 方法二:进入Docker容器的 CPU 控制组目录,并更改cpu.cfs_quota_us文件内容为指定分配CPU使用时间的比例来进行限额
- cd /sys/fs/cgroup/cpu/docker/a4a05d1b6b69644fec398777baa35daeb82606c4cc540d65be0d3e2259737f27/
- echo 50000 > cpu.cfs_quota_us
Docker 通过 --cpu-shares 指定 CPU 份额,默认值为1024,值为1024的倍数
虚拟机修改成单核CPU才有明显的效果
(1)创建并运行两个容器为 c1 和 c2,并设置容器的权重,使得c1和c2的CPU资源占比为1/3和2/3
- #创建并运行两个容器为 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
(2)分别进入这两个容器,并进行压力测试
- #分别进入这两个容器,并进行压力测试
- docker exec -it c1 /bin/bash #进入到c1容器内
- yum install -y epel-release #安装额外源
- yum install -y stress #安装stress压力测试工具
- stress -c 4 #产生四个进程,每个进程都反复不停的计算随机数的平方根
-
- docker exec -it c2 /bin/bash ##进入到c2容器内
- yum install -y epel-release
- yum install -y stress
- stress -c 4
(3)查看容器运行状态(动态更新)
docker stats #查看容器占用的系统资源信息
先分配虚拟机4个CPU核数
(1)创建并运行bak容器绑定CPU1和CPU3
docker run -itd --name bak --cpuset-cpus 1,3 centos:7 /bin/bash
(2) 进入容器,进行压力测试
- #进入容器,进行压力测试
- docker exec -it bak /bin/bash #进入到c1容器内
- yum install -y epel-release #安装额外源
- yum install -y stress #安装stress压力测试工具
- stress -c 4 #产生四个进程,每个进程都反复不停的计算随机数的平方根
(3)使用top查看CPU绑定情况
--memory
标志在Docker中,可以使用内置的功能来限制容器可以使用的内存量
可以在运行容器时使用--memory
标志来设置容器可以使用的内存量,单位可以是字节、千字节、兆字节、千兆字节或者吉字节
- #-m(--memory=) 选项用于限制容器可以使用的最大内存
- docker run -itd --name nc -m 512m centos:7 /bin/bash
- #限制新容器nc的最大使用内存为512MB
docker stats #查看容器占用的系统资源信息
--memory-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 容器就可以使用多少)
- docker run -itd --name swp -m 200m --memory-swap=1g nginx:latest --vm 1 --vm-bypes 100m
- #--vm 1:启动1个内容工作线程
- #--vm-bypes:每个线程分配100M
- --device-read-bps:限制某个设备上的读速度bps(数据量),单位可以是kb、mb(M)或者gb
- 例:docker run -itd --name test9 --device-read-bps /dev/sda:1M centos:7 /bin/bash
-
- --device-write-bps : 限制某个设备上的写速度bps(数据量),单位可以是kb、mb(M)或者gb
- 例:docker run -itd --name test10 --device-write-bps /dev/sda:1mb centos:7 /bin/bash
-
- --device-read-iops :限制读某个设备的iops(次数)
-
- --device-write-iops :限制写入某个设备的iops(次数)
此测试只能在旧版本的docker有效,如20.10.17版本,新版本可能会有问题
- #创建容器,并同时限制读取和写入速率
- docker run -it --name wre --device-read-bps=/dev/sda:5MB --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参数以规避掉文件系统cache
用于限制容器中指定设备的每秒读取和写入操作数 (IOPS)
- #限制读取和写入次数,指定了对 /dev/sda 设备的最大读取 IOPS 为 300,指定了对 /dev/sda 设备的最大写入 IOPS 为 300
- docker run -it --name cis --device-read-iops=/dev/sda:300 --device-read-iops=/dev/sda:300 centos:7 /bin/bash
处理Docker故障导致磁盘爆满的问题通常需要一系列步骤
(1)停止Docker服务
首先,停止Docker服务以阻止持续写入造成的进一步磁盘使用
docker stop 容器ID/名称
(2)删除不必要的容器和镜像
删除不再需要的容器、镜像和数据卷,以释放磁盘空间
#删除所有已停止的容器 docker container prune #删除不再使用的镜像 docker image prune #删除未被任何容器使用的数据卷 docker volume prune #清理docker占用的磁盘空间 docker system prune -a #可以用于清理磁盘,删除关闭的容器、无用的数据卷和网络(3)清理日志文件
#编写脚本,清除日志 vim /opt/clean.sh #!/bin/bash logs=$(find /var/lib/docker/containers/ -name *-json.log*) for log in $logs do cat /dev/null > $log done(4)设置docker日志文件数量及每个日志大小
#设置docker日志文件数量及每个日志大小 vim /etc/docker/daemon.json { "registry-mirrors": ["http://f613ce8f.m.daocloud.io"], "log-driver": "json-file", #日志格式 "log-opts": { "max-size" : "500m", "max-file" : "3"} #日志的参数最大500M,最大容器中有三个日志文件,每个日志文件大小是500M } #修改完需要重新加载 systemctl daemon-reload(5)定期清理
建立计划任务:crontab -e,设定时间执行清除日志的脚步
crontab -e * */3 1 * * /usr/bin/bash /opt/clean.sh(6)监控和预防措施
最后,确保实施监控和预防措施以避免未来的磁盘爆满问题。可以使用监控工具来追踪磁盘使用情况,并且可以设置警报,以便在磁盘使用接近极限时采取行动
完成这些步骤后,您可以重新启动Docker服务,并且应该能够恢复正常运行
(1)模拟新建容器一直在后台持续运行占用资源
- #在后台持续运行 docker run 创建的容器
- #需要在 docker run 命令之后添加 -d 选项让 Docker 容器以守护形式在后台运行。并且容器所运行的程序不能结束
- docker run -itd centos:7 /usr/bin/bash -c "while true;do echo hello;done"
- #切换至存放docker运行中的容器的相关数据的目录
- cd /var/lib/docker/containers/
- #查看文件所占磁盘空间的大小
- du -sh *
此时CPU利用率过高,会导致卡顿等问题
(2)停止运行有问题的容器
docker stop a5e663466278
(3) 清理日志文件
- #编写脚本,清除日志
- vim /opt/clean.sh
- #!/bin/bash
- logs=$(find /var/lib/docker/containers/ -name *-json.log*)
- for log in $logs
- do
- cat /dev/null > $log
- done
-
- #添加执行权限,并执行脚本
- chmod +x /opt/clean.sh
- . /opt/clean.sh
这意味着如果你在容器中运行一个web服务,那么它就直接绑定到主机的网络接口上,而不是通过docker进行任何网络转发
与宿主机共享网络名称空间
这种模式允许容器去共享另一个容器网络命名空间,这说明两个容器可以相同的网络接口和IP地址,他们共享的是同一网络命名空间
多个容器之间共享一个network namespace(命名空间)
此网络模式表示将容器拥有自己的网路命名空间,但不会进行任何网络配置,这实际给了用户完全的自主权来给自己配置容器的网络
自闭空间
每个新创建的容器都将该网络分配一个IP地址,此网络模式允许所有docker容器之间以及docker宿主机之间进行互相通信
默认模式,通过VETH对连接容器docker0网桥,网桥分配给容器IP,同时docker0作为局域网内容器的网关,最后与宿主机网卡进行通讯
docker允许用户创建自己的定义的网络,用户可以定义的网络范围、子网、路由等参数,这种类型网络使用用户可以更好地对容器网络进行控住和隔离(生产业务需求;注:根据甲方指定或领导指定)
根据业务需求指定静态IP地址
control groups:是一个1inux内核的一个特性,用于限制记录和隔离进程组系统资源使用(cpu、内存、磁盘I/0等)
cpu-period 周期:指的是CPU在给与当前管理 控制容器的分配资源时 ,cpu 分配周期默认1s,此配置可以在运行时直接指定
cpu-quota(cpu 配额):直接限制了cgroups可以使用cpu的时间,如果设置了cgroup的配额100000us(微秒),那么在每个100ms(毫秒)的是时间窗口 cgroups是最多只能使用 100000us(微秒)的cpu 时间
cpuset-cpu:指定容器仅能使用指定CPU,按照CPU的下标来表示
--memory:
设置容器可以使用的内存量,单位可以是字节、千字节、兆字节、千兆字节或者吉字节
--memory-swap:
可以用来设置容器可以使用的交换空间大小。强调一下,--memory-swap 是必须要与 --memory 一起使用的
--device-read-bps:限制某个设备上的读速度bps(数据量),单位可以是kb、mb(M)或者gb
例:docker run -itd --name test9 --device-read-bps /dev/sda:1M centos:7 /bin/bash
--device-write-bps : 限制某个设备上的写速度bps(数据量),单位可以是kb、mb(M)或者gb
例:docker run -itd --name test10 --device-write-bps /dev/sda:1mb centos:7 /bin/bash
--device-read-iops :限制读某个设备的iops(次数)
--device-write-iops :限制写入某个设备的iops(次数)