私有云:(9)OpenStack平台安全管理与优化案例
案例描述
本案例讲述了多个Linux系统调优的例子。具体如下:
(1)OpenStack平台内存优化;
(2)Linux系统调优。
案例一:OpenStack平台内存优化
规划节点
节点规划见表1-1。
表1-1 节点规划
IP | 主机名 | 节点 |
---|---|---|
192.168.200.21 | controller | 实验节点 |
基础准备
登录物理OpenStack平台,使用CentOS 7.9镜像创建云主机,云主机类型使用1VCPU/2GB内存/20GB硬盘。创建后的云主机作为本次案例的实验节点。
案例实施
Linux内存大页介绍
随着业务和计算机硬件技术不断发展,出现越来越大的内存机器(≥700G),满足复杂计算处理需求,同时Linux内核的同步持续迭代升级,操作系统可以支持现代硬件架构的大页面容量功能,以适应越来越大的系统内存。
在云上大规模机器集群中,传统内存页面管理机制存在一定的性能问题,以典型推荐系统服务为例,一方面单次请求产生的中间数据规模较大,另一方面程序广泛应用了本地词典&缓存等技术,这使响应单次请求所需要涉及的内存访存范围显著增大。通过perf统计线上部分典型程序的dtlb_load_misses.walk_active和dtlb_store_misses.walk_active的占比,也观测到页表缓存命中率不足的表现,平均观测大多程序有5%-10%的时间周期存在未命中导致陷入Page Walk的现象。
目前在机器硬件大内存和系统内核技术都具备情况下,透明大页(Transparent Huge Page)内存管理应用成为可能。通过增大页面大小,预期可以显著解决页表缓存命中不足的现象,进而普遍提升程序性能。但是由于存在若干缺陷,主要集中在内存用量显著上涨、频繁回收重整带来额外开销增加以及不可控的随机卡顿。基于这些因素,目前业界对透明大页机制的一般认知均偏负向,排查问题追到透明大页,尚无确切结论说明对服务影响情况,这也是应用透明大页技术一道难题。
内存大页技术演进
内存作为计算机上非常重要的一种资源,程序加载运行、CPU指令和数据获取等都依赖内存使用,因此内存访问性能是影响计算机性能的一个很重要的因素。现代Linux系统上内存的分配主要过程如下:
(1)应用程序通过调用内存分配函数(malloc, free, realloc, calloc),系统调用brk或者mmap进行内存分配,申请虚拟内存地址空间。
(2)虚拟内存至物理内存映射处理过程,通过请求MMU分配单元,根据虚拟地址计算出该地址所属的页面,再根据页面映射表的起始地址计算出该页面映射表(PageTable)项所在的物理地址,根据物理地址在高速缓存的TLB中寻找该表项的内容,如果该表项不在TLB中,就从内存将其内容装载到TLB中。包含如下:
- 虚拟内存(Virtual Memory):现代操作系统普遍使用的一种技术,每个进程有用独立的逻辑地址空间,内存被分为大小相等的多个块,称为页(Page)。每个页都是一段连续的地址,对应物理内存上的一块称为页框,通常页和页框大小相等。
- MMU(Memory-Management Unit):内存管理单元,负责管理虚拟地址到物理地址的内存映射,实现各个用户进程都拥有自己的独立的地址空间,提供硬件机制的内存访问权限检查,保护每个进程所用的内存不会被其他的进程所破坏。
- PageTable: 虚拟内存至物理内存页面映射关系存储单元。
- TLB(Translation Lookaside Buffer):高速虚拟地址映射缓存, 主要为了提升MMU地址映射处理效率,加了缓存机制,如果存在即可直接取出映射地址供使用。
标准大页(HugePage)
标准大页Huge pages 通过提升单位页面的大小,替代传统的 4 KB 内存页面,以适应越来越大的系统内存,让操作系统可以支持现代硬件架构的大页面容量功能,降低MMU管理开销,提升内存处理性能。主要有两种格式大小——2MB 和1GB ,2MB块大小适合GB 大小的内存, 1GB 页块大小适合用于 TB 级别的内存;2 MB 是默认的页大小。
优点:
- 无需交换:不存在页面由于内存空间不足而换入换出的问题。
- 减轻 TLB Cache 的压力:相同的内存大小,管理的虚拟地址数量变少,降低了 CPU Cache 可缓存的地址映射压力。
- 降低 Page Table 负载:内存页的数量会减少,从而需要更少的Page Table,节约了页表所占用的内存数量。
- 消除Page Table查找负载:因为页面不需要替换,所以不需要页表查找。
- 提高内存的整体性能:页面变大后,处理的页面较少,因此可以明显避免访问页表时可能出现的瓶颈。
缺点:
- 需要合理设置,避免内存浪费:在操作系统启动期间被动态分配并被保留,共享内存不会被置换,在使用HugePage的内存不能被其他的进程使用,所以要合理设置该值,避免造成内存浪费。
- 静态设置无法自适应:如果增加HugePage或添加物理内存或者是当前服务器增加了新的实例发生变化,需要重新设置所需的HugePage大小。
使用方式:
(1)标准大页查看机器开启情况
可以通过以下命令查看大页开启情况:
1 | grep Huge /proc/meminfo |
(2)大页设置
通过设置 vm.nr_hugepages 参数的值修改大页数量,大页分配需要连续的内存,机器长期运行存在内存碎片,可能不满足分配需要,一般开机启动时就需要分配设置,如使用以下命令设置大页配置:
1 | [root@controller ~]# sysctl -w vm.nr_hugepages=20 |
(3)大页使用
应用需要通过mmap系统调用或者shmat和shmget系统调用适配才可以使用大页,一般的应用进程都是不可以访问此大页空间。
透明大页(Transparent Huge Pages)
标准大页可带来性能提升,但存在配置和管理上的困难,很难手动管理,而且通常不能通用适配应用的接入使用,需要对代码进行重大的更改才能有效使用。从RHEL 6 开始引入透明大页技术(kernel ≥kernel-2.6.32),在标准大页的基础上,通过一个抽象层,能够自动创建、管理和使用传统大页,用来提高内存管理的性能,解决大页手动管理的问题,透明大页为系统管理员和开发人员减少了很多使用传统大页的复杂性。
优点:
- 相对标准大页,操作系统动态管理大页分配,支持大页分配 ,大页→普通页换出拆分,根据具体应用使用情况,自适应调整分配。
- 使用上对应用透明,且开源社区持续测试、优化和适配大部分应用,同时支持多种大页申请方式配置,满足多场景的分配需求。
缺点:
- THP在运行时动态分配内存,可能会带来运行时内存分配的CPU开销和上涨问题。
- THP同步申请模式下,分配失败时触发申请时,导致应用的一些随机卡顿现象。
使用方式:
透明大页生效方式:对匿名内存的透明Hugepage支持可以完全禁用,也可以仅在MADV_HUGEPAGE区域内启用(避免消耗更多内存资源的风险),也可以在系统范围内启用,可以通过以下方法之一实现:
1 | echo always >/sys/kernel/mm/transparent_hugepage/enabled |
内存大页整理模式:
模式 | 功能说明 |
---|---|
always | 同步申请,分配失败时,直接回收页面和压缩内存,以便立即分配THP |
madvise | 使用madvise(MADV HUGEPAGE)的区域,直接回收和压缩内存,提供THP申请 |
never | 关闭内存大页 |
启用透明大页命令如下:
1 | echo always >/sys/kernel/mm/transparent_hugepage/enabled |
关闭透明大页命令如下:
1 | echo never >/sys/kernel/mm/transparent_hugepage/enabled |
案例二:Linux系统调优
规划节点
节点规划见表2-1。
表2-1 节点规划
IP | 主机名 | 节点 |
---|---|---|
192.168.200.21 | controller | 实验节点 |
基础准备
登录物理OpenStack平台,使用CentOS 7.9镜像创建云主机,云主机类型使用1VCPU/2GB内存/20GB硬盘。创建后的云主机作为本次案例的实验节点。
案例实施
SYN攻击简介
所谓SYN攻击,即利用TCP三次握手原理,向服务器发送大量的SYN数据包,却不响应服务器反馈的SYN+ACK数据包,导致服务器的网络、内存等资源被大量占用,从而导致正常用户无法访问,起到了拒绝服务攻击的目的。
如果想要杜绝SYN攻击,那么我们应该设置服务器减少对ACK数据包的等待时间,减少对SYN+ACK数据包的重发次数,增大网络连接队列的长度等等,
防止SYN攻击的相关内核参数如下所示:
(1)net.ipv4.tcp_synack_retries
该参数表示服务器在收到客户端的SYN数据包并发送SYN+ACK数据包后,如果没有收到客户端的ACK数据包的重发SYN+ACK数据包的次数。在默认情况下,该值设置为5,即表示服务器会尝试发送5次SYN+ACK数据包,如果依旧没有收到响应,则中断链接,不再进行尝试。
(2)net.ipv4.tcp_max_syn_backlog
该参数表示SYN队列的长度,默认为128,可以将该参数设置为20480,以容纳更多的网络链接数。
(3)fs.file-max
该参数表示系统允许的文件句柄的最大数目,TCP连接的建立需要占用文件句柄,因此可以将该参数设置的大一点以应对大量的TCP链接请求。
(4)net.core.somaxconn
该参数表示socket监听队列长度,系统在默认情况下会将已经收到但是还没有处理的request请求放入到该队列中,当该队列满后就无法处理其他的request请求。因此增大该队列的长度可以应对更多的TCP连接请求。但是也会消耗系统的内存。
(5)net.core.wmem_max
该参数表示最大的TCP数据发送缓存,单位为字节。
(6)net.core.netdev_max_backlog
该参数表示当网络设备接收数据包的速率大于内核处理数据包速率时,允许将数据包送入队列的最大数目。
(7)net.ipv4.ip_local_port_range
该参数表示本机主动连接其他设备时的端口分配范围,通常设置为10000-65535,防止占用知名端口。
(8)net.ipv4.tcp_syncookies
该参数默认为0,表示关闭SYN Cookies,可以将该参数设置为1,表示开启该功能。SYN Cookies表示当出现SYN等待队列溢出时,启用Cookies来处理,可以防范少量的SYN攻击。
(9)net.ipv4.tcp_tw_reuse
该参数如果设置为1,则表示允许将TIME-WAIT sockets重新应用于新的TCP连接,如果设置为0,则表示关闭该功能。在默认情况下,该参数设置为0。
(10)net.ipv4.tcp_syn_retries
表示当该设备向其他设备发送TCP SYN包尝试建立TCP连接时,如果对方不响应(有可能是网络丢包或者是对方服务忙),则重新发送TCP SYN数据包的次数。
(11)net.ipv4.tcp_fin_timeout
该参数表示对于本端断开的socket连接,TCP保持在FIN-WAIT-2状态的时间,默认为60。
(12)net.ipv4.tcp_tw_recycle
该参数表示是否开启TCP连接中TIME-WAIT sockets快速回收,在默认情况下设置为0,表示不回收,如果设置为1,则表示回收。
解决策略
(1)开启SYN cookie,防止SYN洪水攻击,修改配置文件/etc/sysctl.conf。
配置文件添加参数,如下所示:
1 | vi /etc/sysctl.conf |
生效修改配置,命令如下:
1 | [root@controller ~]# sysctl -p |
(2)允许将TIME-WAIT sockets重新用于新的TCP连接;开启TCP连接中TIME-WAIT sockets的快速回收;修改系統默认的TIMEOUT时间为30。如下所示:
1 | vi /etc/sysctl.conf |
生效修改配置,命令如下:
1 | sysctl -p |