vmware 的虚机磁盘扩容,从 vSphere 到 OS 层面

超详细

vSphere Client

不用关机,直接编辑虚拟机硬件,把磁盘大小改大,如 100G => 120G

确定后,等进度条,一般很快就完成

vmware 层面就搞定了

OS

OS 层面可能并未同步更新

可使用echo 1 > /sys/block/sda/device/rescan触发一下

1
2
3
4
5
6
7
8
9
10
11
12
13
fdisk -l

Disk /dev/sda: 100 GiB, 107374182400 bytes, 209715200 sectors
Disk model: Virtual disk

echo 1 > /sys/block/sda/device/rescan

fdisk -l

GPT PMBR size mismatch (209715199 != 251658239) will be corrected by write.
The backup GPT table is not on the end of the device.
Disk /dev/sda: 120 GiB, 128849018880 bytes, 251658240 sectors
Disk model: Virtual disk

由于是 AlmaLinux 9,这里我们并不使用 fdisk 进行分区调整,而是使用 parted

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
parted -l

Warning: Not all of the space available to /dev/sda appears to be used, you can
fix the GPT to use all of the space (an extra 41943040 blocks) or continue with
the current setting?
Fix/Ignore? fix
Model: VMware Virtual disk (scsi)
Disk /dev/sda: 129GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:

Number Start End Size File system Name Flags
1 1049kB 630MB 629MB fat32 EFI System Partition boot, esp
2 630MB 1704MB 1074MB xfs
3 1704MB 107GB 106GB lvm


parted /dev/sda resizepart 3 100%

parted -l

Model: VMware Virtual disk (scsi)
Disk /dev/sda: 129GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:

Number Start End Size File system Name Flags
1 1049kB 630MB 629MB fat32 EFI System Partition boot, esp
2 630MB 1704MB 1074MB xfs
3 1704MB 129GB 127GB lvm

此时的 pv 还未更新,使用pvresize生效

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
pvdisplay

--- Physical volume ---
PV Name /dev/sda3
VG Name almalinux_211
PV Size 98.41 GiB / not usable 2.00 MiB
Allocatable yes (but full)
PE Size 4.00 MiB
Total PE 25193
Free PE 0
Allocated PE 25193
PV UUID 77PAja-dDP3-K2Ii-5jgw-AOFW-KnF5-ib8qg2

pvresize /dev/sda3

pvdisplay
--- Physical volume ---
PV Name /dev/sda3
VG Name almalinux_211
PV Size 118.41 GiB / not usable 1.98 MiB
Allocatable yes
PE Size 4.00 MiB
Total PE 30313
Free PE 5120
Allocated PE 25193
PV UUID 77PAja-dDP3-K2Ii-5jgw-AOFW-KnF5-ib8qg2

接着lvextend你要扩容的 lv,通过df查看挂载点对应的 lv,比如这里我们扩容 root

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
df -hT

Filesystem Type Size Used Avail Use% Mounted on
devtmpfs devtmpfs 4.0M 0 4.0M 0% /dev
tmpfs tmpfs 7.7G 0 7.7G 0% /dev/shm
tmpfs tmpfs 3.1G 65M 3.1G 3% /run
/dev/mapper/almalinux_211-root xfs 61G 56G 4.9G 93% /
/dev/sda2 xfs 960M 324M 637M 34% /boot
/dev/sda1 vfat 599M 7.1M 592M 2% /boot/efi
/dev/mapper/almalinux_211-home xfs 30G 4.5G 26G 16% /home

lvextend -l +100%FREE /dev/almalinux_211/root

Size of logical volume almalinux_211/root changed from <60.84 GiB (15574 extents) to <80.84 GiB (20694 extents).
Logical volume almalinux_211/root successfully resized.

这里直接再df查看会发现 root 并未扩大,需要最 grow 一下生效,这里是 xfs 所以使用 xfs_growfs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
xfs_growfs /dev/almalinux_211/root

meta-data=/dev/mapper/almalinux_211-root isize=512 agcount=4, agsize=3986944 blks
= sectsz=512 attr=2, projid32bit=1
= crc=1 finobt=1, sparse=1, rmapbt=0
= reflink=1 bigtime=1 inobtcount=1 nrext64=0
data = bsize=4096 blocks=15947776, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0, ftype=1
log =internal log bsize=4096 blocks=16384, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
data blocks changed from 15947776 to 21190656

df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 4.0M 0 4.0M 0% /dev
tmpfs 7.7G 0 7.7G 0% /dev/shm
tmpfs 3.1G 65M 3.1G 3% /run
/dev/mapper/almalinux_211-root 81G 56G 26G 69% /
/dev/sda2 960M 324M 637M 34% /boot
/dev/sda1 599M 7.1M 592M 2% /boot/efi
/dev/mapper/almalinux_211-home 30G 4.5G 26G 16% /home

打完收工

AIGC 生成式人工智能

以 ChatGPT 为代表的各种大模型所展现出来的能力自不用说,但限于大模型的原理,AIGC 并不是真的懂了什么,它只是觉得这样回答会获得更高的认可

不过,只要能够找准场景,AIGC 还是帮助颇多

高效文档

不想看文档?没问题,大模型就是干这个的!

Prompt: 我要给一台 H3C 的交换机,1/0/16 口配置 vlan20,请写出具体的配置脚本

ChatGPT:

以下是为 H3C 交换机配置 1/0/16 端口加入 VLAN 20 的具体配置脚本:

1
2
3
4
5
6
system-view
interface GigabitEthernet1/0/16
port link-type access
port access vlan 20
quit
save

脚本说明:

  1. system-view: 进入全局配置模式。
  2. interface GigabitEthernet1/0/16: 进入目标接口配置模式。
  3. port link-type access: 将端口设置为 Access 模式(适合单一 VLAN)。
  4. port access vlan 20: 指定该端口属于 VLAN 20。
  5. quit: 退出接口配置模式。
  6. save: 保存配置,使其在设备重启后生效。

额外说明:

  • 如果 VLAN 20 在交换机上还未创建,可在配置前执行以下命令:
    1
    2
    vlan 20
    quit
    这样可以确保 VLAN 20 存在于交换机中。

思路打开

遇到问题不知从何下手,让大模型帮你打开思路

但大模型也可能在这种时候,不懂装懂,所以最好再让它提供可验证的方法

Prompt: 公司有一颗 Aruba 的 AP 掉线了,AP 名称是 North-1,型号是 225,可能是什么原因,这些原因怎么验证

ChatGPT

Aruba AP 掉线可能由多种原因引起,以下是一些常见的原因和验证方法:


  1. 电源问题
  • 可能原因:PoE 供电异常或电源适配器故障。
  • 验证方法
    • 检查 AP 的 LED 状态指示灯是否正常工作。
    • 如果使用 PoE 供电,检查交换机 PoE 端口是否正常供电(可以登录交换机查看端口供电状态)。
    • 如果使用电源适配器,尝试更换适配器测试。

  1. 网络连接问题
  • 可能原因:AP 与控制器或交换机之间的网络中断。
  • 验证方法
    • 确认 AP 连接的网线是否松动或损坏。
    • 使用 ping 命令测试 AP 与控制器之间的连通性。
    • 登录交换机检查 AP 端口的状态(使用 show interfaces 查看端口是否 UP)。
    • 检查交换机和路由器配置,确认相关 VLAN 和 Trunk 是否配置正确。

  1. AP 与控制器的配置问题
  • 可能原因:控制器没有正确注册该 AP,或 AP 的配置文件损坏。
  • 验证方法
    • 登录控制器,检查是否可以看到North-1 AP 的状态。
    • 查看控制器上的日志(例如show log system)以确认是否有 AP 掉线的记录。
    • 确认 AP 是否绑定到正确的组,并且配置同步。

  1. IP 地址分配问题
  • 可能原因:AP 未正确获取 IP 地址。
  • 验证方法
    • 登录控制器,检查 AP 的 IP 地址是否正常。
    • 登录 DHCP 服务器,查看是否有 IP 分配给 AP。
    • 使用控制器或 CLI 访问 AP,确认 AP 的 IP 地址配置(静态或动态)。

  1. 固件或软件问题
  • 可能原因:AP 固件或控制器软件版本不兼容,导致 AP 无法正常运行。
  • 验证方法
    • 登录控制器检查固件版本,确认是否与 AP 的型号(225)兼容。
    • 检查控制器是否有提示需要升级或降级固件。
    • 如果怀疑固件问题,可以重启 AP 或尝试升级固件。

  1. 物理或环境问题
  • 可能原因:AP 的硬件损坏、过热或环境干扰。
  • 验证方法
    • 检查 AP 表面是否过热。
    • 确认 AP 的安装环境是否有强电磁干扰。
    • 尝试更换位置或替换一个相同型号的 AP 测试。

  1. 认证或许可证问题
  • 可能原因:控制器的许可证过期,或者 AP 认证失败。
  • 验证方法
    • 登录控制器,检查许可证状态。
    • 确认 AP 的序列号是否正确注册。
    • 检查控制器上的 AP 许可是否达到上限。

初步排查步骤:

  1. 观察指示灯:记录 AP 的状态指示灯是否异常。
  2. 控制器检查:登录控制器查看该 AP 的状态和日志。
  3. 网络连通性测试:确认 AP 到控制器的网络路径是否正常。
  4. 重启 AP:如果无法解决,尝试重启 AP,看是否能重新上线。

如果问题仍未解决,可以提供 AP 日志或控制器日志,我们可以进一步分析问题。

日志解读

Prompt 以下为某台 H3C 交换机的日志,请总结一下发生了什么

1
2
3
4
5
6
7
8
9
10
%Oct 28 13:16:16:895 2024 IDC-12 OPTMOD/4/MODULE_IN: Ten-GigabitEthernet1/0/50: The transceiver is 10G_BASE_SR_SFP.
%Oct 28 13:16:17:705 2024 IDC-12 OPTMOD/4/PHONY_MODULE: Ten-GigabitEthernet1/0/50: This transceiver is NOT sold by H3C. H3C therefore shall NOT guarantee the normal function of the device or assume the maintenance responsibility thereof!
%Oct 28 13:20:10:883 2024 IDC-12 IFNET/3/PHY_UPDOWN: Physical state on the interface Ten-GigabitEthernet1/0/50 changed to up.
%Oct 28 13:20:10:890 2024 IDC-12 IFNET/5/LINK_UPDOWN: Line protocol state on the interface Ten-GigabitEthernet1/0/50 changed to up.
%Oct 28 13:20:12:691 2024 IDC-12 LLDP/6/LLDP_CREATE_NEIGHBOR: Nearest bridge agent neighbor created on port Ten-GigabitEthernet1/0/50 (IfIndex 50), neighbor's chassis ID is 8cfd-18fd-fee5, port ID is 8cfd-18fd-fee5.
%Oct 28 13:28:21:344 2024 IDC-12 IFNET/3/PHY_UPDOWN: Physical state on the interface Ten-GigabitEthernet1/0/50 changed to down.
%Oct 28 13:28:21:344 2024 IDC-12 IFNET/5/LINK_UPDOWN: Line protocol state on the interface Ten-GigabitEthernet1/0/50 changed to down.
%Oct 28 13:28:22:160 2024 IDC-12 IFNET/3/PHY_UPDOWN: Physical state on the interface Ten-GigabitEthernet1/0/50 changed to up.
%Oct 28 13:28:22:161 2024 IDC-12 IFNET/5/LINK_UPDOWN: Line protocol state on the interface Ten-GigabitEthernet1/0/50 changed to up.
%Oct 28 13:28:23:692 2024 IDC-12 LLDP/6/LLDP_CREATE_NEIGHBOR: Nearest bridge agent neighbor created on port Ten-GigabitEthernet1/0/50 (IfIndex 50), neighbor's chassis ID is 8cfd-18fd-fee5, port ID is 8cfd-18fd-fee5.

ChatGPT

通过分析日志,可以总结以下事件:

  1. 光模块插入

    • 时间: 2024 年 10 月 28 日 13:16:16
    • 日志:
      • 光模块插入接口 Ten-GigabitEthernet1/0/50,类型为 10G_BASE_SR_SFP
      • 随后系统检测到该模块非 H3C 官方销售,提示可能不保证其正常功能或维护责任。
  2. 链路状态变为 UP

    • 时间: 2024 年 10 月 28 日 13:20:10
    • 日志:
      • 接口物理状态变为 up
      • 链路协议状态变为 up
      • LLDP 检测到新的邻居设备,邻居的 Chassis IDPort ID 均为 8cfd-18fd-fee5
  3. 链路异常波动(短暂掉线并恢复)

    • 时间: 2024 年 10 月 28 日 13:28:21
    • 日志:
      • 接口物理状态和链路协议状态短暂变为 down
      • 约 1 秒后状态恢复为 up
      • LLDP 重新检测

以上这些场景,还可以通过精心构造 Prompt engineering,把输出变成格式化的,可执行的命令,借由系统自动的到环境中验证,再返回结果,多轮 Prompt,直到发现原因或问题恢复。也算是某种 Agent 吧

时序预测

【时序合集】常用时序算法总结

时间序列算法有很多,我们对如 cpu_usage, mem_usage, if_in, if_out 这些数据的关心点主要有两个,周期性和趋势

阈值细分

园区网的一些时序是有明显周期性的,如出口流量,流量的主要用户是人,人有日常作息。当我们强调周期性,忽略趋势时,就可以得到一个随时间变化的、动态的、上下限阈值。这样的阈值能够发现不寻常的事情,相对固定的一个上限值更有信息量

容量预警

当我们同时考虑周期性和趋势时,就可以做容量预警了。你的磁盘可能将会在 X 天后占满,请及时处理。相比于针对用量的阈值,从剩余天数的维度去做提醒使得问题的处理可以更加从容,甚至防范于未然

容量与用量

如果硬件没有故障,配置也没有变更,那遇到的问题大概率会与容量或用量相关

相对于用量,知晓容量从而得其利用的百分比,在实践中更为有用。单纯的用量往往无法直观的评价现状。一台服务器的内存占用了 8G,如何判断占用得多不多,服务器运行得还正不正常,自然是要知晓内存的总大小

实践中,并不是所有容量都像内存这样可以容易的取到,一些只停留在纸面上(说明书、规格文档,虽然可能是 PDF),另一些只能靠人工填一个,甚至估一个

关注容量与用量不仅仅在故障判断上有作用,其与分类系统(如标签)结合,还能发挥管理意义上的统计作用,如

  • 对虚拟机、云主机、服务器、IP 等资源使用情况进行统计,发现闲置资源、低效资源
  • 对资源的分配情况进行统计,多维度考评对资源的利用是否合理

下面总结一些常用的容量

接口流量与带宽

自不必多说,实践中需要注意的有

  • 一些通过 SNMP 取得的带宽不正确,尤其在一些厂商的子接口实现,和他们的公有 MIB 中,需要留意校正
  • 出口带宽的上限,大多时候出口带宽是小于出口设备接口能力的吧,好好的标记上吧

CPU 与内存

这里可以区分一下经典网络设备的 CPU 内存,与经典服务器的 CPU 内存

  • 网络设备的 CPU 内存,可能有很多个,一些的通用的,一些是专用的。所以平均的 CPU 内存意义不大,长时间的 100%占用才需要关注
  • 服务器的 CPU 内存
  • 操作系统中进程的 CPU 内存
  • 虚拟化平台中,主机与虚机的 CPU 内存

IP 与地址池

  • 一个 IPv4 子网的容量
  • 还有可能虽然子网够大,但是在 DHCP 上的 pool,没有配置那么大。这个容量要看 DHCP 系统是否能提供接口了

存储与 IOPS

  • 存储的总容量,各个 LUN 的容量
  • 存储所能提供的总 IOPS,总是一个容易被人忽视的指标,但许多虚拟化平台的卡顿,都源于几台虚机占用了大量的 IOPS

机房与布线

  • 机房的动力,主要是电力。总功率与各 PDU 功率
  • 物理意义上的空间,机柜的 Rack
  • 配线架占用
  • 管井纤芯占用

无线

  • 单 AP 承载终端数
  • 信道容量,这个一般比承载终端数先到达上限,但没有承载终端数那么好评估,一般反映在重传率的上升

其它

  • 网络设备的 MAC 地址转发表,ARP 表,一般不会满,除非网络设计不合理,或者有攻击,网内有主机中病毒
  • DNS 的 QPS,容量要看 DNS 系统能力

人是目的,而非手段

运维软件服务的是运维人员,管好 IT 资源也是为了给用户更好的信息化体验

现状

H 所面对的客户,目前有这样一些困境

  • 与维护的 IT 资源数量,和服务的信息化用户相比,运维人员相对缺失
  • 除较少的编内人员,还可能会有代维、驻厂等三方人员,且这些人流动性高,水平一般
  • 与校内的其它部门相比,信网中心与教育教学的相关性较低,分到的经费,得到的关注都可能有限
  • 部门一把手可能是空降的,并不一能具备相关的专业知识。但却又是能分这块不大的蛋糕的人

我们把软件的使用者分为三类,希望能够站在不同的角度去思考功能设计

管理员 Admin

关键词: 知识 经验

网在心中,手拿把掐。不一定是部门的领导,但是技术绝对的大头

运维软件要想能落地,转起来,首先要去讨好这些人,取得他们的信赖,哄着他们把心中的网,记录到系统中,即所谓的 CMDB

  • 基本信息: 管理 IP,访问凭据
  • 资产信息: 合同,维保,备件,配件
  • 归属信息: 资源谁用的,子网划给了谁,域名谁申请的,策略为谁服务
  • 地理信息: 园区,机房,机柜信息资源与所在位置
  • 综合布线: 从用户接入的 AP 或面板网口,到园区网出口,一些是可以通过 DP 协议计算的,更多的如这个接口出去连到哪个楼的哪个房间,是人工录入的
  • IP 地址规划
  • 出口配额

还有要管好 IT 资源所需要的经验和知识,不仅限于知识库,还有结合自身情况,适应部门运行的各种细化的设置

  • 告警相关: 细化的阈值,自定的等级,何时发通知,要不要升级
  • 看板与报表: 定制实用的看板,配置周期性报表
  • 常用信息: 快速故障恢复
  • 实用信息: 实用工具,实用命令

这些信息记在心中,停留在纸上,都没有录入系统能发挥更大的价值。信网中心,人来人往,唯有电子化、信息化才能最大限度的共享信息,分享价值。信息化中心自身的信息化,本就该是其它部门的标杆模范

这样的管理员是行业中的中流砥柱,与他们站在一起,倾听他们的需求,是好的运维软件替客户着想,为客户分忧的前提

在这些信息的收集上,真应该向游戏学习。你做对了什么,立刻就给正反馈,引导用户不断地按照游戏策划设想的那样去玩这个游戏。反观运维软件,又想从管理员那些套取大量信息,又没有明确及时的正反馈,这软件怎么能落地?怎么能真正在运维工作中发挥作用呢?怎么能产生用户粘性呢?

运维人员 Operator

关键词: 时间 绩效

虽说我们希望系统或软件替人去完成那些简单、机械、重复、低价值的工作,但诸如设备上下架、布线、出现场等还是要人工的。运维软件的价值,就是把系统先把能做的都做了,然后再所谓的 人在回路

工作台

H 倾向于在真正干活的时候,系统提供一个工作台看板。这类似游戏中的任务板,任务板上没有任务,或者看板中一片绿,说明万事大吉,我可以继续摸鱼。任务板上有任务了,那我就开始干活

任务也应该是由系统判断后,精心处理且分门别类的呈现在工作台上。每一种分类的任务不能太多,会给人一种虱子多了不痒,债多了不愁的懈怠感。H 见了太多的客户,告警列表里躺着几百几千条,从最近到一年前发生的,未处理未恢复的告警。

可能分类有

  • 告警: 现在而今眼目下,你的什么东西出问题了。系统已经帮你排除了 a, b, c…几种原因,还剩 d, e, f…种可能;也自动的按照 1, 2, 3…尝试恢复,但未能成功,需要你来介入一下。这些告警应该有一个合理的严重等级,可以是根据事件类型,影响范围,影响对象(大领导办公室的 AP,就影响一个人,但你说比不比宿舍楼的重要吧)。常用的事件等级有 CRITICAL, ERROR, WARNING, INFO 等。但可能还不够,归于某一等级的告警还是太多。还有许多帮助给事件排出个一二三顺序的方法,后面详见事件及告警篇
  • 信息完善: 有一条链路可能变动了,确认一下;有一颗 AP 可能更换了,确认一下
  • 提醒: 某些资产维保要到期了;机柜的空间容量不够了;某些软件的授权要到期了,你也不希望到时候全校分不到地址吧

统一处理带来方便考核

分类带来知识积累、效率与专精

领导 Leader

关键词: 容量 业绩

领导从宏观的角度看问题,自然可以看成是各种模拟经营类游戏的玩家。试想,哪个模拟经营类游戏没有几个面板,告诉玩家你的资源现在有多少,用了多少,运行得多平稳高效,达到了多大规模,服务了多少用户,助力了多少发展,(击败了百分之多少的同行)。系统就应该提供这些情绪价值

  • 大屏: 精心设计的,突出容量、用量
  • 报表: 月度的、季度的、年度的
  • 总结: 面向最终用户的,能让他们体会到信网中心和重要性,体会到中心领导的高瞻远瞩和辛勤付出

写在前面

2014 - 2024 作者 H 入职一家 IT 运维软件开发公司十年来,对 ITMS 的一些想法

主要工作对象为高校的园区网、数据中心等 IT 基础设施

想法很多、很杂,先记录下来,有空慢慢整理、归类、迭代

网络设备 配置管理

设想,理想情况下如果一个网络,硬件没变过,配置也没变过,那么这个网络只要今天是好的,那么明天肯定也是好的

虽然现实中有更多的意外会发生,如断电、断线、被偷等等,但配置管理应该是 ITMS 中的重要一环

硬件确定了,配置确定了,那么这个网络就确定了,网络的功能和行为都确定了

Configuration-as-code

CaC 配置即代码

借鉴代码管理中应用最广的 git 版本管理的经验,网络的配置也有必要这么管理

我们不妨来对应一下

  • repo: 一张网就是一个 repo,其中有文件,即某台设备的配置,和文件类,即某种分类组织方式
  • branch, tag: 如果有条件做网络仿真,倒也可以区分 dev 和 prod 分支,但一般不太可能;tag 打标签是有用的
  • commit: 配置一般可分为 startup config 和 running config,如果有差异,则可视 running config 为未提交的修改

除了版本管理之外,在代码管理方面的成熟经验也很有启发

  • comment: 备注,这段配置是干嘛的 for who, for what
  • diff: 设备间横向对比,时间上纵向对比
  • template: 许多接入设备是不是配置都差差不多,模板库不考虑一下么
  • snippet: 实用配置收集
  • static analysis: 合规性检查
  • ci/cd: 持续集成,hook
  • ai: 输入硬件型号、固件版本,输入想做的操作,让 AI 帮你生成配置吧

汇总一些用过的 keepalived 问题的排查方法

  1. 统计信息
1
kill -USR2 $(cat /var/run/keepalived.pid)

向 keepalived 进程发 signal,其它可用的参考man keepalived

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
HUP or SIGFUNC=RELOAD
This causes keepalived to close down all interfaces, reload its configuration, and start up with the new
configuration.

TERM, INT or SIGFUNC=STOP
keepalived will shut down.

USR1 or SIGFUNC=DATA
Write configuration data to /tmp/keepalived.data

USR2 or SIGFUNC=STATS
Write statistics info to /tmp/keepalived.stats

SIGFUNC=JSON
Write configuration data in JSON format to /tmp/keepalived.json

默认会生成/tmp/keepalived.stats,包含各 Instance 的统计信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
VRRP Instance: VI_0
Advertisements:
Received: 7233644
Sent: 8
Became master: 2
Released master: 2
Packet Errors:
Length: 0
TTL: 0
Invalid Type: 0
Advertisement Interval: 0
Address List: 0
Authentication Errors:
Invalid Type: 0
Type Mismatch: 0
Failure: 0
Priority Zero:
Received: 2
Sent: 0
  1. 当前状态
1
snmpwalk -v2c -cpublic 127.0.0.1 -mALL .1.3.6.1.4.1.9586

利用 SNMP 查询,结果包含当前状态和一些配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
KEEPALIVED-MIB::version.0 = STRING: Keepalived v2.0.20 (01/22,2020)
KEEPALIVED-MIB::routerId.0 = STRING: ***
KEEPALIVED-MIB::smtpServerAddressType.0 = INTEGER: ipv4(1)
KEEPALIVED-MIB::smtpServerAddress.0 = Hex-STRING: 00 00 00 00
KEEPALIVED-MIB::smtpServerTimeout.0 = Gauge32: 0 seconds
KEEPALIVED-MIB::smtpServerPort.0 = Gauge32: 0
KEEPALIVED-MIB::smtpEmailFaults.0 = INTEGER: enabled(1)
KEEPALIVED-MIB::smtpEmailSmtpAlert.0 = INTEGER: unset(3)
KEEPALIVED-MIB::smtpEmailSmtpAlertVrrp.0 = INTEGER: unset(3)
KEEPALIVED-MIB::smtpEmailSmtpAlertChecker.0 = INTEGER: unset(3)
KEEPALIVED-MIB::trapEnable.0 = INTEGER: disabled(2)
KEEPALIVED-MIB::linkBeat.0 = INTEGER: netlink(1)
KEEPALIVED-MIB::lvsFlush.0 = INTEGER: disabled(2)
KEEPALIVED-MIB::netNamespace.0 = STRING:
KEEPALIVED-MIB::dynamicInterfaces.0 = INTEGER: false(2)
KEEPALIVED-MIB::lvsFlushOnStop.0 = INTEGER: disabled(2)
KEEPALIVED-MIB::vrrpInstanceName.1 = STRING: VI_0
KEEPALIVED-MIB::vrrpInstanceVirtualRouterId.1 = Gauge32: 29
KEEPALIVED-MIB::vrrpInstanceState.1 = INTEGER: backup(1)
KEEPALIVED-MIB::vrrpInstanceInitialState.1 = INTEGER: backup(1)
KEEPALIVED-MIB::vrrpInstanceWantedState.1 = INTEGER: backup(1)
KEEPALIVED-MIB::vrrpInstanceBasePriority.1 = INTEGER: 100
KEEPALIVED-MIB::vrrpInstanceEffectivePriority.1 = INTEGER: 100
KEEPALIVED-MIB::vrrpInstanceVipsStatus.1 = INTEGER: notAllSet(2)
KEEPALIVED-MIB::vrrpInstancePrimaryInterface.1 = STRING: eth0
KEEPALIVED-MIB::vrrpInstanceTrackPrimaryIf.1 = INTEGER: tracked(1)
KEEPALIVED-MIB::vrrpInstanceAdvertisementsInt.1 = Gauge32: 1 seconds(VRRPv2) / centiseconds(VRRPv3)
KEEPALIVED-MIB::vrrpInstancePreempt.1 = INTEGER: preempt(1)
KEEPALIVED-MIB::vrrpInstancePreemptDelay.1 = Gauge32: 0 seconds
KEEPALIVED-MIB::vrrpInstanceAuthType.1 = INTEGER: password(1)
KEEPALIVED-MIB::vrrpInstanceLvsSyncDaemon.1 = INTEGER: disabled(2)
KEEPALIVED-MIB::vrrpInstanceGarpDelay.1 = Gauge32: 5 seconds
KEEPALIVED-MIB::vrrpInstanceSmtpAlert.1 = INTEGER: disabled(2)
KEEPALIVED-MIB::vrrpInstanceNotifyExec.1 = INTEGER: enabled(1)
KEEPALIVED-MIB::vrrpInstanceScriptFault.1 = STRING: ***
KEEPALIVED-MIB::vrrpInstanceAccept.1 = INTEGER: 0
KEEPALIVED-MIB::vrrpInstancePromoteSecondaries.1 = INTEGER: false(2)
KEEPALIVED-MIB::vrrpInstanceUseLinkbeat.1 = INTEGER: false(2)
KEEPALIVED-MIB::vrrpInstanceVrrpVersion.1 = INTEGER: vrrpv2(2)
KEEPALIVED-MIB::vrrpTrackedScriptName.1.1 = STRING: ***
KEEPALIVED-MIB::vrrpTrackedScriptWeight.1.1 = INTEGER: 0
KEEPALIVED-MIB::vrrpTrackedScriptWgtRev.1.1 = INTEGER: false(2)
KEEPALIVED-MIB::vrrpAddressType.1.1 = INTEGER: ipv4(1)
KEEPALIVED-MIB::vrrpAddressValue.1.1 = STRING: "
{zE"
KEEPALIVED-MIB::vrrpAddressBroadcast.1.1 = Hex-STRING: 00 00 00 00
KEEPALIVED-MIB::vrrpAddressMask.1.1 = Gauge32: 32
KEEPALIVED-MIB::vrrpAddressScope.1.1 = INTEGER: global(14)
KEEPALIVED-MIB::vrrpAddressIfIndex.1.1 = INTEGER: 2
KEEPALIVED-MIB::vrrpAddressIfName.1.1 = STRING: eth0
KEEPALIVED-MIB::vrrpAddressStatus.1.1 = INTEGER: unset(2)
KEEPALIVED-MIB::vrrpAddressAdvertising.1.1 = INTEGER: advertised(1)
KEEPALIVED-MIB::vrrpScriptName.1 = STRING: ***
KEEPALIVED-MIB::vrrpScriptCommand.1 = STRING: ***
KEEPALIVED-MIB::vrrpScriptInterval.1 = INTEGER: 5 seconds
KEEPALIVED-MIB::vrrpScriptWeight.1 = INTEGER: 0
KEEPALIVED-MIB::vrrpScriptResult.1 = INTEGER: good(3)
KEEPALIVED-MIB::vrrpScriptRise.1 = Gauge32: 2
KEEPALIVED-MIB::vrrpScriptFall.1 = Gauge32: 2
KEEPALIVED-MIB::vrrpScriptWgtRev.1 = INTEGER: false(2)
  1. 抓包

一般来说,就以往遇到的问题,往往都是 VRRP 包的收发不对劲,所以可以通过 tcpdump 抓包查看

同时结合 keepalived 的配置,关注抓包的网口,进出方向,vrid, prio

1
tcpdump -i any -n vrrp and inbound

最近用到 s6-overlay 记录一下踩到的坑

定位

容器中的 supervisor

https://github.com/just-containers/s6-overlay

上手

以 alpine 为例

1
2
3
4
5
6
7
8
9
10
11
12
13
FROM alpine

# dev
RUN apk update && apk add bash
ENV S6_KEEP_ENV=1

RUN apk add --no-cache redis s6-overlay

COPY s6-overlay /etc/s6-overlay

ENTRYPOINT ["/init"]

CMD ["bash"]

官方推荐用新格式启服务,即使用 s6-rc.d 目录

默认安装 s6 后,会自带 user, user2 目录

user 目录的 type 为 bundle

用法为,在 s6-rc.d 下新建服务定义目录,然后在 user/contents.d 下 touch 一下同名空文件

1
2
3
4
5
6
7
8
9
   0   B          ┌─  redis-server
- ┌─  contents.d
4.0 KiB ├─  type
4.0 KiB ┌─  user
4.0 KiB │ ┌─  type
4.0 KiB │ ├─  run
8.0 KiB ├─  redis-server
12.0 KiB ┌─  s6-rc.d
12.0 KiB  s6-overlay

redis-server/type 为 longrun

redis-server/run 为

1
2
3
#!/usr/bin/execlineb -P
s6-setuidgid redis
redis-server /etc/redis.conf
  • 官方文档中都是#!/command/execlineb -P,但没办法,alpine 中没有把 execlineb 放在 /command 下
  • s6-setuidgid 让 redis-server 以 redis 的用户跑
  • 显示指定 conf 文件,主要为了确保 dump.rdb 的生成目录对 redis 用户可写,默认 /var/lib/redis

可能遇到的问题

  • dockerfile COPY 一行报错,找不到文件

想想有没有 .dockerignore

  • cd 或 composer 报找不到 HOME 的定义

s6-overlay 默认会接手环境变量,可以使用 with-contenv 使单个命令继承原 env,with-contenv env

或指定 S6_KEEP_ENV=1 (default = 0),方便开发环境

近日在维护的某业务系统中发现 dockerd 进程的 CPU 占用高达 55%

感觉上不太可能,开始排查

perf top -g -p <pid> 发现大量调用发生在 logger, json 读写等

1
2
github.com/docker/docker/daemon/logger/loggerutils.(*forwarder).Do
github.com/docker/docker/daemon/logger/jsonfilelog.(*decoder).Decode

docker 默认的 logging driver 为 json-file,json 的读写还是开销大啊!

反正重要的日志也有其它记录方式,不需要依赖 docker logs,果断切换日志记录方式

https://docs.docker.com/config/containers/logging/configure/#configure-the-default-logging-driver

1
2
3
{
"log-driver": "local"
}

重启 dockerd,效果显著,目前 CPU 占用小于 5%

现象

macOS 上 PHP Cli 启动缓慢

php -v等都启动缓慢,大概需要5秒左右

导致 PhpCsFixer 也巨慢,我还以为本身就要花这么久

原因

https://github.com/php/php-src/issues/11673

PHP 的 imap 扩展使用了一个不再更新的库 cclient,且这个库在一些情况下会去解你本机的 hostname

解决方法就是写 /etc/hosts

1
2
3
# FUCK Handle Slow PHP cli with IMAP extension on macOS
::1 localhost HMBP.local
127.0.0.1 localhost HMBP.local

高兴的是 https://wiki.php.net/rfc/unbundle_imap_pspell_oci8

该库将在 PHP 8.4 移出默认 bundle

REF

Handle Slow PHP cli with IMAP extension on macOS

https://samsonasik.wordpress.com/2023/09/30/handle-slow-php-cli-with-imap-extension-on-macos/

1
nmap --script ssh2-enum-algos -sV -p <port> <host>

很好用,结果一目了然

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
PORT      STATE SERVICE VERSION
22/tcp open ssh OpenSSH 4.3 (protocol 2.0)
| ssh2-enum-algos:
| kex_algorithms: (3)
| diffie-hellman-group-exchange-sha1
| diffie-hellman-group14-sha1
| diffie-hellman-group1-sha1
| server_host_key_algorithms: (2)
| ssh-rsa
| ssh-dss
| encryption_algorithms: (13)
| aes128-ctr
| aes192-ctr
| aes256-ctr
| arcfour256
| arcfour128
| aes128-cbc
| 3des-cbc
| blowfish-cbc
| cast128-cbc
| aes192-cbc
| aes256-cbc
| arcfour
| rijndael-cbc@lysator.liu.se
| mac_algorithms: (6)
| hmac-md5
| hmac-sha1
| hmac-ripemd160
| hmac-ripemd160@openssh.com
| hmac-sha1-96
| hmac-md5-96
| compression_algorithms: (2)
| none
|_ zlib@openssh.com

附一些为了兼容老版本 SSH 的配置

1
2
3
KexAlgorithms +diffie-hellman-group1-sha1
HostKeyAlgorithms +ssh-rsa
PubkeyAcceptedKeyTypes +ssh-rsa
0%