当前位置: 首页 > news >正文

Docker安全配置

Docker安全及日志管理

文章目录

  • Docker安全及日志管理
    • 资源列表
    • 基础环境
    • 一、Docker安全相关介绍
      • 1.1、Docker容器与虚拟机的区别
        • 1.1.1、隔离与共享
        • 1.1.2、性能与损耗
      • 1.2、Docker存在的安全问题
        • 1.2.1、Docker自身漏洞
        • 1.2.2、Docker源码问题
      • 1.3、Docker架构缺陷与安全机制
        • 1.3.1、容器之间的局域网攻击
        • 1.3.2、DDos攻击耗尽资源
        • 1.3.3、有漏洞的系统调用
        • 1.3.4、共享root用户权限
      • 1.4、Docker安全基线标准
        • 1.4.1、内核级别
        • 1.4.2、主机级别
        • 1.4.3、网络级别
        • 1.4.4、镜像级别
        • 1.4.5、容器级别
        • 1.4.6、其他设置
    • 实例:容器相关的常用安全配置方法
    • 一、Docker TLS通信安全
      • 1.1、创建密钥
      • 1.2、client连接
    • 二、容器最小化
    • 三、Docker RemoteAPI访问控制
    • 四、限制流量转向
    • 五、DockerBenchforSecurity介绍
    • 六、Cgroup资源配置方法
      • 6.1、子系统实现
      • 6.2、使用Stress工具测试CPU和内存
    • 七、CPU周期限制
    • 八、CPUCore控制
    • 九、CPU配额控制参数的混合使用
    • 十、内存限额
    • 十一、Blocklo的限制
    • 十二、bps和iops的限制

资源列表

操作系统配置主机名IP
CentOS 7.92C4Gmaster192.168.93.165
CentOS 7.92C4Gclient192.168.93.166

基础环境

  • 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
  • 关闭安全内核机制
setenforce 0
sed -i "s/^SELINUX=.*/SELINUX=disabled/g" /etc/selinux/config
  • 修改主机名
hostnamectl set-hostname master
hostnamectl set-hostname client
  • 绑定映射关系
cat >> /etc/hosts << EOF
192.168.93.165 master
192.168.93.166 client
EOF

一、Docker安全相关介绍

1.1、Docker容器与虚拟机的区别

1.1.1、隔离与共享
  • 虚拟机通过添加Hypervisor层,虚拟出网卡、内存、CPU等虚拟硬件,再在其上建立虚拟机,每个虚拟机都有自己的系统内核。而Docker容器则是通过隔离的方式,将文件系统、进程、设备、网络等资源进行隔离,再对权限、CPU资源等进行控制,最终让容器之间互不影响,容器无法影响宿主机。容器与宿主机共享内核、文件系统、硬件等资源
1.1.2、性能与损耗
  • 与虚拟机相比,容器资源损耗要少。同样的宿主机下,能够建立容器的数量要比虚拟机多。但是,虚拟机的安全性要比容器稍好,要从虚拟机攻破宿主机或其他虚拟机,需要先攻破Hypervisor层,这是极其困难的。而docker容器与宿主机共享内核、文件系统等资源,更有可能对其他容器、宿主机产生影响

1.2、Docker存在的安全问题

1.2.1、Docker自身漏洞
  • 作为一款应用Docker本身实现上会有代码缺陷。CVE官方记录Docker历史版本公有超过20项漏洞,可参见Docker官方网站。黑客常用的攻击手段主要有代码执行、权限提升、信息泄露、权限绕过等。目前Docker版本更迭非常快,Docker用户最好将Docker升级为最新的版本
1.2.2、Docker源码问题

Docker提供了Docker hub,可以让用户上传创建的镜像,以便其他用户下载,快速搭建环境。但同时也带来了一些安全问题。例如下面三种方式:

(1)、客户上传恶意镜像

  • 如果有客户在制作的镜像中植入木马】后门等恶意软件,那么环境从一开始就已经不安全了,后续更没有什么安全可言

(2)、镜像使用有漏洞的软件

  • Docker hub上能下载的镜像里面,75%的镜像都安装了有漏洞的软件。所以下载镜像后,需要检查里面软件的版本信息,对应的版本是否存在漏洞,并及时更新打上补丁

(3)中间人攻击篡改镜像

  • 镜像在传输的过程中可能被篡改,目前新版本的Docker已经提供了相应的校验机制来预防这个问题

1.3、Docker架构缺陷与安全机制

Docker本身的架构与机制就可能产生问题,例如这样一种攻击场景,黑客已经控制了宿主机上的一些容器,或者获得了通过在公有云上建立容器的方式,然后对宿主机或其他容器发起攻击

1.3.1、容器之间的局域网攻击
  • 主机上的容器之间可以构成局域网,因此针对局域网的ARP欺骗】嗅探、广播风暴等攻击方式更可以用上。所以,在一个主机上部署多个容器需要合理的配置网络,设置iptables规则
1.3.2、DDos攻击耗尽资源
  • Cgroup安全机制就是要防止此类攻击的,不要为单一的容器分配过多的资源即可避免类似问题
1.3.3、有漏洞的系统调用
  • Docker与虚拟机的一个重要的区别就是Docker与宿主机公有一个操作系统内核。一旦宿主机内核存在可以越权或者提权漏洞,尽管Docker使用普通用户执行,在容器被入侵时,攻击者还可以利用内核漏洞跳到宿主机做更多的事情
1.3.4、共享root用户权限
  • 如果以root用户权限运行容器,容器内的root用户也就拥有了宿主机的root权限

1.4、Docker安全基线标准

  • 根据Docker官方文档整理,下面从内核、主机、网络、镜像、容器以及其他等6个方面总结Docker安全基线标准
1.4.1、内核级别
  • 及时更新内核
  • UserNameSpace(容器内的root权限在容器之外处于非高权限状态)
  • Cgroups(对资源的配额和度量)
  • SElinux/AppArmor/GRSEC(控制文件访问权限)
  • Capability(权限划分)
  • Seccomp(限定系统调用)
  • 禁止将容器的命令空间与宿主机进程命令空间共享
1.4.2、主机级别
  • 为容器创建独立分区

  • 仅运行必要的服务

  • 禁止将宿主机上敏感目录映射到容器

  • 对Docker守护进程、相关文件和目录进行审计

  • 设置适当的默认文件描述符数

  • 用户权限为root的Docker相关文件的访问权限应该为644或者更低权限

  • 周期性检查每个主机的容器清单,并清理不必必要的容器

1.4.3、网络级别
  • 通过iptables设定规则实现禁止或允许容器之间网络流量
  • 允许Docker修改iptables
  • 禁止将Docker绑定到其他IP/Port或者UnixSocket
  • 禁止在容器上映射特权端口
  • 容器上只开放所需要的端口
  • 禁止在容器上使用主机网络模式(host)
1.4.4、镜像级别
  • 创建本地镜像仓库服务器
  • 镜像中软件都为最新版本
  • 使用可信镜像文件,并通过安全通道下载
  • 重新构建镜像而非对容器和镜像打补丁
  • 合理管理镜像标签,及时移除不再使用的镜像
  • 使用镜像扫描
  • 使用镜像签名
1.4.5、容器级别
  • 容器最小化,操作系统镜像最小集
  • 容器以单一主进程的方式运行
  • 禁止privileged标记使用特权容器
  • 禁止在容器上运行ssh服务
  • 以只读的方式挂载容器的根目录系统
  • 明确定义属于容器的数据盘符
  • 通过设置no-failure限制容器尝试重启的次数
  • 限制容器中可用的进程数,以方式fork bomb
1.4.6、其他设置
  • 定期对宿主机系统及容器进行安全审计
  • 使用最少资源和最低权限运行容器
  • 避免在同一宿主机上部署大量容器,维持一个能够管理的数量
  • 监控Docker容器的使用,性能以及其他各项指标
  • 增加实时 威胁检测和事件响应功能
  • 使用中心和远程日志收集服务

实例:容器相关的常用安全配置方法

一、Docker TLS通信安全

  • 按照Docker官方的说法,为了防止链劫持、会话劫持等问题导致Docker通信时被中间人攻击,c/s两端应该通过加密的方式通讯

1.1、创建密钥

hostnamectl set-hostname master
[root@master ~]# mkdir /tls
[root@master ~]# cd /tls/
[root@master tls]# echo "127.0.0.1 master" >> /etc/hosts
# 使用OpenSSL创建CA、服务器的端口段密钥
[root@master tls]# openssl genrsa -aes256 -out ca-key.pem 4096
Generating RSA private key, 4096 bit long modulus
...................++
...........................................................................................................................++
e is 65537 (0x10001)
Enter pass phrase for ca-key.pem:	 # 密码123123
Verifying - Enter pass phrase for ca-key.pem:   # 确定密码[root@master tls]# openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem
Enter pass phrase for ca-key.pem:	# 输入刚刚的密码123123
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:HN
Locality Name (eg, city) [Default City]:ZhengZhou
Organization Name (eg, company) [Default Company Ltd]:kgc
Organizational Unit Name (eg, section) []:kgc
Common Name (eg, your name or your server's hostname) []:master
Email Address []:[root@master tls]# openssl genrsa -out server-key.pem 4096
Generating RSA private key, 4096 bit long modulus
......................................................................................................++
..................................................................................................................++
e is 65537 (0x10001)[root@master tls]# openssl req -subj "/CN=master" -sha256 -new -key server-key.pem -out server.csr# 由于可以通过IP地址贺DNS名称进行TLS连接,因此IP地址需要在创建证书时指定,例如,允许连接的IP为127.0.0.1、192.168.93.166
[root@master tls]# echo subjectAltName = DNS:master,IP:192.168.93.165,IP:127.0.0.1 >> extfile.cnf
# 将Docker守护程序密钥的扩展用法属性设置为仅用于服务器身份验证
[root@master tls]# echo extendedKeyUsage = serverAuth >> extfile.cnf# 生成签名证书
[root@master tls]# openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile extfile.cnf
Signature ok
subject=/CN=master
Getting CA Private Key
Enter pass phrase for ca-key.pem:[root@master tls]# openssl genrsa -out key.pem 4096
Generating RSA private key, 4096 bit long modulus
.....................................................................................................................................................++
...........................................................................................................................................................................................................................................................................................++
e is 65537 (0x10001)[root@master tls]# openssl req -subj '/CN=client' -new -key key.pem -out client.csr
[root@master tls]# echo extendedKeyUsage = clientAuth > extfile-client.cnf# 生成签名证书
[root@master tls]# openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfile extfile-client.cnf
Signature ok
subject=/CN=client
Getting CA Private Key
Enter pass phrase for ca-key.pem:# 生成后,可以安全地删除两个证书签名请求贺扩展配置文件
[root@master tls]# rm -rf client.csr server.csr extfile.cnf extfile-client.cnf# 为了数据的安全,进行对密钥的权限更改
[root@master tls]# chmod -v 0400 ca-key.pem key.pem server-key.pem
[root@master tls]# chmod -v 0444 ca.pem server-cert.pem cert.pem# 把密钥上传到client
[root@master tls]# scp ca.pem root@192.168.93.166:/etc/docker/
[root@master tls]# scp cert.pem root@192.168.93.166:/etc/docker/
[root@master tls]# scp key.pem root@192.168.93.166:/etc/docker/# 重新启动docker开启TLS认证加密
## 方法1:
[root@master tls]# vim /lib/systemd/system/docker.service 
ExecStart=/usr/bin/dockerd --tlsverify --tlscacert=/tls/ca.pem --tlscert=/tls
/server-cert.pem --tlskey=/tls/server-key.pem -H tcp://0.0.0.0:2376 -H unix:/
//var/run/docker.sock
#ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
[root@master tls]# systemctl daemon-reload 
[root@master tls]# systemctl restart docker## 方法2:
[root@master tls]# systemctl stop docker
[root@master tls]# dockerd --tlsverify --tlscacert=ca.pem --tlscert=server-cert.pem --tlskey=server-key.pem -H=0.0.0.0:2376

1.2、client连接

hostnamectl set-hostname client
[root@client ~]# vim /etc/hosts
192.168.93.165 master
[root@client ~]# cd /etc/docker/
# 使用密钥连接master并查看master的docker版本
[root@client docker]# docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H=master:2376 version
Client: Docker Engine - CommunityVersion:           26.1.2API version:       1.45Go version:        go1.21.10Git commit:        211e74bBuilt:             Wed May  8 14:01:02 2024OS/Arch:           linux/amd64Context:           defaultServer: Docker Engine - CommunityEngine:Version:          26.1.2API version:      1.45 (minimum version 1.24)Go version:       go1.21.10Git commit:       ef1912dBuilt:            Wed May  8 13:59:55 2024OS/Arch:          linux/amd64Experimental:     falsecontainerd:Version:          1.6.31GitCommit:        e377cd56a71523140ca6ae87e30244719194a521runc:Version:          1.1.12GitCommit:        v1.1.12-0-g51d5e94docker-init:Version:          0.19.0GitCommit:        de40ad0

二、容器最小化

  • 如果仅在容器中运行必要的服务,像SSH等服务是不能轻易开启去连接容器的。通常使用以下方式来进入容器
[root@master ~]# docker exec -it 容器名称 bash

三、Docker RemoteAPI访问控制

  • Docker的远程调用API接口存在未授权访问漏洞,至少应显示外网访问。建议使用Socket方式访问
# docker.scok是daemon监听的套接字,容器中的进程可以通过它与docker daemon通信
[root@master ~]# dockerd -H unix:///var/run/docker.sock[root@master ~]# vim /usr/lib/systemd/system/docker.service
# 进行修改即可
ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://192.168.93
.165:2375
[root@master ~]# systemctl daemon-reload 
[root@master ~]# systemctl restart docker
[root@master ~]# netstat -anpt | grep docker
tcp        0      0 192.168.93.165:2375     0.0.0.0:*               LISTEN      13281/dockerd
  • 然后在宿主机的firewalld上做IP访问控制即可。(source address 是客户端地址)
[root@master ~]# systemctl start firewalld# 添加防火墙富规则
[root@master ~]# firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="192.168.93.166" port protocol="tcp" port="2375" accept"
success# 刷新防火墙
[root@master ~]# firewall-cmd --reload
success
  • 然后在客户端192.168.93.166上即授权访问控制
# 在客户端控制服务端拉去一个nginx镜像
[root@client ~]# docker -H=tcp://192.168.93.165:2375 pull nginx# 在服务端查看是否有nginx镜像
[root@master ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED      SIZE
nginx        latest    4f67c83422ec   3 days ago   188MB

四、限制流量转向

  • 使用防火墙过滤器限制Docker容器的源IP地址范围与外界通信
# 拒绝10.0网段的主机与服务器通信
[root@master ~]# firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.10.0/24" reject"

五、DockerBenchforSecurity介绍

  • Docker Bench for Security是一个脚本,它是在生产环境中常见的检测检查部署Docker容器的最佳安全实现,测试都是自动化的,受CIS Docker 1.13基准的启发而来
  • 要使用docker-slim,从Github下载其二进制文件。二进制文件可用于Linux和Mac。下载二进制文件后,将其添加到环境变量PATH中
[root@master ~]# yum -y install git
[root@master ~]# git clone https://github.com/docker/docker-bench-security.git
Cloning into 'docker-bench-security'...
remote: Enumerating objects: 2726, done.
remote: Counting objects: 100% (804/804), done.
remote: Compressing objects: 100% (242/242), done.
remote: Total 2726 (delta 611), reused 634 (delta 554), pack-reused 1922
Receiving objects: 100% (2726/2726), 4.46 MiB | 1.50 MiB/s, done.
Resolving deltas: 100% (1889/1889), done.
[root@master ~]# cd docker-bench-security/
[root@master docker-bench-security]# sh docker-bench-security.sh
##################################################################
# --------------------------------------------------------------------------------------------
# Docker Bench for Security v1.6.0
#
# Docker, Inc. (c) 2015-2024
#
# Checks for dozens of common best-practices around deploying Docker containers in production.
# Based on the CIS Docker Benchmark 1.6.0.
# --------------------------------------------------------------------------------------------Initializing 2024-06-02T06:50:17-04:00Section A - Check results[INFO] 1 - Host Configuration
[INFO] 1.1 - Linux Hosts Specific Configuration
[DEPRECATION NOTICE]: API is accessible on http://192.168.93.165:2375 without encryption.Access to the remote API is equivalent to root access on the host. Referto the 'Docker daemon attack surface' section in the documentation formore information: https://docs.docker.com/go/attack-surface/
In future versions this will be a hard failure preventing the daemon from starting! Learn more at: https://docs.docker.com/go/api-security/
[WARN] 1.1.1 - Ensure a separate partition for containers has been created (Automated)
[INFO] 1.1.2 - Ensure only trusted users are allowed to control Docker daemon (Automated)
[INFO]       * Users: 
[WARN] 1.1.3 - Ensure auditing is configured for the Docker daemon (Automated)Section C - Score[INFO] Checks: 86
[INFO] Score: -2
# 部分内容省略
################################################################### 输出结果中,带有不同的级别,说明问题的严重程度,最后会给出整体检查结果和评分
1、标红[WARN]是需要调整
2、标绿[PASS]表示通过检测
3[INFO]可根据实际需要确定是否进行调整
# 一般要尽量避免出现WARN或以上的问题

六、Cgroup资源配置方法

  • Docker通过Cgroup来控制容器使用的资源配额,包括CPU、内存、磁盘三大方面,基本覆盖了常见的资源配额和使用量控制
  • Cgroup是ControlGroups的缩写,是Linux内核提供的一种可以限制、记录、隔离进程组所使用的物理资源(如CPU、内存、磁盘IO等等)的机制,被LXC、docker等很多项目用于实现进程资源控制。Cgroup本身是提供将进程分组话管理的功能和接口的基础结构,I/O或内存的分配控制等具体的资源管理是通过该功能来实现的。这些具体的资源管理功能称为Cgroup子系统

6.1、子系统实现

  • blkio:设置限制每个块设备的输入输出控制。例如:磁盘,光盘以及usb等等
  • CPU:使用调度程序为cgroup任务提供CPU的访问
  • cpuacct:产生cgroup任务的CPU资源报告
  • cpuset:如果是多核心的CPU,这个子系统会为cgroup任务分配单独的CPU和内存
  • devices:允许或拒绝cgroup任务对设备的访问
  • freezer:暂停和恢复cgroup任务
  • memory:设置每个cgroup的内存限制以及生产内存资源报告
  • net_cls:标记每个网络包以供cgroup方便使用
  • ns:命令空间子系统
  • perf_event:增加了对每个group的监测跟踪的能力,可以监测属于某个特定的group的所有线程以及运行在特定CPU上的线程

6.2、使用Stress工具测试CPU和内存

  • 使用Dockerfile来创建一个基于CentOS的stress工具镜像
root@master ~]# docker pull centos:7
[root@master ~]# mkdir /root/stress
[root@master ~]# cat /root/stress/Dockerfile
FROM centos:7
MAINTAINER Wzh
RUN yum -y install wget
RUN wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
RUN wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
RUN yum -y install stress
[root@master ~]# cd /root/stress/
[root@master stress]# docker build -t centos:stress .
  • 使用如下命令创建容器,命令中的–cpu-shares参数值不能保证可以获得1个vcpu或者多少GHz的CPU资源,它仅是一个弹性的加权值,值越大或者分配的资源就越多
[root@master stress]# docker run -itd --cpu-shares 100 centos:stress
  • Cgroups只在容器分配的资源紧缺时,即在需要对容器的资源进行限制时,才会生效。因此,无法单纯根据某个容器的CPU份额来确定有多少CPU资源分配给它,资源分配结果取决于同时运行的其他容器的CPU分配和容器中进程运行情况
  • 可以通过cpushare可以设置容器使用CPU的优先级,比如启动了两个容器及运行查看CPU百分比
 # stress -c 10向容器中开启10个进程用于测试
[root@master stress]# docker run -itd --name cpu512 --cpu-shares 512 centos:stress stress -c 10# 进入容器使用top查看资源咱占用情况
[root@master ~]# docker exec -it cpu512 bash
[root@5a30bc38e2d9 /]# top
top - 11:26:33 up 10 min,  0 users,  load average: 7.89, 2.69, 0.98
Tasks:  13 total,  11 running,   2 sleeping,   0 stopped,   0 zombie
%Cpu(s): 98.8 us,  1.2 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0
KiB Mem :  3861260 total,  2380572 free,   312972 used,  1167716 buff/cache
KiB Swap:  4063228 total,  4063228 free,        0 used.  3302036 avail Mem PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND9 root      20   0    7312     96      0 R  20.3  0.0   0:17.46 stress 12 root      20   0    7312     96      0 R  20.3  0.0   0:17.62 stress 13 root      20   0    7312     96      0 R  20.3  0.0   0:18.17 stress 6 root      20   0    7312     96      0 R  19.9  0.0   0:17.96 stress 7 root      20   0    7312     96      0 R  19.9  0.0   0:17.58 stress 8 root      20   0    7312     96      0 R  19.9  0.0   0:17.66 stress 15 root      20   0    7312     96      0 R  19.9  0.0   0:17.59 stress 10 root      20   0    7312     96      0 R  19.6  0.0   0:17.47 stress 11 root      20   0    7312     96      0 R  19.6  0.0   0:17.58 stress 14 root      20   0    7312     96      0 R  19.6  0.0   0:18.16 stress 1 root      20   0    7312    624    528 S   0.0  0.0   0:00.01 stress 16 root      20   0   11828   1896   1492 S   0.0  0.0   0:00.01 bash   30 root      20   0   56192   2012   1444 R   0.0  0.1   0:00.00 top    
  • 下面设置CPU资源份额翻倍
[root@master ~]# docker run -itd --name cpu1024 --cpu-shares 1024 centos:stress stress -c 10
[root@master ~]# docker exec -it cpu1024 bash
[root@dc64e7513c1f /]# top
top - 11:28:19 up 12 min,  0 users,  load average: 13.22, 5.74, 2.24
Tasks:  13 total,  11 running,   2 sleeping,   0 stopped,   0 zombie
%Cpu(s):100.0 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0
KiB Mem :  3861260 total,  2369580 free,   323532 used,  1168148 buff/cache
KiB Swap:  4063228 total,  4063228 free,        0 used.  3291300 avail Mem PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND7 root      20   0    7312     92      0 R  14.2  0.0   0:03.71 stress 13 root      20   0    7312     92      0 R  14.2  0.0   0:03.68 stress 15 root      20   0    7312     92      0 R  14.2  0.0   0:03.50 stress 14 root      20   0    7312     92      0 R  13.9  0.0   0:03.51 stress 9 root      20   0    7312     92      0 R  12.9  0.0   0:03.32 stress 10 root      20   0    7312     92      0 R  12.6  0.0   0:03.32 stress 12 root      20   0    7312     92      0 R  12.6  0.0   0:03.29 stress 11 root      20   0    7312     92      0 R  12.3  0.0   0:03.31 stress 16 root      20   0    7312     92      0 R  12.3  0.0   0:03.33 stress 8 root      20   0    7312     92      0 R  11.9  0.0   0:03.31 stress 1 root      20   0    7312    620    528 S   0.0  0.0   0:00.01 stress 17 root      20   0   11828   1904   1496 S   0.0  0.0   0:00.01 bash   31 root      20   0   56192   2012   1444 R   0.0  0.1   0:00.00 top    # 可以看容器512CPU占用率要比1024高

七、CPU周期限制

Docker提供了–cpu-period、–cpu-quota两个参数控制容器可以分配到CPU时钟周期

  • –cpu-period:是用来指定容器对CPU的使用要在多长事件内做一次重新分配

  • –cpu-quota:是用来指定在这个周期内,最多可以有多少时间跑这个容器。与–cpu-shares不同的是,这种配置是指定一个绝对值,容器对CPU资源的使用绝对不会超过配置的值

  • cpu-period和cpu-quota的单位为微秒(us)。cpu-period的最小值为1000微妙,最大值为1秒。默认值为0.1秒。cpu-quota的值默认为-1,表示不做控制。cpu-period和cpu-quota参数一般联合使用

# 例如:容器进程需要每1秒使用单个CPU的0.2秒时间,可以将cpu-period设置为1000000(即1秒),cpu-quota设置为200000(0.2秒)
[root@master ~]# docker run -itd --cpu-period 1000000 --cpu-quota 200000 centos:stress 
[root@master ~]# docker exec -it condescending_spence bash
[root@3d0f9e29cc61 /]# cat /sys/fs/cgroup/cpu/cpu.cfs_period_us 
1000000
[root@3d0f9e29cc61 /]# cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us 
200000

八、CPUCore控制

  • 对于多核CPU的服务器,Docker还可以控制容器运行使用哪些CPU内核,即使用–cpuset-cpus参数,这对具有多CPU的服务器尤其有用,可以对需要高性能计算的容器进行性能最优的配置
# 只允许这个容器使用0、1两个内核
[root@master ~]# docker run -itd --name cpu1 --cpuset-cpus 0-1 centos:stress
[root@master ~]# docker exec -it cpu1 bash
[root@ea4cd6c80f5e /]# cat /sys/fs/cgroup/cpuset/cpuset.cpus
0-1

九、CPU配额控制参数的混合使用

  • 通过cpuset-cpus参数指定容器A使用CPU内核0,容器B使用CPU内核1
[root@master ~]# docker run -itd --name cpu3 --cpuset-cpus 1 --cpu-shares 512 centos:stress stress -c 1
[root@master ~]# docker exec -it cpu3 bash
[root@3a197567bf58 /]# top
top - 11:52:58 up 37 min,  0 users,  load average: 20.67, 20.14, 16.51
Tasks:   4 total,   2 running,   2 sleeping,   0 stopped,   0 zombie
%Cpu(s):100.0 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0
KiB Mem :  3861260 total,  2333408 free,   357196 used,  1170656 buff/cache
KiB Swap:  4063228 total,  4063228 free,        0 used.  3256448 avail Mem PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND7 root      20   0    7312     96      0 R  54.8  0.0   0:32.37 stress 1 root      20   0    7312    424    344 S   0.0  0.0   0:00.00 stress 8 root      20   0   11828   1900   1496 S   0.0  0.0   0:00.01 bash   22 root      20   0   56192   2000   1444 R   0.0  0.1   0:00.00 top  [root@master ~]# docker run -itd --name cpu4 --cpuset-cpus 1 --cpu-shares 1024 centos:stress stress -c 1
[root@master ~]# docker exec -it cpu4 bash
[root@080ee5432922 /]# top
top - 11:56:33 up 40 min,  0 users,  load average: 21.80, 20.81, 17.52
Tasks:   4 total,   2 running,   2 sleeping,   0 stopped,   0 zombie
%Cpu(s):100.0 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0
KiB Mem :  3861260 total,  2325228 free,   364704 used,  1171328 buff/cache
KiB Swap:  4063228 total,  4063228 free,        0 used.  3248516 avail Mem PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND7 root      20   0    7312     96      0 R  66.7  0.0   0:16.50 stress 1 root      20   0    7312    424    344 S   0.0  0.0   0:00.01 stress 8 root      20   0   11828   1896   1496 S   0.0  0.0   0:00.01 bash   22 root      20   0   56192   1964   1428 R   0.0  0.1   0:00.00 top   
# 上面的centos:stress镜像安装了stress工具,用来测试CPU和内存的负载。通过在两个容器上分别执行stress -c 1命令,将会给系统一个随机负载,产生1个进程,这个进程都反复不停的计算有rand()产生随机数的平方根,知道资源耗尽

十、内存限额

与操作系统类似,容器可使用的内存包括两部分:物理内存和Swap。Docker通过下面两组参数来控制容器内存的使用量

  • -m或–memory:设置内存的使用限额,例如100M、1024M
  • –memory-swap:设置内存+swap的使用限额
# 执行如下命令允许该容器最多使用200M的内存和不能超过300的swap(swap100内存)
[root@master ~]# docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 280M
stress: info: [1] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] --> hogvm worker 1 [7] forked
stress: dbug: [7] allocating 293601280 bytes ...
stress: dbug: [7] touching bytes in strides of 4096 bytes ...
stress: dbug: [7] freed 293601280 bytes
stress: dbug: [7] allocating 293601280 bytes ...
stress: dbug: [7] touching bytes in strides of 4096 bytes ...
stress: dbug: [7] freed 293601280 bytes
stress: dbug: [7] allocating 293601280 bytes ...
stress: dbug: [7] touching bytes in strides of 4096 bytes ...
stress: dbug: [7] freed 293601280 bytes
stress: dbug: [7] allocating 293601280 bytes ...
stress: dbug: [7] touching bytes in strides of 4096 bytes ...
--vm 1:启动1个内存工作线程
--vm-bytes 280M:每个线程分配280内存# 默认情况下,容器可以使用主机上的所有空闲内存。与CPU的cgroups配置类似,Docker会自动为容器在目录/sys/fs/cgroup/memory/docker<容器的完整长度 ID>中创建相应cgroup配置文件# 因为280M在可分配的范围(300M)内,所以工作线程能够正常工作,其工作过程是
分配280M内存
释放280M内存
再分配280M内存
再释放280M内存
一直循环# 如果让工作线程分配的内存超过300M,分配的内存超过限制,stress线程报错,容器退出
[root@master ~]# docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 310M
stress: info: [1] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] --> hogvm worker 1 [7] forked
stress: dbug: [7] allocating 325058560 bytes ...
stress: dbug: [7] touching bytes in strides of 4096 bytes ...
stress: FAIL: [1] (416) <-- worker 7 got signal 9
stress: WARN: [1] (418) now reaping child worker processes
stress: FAIL: [1] (422) kill error: No such process
stress: FAIL: [1] (452) failed run completed in 0s

十一、Blocklo的限制

  • 默认情况下,所有容器能平等地读写磁盘,可以通过设置–blkio-weight参数来改变容器的vlock IO的优先级
  • –blkio-weigit与–cpu-shares类似,设置的是相对权重值,默认为500。在下面的例子中,容器A读写磁盘的宽带是容器B的两倍
[root@master ~]# docker run -it --name IO_A --blkio-weight 600 centos:stress [root@c3d24510ba18 /]# cat /sys/fs/cgroup/blkio/blkio.weight
600[root@master ~]# docker run -it --name IO_B --blkio-weight 300 centos:stress
[root@5f98b4ad5a2a /]# cat /sys/fs/cgroup/blkio/blkio.weight
300

十二、bps和iops的限制

  • bps是byte per second,每秒读写的数据量。iops是io per second,每秒的IO的次数
  • 可以通过以下参数控制容器的bps和iops
--device-read-bps:限制读某个设备的bps
--device-write-bsp:限制写某个设备的bps
--device-read-iops:限制某个设备的iops
--device-write-iops:限制写某个设备的iops# 下面的示例是显示容器写/dev/sda的速率为5MB/s
[root@master ~]# docker run -it --device-write-bps /dev/sda:5MB centos:stress
# 输出完时间为20秒左右
[root@4775b55a6f0b /]# dd if=/dev/zero of=test bs=1M count=100 oflag=direct 
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 20.0017 s, 5.2 MB/s# 不限速,不限速时间还没1秒就输出完毕了
[root@master ~]# docker run -it centos:stress
[root@ee280332da35 /]# dd if=/dev/zero of=test bs=1M count=100 oflag=direct
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 0.0775017 s, 1.4 GB/s# 通过dd命令测试在容器中写磁盘的速度。因为容器的文件系统是在host/dev/sda上的,在容器中写文件相当于对host/dev/sda进行写操作。另外,oflag=direct指定用direct IO方式写文件,这样--device-weite-bps才能生效

相关文章:

Docker安全配置

Docker安全及日志管理 文章目录 Docker安全及日志管理资源列表基础环境一、Docker安全相关介绍1.1、Docker容器与虚拟机的区别1.1.1、隔离与共享1.1.2、性能与损耗 1.2、Docker存在的安全问题1.2.1、Docker自身漏洞1.2.2、Docker源码问题 1.3、Docker架构缺陷与安全机制1.3.1、…...

文件上传之使用一个属性接收多个文件

在开发过程中&#xff0c;可能遇到这样的业务&#xff1a;文件上传时个数不定&#xff0c;这样我们不能枚举出所有的文件name&#xff0c;这种情况下我们可以使用一个name将所有的文件接收下来&#xff1b; html代码 <!DOCTYPE html> <html lang"en"> …...

chat4-Server端保存聊天消息到mysql

本文档描述了Server端接收到Client的消息并转发给所有客户端或私发给某个客户端 同时将聊天消息保存到mysql 服务端为当前客户端创建一个线程&#xff0c;此线程接收当前客户端的消息并转发给所有客户端或私发给某个客户端同时将聊天消息保存到mysql 本文档主要总结了将聊天…...

vivo鄢楠:基于OceanBase 的降本增效实践

在3 月 20 日的2024 OceanBase 数据库城市行中&#xff0c;vivo的 体系与流程 IT 部 DBA 组总监鄢楠就“vivo 基于 OceanBase 的降本增效实践”进行了主题演讲。本文为该演讲的精彩回顾。 vivo 在1995年于中国东莞成立&#xff0c;作为一家全球领先的移动互联网智能终端公司&am…...

arm cortex-m架构 SVC指令详解以及其在freertos的应用

1. 前置知识 本文基于arm cortex-m架构描述&#xff0c; 关于arm cortex-m的一些基础知识可以参考我另外几篇文章&#xff1a; arm cortex-m 架构简述arm异常处理分析c语言函数调用规范-基于arm 分析 2 SVC指令 2.1 SVC指令位域表示 bit15 - bit12&#xff1a;条件码&#…...

k8s笔记——kubernetes中的三种IP

kubernetes概念 Master&#xff1a;集群控制节点&#xff0c;每个集群需要至少一个master节点负责集群的管控 Node&#xff1a;工作负载节点&#xff0c;由master分配容器到这些node工作节点上&#xff0c;然后node节点上的docker负责容器的运行 Pod&#xff1a;kubernetes的…...

Golang | Leetcode Golang题解之第127题单词接龙

题目&#xff1a; 题解&#xff1a; func ladderLength(beginWord string, endWord string, wordList []string) int {wordId : map[string]int{}graph : [][]int{}addWord : func(word string) int {id, has : wordId[word]if !has {id len(wordId)wordId[word] idgraph a…...

微服务中feign远程调用相关的各种超时问题

1. 引言 在spring cloud微服中&#xff0c;feign远程调用可能是大家每天都接触到东西&#xff0c;但很多同学却没咋搞清楚这里边的各种超时问题&#xff0c;生产环境可能会蹦出各种奇怪的问题。 首先说下结论&#xff1a; 1)只使用feign组件&#xff0c;不使用ribbion组件&…...

springboot整合chatgpt,并且让其可以记录上下文

整合很简单&#xff0c;不过需要几个小条件 1.必须要有openai官方的key 2.国内需要有代理服务器或者国外的服务器把项目部署出去也没问题 我没有使用spring的springAI&#xff0c;听说很方便&#xff0c;日后有机会去体验体验&#xff0c;我今天用了两种方式整合了gpt 1.Ch…...

CTP前端:解码数字世界的魔法师

CTP前端&#xff1a;解码数字世界的魔法师 CTP前端&#xff0c;一个充满神秘与魅力的职业&#xff0c;他们在数字世界中挥舞着魔法棒&#xff0c;创造着令人惊叹的奇迹。那么&#xff0c;CTP前端究竟是做什么的呢&#xff1f;让我们从四个方面、五个方面、六个方面和七个方面&…...

rabbitmq的交换机类型以及他们的区别

RabbitMQ中有四种主要的交换机类型&#xff0c;它们是&#xff1a;Direct&#xff0c;Topic&#xff0c;Fanout&#xff0c;Headers。 Direct&#xff08;直连交换机&#xff09;&#xff1a;接收到消息后&#xff0c;会将消息发送到与消息的routing key完全匹配的队列上。Dire…...

理解不同层的表示(layer representations)

在机器学习和深度学习领域&#xff0c;特别是在处理音频和自然语言处理&#xff08;NLP&#xff09;任务时&#xff0c;"层的表示"&#xff08;layer representations&#xff09;通常是指神经网络不同层在处理输入数据时生成的特征或嵌入。这些表示捕获了输入数据的…...

原生js访问http获取数据的方法

在原生JavaScript中&#xff0c;直接通过浏览器端的JavaScript访问HTTP接口获取数据通常涉及XMLHttpRequest对象或现代的fetch API。 1. 使用XMLHttpRequest XMLHttpRequest是一个老旧的API&#xff0c;但在某些情况下仍然很有用。以下是一个简单的例子&#xff1a; javascr…...

Windows 2000 Server:安全配置终极指南

"远古技术&#xff0c;仅供娱乐" &#x1f4ad; 前言&#xff1a;Windows 2000 服务器在当时的市场中占据了很大的比例&#xff0c;主要原因包括操作简单和易于管理&#xff0c;但也经常因为安全性问题受到谴责&#xff0c;Windows 2000 的安全性真的那么差吗&#x…...

基于 FastAI 文本迁移学习的情感分类(93%+Accuracy)

前言 系列专栏:【深度学习:算法项目实战】✨︎ 涉及医疗健康、财经金融、商业零售、食品饮料、运动健身、交通运输、环境科学、社交媒体以及文本和图像处理等诸多领域,讨论了各种复杂的深度神经网络思想,如卷积神经网络、循环神经网络、生成对抗网络、门控循环单元、长短期记…...

集成Google Authenticator实现多因素认证(MFA)

目录 参考1、应用背景2、多因素认证3、谷歌google authenticator集成用法3.1、原理3.2、 MFA绑定3.2.1、 用户输入用户名密码登录3.2.2、检查是否已经绑定MFA&#xff08;检查数据库是否保存该用户的google secret&#xff09;3.2.3、谷歌身份证认证器扫描绑定3.2.4、手动测试验…...

网关(Gateway)- 自定义过滤器工厂

自定义过滤工厂类 DemoGatewayFilterFactory package com.learning.springcloud.custom;import org.apache.commons.lang.StringUtils; import org.springframework.cloud.gateway.filter.GatewayFilter; import org.springframework.cloud.gateway.filter.GatewayFilterChai…...

HTML静态网页成品作业(HTML+CSS)—— 香奈儿香水介绍网页(1个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有1个页面。 二、作品演示 三、代…...

C++11 lambda表达式和包装器

C11 lambda表达式和包装器 一.lambda表达式1.lambda表达式的引入2.基本语法和使用1.基本语法2.使用1.传值捕捉的错误之处2.传引用捕捉 3.lambda表达式的底层原理4.lambda的特殊之处5.lambda配合decltype的新玩法 二.function包装器1.概念2.包装函数1.包装普通函数2.包装成员函数…...

3. MySQL 数据表的基本操作

文章目录 【 1. MySQL 创建数据表 】【 2. MySQL 查看表 】2.1 查看表的属性DESCRIBE/DESC 以表格的形式展示表属性SHOW CREATE TABLE 以SQL语句的形式展示表属性 2.2 查看表的内容 【 3. MySQL 修改数据表结构 】3.1 修改表名3.2 修改表字符集3.3 添加字段在末尾添加字段在开头…...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误&#xff0c;它们的含义、原因和解决方法都有显著区别。以下是详细对比&#xff1a; 1. HTTP 406 (Not Acceptable) 含义&#xff1a; 客户端请求的内容类型与服务器支持的内容类型不匹…...

golang循环变量捕获问题​​

在 Go 语言中&#xff0c;当在循环中启动协程&#xff08;goroutine&#xff09;时&#xff0c;如果在协程闭包中直接引用循环变量&#xff0c;可能会遇到一个常见的陷阱 - ​​循环变量捕获问题​​。让我详细解释一下&#xff1a; 问题背景 看这个代码片段&#xff1a; fo…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

【论文笔记】若干矿井粉尘检测算法概述

总的来说&#xff0c;传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度&#xff0c;通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...

分布式增量爬虫实现方案

之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面&#xff0c;避免重复抓取&#xff0c;以节省资源和时间。 在分布式环境下&#xff0c;增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路&#xff1a;将增量判…...