做奇安信运维工程师这几年,总有朋友问我,在安全公司做运维是不是特别刺激,天天跟攻击者打交道。说实话,大部分时间我面对的不是网络攻击,而是告警、工单、终端agent、国产操作系统适配,还有一堆“拆不掉”的软件。这篇是奇安信2020运维工程师系列的(二),上一篇写了入职时的整体感受,这篇我打算把真正干活的经验摊开讲:从奇安信天擎这类终端安全产品的日常维护,到Kubernetes和containerd的调用链路,再到UOS、麒麟系统上的适配实战。如果你正准备投安全厂商的运维岗位,或者已经在做相关产品的运维,这篇文章里的经验应该能让你少走很多弯路。
1. 安全厂商运维和传统业务运维的差异在哪里
1.1 两种运维的核心目标不同
在互联网公司做业务运维,核心目标只有一个:让业务稳定。Web集群不飘、数据库不丢数据、接口延迟在指标内。在奇安信这类安全厂商,运维的核心目标是“让安全产品自己先稳定运行”,并且要保证这些产品在客户现场也能正常工作。安全产品的形态非常多样:终端上的agent、服务端的检测引擎、大数据平台、可视化态势大屏,每一类产品的运维手段都不一样。比如终端agent,你得关注它是否真的在终端上运行、策略有没有成功下发;而服务端的检测引擎,你要关注的是CPU、内存、磁盘I/O这些基础指标以及日志有没有持续写入。这两种形态的运维逻辑完全是两套,但在一家安全厂商里,可能是同一个运维团队在负责,所以对工程师的知识面要求会更高。
1.2 我的日常循环:告警、工单、复盘
我具体说说一天的节奏。早上到公司第一件事,先看告警平台。告警分几类:基础设施告警(CPU、内存、磁盘、网络)、产品组件告警(引擎down、数据库连接数超阈值)、终端告警(agent离线、病毒库过期)。然后打开工单系统,处理内部同事或客户提上来的问题。2020年之后,远程办公变多,很多原来要跑到机房里看的服务器,现在都靠远程接入处理,这就要求你在排查问题时更谨慎:能通过命令行确认的,就不要轻易重启服务;需要重启的,先保存现场。我后来给自己定了一个流程:收到告警后先做三件事——看影响面、采集现场信息、判断根因;确认根因后再操作;操作后必须验证,并在笔记里记录。这个流程看起来多花几分钟,实际能省下反复重启、反复试探的时间。
1.3 2020年前后的一个明显变化
2020年有一个明显变化:安全产品私有化交付的需求增多了。很多客户不希望安全数据出机房,要求把整套平台部署到他们自己的环境里。这对运维工程师提出了新要求:不能只会维护自家环境,还要能到客户现场部署、巡检、培训。而且客户现场的网络环境和公司内部差别很大:有内网隔离的、有不能连外网的、有对端口严格限制的。我第一次去客户现场部署时,最大的不适应就是“没有那么多权限”,操作每一步都要记录、要申请、要确认。这个转变逼着我重新审视自己平时那些“熟练操作”:改配置前先备份、升级前先验证回滚方案、操作后留下变更记录。这些习惯在公司内部环境里可能叫“规范”,在客户现场就是“必须”。
2. 终端安全产品实战:天擎为什么这么“难卸”
2.1 天擎在企业里的定位
奇安信天擎是一款终端安全管理系统,它做的事可以概括为四件事:病毒查杀、补丁管理、终端管控、违规外联检测。在企业网络里,它通常以控制台加终端agent的形态存在。控制台部署在服务器上,管理员在控制台里配置策略,比如“不允许U盘写入”“不允许安装某类软件”“发现恶意文件自动隔离”,然后这些策略自动下发到每一台装有agent的终端上。作为运维工程师,我们不一定是策略的制定者,但一定是天擎服务端的维护者和终端问题的处理者。很多同事第一次接触安全产品运维时,会觉得这类软件“怎么这么多限制”,其实想明白它的定位就理解了:它本身就是安全防御体系的一部分,限制越多,说明管控越严。
2.2 服务端维护的四个高频坑
服务端维护其实比终端维护更“危险”,因为服务端一旦挂了,所有终端的策略下发、病毒库更新都会中断。我遇到的高频坑有四个:
- 磁盘空间:控制台的历史日志、审计记录、病毒库更新包都堆在数据库里,时间久了磁盘会满。处理办法是定期清理过期数据,最好在配置里设置日志保留天数。
- 数据库性能:天擎控制台后端有数据库,数据量大了之后,查询会变慢,控制台打开都卡。这个要靠索引优化和归档,不能只靠重启。
- 时间同步:agent和控制台之间时间偏差大,会导致策略下发失败。这个我强调过很多次,一定要在控制台和终端统一配置NTP。
- 版本升级:安全产品版本升级比普通软件更讲究,要先把升级包同步到内网,再分批升级控制台和终端agent,不能一次性全量升,否则出问题影响面太大。
这四个坑里面,磁盘满是我见过最多的。有一回客户反馈“天擎控制台登录不进去了”,我远程一看,磁盘使用率100%,数据库文件把盘写满了。处理办法是先把数据库文件迁移到另一块大磁盘,再清理历史归档日志,最后给数据目录加了监控告警。从那以后,我给所有天擎服务端都加了一条磁盘空间告警,阈值设在85%,避免再踩同样的坑。
2.3 热门搜索里的“卸载天擎”是怎么回事
很多人搜“天擎卸载密码”“天擎卸载要验证码”,其实是因为天擎默认启用了防卸载功能。为什么一个软件要设计得这么“难卸”?原因很简单:终端安全软件如果不防止卸载,攻击者或恶意软件直接把它卸掉,安全防线就没了。所以卸载时要求管理员密码或动态验证码,本质上是权限控制。
但真正在企业环境里,这类需求也确实存在:设备报废、系统重装、agent安装异常需要重装。这时候就牵扯出一个流程问题:终端卸载权限通常由安全部门把控,运维手里不一定有密码。我的建议是建立明确的审批流程:运维提交需求,安全部门审批,审批通过后发放一次性卸载验证码。卸载完成后30分钟内要重新安装agent,避免防护空窗。我不建议任何人为了图省事去尝试绕过卸载机制,一个是安全事件责任问题,另一个是绕过操作在合规审计里会留下记录,万一出了事,成本比走流程高得多。
2.4 终端agent的常见病和处理思路
终端侧的问题,我按频率排序:
- agent离线:网络不通、agent服务被禁用、控制台地址配置错误。先ping控制台地址,再检查服务状态,再查配置文件。
- 病毒库更新失败:更新源不通,或者终端无法访问内网更新服务器。解决方法是重新配置更新源地址,或用离线升级包。
- 误杀业务软件:安全软件查杀到业务程序,需要把目录或进程加入信任区。但信任区不能乱加,要经过确认,否则真病毒也会被放过去。
- 资源占用高:全盘扫描时间设置不合理,把扫描时段放到业务低峰,或者限制扫描时CPU占用。
终端问题看着琐碎,但非常考验耐心,因为每一台终端的系统版本、已装软件、网络环境都不同。很多问题的共性就是日志,先看agent日志,再看系统事件日志,不要瞎猜。我记得有一次处理一台Windows终端的agent反复崩溃,查了半天,最后发现是某个第三方软件和天擎的驱动冲突。这种问题光靠重启agent解决不了,只有从日志里找到冲突线索,再联系软件厂商给出修复方案。
3. 国产操作系统适配:UOS、麒麟、livecd和可信浏览器
3.1 必须先搞清楚的架构问题
热搜里有“怎么从x64版本银河麒麟系统下载奇安信浏览器arm版本”,这个问题的本质不是下载入口找不到,而是架构匹配。国产操作系统的硬件平台五花八门:X86、ARM、MIPS、LoongArch都有,同一款软件必须选择对应架构的安装包。我先教大家一个最基本的命令:在终端里执行uname -m,输出x86_64说明是X64平台,输出aarch64说明是ARM平台,然后去下载对应架构的安装包。麒麟和UOS的软件包格式也不同,有的环境是deb,有的环境是rpm,安装命令分别是dpkg -i和rpm -ivh。遇到依赖缺失,UOS可以用apt-get install -f修复,麒麟可以试试yum install -y补依赖。很多同事在ARM机器上装X64包,装不上还以为是系统有问题,其实换个包就能解决。
终端执行uname -m | CPU架构 | 对应安装包 |
|---|---|---|
| x86_64 | X64 | x64版本 |
| aarch64 | ARM64 | arm64版本 |
| mips64el | MIPS | mips64版本 |
3.2 livecd:系统进不去时的救援主力
提到“统信运维工具-livecd”,我就想起好几次深夜处理客户电话的经历。系统起不来,客户很着急,开口就问“数据还能不能要回来”。只要硬盘没有物理坏道,大部分情况数据都在。办法就是用官方livecd启动盘。具体操作思路是:把livecd写入U盘,服务器或PC用U盘引导启动,进入一个临时的Linux桌面环境,然后打开终端,用lsblk或fdisk -l查看硬盘分区,把根分区挂载到/mnt下面。需要修复引导的,可以chroot进去重新生成grub配置;需要备份数据的,直接把数据拷到移动硬盘。这里有个经验:挂载分区前先fdisk -l看分区表,不要凭感觉挂载,更不要在系统环境未确认时直接格式化。livecd不只是“重装系统”一个用途,很多时候它是数据救援的最后一道保障。
3.3 可信浏览器的安装与更新
奇安信可信浏览器在国产系统里用得很多,但它本身也需要运维。安装的时候要注意下载对应架构的deb或rpm包。更新的时候,很多客户的内网环境不能访问外网,需要离线更新包。帮客户更新时,我一般会先检查版本:浏览器界面里看一下版本号,或者命令行执行对应的查询命令。如果更新失败,最常见的原因是旧版本残留,可以先干净卸载再安装。这里说的干净卸载,指的是通过系统自带的卸载工具操作,不要用暴力删除文件的方式,否则残留的配置会影响后续安装。有些客户找我远程处理浏览器问题,我一问版本和架构,十次里有五次是架构选错了,还有三次是旧版本没卸干净。
3.4 国产化终端运维的一个排查套路
我在处理国产系统终端问题时,养成了一个固定套路:
- 先看是什么CPU架构、什么系统版本。
- 再看软件包格式是deb还是rpm,安装方式对不对。
- 然后用系统日志工具看报错:
journalctl -xe、dmesg | tail。 - 如果软件装好了但起不来,去安装目录下找日志文件。
这套流程非常简单,但能解决80%的国产系统问题。很多人一遇到国产系统就慌,其实底层还是Linux,排查思路和CentOS、Ubuntu没有本质区别,只是软件包格式和桌面环境变了而已。真正需要额外注意的是驱动兼容性。安全软件的agent通常要加载内核模块或网络驱动,在国产系统上就特别依赖内核版本。遇到agent无法上线,先查系统内核版本和软件支持列表,这是最高频的原因。
4. 服务端容器化运维:Kubernetes如何调用containerd
4.1 为什么安全产品后台也开始全面容器化
我接触的安全产品后台,这几年基本都迁移到了容器化架构。原因也好理解:安全产品要私有化交付,客户环境千差万别,容器化能把整个应用和依赖打包在一起,环境一致性大幅提升。部署不再需要关心“这台机器上有几个JDK版本、数据库装在哪个目录”,而是由Kubernetes统一编排。但这套架构对运维提出了新要求:以前是“会看Linux日志就行”,现在还得会看Pod状态、镜像仓库、容器运行时。热搜里“kubernetes是如何调用containerd的”“从原理到实体调用架构”,就是很多运维同学在实际工作中遇到的真问题。
4.2 调用链逐层拆解
Kubernetes调用containerd的链路,我尽量用大白话拆解:
- 用户在控制台创建或更新Pod,这个请求会经过Kubernetes的API Server,被写入etcd。
- 负责调度的组件发现某个节点需要运行一个Pod,于是把任务分配给该节点上的kubelet。
- kubelet是节点上的“监工”,它翻译完Pod定义后,通过CRI接口向容器运行时发请求。
- containerd就是那个容器运行时。它收到请求后,先检查本地有没有镜像,没有就去镜像仓库拉取,然后调用runC创建容器进程。
- 容器创建好后,还涉及网络和存储,这些由containerd调用CNI(容器网络接口)和CSI(容器存储接口)插件完成。
这里有一个很常见的误区:以为Kubernetes还是在调用Docker。其实在Kubernetes 1.24版本之后,dockershim已经被移除了,现在主流的容器运行时就是containerd和CRI-O。判断一个环境用的是哪种运行时,可以看节点上的socket文件:containerd常见的是unix:///run/containerd/containerd.sock,CRI-O是unix:///var/run/crio/crio.sock。
4.3 现场排查Pod问题的一个真实案例
我讲一个真实案例。同事反馈客户现场的某个安全分析组件一直起不来,Pod状态卡在ContainerCreating。我去看,先用kubectl describe pod xxx -n xxx,Events里面报的是Failed to create pod sandbox: failed to setup network for pod。这说明Pod没跑起来,是网络初始化失败。然后我看网络插件,发现这个环境用的CNI是flannel,它的网段配置和客户业务网段冲突了。处理办法是把flannel的Pod CIDR调整到另一个不冲突的网段,然后重建网络插件Pod。整个过程大概花了四十分钟,如果一开始就重启节点,可能半天也定位不到根因,因为问题根本不在节点状态,而在网络规划。
那次经历之后,我总结了一个排查Pod问题的顺序:先kubectl describe看事件,再kubectl logs看容器日志,然后看节点上的kubelet日志,最后看容器运行时日志(journalctl -u containerd)。这个顺序可以避免很多无效操作,比如一上来就重启节点,反而掩盖了现场信息。
4.4 crictl:containerd环境里的调试命令
在containerd环境里调试容器,不能用docker ps了,要用crictl。常用的几条:
crictl ps:列出正在运行的容器。crictl images:列出镜像。crictl logs <container-id>:查看容器日志。crictl exec -it <container-id> sh:进入容器。
还有一个细节:crictl默认连接的是containerd的CRI socket,如果报错连不上,要检查/etc/crictl.yaml里的runtime-endpoint配置。很多同事第一次用crictl时卡在这里,以为是命令没装好,其实只是socket地址没配置。我建议统一在节点上配置好/etc/crictl.yaml,省得每天重敲参数。
4.5 私有化交付时的镜像管理
私有化交付场景里,客户内网往往不能连外网,所以镜像要先在能联网的环境里打好,导出,再导入客户内网的镜像仓库。我建议用Harbor搭仓库,因为自带的界面方便客户自己管理镜像。导出导入的命令,要看现场环境支持哪种:docker save和docker load是传统方式;containerd环境可以用ctr images export和ctr images import。另外,镜像命名一定要规范,要包含产品名、组件名、版本号,不要只写latest,不然升级和回滚时根本分不清哪个是哪个。以前有一回,同事图省事给镜像打了个latest标签,结果第二天要回滚,谁都不敢确定latest对应的是哪个版本,最后只能逐个镜像做比对,特别被动。
5. 常用命令、工具箱和效率思路
5.1 每天高频使用的Linux命令
热搜里有很多“linux常用命令大全运维”“网络运维工具箱”,但我不打算列一个几百条的命令大全,只说平时真正高频使用的。按场景分组:
| 场景 | 常用命令 |
|---|---|
| 系统状态 | top、free -h、df -h、uptime、iostat、vmstat |
| 日志排查 | tail -f、grep、awk、journalctl -xe、dmesg |
| 网络排障 | ping、telnet、ss、tcpdump、ip a |
| 进程管理 | ps -ef、kill、systemctl status |
| 文件处理 | find、rsync、tar、scp、vim |
这几组命令覆盖了我工作中90%的问题。当然,命令会用是一回事,知道什么场景用哪条是另一回事。比如tcpdump很多人知道,但什么时候用什么过滤条件,还是要有点网络基础。我一般先用ss或lsof判断端口是否在监听,确认在监听但连接异常,才用tcpdump抓包看报文。命令是工具,真正值钱的是判断路径。
5.2 我把“经验”变成了一个小工具箱
从入行开始,我就养成了一个习惯:在跳板机上建一个目录,里面存三类东西——常用命令速查、巡检脚本、问题处理笔记。巡检脚本其实就是把操作系统关键的指标收集起来,输出一行文本,方便一眼看出有没有异常。问题处理笔记则是我最珍贵的资产:每次处理完一个线上问题,我会记三行——现象、根因、怎么避免。半年之后,很多问题都是笔记里记过的,照着处理就行,不用再从零开始排查。这个习惯看起来不起眼,但长期积累下来,效率和普通运维的差距会越来越大。运维这行,最怕的不是不会,是“明明踩过的坑还要再踩一遍”。
5.3 监控告警的收敛思路
监控工具我接触过Zabbix、Prometheus、Grafana,但我觉得选型不是重点,重点是告警要收敛。告警设置太敏感,夜里动不动就响,值班的人很快会疲掉,真正的问题反而被当作噪音。我的经验是:告警规则按优先级分层,关键指标(磁盘满、服务down)立即通知,次要指标(负载偏高、内存占用缓慢增长)走日报汇总。另外,告警文本一定要写清楚“怎么处理”,不能只写“CPU过高”,要附带排查步骤或相关文档链接。有一次同事半夜收到“CPU过高”告警,登录上去不知道该看什么,最后发现是某个业务的定时任务在跑,属于正常现象,白白折腾了一小时。告警带上处理指引,这种事情就能避免。
5.4 给新运维的几条实在话
最后给想入行或刚入行的运维同学几句实在话:
- 遇到问题先看日志,不要凭感觉改配置。
- 线上操作前想好回滚方案,操作后必须验证。
- 记录比记忆可靠,好的笔记习惯能让你的经验可复用。
- 别怕做杂活,很多判断力都是从杂活里练出来的。
这些建议听起来简单,但真正做到不容易。我自己早期也犯过“凭感觉重启服务”的毛病,直到有一次重启把现场信息丢了,排查难度翻了倍,才真正记住这个教训。
6. 最后说两句掏心窝的话
做安全产品运维这几年,最大的感受是:安全产品的存在感在于“平时感觉不到它,但出事了它在”。天擎卸载要密码、要验证码,很多人觉得烦,但换个角度想,这正是它保护终端的体现。运维和安全产品最好的相处方式,不是想办法绕开它,而是理解它的逻辑,配合它的流程,同时把底层系统和技术栈掌握得更扎实。回到技术本身,这几年容器化、国产化、自动化一直在变,但运维工程师的核心能力其实很稳定:会看日志、会定位问题、会评估影响面、能给出稳妥的修复方案。工具会迭代,命令会更新,这些判断力不会过时。
最后分享一个小技巧。我每次处理完一个线上故障,无论多晚,都会立刻在笔记里写下三行:现象、根因、怎么避免。这个习惯看起来很笨,但半年之后,它就是我的“个人知识库”。很多别人觉得棘手的故障,在我这里只是翻一下笔记的事。希望你也能建立自己的知识库,让每一份踩坑都不白踩,每一点经验都沉淀下来。