docker网络
网络实现原理
-
Docker 网络是指由 Docker 为应用程序创建的虚拟环境的一部分,它允许应用程序从宿主机操作系统的网络环境中独立出来,形成容器自有的网络设备、IP 协议栈、端口套接字、IP 路由表、防火墙等与网络相关的模块。Docker 的网络功能提供了一种在容器之间进行通信和与外部网络交互的机制。
-
Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的 Container-IP 直接通信。
-
Docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着外部网络无法直接通过 Container-IP 访问到容器。如果容器希望外部访问能够访问到,可以通过映射容器端口到宿主主机(端口映射),即 docker run 创建容器时候通过 -p 或 -P 参数来启用,访问容器的时候就通过[宿主机IP]:[容器端口]访问容器。
Docker 网络实现原理补充
Docker 网桥(Bridge):
- Docker 网桥是由 Docker 在宿主机上虚拟的网络设备,它充当容器之间通信的桥梁。Docker 网桥通过 Linux 桥接技术实现,创建一个虚拟的以太网桥(
docker0
),用于连接同一主机上的各个容器。
IP 地址分配:
- 在容器启动时,Docker 会为每个容器分配一个 IP 地址,这个地址属于 Docker 网桥的子网。这样,容器可以通过 Container-IP 直接进行通信,实现了隔离和网络互联。
端口映射:
-
外部网络无法直接访问容器的 Container-IP,因此 Docker 提供了端口映射功能。通过使用
-p
或-P
参数,可以将容器的端口映射到宿主机上的一个端口,使得外部网络可以通过宿主机的 IP 地址和映射的端口访问容器提供的服务。 -
使用
-p
参数指定映射的宿主机端口,例如-p 43000:80
表示将容器的 80 端口映射到宿主机的 43000 端口。 -
使用
-P
参数可以随机映射容器端口到宿主机的一个高端口。
查看容器信息和日志:
-
使用
docker ps -a
查看容器的详细信息,包括容器的 ID、镜像、启动命令、状态等。 -
使用
docker logs 容器的ID/名称
查看容器的标准输出和日志信息,用于排查容器运行时的问题。
跨主机通信:
-
对于需要在多个 Docker 主机之间通信的场景,可以使用容器编排工具,如 Docker Swarm 或 Kubernetes,实现容器的跨主机通信和协同工作。
-
这些补充信息可以使你的文档更加详尽,帮助读者更好地理解 Docker 网络的实现原理及相关操作。
网络实现实例
用于运行两个Nginx容器,每个容器具有不同的端口映射配置。
docker run -d --name test1 -P nginx
-
该命令以分离模式 (
-d
) 运行一个 Nginx 容器(nginx
镜像),容器名为test1
。 -
选项
-P
会自动将容器中公开的端口映射到主机上的随机端口。
docker run -d --name test2 -p 43000:80 nginx
-
该命令以分离模式 (
-d
) 运行另一个 Nginx 容器(nginx
镜像),容器名为test2
。 -
选项
-p 43000:80
指定容器中的端口80映射到主机上的端口43000。
docker ps -a
- 该命令列出所有容器,包括那些当前未运行的容器。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9d3c04f57a68 nginx "/docker-entrypoint.…" 4 seconds ago Up 3 seconds 0.0.0.0:43000->80/tcp test2
b04895f870e5 nginx "/docker-entrypoint.…" 17 seconds ago Up 15 seconds 0.0.0.0:49170->80/tcp test1
- 输出显示运行中容器的详细信息,包括容器ID、镜像、命令、创建时间、状态和端口映射。
在浏览器中访问Nginx:
使用以下URL在浏览器中访问Nginx实例:
-
http://192.168.80.10:43000 (对应
test2
) -
http://192.168.80.10:49170 (对应
test1
)
查看容器日志:
要查看特定容器的日志,可以使用以下命令:
docker logs <容器ID或名称>
用实际的容器ID或名称替换 <容器ID或名称>
。
例如:
docker logs test1
这将显示 test1
容器的输出和日志。
网络模式
查看Docker中的网络列表:
docker network ls
或者
docker network list
这两个命令都会列出当前Docker主机上的所有网络。输出将包含每个网络的ID、名称、驱动程序和作用域等信息。通过查看这个列表,可以了解到Docker中已创建的网络,并选择适当的网络模式来运行你的容器。
指定容器网络模式
Docker会默认创建三种网络模式:bridge、none和host。
bridge模式:
默认设置,容器会连接到名为”bridge”的网络。这允许容器相互通信,但与主机隔离。通过 --net=bridge
指定。
none模式:
使用 --net=none
指定,表示容器不连接到任何网络。在这种模式下,你需要手动配置网络,或者容器之间的通信需要通过其他方式实现。
host模式:
使用 --net=host
指定,容器共享主机的网络命名空间,即与主机相同的网络。这意味着容器可以直接访问主机上的网络接口。
container模式:
使用 --net=container:NAME_or_ID
指定,容器与另一个容器共享网络命名空间。这使得它们可以直接使用相同的网络配置。
这些网络模式提供了不同的网络隔离和连接方式,允许根据应用程序的需求进行定制。
模式详解
Host模式(主机模式):
特点: 容器不会虚拟出自己的网卡,也不会配置自己的IP等,而是直接使用宿主机的IP和端口。
-
Docker使用了Linux的Namespaces技术来进行资源隔离,如PID Namespace隔离进程,Mount Namespace隔离文件系统,Network Namespace隔离网络等。
-
一个Network Namespace提供了一份独立的网络环境,包括网卡、路由、iptable规则等都与其他的Network Namespace隔离。
-
一个Docker容器一般会分配一个独立的Network Namespace。 但如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace, 而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡、配置自己的IP等,而是使用宿主机的IP和端口。
命令示例:
docker run --name my_container --network host -d nginx
用途: 适用于需要最大化网络性能,容器与宿主机共享相同的网络命名空间。
Container模式(容器模式):
特点: 容器不会创建自己的网卡或配置自己的IP,而是与一个指定的容器共享相同的IP和端口范围。
-
这个模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信。
命令示例:
docker run --name my_container1 -d nginx
docker run --name my_container2 --network container:my_container1 -d nginx
用途: 适用于需要共享相同网络命名空间的容器,它们可以直接访问对方的网络配置。
- 启动一个后台容器
test1
,使用 CentOS 7 镜像,并运行/bin/bash
命令:
docker run -itd --name test1 centos:7 /bin/bash
该命令创建了一个后台运行的容器,命名为 test1
,并使用 CentOS 7 镜像启动了一个交互式 Bash Shell。
- 查看所有容器的状态,包括已停止的容器:
docker ps -a
输出显示了容器的基本信息,包括容器ID、镜像、命令、创建时间等。
- 使用
docker inspect
命令查看容器的进程号(PID):
docker inspect -f '{{.State.Pid}}' 3ed82355f811
此命令显示了容器 test1
的PID,这里是25945。
- 使用
ls -l /proc/<PID>/ns
查看容器的命名空间编号:
ls -l /proc/25945/ns
输出显示了容器的各个命名空间,包括IPC、挂载(Mount)、网络(Net)、PID、用户(User)和UTS。
- 启动另一个后台容器
test2
,使用与test1
相同的网络命名空间:
docker run -itd --name test2 --net=container:3ed82355f811 centos:7 /bin/bash
此命令将容器 test2
的网络命名空间设置为与 test1
相同。
- 再次查看所有容器的状态:
docker ps -a
现在列出了两个容器,test1
和 test2
。
- 使用
docker inspect
命令查看容器test2
的进程号:
docker inspect -f '{{.State.Pid}}' ff96bc43dd27
此命令显示了容器 test2
的PID,这里是27123。
- 使用
ls -l /proc/<PID>/ns
再次查看容器test2
的命名空间编号:
ls -l /proc/27123/ns
输出显示了容器 test2
的各个命名空间,与容器 test1
的命名空间编号相同,表明它们共享了网络命名空间。
- 通过共享网络命名空间,
test2
容器与test1
容器共享相同的网络栈,它们可以直接通信,就好像它们在同一台主机上运行一样。
None模式(无网络模式):
特点: 关闭了容器的网络功能,容器将没有网络接口,不能进行网络通信。
-
使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。 也就是说,这个Docker容器没有网卡、IP、路由等信息。这种网络模式下容器只有lo回环网络,没有其他网卡。这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性。
命令示例:
docker run --name my_container --network none -d nginx
用途: 适用于一些特殊场景,例如不需要网络连接的容器。
Bridge模式(桥接模式):
特点: 默认模式,为每个容器分配和设置IP,并将容器连接到一个名为docker0
的虚拟网桥上。使用iptables NAT表配置容器与宿主机通信。
-
此模式会为每一个容器分配Network Namespace、设置IP等,并将一个主机上的 Docker 容器连接到一个虚拟网桥上。
命令示例:
docker run --name my_container --network bridge -d nginx
用途: 适用于多个容器需要在同一宿主机上运行,并需要通过网络相互通信的情况。
-
虚拟网桥 docker0:
-
Docker进程在主机上启动时,会创建一个名为
docker0
的虚拟网桥。 -
Docker容器连接到这个虚拟网桥,使得主机上的所有容器都能够通过这个网桥连接到一个共享的二层网络中,类似于物理交换机的作用。
-
-
分配IP和设置网关:
-
从
docker0
子网中分配一个IP给每个容器,并将docker0
的IP地址设置为容器的默认网关。 -
在主机上创建一对虚拟网卡 (
veth
pair 设备),它们成对出现,连接两个网络设备,组成了数据通道。
-
-
veth pair 设备:
-
Docker将
veth
pair 设备的一端放在新创建的容器中,并命名为eth0
(容器的网卡)。 -
另一端放在主机中,命名类似于
veth*
,并将这个网络设备加入到docker0
网桥中。 -
使用
brctl show
命令可以查看网桥上的连接情况。
-
-
端口转发和 iptables:
-
当使用
docker run -p
时,Docker实际上在主机的iptables
中设置了DNAT
(Destination NAT)规则,以实现端口转发功能。 -
你可以使用
iptables -t nat -vnL
命令来查看nat
表中的规则。
-
-
这些步骤描述了Docker容器如何在主机上进行网络连接、IP分配、网关设置以及端口转发。这种网络架构使得Docker容器可以方便地与主机和其他容器进行通信,同时通过端口转发功能可以将容器的服务映射到主机上的特定端口。
- –
自定义网络:
特点: 用户可以创建自己的自定义网络,容器可以连接到这个网络。用户可以配置自定义网络的属性,如子网、网关等。
命令示例:
docker network create my_network
docker run --name my_container --network my_network -d nginx
用途: 适用于需要更精细控制容器之间通信和隔离程度的场景。可以定义自己的网络拓扑和配置。
直接使用bridge模式,是无法支持指定IP运行docker的
在Docker中创建自定义网络,并在自定义网络中指定IP运行容器的一系列操作。
创建自定义网络:
docker network create --subnet=172.16.0.0/16 --opt "com.docker.network.bridge.name"="docker1" mynetwork
-
docker network create
: 创建一个自定义网络。 -
--subnet=172.16.0.0/16
: 指定网络的子网范围为172.16.0.0/16。 -
--opt "com.docker.network.bridge.name"="docker1"
: 使用--opt
参数指定了自定义网络的桥接名称为docker1
。如果不使用 –opt 参数指定此名称,那你在使用 ifconfig -a 命令查看网络信息时,看到的是类似 br-110eb56a0b22 这样的名字,这显然不怎么好记。 -
mynetwork
: 为自定义网络指定名称为mynetwork
。这样的操作创建了一个名为
mynetwork
的自定义网络,其子网范围为172.16.0.0/16,并使用docker1
作为桥接名称。查看网络信息:
-
docker1
是执行ifconfig -a
命令时,显示的网桥名称。 -
mynetwork
是执行docker network list
命令时,显示的bridge网络模式的名称。
-
运行容器并指定IP:
docker run -itd --name test4 --net mynetwork --ip 172.16.0.10 centos:7 /bin/bash
-
--name test4
: 为容器指定名称为test4
。 -
--net mynetwork
: 将容器连接到名为mynetwork
的自定义网络。 -
--ip 172.16.0.10
: 为容器指定IP地址为172.16.0.10。 -
centos:7
: 使用CentOS 7镜像启动容器。 -
/bin/bash
: 在容器中运行Bash Shell。
通过这些步骤,创建了一个自定义网络 mynetwork
,并在该网络中启动了一个名为 test4
的容器,并指定了容器的IP地址为172.16.0.10。这样,可以通过自定义网络的IP地址访问容器,并且容器可以在该网络中与其他容器进行通信。
cpu优化概述
1. 资源限制:
- –cpus=:限制容器使用的 CPU 数量。
docker run --cpus=2 my_container
这将限制容器 my_container
最多只能使用两个 CPU 核心。
- –cpu-shares=:设置容器 CPU 使用的权重。
docker run --cpu-shares=512 my_container1
docker run --cpu-shares=1024 my_container2
在这个例子中,my_container1
拥有更低的权重(512),而 my_container2
拥有更高的权重(1024),即在 CPU 分配上,my_container2
在竞争中更有优势。
2. CPU 实时调度策略:
- –cpu-rt-runtime= 和 –cpu-rt-period=:设置容器的 CPU 实时运行时间和周期。
docker run --cpu-rt-runtime=2000000 --cpu-rt-period=10000000 my_realtime_container
这个例子中,my_realtime_container
被设置为具有 2 秒(2000000 微秒)的实时运行时间,并且在 10 秒(10000000 微秒)的周期内。
3. NUMA 控制:
Docker 有一些高级特性可以使用,例如 --cpuset-cpus
和 --cpuset-mems
选项,可以将容器限制在特定的 NUMA 节点上。
-
–cpuset-cpus:指定容器可以使用的 CPU 核心。
-
–cpuset-mems:指定容器可以使用的 NUMA 节点内存。
示例:
docker run --cpus=2 --cpu-shares=512 --cpu-rt-runtime=2000000 --cpu-rt-period=10000000 --cpuset-cpus=0,1 --cpuset-mems=0 my_container
这个命令结合了多个 CPU 优化参数,并将容器 my_container
限制在 NUMA 节点 0 上的 CPU 核心 0 和 1 上运行。它还设置了 CPU 的分享权重、实时运行时间和周期。
4. CPU 隔离:
- –cpu-period 和 –cpu-quota:用于实现 CPU 周期和配额。这允许你设置 CPU 使用率的上限。
docker run --cpu-period=100000 --cpu-quota=50000 my_container
在这个例子中,my_container
的 CPU 使用率被限制在 50%(即 0.5 CPU)。
5. 进程优先级:
- nice 和 renice:这些工具可以用来设置容器中进程的优先级。你可以为某些任务分配更高的优先级。
docker exec -it my_container nice -n -5 ./my_high_priority_process
docker exec -it my_container renice -n -10 -p <pid>
这里,nice
设置了某个进程的较高优先级,而 renice
则用于改变已经运行的进程的优先级。
6. 实时性能监控和优化:
- 使用各种监控工具(如
docker stats
、cAdvisor
、Prometheus
等)来实时监控容器的 CPU 使用情况,并根据实际情况进行优化。
示例:
docker run --cpus=1.5 --cpu-shares=512 --cpu-period=100000 --cpu-quota=50000 --cpuset-cpus=0 --cpuset-mems=0 my_container
这个命令限制了 my_container
使用 1.5 个 CPU 核心,并设置了 CPU 分享权重为 512。同时,通过周期和配额设置,限制了 CPU 使用率为 50%。此外,容器被限制在 NUMA 节点 0 上的 CPU 核心 0。
优化容器的 CPU 使用是一项复杂的任务,需要根据特定的应用程序需求和可用资源进行调整。这些示例提供了不同参数的用法,可根据具体情况进行调整,以便在 Docker 中实现更好的 CPU 利用和性能优化。
资源控制
Docker 资源控制是指通过 Docker 平台提供的功能和机制,对容器的各种资源(如 CPU、内存、磁盘 I/O、网络带宽等)进行管理和限制,以确保容器在运行过程中能够合理、有效地利用系统资源。
cpu限制
cgroups 是 Linux 内核提供的一种机制,用于对一组进程进行资源限制、优先级分配、资源统计和任务控制。这是 Linux 内核中对容器技术的支持的关键组成部分之一。
以下是 cgroups 的主要功能:
-
资源限制: cgroups 允许你对一组进程(或任务)使用的资源总量进行限制。这可以包括 CPU、内存、磁盘 I/O 等。通过设定资源限制,可以确保容器或进程在运行时不会无节制地占用系统资源。
-
优先级分配: 通过分配 CPU 时间片的数量以及磁盘 I/O 带宽大小,cgroups 实际上允许控制任务的运行优先级。这对于确保高优先级任务获得足够的系统资源而低优先级任务不能无限制地占用资源非常重要。
-
资源统计: cgroups 可以用于统计系统资源的使用量,如 CPU 时间、内存使用等。这对于监控和性能分析很有用,能够帮助了解系统中不同任务的资源消耗情况。
-
任务控制: cgroups 允许对任务执行挂起、恢复等操作。这使得可以更精细地控制和管理系统中运行的任务。
总体而言,cgroups 提供了强大的资源管理和控制机制,为容器化技术(比如 Docker 和 Kubernetes)以及其他多任务环境下的资源隔离和管理提供了基础。这些功能使得管理员能够更精确地控制和调整系统中不同任务的行为,以提高系统的效率和可靠性。
设置cpu使用上限
在 Linux 中通过 CFS(Completely Fair Scheduler)进行 CPU 资源调度的设置,以及如何在容器中限制 CPU 使用率上限的问题。这主要涉及到两个参数:--cpu-period
和 --cpu-quota
。
–cpu-period: 这个参数用于设置 CFS 调度周期的长度。CFS 将 CPU 时间切分为一系列时间片,而 --cpu-period
就是设置这个周期的长度。有效范围是 1ms 到 1s,对应的 --cpu-period
数值范围是 1000 到 1000000。
docker run --cpu-period=100000 my_container
以上示例将容器的 CFS 调度周期设置为 100ms。
–cpu-quota: 这个参数用于设置在每个调度周期内容器能够使用的 CPU 时间。它的值是一个配额,有效范围必须不小于 1ms,即 --cpu-quota
的值必须大于等于 1000。
docker run --cpu-quota=50000 my_container
以上示例将容器的 CPU 配额设置为 50ms。这表示容器在每个 100ms 的调度周期内最多能够使用 50ms 的 CPU 时间。
- 通过这两个参数的组合,可以有效地控制容器的 CPU 使用率。例如,如果你希望容器最多使用整个系统的一半 CPU 资源,可以将
--cpu-period
设置为 100000(100ms),而将--cpu-quota
设置为 50000(50ms),以实现这一目标。这样,容器将被允许在每个周期内使用的 CPU 时间最多为 50ms。
限制cpu示例
Docker 中容器的 CPU 资源限制
docker run -itd --name test5 centos:7 /bin/bash
Docker Run 命令:
-
-itd
: 这是三个选项的结合。 -
-i
: 交互模式,允许你与容器进行交互。 -
-t
: 在新容器内分配一个伪终端(pseudo-tty)。 -
-d
: 后台运行容器,并返回容器的唯一标识符。 -
--name test5
: 为容器指定了一个名字,即 “test5″。 -
centos:7
: 使用的基础镜像,即 CentOS 7。 -
/bin/bash
: 容器启动后执行的命令,这里是启动 Bash shell。
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3ed82355f811 centos:7 "/bin/bash" 0 days ago Up 1 hours test
Docker PS -a 命令:
输出显示容器的详细信息,其中包括容器 ID、使用的镜像、启动命令、创建时间、状态等。在示例结果中,容器名为 “test” 的容器处于 “Up 1 hours” 的状态,表示容器已经运行了 1 小时。
cd /sys/fs/cgroup/cpu/docker/3ed82355f81151c4568aaa6e7bc60ba6984201c119125360924bf7dfd6eaa42b/
cgroup 路径解析:
这里进入了 cgroup 中的路径,其中 3ed82355f81151c4568aaa6e7bc60ba6984201c119125360924bf7dfd6eaa42b
是容器的 ID,该路径下的文件反映了该容器的 cgroup 参数。
查看 cpu.cfsquotaus:
cat cpu.cfs_quota_us
输出 -1
表示该 cgroup 未设置 CPU 时间配额,即不受限制。
查看 cpu.cfsperiodus:
cat cpu.cfs_period_us
输出 100000
表示 CPU 时间的周期为 100000 微秒,即 100 毫秒。
-
总结一下,容器 “test” 在 CPU cgroup 中的设置显示出默认的无限制状态,即该容器未受到 CPU 时间的限制。这意味着容器可以使用系统上的所有 CPU 时间。如果需要限制容器的 CPU 使用率,可以使用
--cpu-quota
和--cpu-period
等参数进行设置,以实现对容器 CPU 资源的精确控制。 -
cpu.cfsperiodus:cpu分配的周期(微秒,所以文件名中用 us 表示),默认为100000。
-
cpu.cfsquotaus:表示该cgroups限制占用的时间(微秒),默认为-1,表示不限制。 如果设为50000,表示占用50000/100000=50%的CPU。
cpu压力测试
进行CPU压力测试
执行 CPU 资源密集型脚本:
使用 docker exec
命令进入容器,并创建一个无限循环的 Bash 脚本(cpu.sh
),该脚本会不断地递增变量 i
,导致 CPU 使用率上升。
docker exec -it 3ed82355f811 /bin/bash
在容器内,创建并运行以下脚本:
vim /cpu.sh
#!/bin/bash
i=0
while true
do
let i++
done
接着给予该脚本执行权限并运行它:
chmod +x /cpu.sh
./cpu.sh
使用 top
命令观察容器内的 CPU 使用率会显著上升,因为这个脚本持续地消耗 CPU 资源。
设置 CPU 时间配额为 50%:
- 使用 Docker 命令:
docker run -itd --name test6 --cpu-quota 50000 centos:7 /bin/bash
这里创建了一个新容器 test6
并设置了 CPU 时间配额为 50%(50000 微秒)。这意味着容器 test6
在每 100 毫秒的周期内只能使用 50% 的 CPU 资源。
-
手动设置 cgroup 参数:
你可以直接修改 cgroup 的
cpu.cfs_quota_us
文件来设置容器的 CPU 时间配额。这相当于手动设置 CPU 时间配额。
cd /sys/fs/cgroup/cpu/docker/3ed82355f81151c4568aaa6e7bc60ba6984201c119125360924bf7dfd6eaa42b/
echo 50000 > cpu.cfs_quota_us
接着,再次在容器中运行上述的 cpu.sh
脚本,你会发现 CPU 使用率近似于 50%,这证明了 cgroups 对 CPU 资源的控制起到了效果。
通过这个示例,你可以看到如何使用 Docker 和 cgroups 功能来限制容器的 CPU 资源使用,从而确保系统中其他任务也能得到足够的 CPU 资源。
设置CPU资源占用比(设置多个容器时才有效)
创建两个容器并设置 CPU 份额:
使用 docker run
命令创建两个容器,分别命名为 c1
和 c2
,并分别设置不同的 CPU 份额。这里,--cpu-shares
选项的值分别为 512 和 1024,表示它们的 CPU 份额比例。
docker run -itd --name c1 --cpu-shares 512 centos:7
docker run -itd --name c2 --cpu-shares 1024 centos:7
进入容器并进行压力测试:
进入容器并使用 yum
安装 stress
工具,然后使用 stress
工具模拟 CPU 资源压力。这里的命令会创建四个进程,每个进程都会反复计算随机数的平方根,产生 CPU 负载。
yum install -y epel-release
yum install -y stress
stress -c 4
查看容器运行状态:
使用 docker stats
命令实时查看容器的资源使用情况,包括 CPU 使用率、内存使用情况等。
docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
c3ee18e65852 c2 66.50% 5.5MiB / 976.3MiB 0.56% 20.4MB / 265kB 115MB / 14.2MB 4
bb02d3b345d8 c1 32.68% 2.625MiB / 976.3MiB 0.27% 20.4MB / 325kB 191MB / 12.7MB 4
这个命令输出的结果包含每个容器的 ID、名称、CPU 使用率、内存使用情况、网络 I/O、块 I/O、进程数量等信息。在示例中,c1
和 c2
的 CPU 使用率分别为 32.68% 和 66.50%,反映了它们的 CPU 份额设置的比例关系。
通过这个例子,可以在容器间动态调整 CPU 资源占用比例,确保资源按照预期的比例分配给不同的容器。
设置容器绑定指定的CPU
分配虚拟机 4 个 CPU 核心:
在虚拟机中,首先确保有 4 个可用的 CPU 核心。然后使用 docker run
命令创建一个名为 test7
的容器,并通过 --cpuset-cpus
选项将容器绑定到虚拟机的第 1 和第 3 个 CPU 核心。
docker run -itd --name test7 --cpuset-cpus 1,3 centos:7 /bin/bash
进入容器并进行压力测试:
进入容器并使用 yum
安装 stress
工具,然后使用 stress
工具模拟 CPU 资源压力。这里的命令会创建四个进程,每个进程都会产生 CPU 负载。
yum install -y epel-release
yum install -y stress
stress -c 4
退出容器,查看 CPU 使用情况:
退出容器后,可以使用 top
命令查看主机上的 CPU 使用情况。按 1
键可以查看每个 CPU 核心的详细信息。
top
这将显示实时的 CPU 使用情况,你应该能够看到绑定的 CPU 核心(在这个例子中是第 1 和第 3 个核心)上有相应的 CPU 使用率。
通过这个例子,你可以将容器限制在特定的 CPU 核心上,以确保它只使用指定的 CPU 资源。
内存限制
内存使用限制示例
使用 -m
选项限制容器内存:
使用 -m
(或 --memory=
)选项,可以限制容器可以使用的最大物理内存。在你的例子中,通过以下命令创建了一个名为 test8
的容器,限制了容器可用的物理内存为 512MB:
docker run -itd --name test8 -m 512m centos:7 /bin/bash
通过这个限制,test8
容器在运行时只能使用最多 512MB 的物理内存。
执行以下命令可以查看所有运行中容器的实时资源使用情况:
docker stats
docker stats
输出的信息包括:
-
CONTAINER ID:容器的唯一标识符。
-
NAME:容器的名称。
-
CPU %:CPU 使用百分比。
-
MEM USAGE / LIMIT:内存使用情况和限制。
-
MEM %:内存使用百分比。
-
NET I/O:网络输入/输出。
-
BLOCK I/O:块输入/输出。
-
PIDS:进程数量。
使用 --memory-swap
选项限制可用的 Swap 空间:
--memory-swap
选项是用于限制容器可用的 swap 空间。它需要与 --memory
一起使用。你提到的这个选项是确保 swap 大小包含了可用内存和 swap,其计算方式为 --memory-swap = --memory + swap
。
例如,使用以下命令:
docker run -itd --name test9 -m 300m --memory-swap=1g centos:7 /bin/bash
这表示容器可以使用 300MB 的物理内存,并且可以使用 700MB(1GB – 300MB)的 swap 空间。
关于 --memory-swap
不同值的含义:
-
如果
--memory-swap
设置为 0 或者不设置,则容器可以使用的 swap 大小为-m
值的两倍。 -
如果
--memory-swap
的值和-m
值相同,则容器不能使用 swap。 -
如果
--memory-swap
值为 -1,表示容器程序使用的内存受限,而可以使用的 swap 空间则没有限制,它可以使用宿主机上所有的 swap 空间。
这些选项允许在 Docker 容器中对内存资源进行更细粒度的控制和限制。
磁盘IO配额控制(blkio)的限制
这些 Docker 命令行选项用于限制容器中设备的读写速度和 IOPS(每秒的输入/输出操作次数)。
--device-read-bps
:限制读速度
通过该选项,可以限制容器对指定设备的读取速度(每秒读取的字节数)。单位可以是kb、mb(M)或者gb。例如:
docker run -itd --name test9 --device-read-bps /dev/sda:1M centos:7 /bin/bash
这个例子中,容器 test9
限制了对 /dev/sda
设备的读取速度为每秒 1MB。
--device-write-bps
:限制写速度
这个选项用于限制容器对指定设备的写入速度(每秒写入的字节数)。单位可以是kb、mb(M)或者gb。例如:
docker run -itd --name test10 --device-write-bps /dev/sda:1mb centos:7 /bin/bash
这个例子中,容器 test10
限制了对 /dev/sda
设备的写入速度为每秒 1MB。
--device-read-iops
:限制读取 IOPS
通过该选项,你可以限制容器对指定设备的读取 IOPS(每秒读取的操作次数)。例如:
docker run -itd --name test11 --device-read-iops /dev/sdb:100 centos:7 /bin/bash
这个例子中,容器 test11
限制了对 /dev/sdb
设备的读取 IOPS 为每秒 100 次。
--device-write-iops
:限制写入 IOPS
这个选项用于限制容器对指定设备的写入 IOPS(每秒写入的操作次数)。例如:
docker run -itd --name test12 --device-write-iops /dev/sdb:50 centos:7 /bin/bash
这个例子中,容器 test12
限制了对 /dev/sdb
设备的写入 IOPS 为每秒 50 次。
磁盘限制示例
创建容器并限制写速度:
使用 docker run
命令创建了一个名为 test10
的容器,并通过 --device-write-bps
选项限制了对 /dev/sda
设备的写入速度为每秒 1MB。
docker run -it --name test10 --device-write-bps /dev/sda:1MB centos:7 /bin/bash
这个命令会在后台运行一个交互式的容器,并将其命名为 test10
,同时限制了对 /dev/sda
设备的写入速度。
使用 dd
验证写速度:
进入容器后,使用 dd
命令从 /dev/zero
设备写入数据到 test.out
文件中,以验证写入速度。
dd if=/dev/zero of=test.out bs=1M count=10 oflag=direct
这个命令从 /dev/zero
设备读取数据,写入到 test.out
文件中,使用 1MB 的块大小,总共写入 10MB 的数据。根据输出,写入速度为每秒 1.0 MB/s。
清理 Docker 占用的磁盘空间:
使用 docker system prune -a
命令可以清理 Docker 占用的磁盘空间,包括删除关闭的容器、无用的数据卷和网络。这对于释放磁盘空间以及清理不再需要的 Docker 资源非常有用。
docker system prune -a
这个命令会列出要删除的所有未使用的资源,并提示确认是否进行清理。确认后,Docker 将删除这些不再需要的资源,从而释放磁盘空间。
通过这些步骤,成功地创建了一个限制写速度的容器,并通过 dd
命令验证了写入速度,最后通过 docker system prune -a
清理了不再需要的 Docker 资源。
容器日志占满磁盘空间怎么办
解决方案一:清空日志
#!/bin/bash
logs=$(find /var/lib/docker/containers/ -name *-json.log*)
for log in $logs
do
cat /dev/null > $log
done
这个脚本的目的是通过查找 Docker 容器日志文件并将其清空来释放磁盘空间。脚本使用 find
命令查找所有以 -json.log
结尾的日志文件,并通过 cat /dev/null > $log
将它们的内容清空。
解决方案二:设置 Docker 日志文件大小和数量限制
编辑 Docker daemon 的配置文件 /etc/docker/daemon.json
,并添加以下配置:
{
"registry-mirrors": ["http://f613ce8f.m.daocloud.io"],
"log-driver": "json-file",
"log-opts": {
"max-size": "500m",
"max-file": "3"
}
}
-
"max-size": "500m"
:设置每个日志文件的最大大小为 500MB。 -
"max-file": "3"
:设置最大保留的日志文件数量为 3 个。
修改完配置文件后,需要重新加载 Docker daemon:
systemctl daemon-reload
这样设置后,Docker 将限制每个容器的日志文件大小,并定期轮转日志文件以保持文件数量在指定的范围内。这可以防止日志文件无限增长导致磁盘空间耗尽的问题。
请注意,第二个方案是一个更加长期的解决方案,可以预防日志文件过大的问题。
端口映射
-
端口映射机制是 Docker 中重要的网络特性之一。在容器内运行的服务通常需要对外部网络提供访问,而端口映射是一种实现容器与外部网络通信的关键方式。
-
当容器内的服务绑定到特定的端口时,通过端口映射,Docker 允许将宿主机上的一个端口映射到容器内服务的相应端口。这样一来,外部网络可以通过宿主机的 IP 地址和映射的端口来访问容器内的服务。
docker run -d --name test1 -P nginx
-
-d
: 表示以后台(detached)模式运行容器。 -
--name test1
: 为容器指定一个名称为test1。 -
-P
: 随机映射容器内部的端口到主机的高端口(从32768开始)。这意味着Docker会自动选择一个未被占用的主机端口,并将它映射到容器的80端口。
docker run -d --name test2 -p 43000:80 nginx
-
-d
: 同样表示以后台(detached)模式运行容器。 -
--name test2
: 为容器指定一个名称为test2。 -
-p 43000:80
: 指定将主机的43000端口映射到容器的80端口。
docker ps -a
- 显示所有容器的信息,包括已停止的容器。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9d3c04f57a68 nginx "/docker-entrypoint.…" 4 seconds ago Up 3 seconds 0.0.0.0:43000->80/tcp test2
b04895f870e5 nginx "/docker-entrypoint.…" 17 seconds ago Up 15 seconds 0.0.0.0:49170->80/tcp test1
-
显示两个容器的基本信息,包括它们的状态和端口映射关系。
-
对于test2容器,主机的43000端口映射到容器的80端口。
-
对于test1容器,Docker自动选择了主机的49170端口映射到容器的80端口。
浏览器访问:
-
通过
http://192.168.41.10:43000
可以访问test2容器的Nginx服务。 -
通过
http://192.168.41.10:49170
可以访问test1容器的Nginx服务。
容器互联
Docker容器互联是指通过Docker提供的连接系统,将多个容器连接在一起,实现容器之间的通信和共享信息。简单点说,就是会在源容器和接收容器之间建立一条隧道,接收容器可以看到源容器指定的信息。
容器连接:
-
Docker提供了
docker connect
命令,用于将一个容器连接到另一个容器。 -
连接会创建一个父子关系,其中父容器可以看到子容器。
容器之间的通信:
-
通过容器互联,容器之间可以直接使用容器名称进行通信,而不需要使用IP地址。
-
Docker会在连接时设置一些环境变量,使得容器之间能够识别对方。
共享连接信息:
- 容器互联允许容器共享连接信息,使得它们能够更方便地协同工作。
下面是一个简单的例子,演示如何通过Docker容器互联连接两个容器:
创建两个CentOS 7容器(web1和web2),并使用--link
选项实现容器互联。以下是每个命令的解释:
创建web1容器:
docker run -itd -P --name web1 centos:7 /bin/bash
-
-itd
: 表示以交互式方式运行并保持容器后台运行。 -
-P
: 随机映射容器内部的端口到主机的高端口(从32768开始)。 -
--name web1
: 给容器取名为web1。 -
centos:7
: 使用CentOS 7镜像。 -
/bin/bash
: 启动容器后执行的命令,这里是启动bash shell。
创建web2容器并连接到web1:
docker run -itd -P --name web2 --link web1:web1 centos:7 /bin/bash
-
-itd
: 同样表示以交互式方式运行并保持容器后台运行。 -
-P
: 随机映射容器内部的端口到主机的高端口(从32768开始)。 -
--name web2
: 给容器取名为web2。 -
--link web1:web1
: 使用--link
选项将web2容器连接到web1容器,并为连接指定一个别名为web1。 -
centos:7
: 使用CentOS 7镜像。 -
/bin/bash
: 启动容器后执行的命令,这里是启动bash shell。
进入web2容器并ping web1:
docker exec -it web2 bash
这条命令用于进入web2容器的bash shell。
在web2容器内执行:
ping web1
由于使用--link
选项连接了web1容器,并为连接指定了别名web1,web2容器内部可以通过别名web1来访问web1容器。
请注意,虽然容器互联是一种简单的方法,但在较新的Docker版本中,推荐使用用户自定义的Docker网络(User-Defined Bridge Networks)来实现容器之间的通信。这种方法更灵活,而且在网络设置上更为强大。
原文地址:https://blog.csdn.net/qq_51545656/article/details/135500459
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_54809.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!