--exclude=FILE_PATTERN skip files and directories matching FILE_PATTERN
--exclude-from=FILE skip files matching any file pattern from FILE
--exclude-dir=PATTERN directories that match PATTERN will be skipped.
分类目录归档:技术笔记
Debian 11 + PVE LACP Mac 冲突问题调查与解决方案
By TL.S
问题背景
在Debian 11 + Proxmox VE环境中,当配置LACP(Link Aggregation Control Protocol)绑定接口时,有一个环境遇到一个令人困惑的问题:相同硬件配置的多台服务器上,所有服务器的同名bond接口都被分配了相同的MAC地址。这种情况会导致严重的网络连接问题,特别是在集群环境中。
根本原因分析
经过深入调查,这个问题的根本原因可以归纳为以下几个方面:
1. systemd/udev MAC 地址生成策略变更
从 systemd 242 版本开始,引入了新的MACAddressPolicy=persistent策略。该策略的目标是为虚拟网络设备(如bond、bridge、vlan等)生成持久的MAC地址,避免重启后MAC地址变化。
核心变更:systemd通过哈希算法,基于机器的machine-id和接口名称来生成MAC地址,确保在同一台机器上重启后MAC地址保持不变。
2. machine-id 相同导致的问题
关键问题:当多台服务器具有相同的machine-id时,相同的接口名称会生成完全相同的MAC地址。
machine-id 相同的几种情况:
- 克隆安装:从同一个镜像克隆安装的系统
- 模板部署:使用相同模板部署的虚拟机或物理机
- 其他原因:其他原因导致
/etc/machine-id文件内容重复
3. MAC地址分配类型
通过查看系统文件可以确认MAC地址的分配方式:
root@server:~# cat /sys/class/net/bond0/addr_assign_type
3
根据Linux内核文档,addr_assign_type=3表示”set using dev_set_mac_address”,即通过dev_set_mac_address函数设置的MAC地址。
4. 虚拟设备的特殊性
问题主要影响虚拟网络设备,因为这些设备缺少必要的ID_NET_NAME_*属性,udev 无法为它们分配稳定的MAC地址。systemd 的解决方案是使用 接口名称+machine-id 的组合来生成MAC地址。
技术原理深度解析
MAC地址生成算法
systemd使用以下算法生成MAC地址:
- 获取
/etc/machine-id的内容 - 结合接口名称(如bond0、vmbr0等)
- 通过哈希算法计算出唯一的MAC地址
- 确保生成的MAC地址符合本地管理地址规范
解决方案
方案一:重置machine-id(推荐)
这是最根本的解决方案,适用于所有情况:
# 停止网络服务
systemctl stop networking
# 备份原machine-id(可选)
cp /etc/machine-id /etc/machine-id.backup
# 清空machine-id
echo -n > /etc/machine-id
# 重新生成machine-id
systemd-machine-id-setup
# 验证新的machine-id
cat /etc/machine-id
# 重启系统使配置生效
reboot
注意事项:
- 重置machine-id可能影响其他依赖machine-id的服务
- 建议在维护窗口期间执行
- 重启后所有虚拟网络接口的MAC地址都会更新
方案二:手动指定MAC地址
如果不想更改machine-id,可以在网络配置中手动指定MAC地址:
# 编辑网络配置文件
vim /etc/network/interfaces
# 为bond接口指定唯一的MAC地址
auto bond0
iface bond0 inet manual
bond-slaves ens1f0 ens1f1
bond-miimon 100
bond-mode 802.3ad
bond-xmit-hash-policy layer3+4
hwaddress ether 02:01:02:03:04:05 # 手动指定MAC地址
# 为bridge接口指定唯一的MAC地址
auto vmbr0
iface vmbr0 inet static
address 10.10.4.41/24
gateway 10.10.4.1
bridge-ports bond0
bridge-stp off
bridge-fd 0
hwaddress ether 02:01:02:03:04:06 # 手动指定MAC地址
方案三:更改MAC地址策略
修改systemd的MAC地址策略来解决MAC冲突问题。首先了解当前策略和可选项:
当前默认策略查看
# 查看当前systemd网络配置
ls -la /etc/systemd/network/
ls -la /lib/systemd/network/
# 查看当前默认策略文件(如果存在)
cat /lib/systemd/network/99-default.link 2>/dev/null || echo "默认策略文件不存在"
# 查看当前接口的MAC策略
networkctl status bond0
MAC地址策略选项说明
systemd支持以下MACAddressPolicy选项:
| 策略 | 说明 | 适用场景 |
|---|---|---|
persistent |
当前默认策略,基于machine-id和接口名生成稳定MAC | 需要MAC地址在重启后保持不变 |
random |
每次启动时生成随机MAC地址 | 不需要MAC地址稳定性 |
none |
不设置MAC地址,使用驱动程序默认值 | 物理接口或需要保持原有MAC |
当前问题的根源:默认的persistent策略在相同machine-id的服务器上会生成相同的MAC地址。
实施步骤
# 1. 检查是否已有配置文件
echo "检查现有配置..."
if [ -f /etc/systemd/network/99-default.link ]; then
echo "发现现有配置文件:"
cat /etc/systemd/network/99-default.link
echo ""
echo "是否要备份现有配置?(y/n)"
read -r response
if [ "$response" = "y" ]; then
cp /etc/systemd/network/99-default.link /etc/systemd/network/99-default.link.backup.$(date +%Y%m%d_%H%M%S)
echo "已备份到: /etc/systemd/network/99-default.link.backup.$(date +%Y%m%d_%H%M%S)"
fi
else
echo "未发现现有配置文件,将创建新配置"
fi
# 2. 创建网络配置目录(如果不存在)
mkdir -p /etc/systemd/network
# 3. 根据需求选择策略创建配置文件
# 选项A:使用random策略(推荐用于解决冲突)
cat > /etc/systemd/network/99-default.link << EOF
# MAC地址策略配置
# 创建时间: $(date)
# 目的: 解决LACP MAC地址冲突问题
[Match]
OriginalName=*
[Link]
MACAddressPolicy=random
NamePolicy=keep kernel database onboard slot path
EOF
# 选项B:仅对虚拟接口使用random策略
cat > /etc/systemd/network/99-virtual.link << EOF
# 虚拟接口MAC地址策略配置
# 创建时间: $(date)
[Match]
Kind=bond bridge vlan macvlan veth
[Link]
MACAddressPolicy=random
EOF
# 选项C:禁用MAC地址自动分配
cat > /etc/systemd/network/99-no-mac.link << EOF
# 禁用MAC地址自动分配
# 创建时间: $(date)
[Match]
OriginalName=*
[Link]
MACAddressPolicy=none
EOF
# 4. 验证配置文件语法
echo "验证配置文件..."
systemd-analyze verify /etc/systemd/network/99-default.link
# 5. 应用新策略
echo "应用新的MAC地址策略..."
# 重新加载systemd配置
systemctl daemon-reload
# 重启网络服务(根据系统使用的网络管理器)
if systemctl is-active --quiet systemd-networkd; then
systemctl restart systemd-networkd
echo "已重启systemd-networkd"
elif systemctl is-active --quiet networking; then
systemctl restart networking
echo "已重启networking服务"
else
echo "警告:未检测到活跃的网络服务,可能需要手动重启网络或系统"
fi
# 6. 验证策略是否生效
echo "等待网络接口重新初始化..."
sleep 5
echo "验证新的MAC地址策略:"
networkctl status | grep -E "(bond|vmbr|bridge)"
策略选择建议
推荐策略组合:
-
对于生产环境:
# 仅对虚拟接口使用random策略,物理接口保持默认 [Match] Kind=bond bridge vlan [Link] MACAddressPolicy=random -
对于测试环境:
# 所有接口使用random策略 [Match] OriginalName=* [Link] MACAddressPolicy=random -
对于特定接口:
# 只对特定名称的接口应用 [Match] OriginalName=bond* vmbr* [Link] MACAddressPolicy=random
回滚方案
如果新策略导致问题,可以快速回滚:
# 删除自定义策略文件
rm -f /etc/systemd/network/99-default.link
# 或者恢复备份
if [ -f /etc/systemd/network/99-default.link.backup.* ]; then
cp /etc/systemd/network/99-default.link.backup.* /etc/systemd/network/99-default.link
fi
# 重启网络服务
systemctl daemon-reload
systemctl restart systemd-networkd
注意事项
- 影响范围:此方案会影响系统中所有匹配的网络接口
- 重启要求:配置更改后,需要重启网络服务或重启系统
- 兼容性:确保你的系统使用systemd-networkd而不是NetworkManager
- 监控:更改后应监控网络连接是否正常
方案四:运行时动态修改
如果需要立即解决问题而不重启:
# 生成随机MAC地址(注意要符合本地管理地址规范)
NEW_MAC=$(printf '02:00:00:%02x:%02x:%02x\n' $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)))
# 停止接口
ip link set dev bond0 down
# 设置新的MAC地址
ip link set dev bond0 address $NEW_MAC
# 启动接口
ip link set dev bond0 up
# 验证更改
ip link show bond0
预防措施
1. 标准化部署流程
在部署新系统时,确保:
# 在系统部署脚本中加入
if [ -f /etc/machine-id ]; then
echo "重置machine-id..."
echo -n > /etc/machine-id
systemd-machine-id-setup
fi
2. 监控和检查
定期检查集群中的MAC地址冲突:
#!/bin/bash
# mac_check.sh - 检查MAC地址冲突
echo "检查集群MAC地址冲突..."
for host in server1 server2 server3; do
echo "=== $host ==="
ssh $host "ip link show | grep -E 'bond|vmbr' | grep 'link/ether'"
done
3. 文档化和记录
建立标准的网络配置文档,记录:
- 每台服务器的machine-id
- 手动分配的MAC地址范围
- 网络拓扑和接口映射
影响范围和版本信息
受影响版本:
- Debian 10/11 + systemd >= 242
- Proxmox VE 6.x/7.x/8.x
- 其他基于systemd的Linux发行版
特别注意:
- Intel网卡比Broadcom网卡更容易出现此问题
- 虚拟化环境中的问题更加常见
- 集群环境影响更严重
总结
Debian 11 + PVE LACP Mac冲突问题的根本原因是systemd的MAC地址生成策略与machine-id机制的相互作用。当多台服务器具有相同的machine-id时,会为相同名称的虚拟网络接口生成相同的MAC地址,导致网络冲突。
References
- https://forum.proxmox.com/threads/duplicate-mac-addresses-generated-for-bonded-interfaces-on-identical-server-hardware.70576/
- https://forum.proxmox.com/threads/same-mac-on-all-lacp-bonds-bridges-after-upgrade-proxmox-8.136359/
- https://unix.stackexchange.com/questions/719379/how-can-i-make-linux-generate-different-mac-addresses-for-different-bridge-devic
- https://github.com/systemd/systemd/pull/11382
- https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-class-net
Claude Code 实用技巧
-
CLAUDE.md(规则文件)= 冰箱家规 先把“进门换鞋、10点关灯、刀具归位”写清楚,Claude 做任何事之前都要看一遍并遵守。
-
Task(多任务并行)= 多台家电同时干活 扫地机器人+洗碗机+空调一起开工,Claude 同时跑多个任务,效率翻倍。
-
/自定义指令(常用操作快捷)= 场景模式 设好“回家模式”:开门回家就自动 开灯→开空调→放音乐。
-
Hook (事件触发器)= 自动提醒/联动开关 洗衣机结束→手机提醒你晾衣服;门磁感应到你进门→灯自己亮。
-
Sub Agent(子智能体)= 家里的专业小队 管家、厨师、保洁、物业、维修师傅……每个都有专长,随叫随到
还有个mcp,这个是标配了~ ————
可以按照如下流程来打造“满血版 Claude Code”
先定家规(CLAUDE.md)→ 招专业团队(Sub Agent)→ 设自动触发器(Hook)→ 添加mcp → 做几个一键场景口令(/自定义指令)→ 一点全自动多任务Task同时执行
References
CentOS 7 重置 root 密码
引言
很多遗留系统都采用 CentOS 系统,经常出现忘记密码,故在此记录方法。
以下内容转自 CentOS 7 重置 root 密码
CentOS 7 重置 root 密码
与之前的 CentOS 5、 CentOS 6 不同的是,当忘记 CentOS 7 root 密码,并采用 GRUB2 为启动器时,
将无法通过单用户模式重置 root 密码,下面介绍 CentOS 7 如何重置 root 密码。
- 启动系统,并在 GRUB2 启动屏显时,按下 e 键进入编辑模式。
- 在
linux16/linux/linuxefi所在参数行尾添加以下内容:init=/bin/sh - 按 Ctrl + X 启动到 Shell。
- 挂载文件系统为可写模式:
mount -o remount,rw / - 运行 passwd, 并按提示修改 root 密码。
- 运行命令
exec /sbin/init来正常启动,或者用命令exec /sbin/reboot重启
遇到的问题,不确认是 VMware Workstation 有 Bug 还是键盘问题,进行密码重置时,
输入 2 次密码很多次,总是提示密码不匹配,用很简单的密码也提示。
然后采用直接清空 root 密码的方式(/etc/passwd root 用户密码列 x 删除)先登录系统,然后再修改。
Ref
telnet 如何退出
telnet 的退出 分成两种,一中是在telnet命令中,直接输入 quit 或者 q 即可退出。 二种情况是 已经进入了端口中,需要先从端口中退出,然后再退出telnet。
telnet 直接退出
输入 q 或者 quit 即可退出。
telnet 退出端口后退出telnet
- 输出
ctrl + ] q或者quit
Ref
kubernetes 的挂载传播(mount propagation)机制
概述
今天在看 kubectl-debug 这个项目的时候,看到其部署文件的 volumeMounuts 中使用了一个 mountPropagation 字段,因为不清楚这个字段的作用,就做了一下了解。mount propagation 背后的东西还是很多的,因此整理了这篇文章,顺便梳理一下知识点。
kubernetes 的 mount propagation 翻译成中文就是挂载传播。挂载传播提供了共享卷挂载的能力,它允许在同一个 Pod,甚至同一个节点内,在多个容器之间共享卷的挂载。
kubernetes 的挂载传播
卷的挂载传播由 Container.volumeMounts 的 mountPropagation 字段控制。它的值有:
None: 这种卷挂载将不会收到任何后续由 host 创建的在这个卷上或其子目录上的挂载。同样的,由容器创建的挂载在 host 上也是不可见的。这是默认的模式。这个其实很好理解,就是容器内和 host 的后续挂载完全隔离。HostToContainer: 这种卷挂载将会收到之后所有的由 host 创建在该卷上或其子目录上的挂载。换句话说,如果 host 在卷挂载内挂载的任何内容,在容器中都是可见的。同样,如果任何具有Bidirectional的 Pod 挂载传播到该卷挂载上,具有HostToContainer的挂载传播都可以看见。整个挂载传播的流程如下:

Bidirectional: 这种挂载机制和HostToContainer类似。此外,任何在容器中创建的挂载都会传播到 host,然后传播到使用相同卷的所有 Pod 的所有容器。注意:Bidirectional 挂载传播是很危险的。可能会危害到 host 的操作系统。因此只有特权容器在允许使用它。
在了解了这几种挂载传播之后,我们可以做一些实验来验证一下,首先验证的是 None 的挂载传播类型,我们创建一个 nginx 的Pod:
apiVersion: v1
kind: Pod
metadata:
name: mount-a
namespace: default
label:
app: mount
spec:
containers:
- name: main
image: nginx:latest
volumeMounts:
- name: testmount
mountPath: /home
mountPropagation: None
volumes:
- name: testmount
hostPath:
path: /mnt/
YAML
然后我们分别向 host 的 /mnt 和容器的 /home 下挂载目录并查看容器和 host 的情况:
容器中:
$ kubectl exec -it mount-a sh
$ cd /home
$ ls
sda1
Bash
host 上:
$ cd /mnt
$ ls
sda1
Bash
然后在 host 上创建挂载:
$ mkdir /mnt/none
$ sudo mount --bind /var /mnt/none
$ ls none
cache empty lib lock log run spool tmp
Bash
这个时候,我们再看容器中的文件:
$ ls none
# 无输出
Bash
这说明 host 上在该卷下的挂载并不会改变容器中的文件。接下来我们可以在容器中按照上面的方案来验证容器中的挂载也不会影响 host 中的目录视图。这里就不展示了。接下来看一下 HostToContainer 的挂载传播,我们将上面的 Pod 的 mountPropagation 字段改成 HostToContainer,然后先取消 host 上的挂载:
sudo umoint /mnt/none
然后重新创建 Pod,和上面一样,在 host 上创建挂载,查看容器中的挂载情况:
$ ls none
cache empty lib lock log run spool tmp
Bash
host 上的挂载因为 HostToContainer 机制传播到了容器中。我们继续看最后一种 Bidirectional 机制。这次我们要创建两个 Pod: mount-a, mount-b,并把 mountPropagation 字段改成 Bidirectional。注意,因为 Bidirectional 是危险的,所以只有特权容器才可以使用。因此这里还需要把容器改成特权模式,最后在 mount-a 中的容器执行挂载,验证挂载是否传播到 host 和 mount-b 的容器中。
apiVersion: v1
kind: Pod
metadata:
name: mount-a
namespace: default
labels:
app: mount
spec:
containers:
- name: main
image: nginx:latest
securityContext:
privileged: true
volumeMounts:
- name: testmount
mountPath: /home
mountPropagation: Bidirectional
volumes:
- name: testmount
hostPath:
path: /mnt/
---
apiVersion: v1
kind: Pod
metadata:
name: mount-b
namespace: default
labels:
app: mount
spec:
containers:
- name: main
image: nginx:latest
securityContext:
privileged: true
volumeMounts:
- name: testmount
mountPath: /home
mountPropagation: Bidirectional
volumes:
- name: testmount
hostPath:
path: /mnt/
YAML
然后进入 mount-a,创建挂载:
$ kubectl exec -it mount-a sh
$ su
$ mount --bind /var /home/none
$ ls /home/none
backups lib lock mail run tmp
cache local log opt spool
Bash
这时候查看 host 下的 /mnt/none:
$ ls /mnt/none
backups lib lock mail run tmp
cache local log opt spool
Bash
可以发现,容器中的挂载传播到了 host 上。这时候再查看 mount-b 中的容器。
$ ls /home/none
backups lib lock mail run tmp
cache local log opt spool
Bash
挂载也传播到了 mount-b 的容器中。
linux mount 的几种类型
上面分析了 kubernetes 的挂载传播机制,在 linux mount 中,也有类似的概念。mount 分为下面几种:
- shared mount: 相当于上面所说的
Bidirectional的挂载传播 - slave mount: 每个 slave mount 都有一个 shared master mount,挂载传播只能从 master -> slave,等同于上面的
HostToContainer, host 是 master,container 是 slave。 - private mount: 很明显,private 就是相当于
None,挂载不会向任何一方传播。 - unbindable mount:unbindable mount 其实就是 unbindable private mount,也就是不允许使用
--bind的挂载。
mount namespace 的机制
kubernetes 的挂载传播不是其本身实现的,也不是 docker 之类的容器运行时提供的。这是由容器化技术的基础:linux namespace 提供的,linux namespace 当前共有 6 种:
- cgroup namespace: 隔离 cgroup 根目录
- pid namespace: 隔离进程 id
- ipc namespace: 隔离 System V IPC, POSIX message queues
- uts namespace: 隔离 Hostname 和 NIS domain name
- user namespace: 隔离用户和用户组 ID
- mount namespace: 隔离挂载点
- network namespace: 隔离网络设备,网络栈,端口等
其中,mount namespace 是这篇文章的重点。我们可以通过 clone 调用来看看 mount namespace 的使用:
#define _GNU_SOURCE
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/mount.h>
#include <sched.h>
#include <signal.h>
#include <unistd.h>
#define STACK_SIZE (1024*1024)
static char container_stack[STACK_SIZE];
char* const container_args[] = {
"/bin/bash",
NULL
};
int container_main(void* arg)
{
printf("Container [%5d] - inside the container!\n", getpid());
mount("none", "/", NULL, MS_REC|MS_PRIVATE, NULL);
execv(container_args[0], container_args);
printf("Something's wrong!\n");
return 1;
}
int main()
{
printf("Parent [%5d] - start a container!\n", getpid());
/* 启用Mount Namespace - 增加CLONE_NEWNS参数 */
int container_pid = clone(container_main, container_stack+STACK_SIZE, CLONE_NEWNS | SIGCHLD, NULL);
waitpid(container_pid, NULL, 0);
printf("Parent - container stopped!\n");
return 0;
}
C
编译运行:
$ gcc main.c -o mount
$ sudo ./mount
Bash
然后尝试挂载,来验证挂载 MS_PRIVATE 的挂载传播问题。MS_PRIVATE 下 namespace 内和 host 应该是隔离的。MS_PRIVATE 还可以替换成 MS_UNBINDABLE, MS_SLAVE,MS_SHARED。
关于更多的 namespace 的资料,建议看这两篇文章:
参考资料
vim 将命令输出到当前位置
在Vim 中,可以使用 :read !command 命令将外部命令 command 的输出插入到当前光标所在位置的下一行。
harbor 替换 ssl 证书
最近内网 harbor 经常迁移,迁移到新地址后 ssl 证书需针对新的地址签发。(当然如果你直接使用 http 就不会有这个烦恼,至于为什么i不直接使用 http 就不多说了)。
这里记录一下签发新的 ssl 证书并迁移的命令,方便后面使用。
# 下面以替换为 10.1.40.39 为例
# 若存在残留证书则删除
$ rm 10.1.40.39.*
# 生成新的私钥
$ openssl genrsa -out 10.1.40.39.key 4096
# 生成新的证书签名请求(CSR)
$ openssl req -sha512 -new -subj "/C=CN/ST=Guangdong/L=Guangzhou/O=Wuzhou/OU=RD/CN=10.1.40.39" -key 10.1.40.39.key -out 10.1.40.39.csr
# 编辑 `x509 v3` 扩展文件,增加新的地址,如
# +IP.3 = 10.1.40.39
$ vi v3.ext
# 生成新的证书
$ openssl x509 -req -sha512 -days 3650 -extfile v3.ext -CA ca.crt -CAkey ca.key -CAcreateserial -in 10.1.40.39.csr -out 10.1.40.39.crt
# 转换证书格式供 其他程序 使用
$ openssl x509 -inform PEM -in 10.1.40.39.crt -out 10.1.40.39.cert
$ openssl x509 -in 10.1.40.39.crt -text -noout | grep -A 10 "Subject Alternative Name"
$ openssl x509 -in 10.1.40.39.cert -text -noout | grep -A 10 "Subject Alternative Name"
# 替换 hostname 和 https 配置
$ vim harbor.yml
# 重启 harbor 加载新证书
$ ./install.sh --with-notary --with-trivy --with-chartmuseum
# Docker 客户端仅需在新的地址下存放 CA证书 即可
$ ls /etc/docker/certs.d/10.1.40.39/ca.crt AI提效之使用 cherry-studio + k8sgpt 实现 AI 巡检 k8s
k8sgpt 能够赋予每个人的 Kubernetes 超能力,能够用简单的语言扫描 Kubernetes 集群、诊断和分类问题。利用 k8sgpt 的 mcp 服务,可以为 LLM 赋予访问 k8s 集群的可能性。
工作原理图:
sequenceDiagram
actor U as User
participant CS as Cherry Studio
participant KG as k8sgpt
participant K as K8s API Server
U->>+CS: Add k8sgpt MCP server
CS->>+KG: Check k8sgpt
KG-->>-CS: k8sgpt is work
CS-->>-U: Success to Add MCP
U->>+CS: Ask some Question about K8s cluster
CS->>+KG: Get someinfo throuth MCP
KG->>+K: Get Cluster Info By API
K-->>-KG: Return Cluster info
KG-->>-CS: Return Info About K8s
CS-->>CS: Handle Info
CS-->>-U: Return Answer about K8s cluster
安装 k8sgpt
首先安装 k8sgpt 工具:
brew install k8sgpt
配置步骤
1. 配置 k8sgpt
确保你的 kubectl 已经正确配置并能够访问目标 Kubernetes 集群:
# 验证集群连接
kubectl cluster-info
# 初始化 k8sgpt
k8sgpt auth add --backend openai --model gpt-3.5-turbo
# 我的情况是必须配置一个 ai ,但是我不用 k8sgpt 的 ai 调用能力,只使用 mcp,但是不配置似乎起不来 mcp ,所以随便配置一个即可。
2. 启动 k8sgpt MCP 服务器
k8sgpt 提供了 MCP (Model Context Protocol) 服务器功能,允许 AI 助手通过标准化协议访问 Kubernetes 集群信息:
# 启动 MCP 服务器
k8sgpt serve --mcp
3. 在 Cherry Studio 中配置 MCP
在 Cherry Studio 中添加 k8sgpt MCP 服务器:
- 打开 Cherry Studio 设置
- 导航到 MCP 服务器配置
- 添加新的 MCP 服务器:
- 名称: k8sgpt
- 类型:Stdin
- 命令:
k8sgpt - 参数:“`
serve --mcp
实际使用场景
集群健康检查
通过 Cherry Studio,启动该 mcp 后你可以使用自然语言询问集群状态:
"请检查当前集群的整体健康状况"
"有哪些 Pod 处于异常状态?"
"最近有什么报错信息吗?"
资源分析
"分析一下集群的资源使用情况"
"哪些节点的资源使用率比较高?"
"有没有资源分配不合理的工作负载?"
故障诊断
"namespace default 下的应用为什么起不来?"
"帮我分析一下这个 deployment 的问题"
"为什么服务无法访问?"
示例 MCP Client 配置
可用于 cursor claude code 等:
{
"mcpServers": {
"k8sgpt": {
"command": "k8sgpt",
"args": [
"serve",
"--mcp"
]
}
}
}
总结
通过结合 Cherry Studio 和 k8sgpt,我们可以构建一个智能化的 Kubernetes 运维助手,实现:
- 提升效率: 自然语言交互,降低操作复杂度
- 智能诊断: AI 驱动的问题识别和解决方案推荐
- 实时监控: 持续的集群健康状态监控
- 知识沉淀: 问题和解决方案的智能化管理
这种 AI + DevOps 的结合方式,代表了未来运维工作的发展方向,让复杂的 Kubernetes 集群管理变得更加简单和智能。
References
Claude Code Subagents 快速开始
在Claude Code中的AI子代理,可用于特定任务的工作流程和改进的上下文管理。
Claude Code中的自定义子代理是专门的AI助手,可以被调用来处理特定类型的任务。它们通过提供具有自定义系统提示、工具和独立上下文窗口的特定任务配置,实现更高效的问题解决。
具有如下优势:
- 上下文保护:每个子代理在自己的上下文中操作,防止主对话的污染,并保持其专注于高级目标。
- 专业知识:子代理可以通过特定领域的详细指令进行微调,在指定任务上获得更高的成功率。
- 可重用性:一旦创建,子代理可以在不同项目中使用,并与您的团队共享以实现一致的工作流程。
- 灵活权限:每个子代理可以有不同的工具访问级别,允许您将强大的工具限制在特定的子代理类型上。
什么是Sub Agents?
Sub Agents本质上是预配置的专业AI助手,它们能够被Claude Code主系统委托处理特定类型的任务。每个Sub Agent都拥有独立的上下文窗口、定制化的系统提示词以及特定的工具访问权限。这种设计使得每个Sub Agent都能专注于自己的专业领域,如代码审查、调试或数据分析等。
与传统的单一AI助手不同,Sub Agents采用了”术业有专攻”的理念。当Claude Code遇到匹配某个Sub Agent专业领域的任务时,会自动将任务委托给相应的专业Sub Agent处理,从而获得更精准、更专业的结果。
使用场景与最佳实践
在实际应用中,Sub Agents展现出了强大的适应性。代码审查Sub Agent可以自动检查代码质量、识别潜在bug并提供改进建议;调试Sub Agent专门分析错误日志、追踪问题根源;数据科学Sub Agent则擅长数据清洗、分析和可视化任务。
Anthropic建议用户首先使用Claude生成初始的Sub Agent,然后根据具体需求进行定制。这种方法既保证了基础功能的完整性,又允许用户根据个人或团队的特殊需求进行优化。
Sub Agents的推出代表了AI助手向专业化、模块化发展的重要趋势。这种设计不仅提高了任务执行的效率和准确性,还为构建复杂的AI工作流提供了基础框架。随着Sub Agents链式调用等高级功能的发展,我们有理由相信,这将为软件开发、数据分析等专业领域带来革命性的变化,推动AI技术在垂直领域的深度应用。
快速开始
创建您的第一个子代理:
- 打开子代理界面,运行以下命令:
/agents - 选择
Create new agent - 定义子代理
- 推荐:首先用
Generate with Claude,然后自定义使其成为您的 - 详细描述您的子代理以及何时应该使用它
- 选择您想要授予访问权限的工具(或留空以继承所有工具)
- 界面显示所有可用工具,使选择变得容易
- 如果您正在用
Generate with Claude,您也可以通过按e在自己的编辑器中编辑系统提示
- 推荐:首先用
- 保存并使用
您的子代理现在可用了!Claude会在适当时自动使用它,或者您可以显式调用它:
> 使用代码审查员子代理检查我最近的更改
SubAgents 配置
文件位置
子代理存储为带有YAML前言的Markdown文件,位于两个可能的位置:
| 类型 | 位置 | 范围 | 优先级 |
|---|---|---|---|
| 项目子代理 | .claude/agents/ |
在当前项目中可用 | 最高 |
| 用户子代理 | ~/.claude/agents/ |
在所有项目中可用 | 较低 |
当子代理名称冲突时,项目级子代理优先于用户级子代理。
文件格式
每个子代理在Markdown文件中定义,具有以下结构:
---
name: your-sub-agent-name
description: Description of when this subagent should be invoked
tools: tool1, tool2, tool3 # Optional - inherits all tools if omitted
---
Your subagent's system prompt goes here. This can be multiple paragraphs
and should clearly define the subagent's role, capabilities, and approach
to solving problems.
Include specific instructions, best practices, and any constraints
the subagent should follow.
配置字段
| 字段 | 必需 | 描述 |
|---|---|---|
name |
是 | 使用小写字母和连字符的唯一标识符 |
description |
是 | 子代理目的的自然语言描述 |
tools |
否 | 特定工具的逗号分隔列表。如果省略,从主线程继承所有工具 |
可用工具
子代理可以被授予访问Claude Code的任何内部工具。请参阅工具文档获取可用工具的完整列表。
推荐:使用/agents命令修改工具访问权限 – 它提供了一个交互式界面,列出所有可用工具,包括任何连接的MCP服务器工具,使您更容易选择所需的工具。
您有两个配置工具的选项:
- 省略
tools字段以从主线程继承所有工具(默认),包括MCP工具 - 指定单个工具作为逗号分隔列表以获得更精细的控制(可以手动编辑或通过
/agents)
MCP工具:子代理可以访问来自配置的MCP服务器的MCP工具。当省略tools字段时,子代理继承主线程可用的所有MCP工具。
管理子代理
使用/agents命令(推荐)
/agents命令为子代理管理提供了一个全面的界面:
/agents
这会打开一个交互式菜单,您可以:
- 查看所有可用的子代理(内置、用户和项目)
- 通过引导设置创建新的子代理
- 编辑现有的自定义子代理,包括它们的工具访问权限
- 删除自定义子代理
- 查看当存在重复时哪些子代理是活动的
- 轻松管理工具权限,提供可用工具的完整列表
直接文件管理
您也可以通过直接处理子代理文件来管理它们:
# 创建项目子代理
mkdir -p .claude/agents
echo '---
name: test-runner
description: Use proactively to run tests and fix failures
---
You are a test automation expert. When you see code changes, proactively run the appropriate tests. If tests fail, analyze the failures and fix them while preserving the original test intent.' > .claude/agents/test-runner.md
# 创建用户子代理
mkdir -p ~/.claude/agents
# ... 创建子代理文件
有效使用子代理
自动委托
Claude Code基于以下内容主动委托任务:
- 您请求中的任务描述
- 子代理配置中的
description字段 - 当前上下文和可用工具
为了鼓励更主动的子代理使用,在您的description字段中包含”主动使用”或”必须使用”等短语。
显式调用
通过在命令中提及特定子代理来请求它:
> 使用测试运行器子代理修复失败的测试
> 让代码审查员子代理查看我最近的更改
> 请调试器子代理调查这个错误
示例子代理
代码审查员
---
name: code-reviewer
description: Expert code review specialist. Proactively reviews code for quality, security, and maintainability. Use immediately after writing or modifying code.
tools: Read, Grep, Glob, Bash
---
You are a senior code reviewer ensuring high standards of code quality and security.
When invoked:
1. Run git diff to see recent changes
2. Focus on modified files
3. Begin review immediately
Review checklist:
- Code is simple and readable
- Functions and variables are well-named
- No duplicated code
- Proper error handling
- No exposed secrets or API keys
- Input validation implemented
- Good test coverage
- Performance considerations addressed
Provide feedback organized by priority:
- Critical issues (must fix)
- Warnings (should fix)
- Suggestions (consider improving)
Include specific examples of how to fix issues.
调试器
---
name: debugger
description: Debugging specialist for errors, test failures, and unexpected behavior. Use proactively when encountering any issues.
tools: Read, Edit, Bash, Grep, Glob
---
You are an expert debugger specializing in root cause analysis.
When invoked:
1. Capture error message and stack trace
2. Identify reproduction steps
3. Isolate the failure location
4. Implement minimal fix
5. Verify solution works
Debugging process:
- Analyze error messages and logs
- Check recent code changes
- Form and test hypotheses
- Add strategic debug logging
- Inspect variable states
For each issue, provide:
- Root cause explanation
- Evidence supporting the diagnosis
- Specific code fix
- Testing approach
- Prevention recommendations
Focus on fixing the underlying issue, not just symptoms.
数据科学家
---
name: data-scientist
description: Data analysis expert for SQL queries, BigQuery operations, and data insights. Use proactively for data analysis tasks and queries.
tools: Bash, Read, Write
---
You are a data scientist specializing in SQL and BigQuery analysis.
When invoked:
1. Understand the data analysis requirement
2. Write efficient SQL queries
3. Use BigQuery command line tools (bq) when appropriate
4. Analyze and summarize results
5. Present findings clearly
Key practices:
- Write optimized SQL queries with proper filters
- Use appropriate aggregations and joins
- Include comments explaining complex logic
- Format results for readability
- Provide data-driven recommendations
For each analysis:
- Explain the query approach
- Document any assumptions
- Highlight key findings
- Suggest next steps based on data
Always ensure queries are efficient and cost-effective.
🚀代码审查专家(中文版)
---
name: code-reviewer
description: 专业代码审查专家。主动审查代码质量、安全性和可维护性。在编写或修改代码后必须立即使用。擅长代码质量评估、安全漏洞检测、性能优化建议和最佳实践推荐。MUST BE USED for code review, quality assessment, security check.
tools: file_search, bash, file_edit
---
你是一位资深代码审查专家,致力于确保代码质量和安全性的高标准。
当被调用时:
1. 运行 git diff 查看最近的更改
2. 专注于已修改的文件
3. 立即开始审查
审查清单:
- 代码简洁易读
- 函数和变量命名清晰
- 无重复代码
- 适当的错误处理
- 无暴露的密钥或API密钥
- 实现了输入验证
- 良好的测试覆盖率
- 考虑了性能因素
按优先级组织反馈:
- 严重问题(必须修复)
- 警告问题(应该修复)
- 建议改进(考虑改进)
包含具体的修复示例说明。
🚀调试专家(中文版)
---
name: debugger
description: 错误调试和问题排查专家。专门处理程序错误、测试失败和异常行为。当遇到任何技术问题、代码报错、功能异常或需要问题排查时必须主动使用。擅长根因分析、错误定位、Bug修复和系统诊断。MUST BE USED for debugging, error fixing, troubleshooting.
tools: file_search, file_edit, bash
---
你是一位专业的调试专家,专精于根因分析和问题解决。
当被调用时:
1. 捕获错误信息和堆栈跟踪
2. 确定重现步骤
3. 定位故障位置
4. 实施最小化修复
5. 验证解决方案有效
调试流程:
- 分析错误信息和日志
- 检查最近的代码更改
- 形成并测试假设
- 添加策略性调试日志
- 检查变量状态
对于每个问题,提供:
- 根本原因解释
- 支持诊断的证据
- 具体的代码修复
- 测试方法
- 预防建议
专注于修复根本问题,而不仅仅是症状。
🚀数据科学家(中文版)
---
name: data-scientist
description: 数据分析和数据科学专家。专门处理SQL查询、BigQuery操作和数据洞察分析。当需要数据分析、数据库查询、数据挖掘、统计分析、数据可视化或数据驱动决策时必须主动使用。擅长SQL优化、数据建模、统计分析和商业智能。MUST BE USED for data analysis, SQL queries, data insights.
tools: bash, file_search, file_edit
---
你是一位数据科学家,专精于SQL和BigQuery分析。
当被调用时:
1. 理解数据分析需求
2. 编写高效的SQL查询
3. 适当时使用BigQuery命令行工具(bq)
4. 分析和总结结果
5. 清晰地呈现发现
关键实践:
- 编写带有适当过滤器的优化SQL查询
- 使用适当的聚合和连接
- 为复杂逻辑添加注释
- 格式化结果以提高可读性
- 提供数据驱动的建议
对于每次分析:
- 解释查询方法
- 记录任何假设
- 突出关键发现
- 基于数据建议后续步骤
始终确保查询高效且具有成本效益。
🚀PRD文档生成
---
name: prd-writer
description: 专业的产品需求文档(PRD)生成专家和产品经理助手。当用户需要生成PRD文档、产品需求文档、产品规格书、功能需求分析、产品设计文档、需求整合、产品规划或编写用户故事时必须优先使用。擅长结构化需求分析、用户故事编写、功能规格定义和产品文档标准化。MUST BE USED for PRD creation, product requirements documentation, feature specifications, user story writing.
tools: file_edit, web_search, file_search
---
# 专业PRD文档生成专家
## 角色定位
你是一位资深产品经理和PRD文档专家,专门负责创建高质量的产品需求文档。你具备深厚的产品管理经验、用户体验设计能力和市场洞察力。
## 核心工作流程
### 1. 需求收集阶段
- 主动询问产品背景、目标用户、核心价值主张
- 了解业务目标、成功指标和约束条件
- 收集竞品信息和市场环境
### 2. 需求分析阶段
- 将模糊想法转化为清晰的功能需求
- 定义用户画像和使用场景
- 确定功能优先级和依赖关系
### 3. 方案设计阶段
- 设计用户体验流程和交互方案
- 提供技术实现建议和架构概述
- 评估实现难度和资源需求
### 4. 文档编写阶段
- 生成结构化、完整的PRD文档
- 为每个功能定义明确的验收标准
- 包含时间规划和里程碑
## 标准PRD文档结构
### 1. 产品概述
- 产品背景与目标
- 目标用户群体
- 核心价值主张
- 成功指标定义
### 2. 功能需求
- **用户故事格式**: "作为[用户角色],我希望[功能描述],以便[业务价值]"
- **验收标准**: 使用Given-When-Then格式
- **优先级**: P0/P1/P2分级
- **依赖关系**: 前置条件和影响范围
### 3. 非功能需求
- 性能要求(响应时间、并发量等)
- 安全要求(数据保护、权限控制等)
- 兼容性要求(设备、浏览器支持等)
### 4. 技术方案
- 系统架构概述
- 关键技术选型
- 数据模型设计
- API接口规范
### 5. 用户体验设计
- 用户旅程地图
- 关键页面流程
- 交互原型描述
- UI规范要求
### 6. 实施计划
- 开发里程碑
- 资源需求评估
- 风险识别与应对
- 测试验收计划
## 输出质量标准
### 需求描述质量
- **具体性**: 避免模糊表述,使用量化指标
- **可测试性**: 每个需求都有明确的验收标准
- **可实现性**: 技术方案合理可行
- **完整性**: 覆盖所有必要的功能和场景
### 文档结构质量
- 逻辑清晰,层次分明
- 使用统一的格式和术语
- 包含必要的图表和示例
- 便于不同角色阅读理解
## 交互模式
### 初次接触
当用户提出PRD需求时,主动询问:
1. 产品的基本信息(名称、类型、目标用户)
2. 核心功能或解决的问题
3. 预期的项目规模和时间要求
4. 是否有参考的竞品或类似产品
### 迭代优化
- 根据用户反馈调整文档结构
- 提供多个方案供用户选择
- 主动识别需求中的矛盾或遗漏
- 建议最佳实践和行业标准
## 常用模板和工具
### 用户故事模板
作为 [用户角色]
我希望 [功能描述]
以便 [业务价值]
验收标准:
- Given [前置条件]
- When [操作动作]
- Then [预期结果]
### 功能优先级矩阵
- P0: 核心功能,必须实现
- P1: 重要功能,优先实现
- P2: 增值功能,资源允许时实现
### 技术评估维度
- 开发复杂度 (1-5分)
- 业务价值 (1-5分)
- 用户影响面 (1-5分)
- 技术风险 (1-5分)
现在请告诉我您的产品需求,我将为您生成一份专业的PRD文档。