2023年10月

感谢你阅读本文

那些我曾经觉得无比坚毅,勇敢,富有激情的朋友,几年后我从他们的言谈中看到了疲惫和妥协,不知是在城市的钢筋混泥土中穿梭太久而身心疲惫,还是在那午夜12点的霓虹灯下路过而感到失落。

昨天中午准备午休的时候,学弟发了个消息给我,说在深圳太累了,压力很大,想离开深圳了,我瞬间惊讶了,“这小伙曾经可是个卷王啊,在学校时在实验室可以从早上7点可以干到晚上12点呀,把我们这些老人卷回宿舍了他都还不回,现在怎么会累了?”
image

不过后面我仔细想了一想,怎么就不会累呢?

我们的同龄人中,不乏那种家境特别优越的人,有些人去上大学一个月家里可以给四五千的生活费,如果能谈上女朋友,额外还要加两千,毕业后也是一帆风顺的。

不过大部分人家境是十分普通甚至贫穷的,所以无论上学时期还是进入社会参加工作,都没有什么选择的余地,在没有资源,没有背景的情况下,生活都是过得比较艰难的。

就像网上很流行的那句话,“躺又躺不平,卷又卷不赢”。

特别是当下就业环境这么严峻,工作强度又挺强,工资还TM低,所以年轻人的积极性都被打消了,不过能有工作还好,主要是有很多人找不到工作。

可能你在网上看到统计毕业生分平均薪资过万,就业率90%等等类似的报道,但是这与实际情况大相径庭。

我在网络上也认识不少全国各地的高校学生,加上和现实中的很多朋友了解到,现在就业十分困难,无论什么专业,简历基本都石沉大海。

可能你会说,是他自己不努力,在学校没有好好学,所以出来找不到工作怪谁啊,我觉得这样想是不行的,不要以为自己所得到的都是自己努力换来的,比你努力的人多了去了,可能只是你运气稍微好了一点,站在是时代背景好一点,如果把你换到当前这个环境下,你可能还不如别人!

总是有很多成功的人说自己曾经多么难,但是自己依旧不放弃,最后走上了人生的金字塔尖,然后来呵斥现在年轻人怕吃苦,怕累!

但是实际上现在年轻人所经受的苦累并不是他们那时候所受的苦累能比拟的,身体的累尚能恢复,但是心理上的累却压得人喘不过气。

现在的年轻人毕业后好不容易进入一个公司,满怀激情去干,但是现实总是重拳出击,在繁华的都市拿着微薄的收入,加着加不完的班,熬着熬不完的夜,他们比谁都努力,比谁都上进,但是由于他们没有资源,没有阶梯,所以举步维艰。

在面对房价问题,工作压力,裁员,工资缩水等局面,那个坚毅,勇敢,富有激情的人,手心已经不知道攥出了多少汗!

现在的整个经济形势应该是最难的时刻了,那些你看似光鲜亮丽的人,实际上没有你想象的那么好,大家都比较难。

无论是大城市还是小城市,目前都是比较困难的,所以不要以为在大城市卷不动了回小城市就能轻轻松松,哪怕你回到村里都是很卷的。

在这样的局势下我们能苟住就先苟住,不要去触碰风险。

除了工作外我们应该还要注重生活,只有好好生活我们的身心才能更加健康开朗,工作永远是做不完的,而生活是越过越少的。

保持居安思危的意识,越是艰难的时候越要提起精神,积极探索新事物,别固步自封,因为可能现在看似没用的东西在关键时刻能曲线救国,实现人生的第二春!

今天的分享就到这里,感谢你的观看,我们下期见!

Debian 双网卡配置

因为 Hyper-v 不能在 Hyper-v Manger 里设置网卡的静态 IP,
而每次开机自启之后又要连接 Debian 虚拟机,所以使用了双网卡。

双网卡分为内网网卡和外网网卡:

  • 内网网卡设置为静态 IP,供给宿主机连接使用
  • 外网网卡设置为 DHCP 获取 IP 的桥接网卡,联网使用

操作步骤

添加网络适配器

在 Hyper-v Manger 选中虚拟机,
【设置】->【添加硬件】->【网络适配器】添加网卡
添加网卡分为内外网,可使用默认连接作为桥接网卡,
新建一个网卡专门用于与宿主机连接使用。

在 Debian 中,本文假设 eth0 为桥接网卡(外网网卡),eth1 为内网网卡。

方法一:使用 Debian 系统网卡配置文件配置

配置内网网卡

使用默认网卡【Default】作为内网网卡,在 Windows 网卡配置处配置【vEthernet (Internet)】网卡,
将 IP 设置为
192.168.137.1
子网掩码为
255.255.255.0

之所以为
192.168.137.1
,是因为该值为 Hyper-v 默认值,可以通过以太网网卡共享【Internet连接共享】
共享网络,即实现一张网卡可与宿主机通信的同时访问外网,但是每次开机后需要重置才能上网。

在 Debian 虚拟机中编辑文件:
/etc/network/interfaces.d/win-net.conf
(文件名可以自己命名):
尤其需要注意跃点数,因为内网网卡无法连接互联网,所以要将跃点数设置较高,则访问优先级较低,
同时 IP 地址设置为静态地址,供给宿主机连接使用。

auto eth1
iface eth1 inet static
    address 192.168.137.2
    netmask 255.255.255.0
    gateway 192.168.137.1
    dns-nameserver 8.8.8.8 8.8.4.4
    metric 1000  # 跃点数【重要】:点数越小越优先访问

配置外网网卡


/etc/network/interfaces
文件中有相关默认配置:

allow-hotplug eth0
iface eth0 inet dhcp
    metric 200  # 跃点数【重要】:点数越小越优先访问

添加跃点数即可,添加的跃点数要比外网网卡更小,以实现优先访问。

重启网络

systemctl restart networking

方法二:使用 NetworkManager

安装 NetworkManger

# 安装 network-manager
apt install network-manager
# 开机启动 network-manager
systemctl enable NetworkManager

配置网络

通过
nmtui
指令配置网络,进入【Edit a connection】;
如不存在 eth0 和 eth1 网卡,使用【Add】-【Ethernet】添加网络,
分别在两次添加的【Device】中填入 eth0 和 eth1。

保持 eth0 为 DHCP 自动获取 IP;
选择 eth1 在【IPv4】-【Manual】手动分配 IP:

  • IP 地址:192.168.137.2
  • 网关:192.168.137.1

保存即可。

相关

在 Redhat 系的 Linux 可以通过类似配置达到效果,后续可通过 SSH 公私钥访问达到直接访问的效果。

在今年,平台工程正在迅速在 IT 企业中崭露头角,成为软件开发团队的必要实践。根据 CloudBees 发布的最新报告《2023年平台工程:快速采纳和影响》,83%的受访者已经完全实施了平台工程,或正处于某种实施阶段。

平台工程是一门设计和构建内部开发者平台(IDP)、工具链和工作流程的学科,它为软件工程团队提供了自助服务的能力。

IT 领导者一直在不断面临着要用更少的资源做更多事情的挑战。根据各种研究,
开发者每周实际上只用了12.5%到30%的时间来编写代码
。这也促使 IT 和 DevOps 领导者迫切寻找新的方法来提高开发者的生产力。由于平台工程建立了改进开发者生产力和开发者体验(DevEx)的最佳实践,因此已经成为备受关注的领域。

平台工程的实践已经成功地分担了开发者的大部分工作负担。调查数据显示,已经采用或计划采用平台工程的水平相当高(83%),其中:

  • 20% 已经完全实施
  • 33% 正在进行中
  • 11% 最近刚刚开始
  • 19% 处于规划阶段

仅有17%的受访者表示他们没有计划推出平台工程。

图片来源:CloudBees

平台工程的五个主要推动因素各约占回应的20%,并展示了平台工程对开发者和DevOps团队的重要和广泛好处。采用平台工程的推动因素包括:

  • 开发者生产力(21%)
  • 持续集成和持续交付(CI/CD)流水线的实施(20%)
  • 工具和流程的标准化(20%)
  • 安全性增强(20%)
  • 基础设施即代码(19%)

业务影响

在过去的10年中,随着DevOps的崛起,平台工程的突出地位通常被归因于“我们忘记了开发者!”的现象。在DevOps崛起期间,许多事情向左移动,进一步加重了开发者的负担,并分散了注意力,使其远离了编码和创新。组织投资于平台工程,以满足多种需求。

与关注开发者生产力一致,平台工程的前五个用例中有三个:

  • 开发、测试和生产环境的管理(22%)
  • CI/CD 流水线管理(21%)
  • 开发者平台即服务(PaaS)(18%)

目标和成功衡量标准

几乎所有最重要的平台工程目标都与 DevEx 和提高开发者生产力相关。排名最高的三个目标是:

  • 开发者的自助服务(29%)
  • 于采用(25%)
  • 满足开发者需求(20%)

平台工程团队的成功衡量标准包括:

  • 开发者生产力(23%)
  • 内部KPI达标(19%)
  • 成本控制(16%)
  • 管理工具扩张(13%)

最后,调查显示,组织内的平台工程的归属位置各不相同,但最常见的归属位置包括:

  • 云工程(30%)
  • 基础设施团队(25%)
  • 开发部门(20%)
  • 共享服务(13%)
  • 运维部门(13%)

根据调查数据显示,许多组织广泛采用平台工程,并
将平台工程视为最大程度提高软件开发效率的关键元素

平台工程与 AI

平台工程在接下来的12至18个月内将会面临什么挑战?

平台团队需要为持续的变化做好准备。公司被收购,新平台被收购(通常不会放弃旧平台),新应用程序和部署模式将继续出现。最近出现的颠覆性技术是生成式人工智能(AI),紧随其后的是人工智能(AI),特别是机器学习(ML)。AI 可以并将被应用于改进平台工程。

然而,像创建、运营和保护软件和系统的其他方面一样,AI/ML和生成式 AI 也带来了挑战。我们看到了三个关键方面:

首先是管理多个大型数据集和模型,这是 ML 算法和生成式 AI 大型语言模型(LLM)的生命线。类似于专门的专家系统,基于企业内部数据训练的特定领域的 LLM 在采用生成式 AI 时将变得尤为重要,前提是要维护数据的隐私和安全。

平台工程必须适应新的 AI 工作流程和数据、提示以及设计、训练和维护模型、向量数据库和大型数据集的 AI 工程师的流水线,这些数据集会不断增长和演变。这些 AI 流水线必须支持其工作流模式的特定要求,并与相互依赖的软件开发流水线和发布流程相一致和整合。

另外 AI/ML 和生成式 AI 通常具有与我们今天理解和运营的云和应用环境分开的操作特性。AI 引入了新的硬件操作环境,包括 AI 加速器、GPU、VPU和高度可扩展的 CPU,以及具有挑战性的性能和优化学习曲线。随着 AI,特别是生成式 AI 在企业中被采用和推广,平台工程将发挥关键作用。

关于 Walrus

Walrus 是
基于平台工程理念
构建的全新一代应用管理平台,其
一键部署和克隆复杂应用系统、集成 AI 大语言模型简化模板代码生成
以及
灵活强大的应用和环境动态管理能力
等特性备受用户青睐。借助 Walrus 用户可以将云原生的能力和最佳实践扩展到非容器化环境,并支持任意应用形态统一编排部署,降低使用基础设施的复杂度,为研发和运维团队提供易用、一致的应用管理体验,进而构建无缝协作的软件交付流程,加速企业业务创新。开源地址:github.com/seal-io/walrus

参考链接:

  1. https://www.devopsdigest.com/platform-engineering-2023
  2. https://www.cloudbees.com/platform-engineering-research

引言

在我们前面的讲解中,我们详细了解了计算机系统的核心组件,包括CPU、内存和磁盘。然而,总线在这个体系中同样至关重要。总线是计算机内部各部件间通信的桥梁,涉及数据、地址和控制信号的传输。在接下来的内容中,我们将深入探讨各种类型的总线,为你解析计算机系统的关键组成部分。

总线

计算机是由五大部件组成的,包括运算器、存储器、控制器、输入设备和输出设备。这个概念可能有些抽象,简单来说就是CPU包含运算器和控制器,存储器指的是内存,而输入输出设备分别指的是键盘和显示器。这几个部件之间需要共同协作完成信息处理,而它们之间的通信是通过总线来实现的。

在现代的Intel CPU体系结构中,通常有多条总线。首先,CPU和内存以及高速缓存之间有两种总线。这种方式被称为双独立总线(Dual Independent Bus,DIB)。CPU内部有一个快速的本地总线(Local Bus),用于和高速缓存通信;还有一个速度相对较慢的前端总线(Front-side Bus),用于和主内存以及输入输出设备通信。

在前面的几讲中,我们已经讲过,现代的CPU通常配备专门的高速缓存芯片。本地总线用于与高速缓存通信,而前端总线用于与主内存以及输入输出设备通信。有时候,本地总线也被称为后端总线(Back-side Bus),与前端总线相对应。前端总线还有其他名称,比如处理器总线(Processor Bus)、内存总线(Memory Bus)。

image

在计算机硬件体系结构中,除了常见的前端总线,我们还经常听到 PCI 总线、I/O 总线以及系统总线(System Bus)等术语。这些总线的命名常常让人感到混淆,容易让人迷失在技术术语的海洋中。然而,如果我们直接查看CPU的硬件架构图,就能一目了然地解决所有困扰。

在CPU内部,北桥芯片起到了关键作用,将前端总线一分为二,形成了三个独立的总线。实际上,前端总线就是系统总线的一部分。CPU内部的内存接口直接与系统总线通信,而系统总线再连接到一个I/O桥接器(I/O Bridge)。这个I/O桥接器一侧连接了内存总线,使得CPU能够与内存进行高效通信;另一侧则连接了一个独立的I/O总线,用于连接各种输入输出设备。

事实上,在真实的计算机体系结构中,总线层面的划分更为精细。根据不同的设备类型,还会有独立的PCI总线、ISA总线等等,这些总线的存在进一步丰富了计算机硬件架构,使得不同类型的设备能够在计算机系统内部高效协同工作。

image

在物理层面,我们可以将计算机总线视为一组关键的“电线”,这些电线在计算机硬件体系结构中扮演着至关重要的角色。这些电线并非简单的电子连接,而是精密地分工合作,通常分为三大类线路,每一类线路都有其独特的功能和任务,构成了计算机内部信息传递的基础架构。

首先,我们有数据线(Data Bus),它负责传输实际的数据信息,可以将其类比为公交车上的“乘客”。这些数据线承载着计算机内部各种信息,使得数据能够在不同组件之间流动,实现了计算机内部的信息传递和交换。

其次,地址线(Address Bus)起到了一个非常关键的作用,它确定了数据传输的目的地,就像是为“乘客”写下上车和下车的站点信息的纸条。地址线告诉计算机系统数据应该被送往内存的哪个具体位置,或者是某个特定I/O设备的哪个寄存器,从而确保数据能够准确地被存储或者被读取。

最后,控制线(Control Bus)扮演着监管和调度的角色,类似于公交车的“司机”。这些控制线传递控制信号,指示何时读取或写入数据,何时进行内存或I/O设备的访问,确保计算机内部各个部件的协调运作。它们是计算机总线系统的指挥官,负责确保所有操作在正确的时间和顺序下进行。

image

在计算机系统中,地址总线具有关键的作用,主要用于传输源数据或目的数据在主存单元中的位置信息。CPU利用地址总线来明确指定存储单元的位置。地址总线的宽度决定了它能传送的信息量,也就是CPU可以寻址的存储单元数量。

image

和内存之间的信息交换通过了10条地址总线。每一条地址总线能够传递的信息只有0或1,这意味着在一次传递过程中,CPU和内存可以进行2的10次方(即1024)次数据交换。因此,如果CPU的地址总线有N条,那么我们可以说这个地址总线的宽度是N,这样CPU就能够寻址2的N次方个内存单元。

数据总线

数据线,顾名思义,指的是一次可以传递的数据位数。数据总线的位数即为数据总线的宽度,它定义了一次性可以传输的二进制数据的长度。在计算机系统中,CPU与内存以及其他硬件部件之间的数据传送任务通常由数据总线来完成。数据总线的宽度对于计算机系统的性能和数据传输速度有着直接的影响。8 根数据总线可以一次传送一个 8 位二进制数据(即一个字节)。如果数据总线增加到16根,那么每次传输的数据长度就变成了两个字节。同理,32根数据总线可以一次传输四个字节的数据,以此类推。

控制总线

控制总线,作为连接在计算机系统各个组件之间的关键通信通道,承载着来自CPU的各种控制信号。这些控制信号在计算机的正常操作中起到了至关重要的作用,确保了各个硬件部件之间的协调运行。控制总线上常见的信号包括时钟信号(用于同步操作)、复位信号(用于初始化操作)、中断请求/响应信号、存储器读写信号、IO读写信号等。

在计算机系统中,CPU与其他硬件部件之间的控制操作是通过控制总线来实现的。控制总线的宽度即为其中所包含的传输线数量,每一根传输线都承载着不同的控制信号。因此,控制总线的宽度决定了CPU对外部部件的控制能力。换句话说,控制总线的每一根线路都代表了CPU可以发送的一种控制信号类型,而控制总线上的信号种类多少,直接反映了CPU对外部器件进行各种操作的多样性和复杂性。

总结

本文深入介绍了计算机系统中至关重要的总线概念。总线是计算机内部各组件间通信的桥梁,涉及数据、地址和控制信号的传输。文章解释了不同类型的总线,包括数据线、地址线和控制线,并详细探讨了它们在CPU、内存和其他硬件部件之间的作用。地址总线的宽度决定了CPU可以寻址的存储单元数量,数据总线的宽度影响数据传输速度,而控制总线负责传递各种控制信号,确保计算机内部各部件的协调运作。通过对总线系统的深入理解,读者可以更好地了解计算机硬件架构,为进一步学习和研究提供了基础。

写在前面

最近有用户反馈测试环境Java服务总在凌晨00:00左右挂掉,用户反馈Java服务没有定时任务,也没有流量突增的情况,Jvm配置也合理,莫名其妙就挂了

问题排查

问题复现

为了复现该问题,写了个springboot的demo部署在测试环境,其中demo里只做了hello world功能,应用类型为
web_tomcat (war包部署)
,基础镜像是
base_tomcat/java-centos6-jdk18-60-tom8050-ngx197
,镜像使用的Java版本是
1.8.0_60
,有了上次
MySQL被kill
的经验,盲猜是linux limit惹的祸,因此将打好的镜像分别部署了两批不同的机器,果不其然,新机器当晚挂掉了,老机器服务正常

看一下挂掉的limit设置

排查过程

Java进程会受到limits影响?

按理说Java进程是不会受到系统limit open files(系统最大句柄数)影响的,但是为了验证这个问题,我们将他修改为正常机器的值,由于demo是
web_tomcat
应用,没法修改启动脚本,因此我们通过
prlimit
修改java进程的limit

prlimit -p 32672 --nofile=1048576 

结果当晚00:00左右还是挂了,看来open files和java进程挂掉没关系,看
dmesg
也没发现什么问题

Java版本过低导致内存分配不合理?

通过寻求jdos研发组的帮助,jdos研发组的同学认为是java版本的问题,低版本可能没有限制住申请的内存大小,具体原因如下

https://blog.softwaremill.com/docker-support-in-new-java-8-finally-fd595df0ca54?gi=a0cc6736ed14

异常机器java内存情况

正常机器java内存情况

按照这个
文档
描述,使用docker cgroups限制内存可能会导致JVM进程被终止,原因是Java读取的还是宿主机的CPU,而不是docker cgroups限制的CPU,高版本的Java解决了这个问题,文档解决方案截图如下:

对此我们表示怀疑,因为我们的程序里设置了JVM参数

保持着试一试的心态,我们增加了一个实验组,实验组使用的Java版本是
11.0.8

结果当晚实验组的Java进程还是死了,看来和Java版本也没关系

容器上存在定时任务导致的?

由于基础镜像是jdos官方提供的镜像,所以之前从来没有怀疑过是定时任务的问题,但是现在别无他法了,检查下容器的定时任务

虽然有定时任务,但是这个执行的时间点和Java挂掉的时间对不上,为此我们决定删除定时任务试试

结果当晚Java进程还是挂了,并且这次有dmesg的日志,发现Java被kill的同时crond也被kill了,被kill的原因是crond内存过高导致oom

难道还有系统级cron任务?于是查了一下/etc/crontab,发现果然还有cron任务(这是谁打的镜像!!!)

这个时间点和Java进程挂掉的时间点吻合,但是问题来了,执行的任务并没有
logrotate.sh
这个脚本,应该不会出现问题才对

到底是不是定时任务的问题,我们修改下cron的时间验证下,调整时间为中午11:00,验证下Java进程是否会挂,同时使用
strace
打印进程trace log

果然Java进程在中午11.00挂了,看来真的是cron任务导致的,让我们一起看一下strace

19:59:01 close(3)                        = 0
19:59:01 stat("/etc/pam.d", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
19:59:01 open("/etc/pam.d/crond", O_RDONLY) = 3
19:59:01 fstat(3, {st_mode=S_IFREG|0644, st_size=293, ...}) = 0
19:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd770804000
19:59:01 read(3, "#\n# The PAM configuration file f"..., 4096) = 293
19:59:01 open("/lib64/security/pam_access.so", O_RDONLY) = 5
19:59:01 read(5, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0000\17\0\0\0\0\0\0"..., 832) = 832
19:59:01 fstat(5, {st_mode=S_IFREG|0755, st_size=18552, ...}) = 0
19:59:01 mmap(NULL, 2113800, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 5, 0) = 0x7fd769322000
19:59:01 mprotect(0x7fd769325000, 2097152, PROT_NONE) = 0
19:59:01 mmap(0x7fd769525000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 5, 0x3000) = 0x7fd769525000
19:59:01 close(5) = 0
19:59:01 open("/etc/ld.so.cache", O_RDONLY) = 5
19:59:01 fstat(5, {st_mode=S_IFREG|0644, st_size=16203, ...}) = 0
19:59:01 mmap(NULL, 16203, PROT_READ, MAP_PRIVATE, 5, 0) = 0x7fd7707f8000
19:59:01 close(5) = 0
19:59:01 open("/lib64/libnsl.so.1", O_RDONLY) = 5
19:59:01 read(5, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0p@\0\0\0\0\0\0"..., 832) = 832
19:59:01 fstat(5, {st_mode=S_IFREG|0755, st_size=113432, ...}) = 0
19:59:01 mmap(NULL, 2198192, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 5, 0) = 0x7fd769109000
19:59:01 mprotect(0x7fd76911f000, 2093056, PROT_NONE) = 0
19:59:01 mmap(0x7fd76931e000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 5, 0x15000) = 0x7fd76931e000
19:59:01 mmap(0x7fd769320000, 6832, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fd769320000
19:59:01 close(5) = 0
19:59:01 mprotect(0x7fd76931e000, 4096, PROT_READ) = 0
19:59:01 mprotect(0x7fd769525000, 4096, PROT_READ) = 0
19:59:01 munmap(0x7fd7707f8000, 16203) = 0
19:59:01 open("/etc/pam.d/password-auth", O_RDONLY) = 5
19:59:01 fstat(5, {st_mode=S_IFREG|0644, st_size=692, ...}) = 0
19:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)                     = 0x7fd770803000
19:59:01 read(5, "#%PAM-1.0\n# This file is auto-ge"..., 4096) = 692
19:59:01 open("/lib64/security/pam_unix.so", O_RDONLY) = 6
19:59:01 read(6, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\240&\0\0\0\0\0\0"..., 832) = 832
19:59:01 fstat(6, {st_mode=S_IFREG|0755, st_size=51960, ...}) = 0
19:59:01 mmap(NULL, 2196352, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 6, 0) = 0x7fd768ef0000
19:59:01 mprotect(0x7fd768efc000, 2093056, PROT_NONE) = 0
19:59:01 mmap(0x7fd7690fb000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 6, 0xb000) = 0x7fd7690fb000
19:59:01 mmap(0x7fd7690fd000, 45952, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fd7690fd000
19:59:01 close(6)                       = 0
19:59:01 mprotect(0x7fd7690fb000, 4096, PROT_READ) = 0
19:59:01 read(5, "", 4096)              = 0
19:59:01 close(5) = 0
19:59:01 munmap(0x7fd770803000, 4096) = 0
19:59:01 open("/lib64/security/pam_loginuid.so", O_RDONLY) = 5
19:59:01 read(5, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\220\t\0\0\0\0\0\0"..., 832) = 832
19:59:01 fstat(5, {st_mode=S_IFREG|0755, st_size=10240, ...}) = 0
19:59:01 mmap(NULL, 2105480, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 5, 0) = 0x7fd768ced000
19:59:01 mprotect(0x7fd768cef000, 2093056, PROT_NONE) = 0
19:59:01 mmap(0x7fd768eee000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 5, 0x1000) = 0x7fd768eee000
19:59:01 close(5) = 0
19:59:01 mprotect(0x7fd768eee000, 4096, PROT_READ) = 0
19:59:01 open("/etc/pam.d/password-auth", O_RDONLY) = 5
19:59:01 fstat(5, {st_mode=S_IFREG|0644, st_size=692, ...}) = 0
19:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd770803000
19:59:01 read(5, "#%PAM-1.0\n# This file is auto-ge"..., 4096) = 692
19:59:01 open("/lib64/security/pam_keyinit.so", O_RDONLY) = 6
19:59:01 read(6, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0`\10\0\0\0\0\0\0"..., 832) = 832
19:59:01 fstat(6, {st_mode=S_IFREG|0755, st_size=10224, ...}) = 0
19:59:01 mmap(NULL, 2105488, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 6, 0)                      = 0x7fd768aea000
19:59:01 mprotect(0x7fd768aec000, 2093056, PROT_NONE)                     = 0
19:59:01 mmap(0x7fd768ceb000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 6, 0x1000) = 0x7fd768ceb000
19:59:01 close(6) = 0
19:59:01 mprotect(0x7fd768ceb000, 4096, PROT_READ) = 0
19:59:01 open("/lib64/security/pam_limits.so", O_RDONLY) = 6
19:59:01 read(6, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\320\20\0\0\0\0\0\0"..., 832) = 832
19:59:01 fstat(6, {st_mode=S_IFREG|0755, st_size=18600, ...}) = 0
19:59:01 mmap(NULL, 2113848, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 6, 0) = 0x7fd7688e5000
19:59:01 mprotect(0x7fd7688e9000, 2093056, PROT_NONE) = 0
19:59:01 mmap(0x7fd768ae8000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 6, 0x3000) = 0x7fd768ae8000
19:59:01 close(6) = 0
19:59:01 mprotect(0x7fd768ae8000, 4096, PROT_READ) = 0
19:59:01 open("/lib64/security/pam_succeed_if.so", O_RDONLY) = 6
19:59:01 read(6, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\340\v\0\0\0\0\0\0"..., 832) = 832
19:59:01 fstat(6, {st_mode=S_IFREG|0755, st_size=14384, ...}) = 0
19:59:01 mmap(NULL, 2109624, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 6, 0) = 0x7fd7686e1000
19:59:01 mprotect(0x7fd7686e4000, 2093056, PROT_NONE) = 0
19:59:01 mmap(0x7fd7688e3000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 6, 0x2000) = 0x7fd7688e3000
19:59:01 close(6) = 0
19:59:01 mprotect(0x7fd7688e3000, 4096, PROT_READ)                       = 0
19:59:01 read(5, "", 4096) = 0
19:59:01 close(5)                     = 0
19:59:01 munmap(0x7fd770803000, 4096) = 0
19:59:01 open("/etc/pam.d/password-auth", O_RDONLY)                      = 5
19:59:01 fstat(5, {st_mode=S_IFREG|0644, st_size=692, ...}) = 0
19:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)                      = 0x7fd770803000
19:59:01 read(5, "#%PAM-1.0\n# This file is auto-ge"..., 4096) = 692
19:59:01 open("/lib64/security/pam_env.so", O_RDONLY) = 6
19:59:01 read(6, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\300\r\0\0\0\0\0\0"..., 832) = 832
19:59:01 fstat(6, {st_mode=S_IFREG|0755, st_size=18592, ...}) = 0
19:59:01 mmap(NULL, 2113776, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 6, 0)                       = 0x7fd7684dc000
19:59:01 mprotect(0x7fd7684e0000, 2093056, PROT_NONE) = 0
19:59:01 mmap(0x7fd7686df000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 6, 0x3000) = 0x7fd7686df000
19:59:01 close(6) = 0
19:59:01 mprotect(0x7fd7686df000, 4096, PROT_READ)                     = 0
19:59:01 open("/lib64/security/pam_deny.so", O_RDONLY) = 6
19:59:01 read(6, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0000\5\0\0\0\0\0\0"..., 832) = 832
19:59:01 fstat(6, {st_mode=S_IFREG|0755, st_size=5952, ...}) = 0
19:59:01 mmap(NULL, 2101272, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 6, 0)                       = 0x7fd7682da000
19:59:01 mprotect(0x7fd7682db000, 2093056, PROT_NONE) = 0
19:59:01 mmap(0x7fd7684da000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 6, 0)                      = 0x7fd7684da000
19:59:01 close(6) = 0
19:59:01 mprotect(0x7fd7684da000, 4096, PROT_READ) = 0
19:59:01 read(5, "", 4096) = 0
19:59:01 close(5) = 0
19:59:01 munmap(0x7fd770803000, 4096) = 0
19:59:01 read(3, "", 4096)             = 0
19:59:01 close(3) = 0
19:59:01 munmap(0x7fd770804000, 4096)                      = 0
19:59:01 open("/etc/pam.d/other", O_RDONLY)                      = 3
19:59:01 fstat(3, {st_mode=S_IFREG|0644, st_size=154, ...}) = 0
19:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)   = 0x7fd770804000
19:59:01 read(3, "#%PAM-1.0\nauth     required     "..., 4096) = 154
19:59:01 read(3, "", 4096) = 0
19:59:01 close(3) = 0
19:59:01 munmap(0x7fd770804000, 4096) = 0
19:59:01 open("/etc/passwd", O_RDONLY|O_CLOEXEC)   = 3
19:59:01 fstat(3, {st_mode=S_IFREG|0644, st_size=1057, ...}) = 0
19:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd770804000
19:59:01 read(3, "root:x:0:0:root:/root:/bin/bash\n"..., 4096) = 1057
19:59:01 close(3) = 0
19:59:01 munmap(0x7fd770804000, 4096) = 0
19:59:01 uname({sys="Linux", node="host-11-159-73-176", ...}) = 0
19:59:01 open("/etc/security/access.conf", O_RDONLY) = 3
19:59:01 fstat(3, {st_mode=S_IFREG|0644, st_size=4620, ...}) = 0
19:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd770804000
19:59:01 read(3, "# Login access control table.\n#\n"..., 4096) = 4096
19:59:01 read(3, " should get access from ipv4 net"..., 4096) = 524
19:59:01 read(3, "", 4096) = 0
19:59:01 close(3) = 0
19:59:01 munmap(0x7fd770804000, 4096) = 0
19:59:01 getuid() = 0
19:59:01 open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 3
19:59:01 fstat(3, {st_mode=S_IFREG|0644, st_size=1057, ...}) = 0
19:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)  = 0x7fd770804000
19:59:01 read(3, "root:x:0:0:root:/root:/bin/bash\n"..., 4096) = 1057
19:59:01 close(3)                       = 0
19:59:01 munmap(0x7fd770804000, 4096) = 0
19:59:01 geteuid() = 0
19:59:01 open("/etc/shadow", O_RDONLY|O_CLOEXEC) = 3
19:59:01 fstat(3, {st_mode=S_IFREG, st_size=901, ...}) = 0
19:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd770804000
19:59:01 read(3, "root:$6$4.53VPrJ$1wxMpbsWYp4VKea"..., 4096) = 901
19:59:01 close(3) = 0
19:59:01 munmap(0x7fd770804000, 4096)                      = 0
19:59:01 socket(PF_NETLINK, SOCK_RAW, 9)                       = 3
19:59:01 fcntl(3, F_SETFD, FD_CLOEXEC)   = 0
19:59:01 readlink("/proc/self/exe", "/usr/sbin/crond", 4096) = 15
19:59:01 sendto(3, "p\0\0\0M\4\5\0\1\0\0\0\0\0\0\0op=PAM:accountin"..., 112, 0, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12)                      = 112
19:59:01 poll([{fd=3, events=POLLIN}], 1, 500)   = 1 ([{fd=3, revents=POLLIN}])
19:59:01 recvfrom(3, "$\0\0\0\2\0\0\1\1\0\0\0\227\7\0\0\0\0\0\0p\0\0\0M\4\5\0\1\0\0\0"..., 8988, MSG_PEEK|MSG_DONTWAIT, {sa_family=AF_NETLINK, pid=0, groups=00000000}, [12]) = 36
19:59:01 recvfrom(3, "$\0\0\0\2\0\0\1\1\0\0\0\227\7\0\0\0\0\0\0p\0\0\0M\4\5\0\1\0\0\0"..., 8988, MSG_DONTWAIT, {sa_family=AF_NETLINK, pid=0, groups=00000000}, [12]) = 36
19:59:01 close(3) = 0
19:59:01 open("/etc/security/pam_env.conf", O_RDONLY) = 3
19:59:01 fstat(3, {st_mode=S_IFREG|0644, st_size=2980, ...}) = 0
19:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd770804000
19:59:01 read(3, "#\n# This is the configuration fi"..., 4096) = 2980
19:59:01 read(3, "", 4096) = 0
19:59:01 close(3)                      = 0
19:59:01 munmap(0x7fd770804000, 4096)                       = 0
19:59:01 open("/etc/environment", O_RDONLY)   = 3
19:59:01 fstat(3, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
19:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)               = 0x7fd770804000
19:59:01 read(3, "", 4096) = 0
19:59:01 close(3) = 0
19:59:01 munmap(0x7fd770804000, 4096) = 0
19:59:01 socket(PF_NETLINK, SOCK_RAW, 9) = 3
19:59:01 fcntl(3, F_SETFD, FD_CLOEXEC) = 0
19:59:01 sendto(3, "p\0\0\0O\4\5\0\2\0\0\0\0\0\0\0op=PAM:setcred a"..., 112, 0, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12)                       = 112
19:59:01 poll([{fd=3, events=POLLIN}], 1, 500)   = 1 ([{fd=3, revents=POLLIN}])
19:59:01 recvfrom(3, "$\0\0\0\2\0\0\1\2\0\0\0\227\7\0\0\0\0\0\0p\0\0\0O\4\5\0\2\0\0\0"..., 8988, MSG_PEEK|MSG_DONTWAIT, {sa_family=AF_NETLINK, pid=0, groups=00000000}, [12]) = 36
19:59:01 recvfrom(3, "$\0\0\0\2\0\0\1\2\0\0\0\227\7\0\0\0\0\0\0p\0\0\0O\4\5\0\2\0\0\0"..., 8988, MSG_DONTWAIT, {sa_family=AF_NETLINK, pid=0, groups=00000000}, [12]) = 36
19:59:01 close(3) = 0
19:59:01 open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 3
19:59:01 fstat(3, {st_mode=S_IFREG|0644, st_size=1057, ...}) = 0
19:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd770804000
19:59:01 read(3, "root:x:0:0:root:/root:/bin/bash\n"..., 4096) = 1057
19:59:01 close(3) = 0
19:59:01 munmap(0x7fd770804000, 4096) = 0
19:59:01 open("/proc/self/loginuid", O_WRONLY|O_TRUNC|O_NOFOLLOW)        = 3
19:59:01 write(3, "0", 1) = 1
19:59:01 close(3) = 0
19:59:01 open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 3
19:59:01 fstat(3, {st_mode=S_IFREG|0644, st_size=1057, ...}) = 0
19:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd770804000
19:59:01 read(3, "root:x:0:0:root:/root:/bin/bash\n"..., 4096) = 1057
19:59:01 close(3) = 0
19:59:01 munmap(0x7fd770804000, 4096) = 0
19:59:01 getuid() = 0
19:59:01 getgid() = 0
19:59:01 keyctl(0, 0xfffffffd, 0, 0, 0) = 496466385
19:59:01 keyctl(0, 0xfffffffb, 0, 0, 0x30) = 785702132
19:59:01 open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 3
19:59:01 fstat(3, {st_mode=S_IFREG|0644, st_size=1057, ...}) = 0
19:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd770804000
19:59:01 read(3, "root:x:0:0:root:/root:/bin/bash\n"..., 4096) = 1057
19:59:01 close(3) = 0
19:59:01 munmap(0x7fd770804000, 4096) = 0
19:59:01 getrlimit(RLIMIT_CPU, {rlim_cur=RLIM_INFINITY, rlim_max=RLIM_INFINITY}) = 0
19:59:01 getrlimit(RLIMIT_FSIZE, {rlim_cur=RLIM_INFINITY, rlim_max=RLIM_INFINITY}) = 0
19:59:01 getrlimit(RLIMIT_DATA, {rlim_cur=RLIM_INFINITY, rlim_max=RLIM_INFINITY}) = 0
19:59:01 getrlimit(RLIMIT_STACK, {rlim_cur=8192*1024, rlim_max=RLIM_INFINITY}) = 0
19:59:01 getrlimit(RLIMIT_CORE, {rlim_cur=RLIM_INFINITY, rlim_max=RLIM_INFINITY}) = 0
19:59:01 getrlimit(RLIMIT_RSS, {rlim_cur=RLIM_INFINITY, rlim_max=RLIM_INFINITY}) = 0
19:59:01 getrlimit(RLIMIT_NPROC, {rlim_cur=RLIM_INFINITY, rlim_max=RLIM_INFINITY}) = 0
19:59:01 getrlimit(RLIMIT_NOFILE, {rlim_cur=1073741816, rlim_max=1073741816}) = 0
19:59:01 getrlimit(RLIMIT_MEMLOCK, {rlim_cur=64*1024, rlim_max=64*1024}) = 0
19:59:01 getrlimit(RLIMIT_AS, {rlim_cur=RLIM_INFINITY, rlim_max=RLIM_INFINITY}) = 0
19:59:01 getrlimit(RLIMIT_LOCKS, {rlim_cur=RLIM_INFINITY, rlim_max=RLIM_INFINITY}) = 0
19:59:01 getrlimit(RLIMIT_SIGPENDING, {rlim_cur=883632, rlim_max=883632}) = 0
19:59:01 getrlimit(RLIMIT_MSGQUEUE, {rlim_cur=800*1024, rlim_max=800*1024}) = 0
19:59:01 getrlimit(RLIMIT_NICE, {rlim_cur=0, rlim_max=0}) = 0
19:59:01 getrlimit(RLIMIT_RTPRIO, {rlim_cur=0, rlim_max=0}) = 0
19:59:01 getpriority(PRIO_PROCESS, 0) = 20
19:59:01 open("/etc/security/limits.conf", O_RDONLY) = 3
19:59:01 fstat(3, {st_mode=S_IFREG|0644, st_size=1835, ...}) = 0
19:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd770804000
19:59:01 read(3, "# /etc/security/limits.conf\n#\n#E"..., 4096) = 1835
19:59:01 read(3, "", 4096) = 0
19:59:01 close(3) = 0
19:59:01 munmap(0x7fd770804000, 4096) = 0
19:59:01 open("/etc/security/limits.d", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3
19:59:01 getdents(3, /* 3 entries */, 32768) = 88
19:59:01 open("/usr/lib64/gconv/gconv-modules.cache", O_RDONLY)                       = 5
19:59:01 fstat(5, {st_mode=S_IFREG|0644, st_size=26060, ...}) = 0
19:59:01 mmap(NULL, 26060, PROT_READ, MAP_SHARED, 5, 0) = 0x7fd7707f5000
19:59:01 close(5)  = 0
19:59:01 getdents(3, /* 0 entries */, 32768) = 0
19:59:01 close(3) = 0
19:59:01 open("/etc/security/limits.d/90-nproc.conf", O_RDONLY) = 3
19:59:01 fstat(3, {st_mode=S_IFREG|0644, st_size=193, ...}) = 0
19:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd770804000
19:59:01 read(3, "# Default limit for number of us"..., 4096) = 193
19:59:01 read(3, "", 4096)              = 0
19:59:01 close(3)                       = 0
19:59:01 munmap(0x7fd770804000, 4096)   = 0
19:59:01 setrlimit(RLIMIT_NPROC, {rlim_cur=RLIM_INFINITY, rlim_max=RLIM_INFINITY}) = 0
19:59:01 setpriority(PRIO_PROCESS, 0, 0) = 0
19:59:01 getuid() = 0
19:59:01 open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 3
19:59:01 fstat(3, {st_mode=S_IFREG|0644, st_size=1057, ...}) = 0
19:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd770804000
19:59:01 read(3, "root:x:0:0:root:/root:/bin/bash\n"..., 4096) = 1057
19:59:01 close(3) = 0
19:59:01 munmap(0x7fd770804000, 4096)                     = 0
19:59:01 socket(PF_NETLINK, SOCK_RAW, 9)                      = 3
19:59:01 fcntl(3, F_SETFD, FD_CLOEXEC)                      = 0
19:59:01 sendto(3, "t\0\0\0Q\4\5\0\3\0\0\0\0\0\0\0op=PAM:session_o"..., 116, 0, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 116
19:59:01 poll([{fd=3, events=POLLIN}], 1, 500) = 1 ([{fd=3, revents=POLLIN}])
19:59:01 recvfrom(3, "$\0\0\0\2\0\0\1\3\0\0\0\227\7\0\0\0\0\0\0t\0\0\0Q\4\5\0\3\0\0\0"..., 8988, MSG_PEEK|MSG_DONTWAIT, {sa_family=AF_NETLINK, pid=0, groups=00000000}, [12]) = 36
19:59:01 recvfrom(3, "$\0\0\0\2\0\0\1\3\0\0\0\227\7\0\0\0\0\0\0t\0\0\0Q\4\5\0\3\0\0\0"..., 8988, MSG_DONTWAIT, {sa_family=AF_NETLINK, pid=0, groups=00000000}, [12]) = 36
19:59:01 close(3) = 0
19:59:01 setgid(0) = 0
19:59:01 open("/proc/sys/kernel/ngroups_max", O_RDONLY) = 3
19:59:01 read(3, "65536\n", 31)         = 6
19:59:01 close(3)                       = 0
19:59:01 socket(PF_FILE, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 3
19:59:01 connect(3, {sa_family=AF_FILE, path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
19:59:01 close(3) = 0
19:59:01 socket(PF_FILE, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 3
19:59:01 connect(3, {sa_family=AF_FILE, path="/var/run/nscd/socket"}, 110)                       = -1 ENOENT (No such file or directory)
19:59:01 close(3) = 0
19:59:01 open("/etc/group", O_RDONLY|O_CLOEXEC) = 3
19:59:01 fstat(3, {st_mode=S_IFREG|0644, st_size=497, ...}) = 0
19:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd770804000
19:59:01 lseek(3, 0, SEEK_CUR) = 0
19:59:01 read(3, "root:x:0:\nbin:x:1:bin,daemon\ndae"..., 4096) = 497
19:59:01 read(3, "", 4096)              = 0
19:59:01 close(3)                       = 0
19:59:01 munmap(0x7fd770804000, 4096)                     = 0
19:59:01 setgroups(1, [0]) = 0
19:59:01 setreuid(0, 4294967295) = 0
19:59:01 rt_sigaction(SIGCHLD, {SIG_DFL, [CHLD], SA_RESTORER|SA_RESTART, 0x7fd76fa316a0}, {0x558826e03b80, [], SA_RESTORER|SA_RESTART, 0x7fd76fa316a0}, 8) = 0
19:59:01 pipe([3, 5])                   = 0
19:59:01 pipe([6, 7])                   = 0
19:59:01 clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7fd7707fca70) = 1946
19:59:01 gettid()                     = 1943
19:59:01 open("/proc/self/task/1943/attr/exec", O_RDWR) = 8
19:59:01 write(8, NULL, 0) = -1 EINVAL (Invalid argument)
19:59:01 close(8) = 0
19:59:01 close(3) = 0
19:59:01 close(7) = 0
19:59:01 close(5) = 0
19:59:01 fcntl(6, F_GETFL)                       = 0 (flags O_RDONLY)
19:59:01 fstat(6, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
19:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)                     = 0x7fd770804000
19:59:01 lseek(6, 0, SEEK_CUR)                     = -1 ESPIPE (Illegal seek)
19:59:01 read(6, "/bin/bash: ./logrotate.sh: \346\262\241\346\234"..., 4096) = 55
19:59:01 uname({sys="Linux", node="host-11-159-73-176", ...}) = 0
19:59:01 getrlimit(RLIMIT_NOFILE, {rlim_cur=1073741816, rlim_max=1073741816}) = 0
19:59:01 mmap(NULL, 4294967296, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd6682da000
19:59:01 --- SIGCHLD (Child exited) @ 0 (0) ---
19:59:06 +++ killed by SIGKILL +++


可以看到最后用
mmap
一次分配了 4G 内存,然后就被kill了。

mmap
前调用了
getrlimit
,和上次
MySQL的问题
一样,都是根据系统资源限制来分配内存

为了确定就是cron导致java挂掉的元凶,我们把cron进程手动kill掉,这样就不会执行定时任务了,这次我们在验证下Java进程是否会挂掉

果不其然,Java进程并没有挂掉,看来真的是cron任务导致的

高版本CentOS是否也会出现类似问题?

按理说oom killer应该只kill掉占用内存最高的才对,Java进程占用内存又不是最高的,高版本的CentOS系统oom killer策略会不会有升级?

让我们来一起验证下高版本的CentOS系统是否有这个问题

当前镜像的CentOS版本是
CentOS release 6.6 (Final)
,为了验证高版本的CentOS是否也有类似的问题,我们将增加两个实验组,分别升级基础镜像至
CentOS release 6.10 (Final)

CentOS Linux release 7.9.2009 (Core)
,也添加相同的cron任务

结果发现
CentOS release 6.10 (Final)

CentOS Linux release 7.9.2009 (Core)
都没有kill掉Java进程,只kill掉了cron的子进程

结论

由于容器
limit open files(系统最大句柄数)
设置不合理导致cron执行任务时使容器内存飙升,存在内存溢出的风险,linux由于保护机制会kill掉占用内存高的进程,导致cron子任务进程和Java进程一起被kill(但是问题来了,这个jdos基础镜像为什么会执行一个完全不存在的shell脚本,而且还是执行两次???),高版本的CentOS系统不会kill java进程,猜测不同版本的CentOS的kill选择策略略有不同

问题分析

Cron任务执行逻辑

在Linux中,crontab工具是由croine软件包提供的,让我们一起看下cron的执行过程

其中child_process()执行了cron子进程,cron执行子进程时会有发送mail的动作

cron_popen在执行时会按照open files(系统最大句柄数)清除内存

综上,cron oom的原因找到了,是由于open files设置过大且cron任务没有标准输出,导致执行了发送mail逻辑,而清除的内存大小超出了容器本身内存的大小,导致oom。

croine 1.5.4 版本之后修复了该问题,如果想查看当前容器croine版本可执行如下命令:

rpm -q cronie

Linux内核OOM killer机制

Linux 内核有个机制叫OOM killer(Out Of Memory killer),该机制会监控那些占用内存过大,尤其是瞬间占用内存很快的进程,然后防止内存耗尽而自动把该进程杀掉。内核检测到系统内存不足、挑选并杀掉某个进程的过程可以参考内核源代码linux/mm/oom_kill.c,当系统内存不足的时候,
out_of_memory()
被触发,然后调用
select_bad_process()
选择一个”bad”进程杀掉。

以下是一些主要的进程选择策略:

  1. 内存使用情况:OOM Killer首先倾向于选择占用内存最多的进程,因为终止这些进程可以释放最多的内存。

  2. OOM分数:每个进程都有一个OOM分数,该分数是基于其内存使用情况和其他因素计算出来的。OOM Killer倾向于终止OOM分数最高的进程。

  3. 进程优先级:在选择要终止的进程时,OOM Killer通常会避免终止对系统至关重要的系统进程。这些进程通常具有较高的优先级,因此它们更不容易成为终止目标。

  4. 进程资源需求:OOM Killer还会考虑进程的资源需求。它倾向于终止那些请求较少资源的进程,以最小化影响其他进程的运行。

  5. 进程属性:某些进程可能被标记为不可终止,例如通过设置/proc/[PID]/oom_score_adj的值来调整OOM分数。这些进程通常不容易被OOM Killer终止。

注:不同版本的Linux oom killer机制可能会存在一些差异

解决方案

使用高版本稳定的CentOS系统,如果业务无法升级CentOS,则需要设置合理的
limit open files
数量,application_worker类型应用可以在启动脚本中手动修改limit,web_tomcat类型应用没法修改启动脚本,可以选择kill掉cron进程或删除系统cron任务,也可以手动升级
cronie
的版本至
1.5.7-5

写在后面

open files
这个坑很大,栽这个坑两次了,大家一定要检查自己服务对应容器的CentOS版本和limit设置是否合理,本次案例发生在测试环境,尚不会引起事故,如果在生产出现类似情况,后果不堪设想

由于测试环境新增的这批机器都存在这个问题,我们团队已经联系机器提供方上报了该问题,后续这批机器会由提供方统一修改系统最大句柄数,如果当前问题影响到了业务的正常使用,可以临时删除容器中
/etc/crontab
中的任务

参考文献

https://cloud.tencent.com/developer/article/1183262

https://github.com/cronie-crond/cronie

作者:京东零售 杨云龙

来源:京东云开发者社区 转载请注明来源