限制容器运行的资源
限制容器的内存使用
容器的内存包括两部分:物理内存和交换空间(swap)
用户内存限制
-m,--memory:容器可用的最大内存,该值最低为4MB
--memory-swap:允许容器置入磁盘交换空间的内存数量
docker设置用户内存使用的4种方式:
1.对容器内存使用无限制
2.设置内存限制并取消交换空间内存限制
docker run -it -m 300M --memory-swap -1 ubuntu /bin/bash #容器中的进程可以使用300MB内存,并且按需使用尽可能多的交换空间
3.只设置内存限制
docker run -it -m 300M ubuntu /bin/bash
默认情况下,虚拟内存总量--memory-swap将设置为内存大小的两倍
4.同时设置内存和交换空间
docker run -it -m 300M --memory-swap 1G ubuntu /bin/bash
表示容器进程能使用300MB内存和700MB交换空间
内核内存限制
不同于用户内存,内核内存不能交换到磁盘,内核内存无法使用交换空间,容器消耗过多的内核内存可能会导致其阻塞系统服务,内核内存不会完全独立于用户内存,而是在用户内存限制的上下文中限制内核内存
docker run -it -m 500M --kernel-memory 50M ubuntu /bin/bash #设置了用户内存和内核内存,容器进程可以使用共500MB的内存,在500MB的内存中,最多可以使用50MB的内核内存
docker run -it --kernel-memory 50M ubuntu /bin/bash #只设置内核内存限制,容器可以尽可能使用多的内存,但是只可以使用50MB的内核内存
设置内存预留实现软限制
设置内存软限制只是为了确保容器不会长时间消耗过多内存,因为每次内存回收就会缩减容器内存消耗到软限制
--memory-reservation:设置内存预留,是一种内存软限制,允许更大的内存共享
正常情况下,容器可以根据需要尽可能多的使用内存,且只能被-m/--memory所设置的硬限制所约束,设置内存预留后,当docker检测到内存争用或内存不足时,强制容器将其内存限制为预留值
内存预留值应始终低于硬限制,否则硬限制会优先触发,当内存预留值设置为0表示不受限制
作为一个软限制功能,内存预留并不能保证不会超过限制,它的主要目的是确保当内存争用严重时,内存按照预留设置进行分配
docker run -it -m 500M --memory-reservation 200M ubuntu /bin/bash #限制内存为500MB,内存预留值为200MB,当容器内存消耗超过200而小于500MB时,下一次系统内存回收将尝试将容器内存缩减到200MB以下
docker run -it --memory-reservation 1G ubuntu /bin/bash #设置内存软限制为1GB,没有设置硬限制
禁止杀死容器的进程
默认情况下,当发生内存溢出时,内核会杀死容器中的进程
--oom-kill-disable:禁止杀死进程
注意只能在同时设置了-m选项的容器上使用此选项,因为如果未设置-m选项可能会耗尽主机的内存
docker run -it -m 100M --oom-kill-disable ubuntu /bin/bash #设置内存为100MB并禁止杀死容器的进程
docker run -it --oom-kill-disable ubuntu /bin/bash #存在风险,创建的容器会无限制的使用内存,会导致杀死系统进程来释放内存
swappiness限制
在Linux系统中,swappiness值(百分比)越大,表示越积极的使用交换空间,否则表示越积极的使用物理内存
docker run -it --memory-swappiness=0 ubuntu /bin/bash #关闭内存页面交换
限制容器的CPU使用
CPU份额限制
-c(--cpi-shares):将CPU份额权重设置为更高的值,默认值为1024
只有在运行CPU密集型进程才会使用CPU份额权重,实际的CPU时间总数会根据系统上的运行的容器数量变化
可用CPU资源
--cups:指定容器可以使用的的可用CPU资源,其值是一个浮点数,默认是0.000,表示不受限制。例如,如果主机有两个CPU,并且设置了--cups=1.5,则该容器最多可以使用一个半CPU
--cup-period:设置CPU周期以限制CPU的使用,默认的CPU CFS(完全公平调度器)周期为100ms
--cpu-quota:限制容器的CPU使用配额,默认值0表示容器占用百分之百的CPU资源
docker run -it --cpu-period=50000 --cpu-quota=25000 ubuntu /bin/bash
这个命令用--cpus改写,等效命令为:
docker run -it --cpus=0.5 ubuntu /bin/bash
为容器指定CPU或核心
--cpuset-cpus:限制容器可以使用的特定CPU或核心,即允许容器在该CPU或核心上执行
可以用逗号分隔cpu
docker run -it --cpuset-cpus="1,3" ubuntu /bin/bash #表示容器可以在cpu1,cpu3上执行
可以用连字符表示cpu的范围
docker run -it --cpuset-cpus="0-2" ubuntu /bin/bash #表示容器可以在cpu0,cpu1,cpu2上执行
块IO带宽限制
块IO是磁盘的读写
docker可以通过设置权重、限制bit/s和io/s(每秒IO次数)控制容器读写磁盘的带宽
设置块IO权重
--blkio-weight:默认值是500,可设置的范围是10~1000
--blkio-weight-device=“设备名称:权重”
docker run -it --blkio-weight-device "/dev/sda:200" ubuntu
300是默认权重,200是为指定设备设置的权重可覆盖默认权重
docker run -it --blkio-weight 300 --blkio-weight-device "/dev/sda:200" ubuntu
限制设备读写速率
限制每秒读写字节数:
--device-read-bps
docker run -it --device-read-bps /dev/sda:1mb ubuntu #创建一个容器,限制指定设备的读取速率为1MB/s
--device-write-bps
docker run -it --device-write-bps /dev/sda:1mb ubuntu #创建一个容器,限制指定设备的写入速率为1MB/s
限制每秒IO次数:
docker run -it --device-read-iops /dev/sda:1000 ubuntu #创建一个容器,限制它对指定设备的读取速率为每秒IO的次数为1000
写入同理
资源限制的实现机制-控制组
对容器的CPU、内存等进行资源限制具体是由控制组的相应子系统来实现的,例如,memory子系统设定控制组中任务所使用的内存限制
在docker run中使用--cpu-shares其实就是配置控制组,相关的配置保存在/sys/fs/cgroup中
1.启动一个容器,设置内存限额为300MB,CPU权重为512
2.打开另一个终端,获取该容器的完整ID (标号2)
3.查看目录,Linux会为每个正在运行的的容器创建一个Cgroup目录,一容器ID命名 (标号2)
4.每个容器子目录中包含所有与CPU相关的Cgroup配置 (标号3)
查看内存配置与块IO的Cgroup配置
同样的,创建一个centos容器并启动
打开另一个窗口,可以看到centos正在运行,可以查看它的cpu资源配置
动态更改容器的配置
docker update [OPTIONS] CONTAINER [CONTAINER...] #主要容器在主机上使用太多资源,也就是修改的是容器的运行时资源限制
docker update --cpu-shares 512 abef12345 #将一个容器的CPU份额权重改为512
docker update --restart=on-failure:3 abef123455 #更改某容器的重启策略
容器监控
Docker容器监控命令
查看容器中运行的进程信息
docker top CONTAINER [ps OPTIONS]
容器运行时不一定提供/bin/bash终端来交互执行top命令,而且容器中有可能没有top命令
查看容器中正在运行的进程:
选项是指OPTIONS是指Linux的ps命令的选项,可以用于显示特定的信息
可以运行以下命令行脚本来查看所有正在运行的容器中的进程信息:
查看容器系统的使用情况
docker stats [OPTIONS] [CONTAINER...]
--all(-a):显示所有的容器,包括未运行的,默认值显示正在运行的容器
--format:根据指定格式显示内容
--no-stream:仅显示第一条记录(只输出当前的状态)
--no-trunc:不截断输出,显示完整信息
默认情况下,给命令会每隔一秒刷新一次输出的内容,知道按下Ctrl+C退出
8列数据分别为:容器ID、容器名称、CPU使用百分比、使用的内存与最大可用内存、内存使用百分比、网络IO数据、磁盘IO数据和进程ID
docker stats --no-stream #不持续监控,只输出当前状态
docker stats --no-stream 容器名称/容器ID #查看指定容器的资源使用情况
使用cAdvisor监控容器
可以用于分析正在运行的容器的资源占用情况和性能指标,是具有图形界面的Docker容器监控工具。cAdvisor是一个运行时的守护进程,负责收集、聚合、处理和输出正在运行的容器的数据,可以监测到资源隔离参数、历史资源使用和网络统计数据。cAdvisor可以在主机上原生安装,也可以作为Docker容器运行
容器的日志管理
使用docker logs命令查看容器日志
对于一个运行中的容器,Docker 会将日志发送到容器的标准输出设备(STDOUT) 和标准错误设备(STDERR)上,可以将标准输出设备和标准错误设备视为容器的控制台终端。如果容器以前台方式运行,日志会直接输出在当前的终端窗口中。如果以后台方式运行容器,则不能直接看到输出的日志。对于这种情形,可以使用 docker attach 命令连接到后台容器的控制台终端,查看输出的日志。不过这种方法仅用于查看容器日志就没有必要了,因为 Docker 自带的 docker logs 命令专门用于查看容器的日志,其语法格式如下:
docker logs [OPTIONS] CONTAINER
--details:显示更为详细的日志信息
--follow(-f):跟踪日志输出
--since:显示自某个时间开始的所有日志
--tail:仅列出最新的n条日志
--timestamps(-t):显示截止日期
--until:显示到某个截止日期的所有日志
docker logs --since="2024-10-10" --tail=3 容器ID #显示该容器从24年10月10号以来的最新3条日志
配置日志驱动重定向容器的日志记录
容器日志发送到标准输出设备和标准错误设备是Dooker默认的日志行为。实际上,Dooker 提
共了多种日志机制帮助用户从运行的容器中提取日志信息。这些机制被称为日志驱动(logging driver)。Docker 默认的日志驱动是json-file。
配置容器的日志驱动
在启动容器时,可以通过--log-driver 选项将其配置为使用与Docker守护进程不同的日志驱动。
配置日志驱动将容器的日志重定向到Linux日志系统
一直以来,syslog都是Linux标配的日志记录工具,rsyslog是syslog的多线程增强版,也是CentOS7中默认的日志系统。它主要用来收集系统产生的各种日志,日志文件默认放在/var/log/目录下。选择syslog作为日志驱动可将日志输出定向到syslog日志系统,前提是syslog守护进程必须在容器宿主机上运行。例如:
docker run -it --log-driver syslog ubuntu /bin/bash #将该容器的日志记录到syslog文件(centos7是/var/log/messages)
将容器日志记录到 journald:
journald是一个收集并存储日志数据的systemd日志系统服务。它将日志数据存储在带有索引的结构化二进制文件中,便于集中查看和管理,可以使用journalctl命令查看。
选择journald作为日志驱动可将日志输出定向到systemd日志系统,例如:
docker run -it --log-driver journald ubuntu /bin/bash