docker & kubectl #
# 删除所有状态为exited的docker
docker rm $(docker ps -a -q -f status=exited)
# 获取pod对应的nodeName
kubectl get pod $PODNAME -n $NAMESPACE -o=jsonpath='{.spec.nodeName}'
# 获取pod对应状态是否是ready,ready为True,不ready为False
kubectl get pod $PODNAME -n $NAMESPACE -o=jsonpath='{.status.conditions[?(@.type=="Ready")].status}'
# 复制文件到pod中
kubectl cp <本地文件路径> <Pod名称>:<容器内目标路径> -n <命名空间>
# 重定向到pod文件中
cat localfile.txt | kubectl exec -i <Pod名称> -- sh -c 'cat > /path/in/pod/file.txt'
ETCD #
# etcd 授权
export ETCDCTL_API=3 && ./etcdctl --endpoints=http://{ip}:2379 role grant-permission user --prefix=true readwrite /prefix --user="root:{root_pwd}"
# 检查etcd授权
export ETCDCTL_API=3 && ./etcdctl --endpoints=http://{ip}:2379 --user="{userName}:{pwd}" get /prefix
# 检查指定路径的键是否存在
export ETCDCTL_API=3 && etcdctl --user <userName>:<pwd> --endpoints=<etcd地址> get /目标目录 --prefix
# 通过健康检查命令测试凭证有效性
export ETCDCTL_API=3 && etcdctl --user <userName>:<pwd> --endpoints=<etcd地址> endpoint health
redis #
# 识别bigkey
redis-cli -big-keys
# 事务相关命令
- MULTI: 标记一个事务块的开始。
- DISCARD: 取消事务,放弃执行事务块内的所有命令。
- EXEC: 执行所有事务块内的命令。
- UNWATCH: 取消 WATCH 命令对所有 key 的监视。
- WATCH key [key ...]: 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
# 遍历所有的key
- KEYS: KEYS命令用于查找所有符合给定模式的键,例如KEYS *会返回所有键。它在小数据库中使用时非常快,但在包含大量键的数据库中使用可能会阻塞服务器,因为它一次性检索并返回所有匹配的键
- SCANS: 它以游标为基础分批次迭代键集合,每次调用返回一部分匹配的键。SCAN命令不会一次性加载所有匹配的键,因此不会像KEYS命令那样阻塞服务器,更适合用于生产环境中遍历键集合。
获取本机属性 #
获取本机ip #
if [ -z "$AGENT_IP" ]; then
if [ -f "./bin/ip.txt" ]; then
AGENT_IP="$(cat ./bin/ip.txt)"
fi
# 容器变量判断逻辑
if [ -z "$AGENT_IP" ] && [ ! -z "$ZHIYAN_LOG_NAME" ]; then
AGENT_IP="$ZHIYAN_LOG_NAME"
fi
# TKE 判断逻辑
if [ -z "$AGENT_IP" ] && [ ! -z "$CLUSTER_ID" ] && [ ! -z "$POD_NAMESPACE" ] && [ ! -z "$POD_NAME" ]; then
AGENT_IP="[$CLUSTER_ID]-[$POD_NAMESPACE]-[$POD_NAME]"
fi
# 铁将军判断逻辑
if [ -z "$AGENT_IP" ]; then
AGENT_IP=`ifconfig | grep -A1 "^eth1" | grep "inet addr:" | awk -F: '{ print $2 }' | awk '{ print $1 }' | grep -E "^172\.|^11\.|^30\.|^192\.|^10\.|^100\.|^9\." | head -n1`
fi
if [ -z "$AGENT_IP" ]; then
AGENT_IP=`ifconfig | grep -A1 "^eth1" | grep "inet " | awk '{ print $2 }' | grep -E "^172\.|^11\.|^30\.|^192\.|^10\.|^100\.|^9\." | head -n1`
fi
if [ -z "$AGENT_IP" ]; then
AGENT_IP=`ifconfig | grep -A1 "^eth0" | grep "inet addr:" | awk -F: '{ print $2 }' | awk '{ print $1 }' | grep -E "^172\.|^11\.|^30\.|^192\.|^10\.|^100\.|^9\." | head -n1`
fi
if [ -z "$AGENT_IP" ]; then
AGENT_IP=`ifconfig | grep -A1 "^eth0" | grep "inet" | awk '{print $2}' | grep -E "^172\.|^11\.|^30\.|^192\.|^10\.|^100\.|^9\." | head -n 1`
fi
if [ -z "$AGENT_IP" ]; then
AGENT_IP=`ifconfig | grep -A1 "^bond0:" | grep "inet addr:" | awk -F: '{ print $2 }' | awk '{ print $1 }' | grep -E "^172\.|^11\.|^30\.|^192\.|^10\.|^100\.|^9\." | head -n1`
fi
if [ -z "$AGENT_IP" ]; then
AGENT_IP=`ifconfig | grep -A1 "^bond0:" | grep "inet" | awk '{print $2}' | grep -E "^172\.|^11\.|^30\.|^192\.|^10\.|^100\.|^9\." | head -n 1`
fi
if [ -z "$AGENT_IP" ]; then
AGENT_IP=`ifconfig | grep -A1 "^bond1:" | grep "inet addr:" | awk -F: '{ print $2 }' | awk '{ print $1 }' | grep -E "^172\.|^11\.|^30\.|^192\.|^10\.|^100\.|^9\." | head -n1`
fi
if [ -z "$AGENT_IP" ]; then
AGENT_IP=`ifconfig | grep -A1 "^bond1:" | grep "inet" | awk '{print $2}' | grep -E "^172\.|^11\.|^30\.|^192\.|^10\.|^100\.|^9\." | head -n 1`
fi
if [ -z "$AGENT_IP" ]; then
AGENT_IP=`ss -aut | egrep ":36000|:56000" | awk '{print $5}' | awk -F: '{ print $1 }' | grep -E "^172\.|^11\.|^30\.|^192\.|^10\.|^100\.|^9\." | head -n1`
fi
fi
抓包 #
nohup tcpdump -i any -s 0 -nn -vvv -C 100 -W 5 -w /data/trpc_go/logs/mysql.pcap port 37478 &
-s 0: 设置抓取数据包时的抓取长度,0 表示抓取整个数据包。
-nn: 禁用地址解析,不对 IP 地址和端口号进行解析。
-vvv: 设置详细程度,-vvv 表示输出详细的信息,包括更多的协议解析信息。
-c: 限制要抓取的网络包的个数
tcpdump -r xxx.pcap -nn -tttt
-tttt: 显示完整可读时间
-v:详细模式,-vv/-vvv 更详细
-n:不解析主机名
-nn:同时禁用端口解析
cgroup #
cgroup.procs 文件中的 PID 列表才是我们通常意义上的进程列表,而 tasks 文件中包含的 PID 实际上可以是 Linux 轻量级进程(LWP) 的 PID,而由于 Linux pthread 库的线程实际上轻量级进程实现的(Linux 内核不支持真正的线程,可通过getconf GNU_LIBPTHREAD_VERSION
查看使用的 pthread 线程库版本,Ubuntu16.04上是NPTL2.23(Native Posix Thread Lib),简单来说,Linux 进程主线程 PID = 进程 PID,而其它线程的 PID (LWP PID)则是独立分配的,可通过syscall(SYS_gettid)
得到。LWP 在 ps 命令中默认是被隐藏的,在/proc/目录下可以看到
通过-T参数将 LWP 在 SPID 列显示出来:
root# ps -p 28051 -lfT
F S UID PID SPID PPID C PRI NI ADDR SZ WCHAN STIME TTY TIME CMD
0 Z root 28051 28051 26889 0 80 0 - 0 exit 10:30 pts/10 00:00:00 [a.out] <defunct>
1 R root 28051 28054 26889 99 80 0 - 12409 - 10:30 pts/10 00:00:10 [a.out] <defunct>
1 R root 28051 28055 26889 99 80 0 - 12409 - 10:30 pts/10 00:00:10 [a.out] <defunct>
针对cgroup v1中的task和procs特性
- 将 Thread PID 写入 tasks: 仅对该”线程”(LWP) 生效
- 将 Thread PID 写入 cgroup.procs: 会加入整个 Proc PID
- 将 Proc PID 写入 tasks: 没有效果,写不进去
- 将 Proc PID 写入 cgroup.procs: 会加入整个 Proc PID
// 查看已有的subsystem
lssubsys -m
系统层级 #
文件描述符 #
- 系统级: 当前系统可打开的最大数量,
cat /proc/sys/fs/file-max
- 用户级: 指定用户可打开的最大数量,
cat /etc/security/limits.conf
- 进程级: 单个进程可打开的最大数量,
cat /proc/sys/fs/nr_open
获取镜像地址 #
grep -E '(^baseurl)|(^mirrorlist)' /etc/yum.repos.d/*.repo |awk -F= '{print $2}' | awk -F/ '{print $1$3}' | sort -u
drop_cache #
sync && echo 3 > /proc/sys/vm/drop_caches
模拟 #
# 分配1G的内存
stress-ng --vm 1 --vm-bytes 1G --timeout 60s
性能 #
top -Hp <pid> 显示某个pid的所有线程信息
shift + T 按照 CPU TIME进行排序
perf record -ag -F 999 <pid>
• -a 选项:-a 选项表示记录所有可用的 CPU 上的事件,即记录系统上所有 CPU 的性能数据。
• -g 选项:-g 选项表示记录调用图(Call Graph),即记录函数调用关系,包括用户态和内核态的函数调用关系。
• -F 999 选项:-F 999 选项表示设置记录频率为 999 Hz,即每秒记录 999 次性能事件数据。
内存相关 #
# 查看前10个占用内存最大的服务
ps aux --sort=-%mem | head -n 10 | awk '{sum += $6} END {print "Total memory used by top 10 processes: " sum " KB"}'
CPU相关 #
记录CPU使用率最高的进程信息 #
#!/bin/bash
# 循环执行时间段 (以秒为单位)
DURATION=1800 # 30 分钟 (8:00 - 8:30)
# 设置日志文件路径
log_file="./cpu_monitor.log"
start_time=$(date +%s)
# 循环监控
while [[ $(($(date +%s) - start_time)) -le $DURATION ]]; do
# 获取 CPU 利用率最高的进程信息
top_process=$(ps aux --sort=-%cpu | head -n 2 | tail -n 1)
# 提取进程 ID 和 CPU 利用率
pid=$(echo $top_process | awk '{print $2}')
cpu=$(echo $top_process | awk '{print $3}')
process=$(echo $top_process | awk '{print $NF}')
# 记录信息到日志文件
echo "$(date '+%Y-%m-%d %H:%M:%S') - CPU 利用率最高的进程:PID=$pid, CPU=$cpu%, 进程名=$process" >> $log_file
# 等待下一次监控
sleep 20
done
#!/bin/bash
current_datetime=$(date)
echo "当前日期和时间(默认格式): $current_datetime"
while true; do
# 使用 top 命令获取所有进程的CPU使用率
# -b 表示 batch 模式,-n 1 表示只获取一次数据
# 使用 awk 进行数据处理,查找 CPU 使用率大于80%的进程
top -b -n 1 | awk '
BEGIN {
# 设置输出字段的宽度,防止输出混乱
FS=" ";
OFS=" ";
}
/%Cpu/{
# 跳过标题行
next
}
{
# 获取进程的PID、用户、优先级、NI、虚拟内存大小、物理内存大小、状态、%CPU、%MEM、时间和命令
pid=$1; user=$2; pri=$3; ni=$4; vsize=$5; rss=$6; state=$7; cpu=$9; mem=$10; time=$11; command=$12
if (cpu > 80) {
# 如果 CPU 使用率超过80%,打印相关信息
print "High CPU usage detected:"
print "PID: " pid ", User: " user ", %CPU: " cpu "%"
print "Command: " command
print ""
}
}
'
sleep 5 # 每隔5秒检查一次
done
计算各个进程从各自拉起后CPU使用率 #
uptime=`awk '{print $1}' /proc/uptime`
hertz=`zcat /proc/config.gz | grep CONFIG_HZ= |awk -F"=" '{print $2}'`
awk -v uptime=$uptime -v hertz=$hertz -- '{printf("%d\t%s\t%11.3f\n", $1, $2, (100 *($14 + $15) / (hertz * uptime - $22)));}' /proc/*/stat 2> /dev/null | sort -gr -k +3 | head -n 20
如果存在大量系统调用,使用strace命令,否则可以用perf命令来进行采样
监听某个pid cpu使用率大于一个阈值,就执行某个命令 #
#!/bin/bash
# 检查是否传入了 PID 参数
if [ $# -ne 1 ]; then
echo "用法: $0 <process_pid>"
exit 1
fi
# 获取传入的 PID
PROCESS_PID=$1
# 设置 CPU 使用率阈值
THRESHOLD=80
# 检查 PID 是否存在
if ! ps -p "$PROCESS_PID" > /dev/null; then
echo "未找到 PID 为 $PROCESS_PID 的进程"
exit 1
fi
while true; do
# 获取进程的 CPU 使用率
CPU_USAGE=$(top -b -n1 | grep "$PROCESS_PID" | awk '{print $9}' | tr -d ',')
echo $CPU_USAGE
if (( $(echo "$CPU_USAGE >= $THRESHOLD" | bc -l) )); then
echo "进程 $PROCESS_PID 的 CPU 使用率超过 $THRESHOLD%,正在终止..."
# todo: 填写执行的命令
break
fi
sleep 5
done