📚 知识库更新 2026-06-10

更新项目:更新类型

  • Kubernetes 容器云学习路线总览
    • 集群架构与搭建
    • Pod 与核心工作负载
    • 网络与服务发现
    • 存储与配置管理
    • 调度与资源管理
    • 安全与认证
    • 监控日志与排错
    • 综合实战与赛题模拟

📚 知识库使用须知

欢迎来到职业技能大赛云计算赛项资料共享知识库!本知识库旨在为大家提供一个便捷、共享的信息检索与知识沉淀平台。为了帮助您更高效地使用本库,请在使用前阅读以下须知。

⚠️ 重要声明

  1. 文章无特定的顺序:本知识库中的文章并未按照特定的逻辑、优先级或时间线进行严格排序。文章的排列位置不代表其重要程度或阅读先后顺序,请您根据实际需求通过标题或关键词进行查阅。
  2. 可能会有文章无法索引:受限于系统机制、格式兼容性或标签缺失,部分文章可能无法被搜索框准确检索到。如果您通过搜索未能找到所需内容,建议尝试浏览相关分类目录,或直接向维护人员咨询。

🔍 常见问题与解答 (FAQ)

Q1:为什么我搜索关键词,却找不到明明存在的文章?

  • A:这正是由于上述声明中提到的“索引限制”。部分历史导入的文章、特殊格式内容或未添加标签的文章可能会被搜索引擎忽略。建议您:
    • 更换同义词或缩短关键词再次搜索;
    • 直接前往对应的书籍/分类目录下手动查找;
    • 向管理员反馈,补充该文章的搜索标签。

Q2:文章内容出现错别字、过时或不准确怎么办?

  • A:知识库需要大家共同维护。如果您发现内容有误,欢迎直接点击编辑进行修改;如果您无编辑权限,请通过邮箱联系管理员进行更正。

Q3:我可以自己新建页面/文章吗?

  • A:目前仅管理员拥有编辑权限,如需新增内容请联系管理员。

Q4:为什么有些页面里的图片无法显示/链接失效?

  • A:部分文章可能是从外部导入或迁移而来的,其中的附件、图片或外部链接可能已失效。如遇此类情况,请及时联系维护人员修复。

Q5:如何快速找到我需要的内容?

  • A:推荐以下几种检索方式:
    • 精准搜索:使用搜索框输入核心专业词汇;
    • 分类浏览:通过左侧导航栏的“书籍”或“章节”分类逐级查找;
    • 标签筛选:通过文章底部的标签,快速聚合同类文章。

🤝 维护与反馈

本知识库的内容依赖于大家的共同完善。如果您在使用过程中遇到任何问题,包括但不限于文章无法索引、页面加载异常、权限申请等,请随时联系知识库管理员:lzf@lizf.cn 感谢您的理解与配合,祝您使用愉快!

Linux 基础命令大全

Linux 常用命令按功能类别分类整理,涵盖 10 大类别130+ 命令及常用示例。按使用频率从高到低排列。


📁 一、文件与目录管理

日常操作最频繁的类别,几乎每次终端会话都会用到。

命令 功能说明 常用示例
cd 切换工作目录 cd ~ 回 HOME;cd - 回上一目录
ls 列出目录内容 ls -lah 显示所有文件(含隐藏)+ 人类可读大小
pwd 显示当前路径 pwd
mkdir 创建目录 mkdir -p A/B/C 递归创建多级
cp 复制文件/目录 cp -r SRC/ DEST/ 递归复制
mv 移动/重命名 mv OLD.TXT NEW.TXT
rm 删除文件/目录 rm -rf DIR/ ⚠️ 谨慎使用
touch 创建空文件 / 更新 MTIME touch FILE.TXT
ln 创建链接 ln -s /REAL/PATH LINK 软链接
find 搜索文件 find /var -name "*.log" -type f
tree 树形展示目录 tree -L 2 限制 2 层深度
stat 查看 INODE 元数据 stat FILE.TXT
file 探测文件真实类型 file SCRIPT.SH
df 查看文件系统使用率 df -hT 人类可读 + 类型
du 统计磁盘用量 du -sh /* 统计各目录总大小
locate 快速搜索(依 MLOCATE 库) locate NGINX.CONF
rmdir 删除空目录 rmdir EMPTYDIR/

📄 二、文件查看与文本处理

日常查阅文件、搜索日志、文本分析的常用工具。

命令 功能说明 常用示例
cat 输出文件全部内容 cat -n FILE.TXT 显示行号
less 交互式分页(支持 ↑↓ / 搜索) less /var/log/syslog
grep 正则搜索文本 grep -rn "FIXME" SRC/ 递归 + 行号
head 查看开头 N 行 head -n 20 DATA.CSV
tail 查看末尾 N 行 tail -f APP.LOG 实时追踪
echo 输出文本 echo "$HOME"
wc 统计行/词/字符 wc -l FILE.SH 行数
sort 排序 sort -t, -k2 -rn DATA.CSV
sed 流编辑器(替换/删除/插入) sed 's/foo/bar/g' FILE
awk 列式文本分析语言 awk '{print $1}' DATA.LOG 取第一列
cut 按分隔符截取列 cut -d: -f1 /etc/passwd
uniq 去重(需配合 SORT) sort FILE | uniq -c 统计频次
tr 字符替换/删除 echo HELLO | tr 'A-Z' 'a-z' 转小写
tee 分叉输出(落盘 + 屏幕) command | tee -a LOG.TXT
xargs 将 STDIN 转为命令参数 find . -name "\*.tmp" | xargs rm -f
diff 逐行比较差异 diff -u F1 F2 统一格式
more 分页(仅 ↓) more LONGFILE.TXT
tac 倒序输出(最后一行在前) tac FILE.LOG
nl 带行号输出 nl -ba FILE.TXT 空行也编号
paste 按列合并 paste NAMES.TXT PHONES.TXT
join 按公共字段关联 join -t, -1 1 -2 1 A.CSV B.CSV
column 对齐为表格 column -t -s: /etc/passwd
rev 反转每行字符 rev FILE.TXT
fold 按宽度折行 fold -w 80 TEXT.TXT
split 切分大文件 split -l 10000 BIG.LOG CHUNK_
od 八进制/十六进制 DUMP od -c FILE.BIN 以字符形式查看
comm 比较已排序文件 comm F1 F2 显示独有/共有行

🔐 三、权限与用户管理

系统安全和日常用户管理的核心命令。

命令 功能说明 常用示例
sudo 提权执行 sudo -u POSTGRES PSQL
chmod 修改文件权限 chmod 755 SCRIPT.SHchmod u+x SCRIPT.SH
chown 修改所有者 chown USER:GROUP FILE.TXT
id 显示 UID/GID/组 id
whoami 当前用户名 whoami
su 切换用户 su - USER1 加载目标环境
passwd 设置/更改密码 passwd USER1
useradd 创建用户 useradd -m -s /bin/bash USER1
usermod 修改用户属性 usermod -aG DOCKER USER1 追加组
userdel 删除用户 userdel -r USER1 连带删除 HOME
who 已登录用户 who -b 含系统启动时间
w 登录用户 + 活动 w
users 当前登录用户列表 users
last 最近登录记录 last -n 5 最近 5 条
chgrp 修改所属组 chgrp DEV FILE.TXT
groupadd 创建组 groupadd DEVOPS
groupdel 删除组 groupdel DEVOPS
umask 设置默认权限掩码 umask 022

⚙️ 四、进程管理

系统运行中进程的查看、监控和控制。

命令 功能说明 常用示例
ps 进程快照 ps aux | grep NGINX
top 实时进程监控 P CPU 排序;M 内存排序
kill 按 PID 终止 kill -15 PID 优雅;kill -9 PID 强制
uptime 运行时长 + 负载 uptime
nohup 忽略 HUP 信号运行 nohup ./SERVER.SH &
bg / fg 后台 / 前台切换 Ctrl+Zbg
jobs 列出后台任务 jobs -l 含 PID
htop TOP 增强版(需安装) htop
watch 周期执行 watch -n 2 'free -h' 每 2 S 刷新
killall 按名称终止全部 killall -9 NGINX
pkill 按模式匹配终止 pkill -f "PYTHON APP.PY"
pidof 查看进程 PID pidof NGINX
pgrep 按名称查找 PID pgrep -u ROOT NGINX
nice 以指定优先级启动 nice -n 10 ./SLOW-TASK
renice 调整运行中进程优先级 renice -n 5 -p 1234
time 计时 time ./SCRIPT.SH

🖥️ 五、系统管理

系统信息查看、服务管理、日志分析和环境配置。

命令 功能说明 常用示例
man 查看手册 man LS
systemctl SYSTEMD 服务管理 systemctl status NGINXenable/start/stop
free 内存使用 free -ht 人类可读 + 总计
date 日期时间 date +%F → 2026-05-24
history 命令历史 history | grep CURL!! 重复上条
hostname 主机名 / IP hostname -I 显示 IP
uname 内核/架构信息 uname -a
export 设置环境变量 export PATH=$PATH:/usr/local/bin
alias 设置别名 alias ll='ls -lh'
unalias 取消别名 unalias LL
env 查看所有环境变量 env | grep PATH
journalctl SYSTEMD 日志 journalctl -u NGINX --since "1 hour ago"
whatis 命令简短说明 whatis LS
dmesg 内核日志 dmesg -T | tail -20 加时间戳
shutdown 关机/重启 shutdown -h nowshutdown -r +5
reboot 重启 reboot
cal 日历 cal 2026 全年
crontab 定时任务 crontab -e0 3 * * * BACKUP.SH
timedatectl 时区/时间管理 timedatectl list-timezones
lscpu CPU 信息 lscpu
lsblk 块设备列表 lsblk -f 含文件系统
lspci PCI 设备 lspci -v
at 一次性定时 at now + 1 HOUR
locale 查看语言环境 locale -a 可用 LOCALE 列表
lsusb USB 设备 lsusb -t 树形
dmidecode 硬件信息(需 ROOT) dmidecode -t MEMORY

🌐 六、网络管理

网络连通性、连接状态、远程访问和下载工具。

命令 功能说明 常用示例
ping 连通性测试 ping -c 4 8.8.8.8
ssh 远程登录 ssh -i KEY.PEM USER@HOST -p 22
curl 数据传输工具 curl -I HTTP://EXAMPLE.COM 含请求头
ip 网络配置(现代) ip addrip route show
ss 套接字统计(推荐) ss -tulnp 监听端口 + 进程
wget 下载工具 wget -c URL 断点续传
scp 远程复制 scp FILE USER@HOST:/TMP/
rsync 增量同步 rsync -avz --delete /SRC/ USER@HOST:/DEST/
ifconfig 网卡配置(旧) ifconfig ETH0 UP
lsof 打开文件/端口 lsof -i :80
netstat 网络状态(旧) netstat -tulnpnetstat -r
nc 网络瑞士军刀 nc -zv HOST 22 端口测试
dig DNS 查询 dig +short EXAMPLE.COM
nslookup DNS 查询 nslookup GOOGLE.COM
traceroute 路由追踪 traceroute -n GOOGLE.COM
mtr 网络诊断 mtr -rw GOOGLE.COM
tcpdump 抓包 tcpdump -i ETH0 port 80 -w OUT.PCAP
host DNS 简易查询 host EXAMPLE.COM
nmap 端口扫描 nmap -sT 192.168.1.1
route 路由表 route -n
arp ARP 缓存 arp -a
ufw 简易防火墙 ufw allow 22/tcpufw status verbose
ethtool 网卡参数 ethtool ETH0

💾 七、磁盘与存储管理

磁盘分区、格式化、挂载和状态查看。

命令 功能说明 常用示例
mount 挂载 mount /dev/sdb1 /mnt/data
df 磁盘空间使用率 df -hT
du 目录/文件磁盘用量 du -sh /home/*
umount 卸载 umount /mnt/data
blkid 查看 UUID / 类型 blkid
findmnt 挂载树视图 findmnt -t EXT4
sync 刷写磁盘缓存 sync
fdisk 磁盘分区 sudo fdisk -l /dev/sda
mkfs 格式化(创建文件系统) mkfs.ext4 /dev/sdb1
parted 高级分区 sudo parted /dev/sda print
fsck 检查/修复文件系统 fsck -f /dev/sda1
swapon / swapoff 启用/关闭 SWAP swapon --show 查看
dd 低级数据拷贝 dd if=/dev/sda of=/BACKUP.IMG bs=4M status=progress
smartctl 硬盘健康/属性(S.M.A.R.T.) smartctl -H /dev/sda 查看健康状态
eject 弹出光驱 eject /dev/sr0

📦 八、压缩与归档

文件打包、压缩和解压工具。

命令 功能说明 常用示例
tar 打包/压缩 tar -czvf ARCHIVE.TAR.GZ DIR/
gzip / gunzip 压缩/解压 .GZ gzip FILE.TXT
zip / unzip ZIP 格式压缩/解压 zip -r ARCHIVE.ZIP DIR/
bzip2 / bunzip2 压缩/解压 .BZ2(高压缩率) bzip2 FILE.TXT
xz / unxz 压缩/解压 .XZ(极高压缩率) xz -k FILE.TXT 保留原文件
zcat 读取 .GZ 内容 zcat ACCESS.LOG.GZ
zgrep .GZ 中搜索 zgrep "500" ACCESS.LOG.GZ
zless 分页查看 .GZ zless SYSLOG.1.GZ
compress / uncompress 旧式 .Z 压缩 compress FILE.TXT

TAR 参数速查

操作 命令
打包 tar -cvf ARCHIVE.TAR DIR/
解包 tar -xvf ARCHIVE.TAR
压缩为 .TAR.GZ tar -czvf ARCHIVE.TAR.GZ DIR/
解压 .TAR.GZ tar -xzvf ARCHIVE.TAR.GZ
压缩为 .TAR.BZ2 tar -cjvf ARCHIVE.TAR.BZ2 DIR/
解压 .TAR.BZ2 tar -xjvf ARCHIVE.TAR.BZ2
压缩为 .TAR.XZ tar -cJvf ARCHIVE.TAR.XZ DIR/
解压 .TAR.XZ tar -xJvf ARCHIVE.TAR.XZ
仅查看内容 tar -tvf ARCHIVE.TAR

📦 九、包管理

各发行版的软件包安装、升级和卸载命令。

系统 命令 功能说明 常用示例
Debian/Ubuntu apt 高级包管理(推荐) apt update && apt install -y NGINX
Debian/Ubuntu apt-get 传统包管理 apt-get install -y NGINX
Debian/Ubuntu dpkg 底层 .DEB 操作 dpkg -i PACKAGE.DEBdpkg -l 列出
RHEL/CentOS 8+ dnf 新一代包管理器 dnf install NGINX
RHEL/CentOS 7 yum 传统包管理器 yum install -y NGINX
RHEL/CentOS rpm 底层 .RPM 操作 rpm -ivh PKG.RPMrpm -qa 查询
Arch Linux pacman ARCH 包管理器 pacman -S NGINX
通用(跨发行版) snap SNAP 包 snap install LXD
通用(跨发行版) flatpak FLATPAK 包 flatpak install FLATHUB ORG.VIDEOLAN.VLC

🛠️ 十、Shell 内置与杂项

Shell 编程和终端操作的基础指令集。

命令 功能说明 常用示例
echo 输出文本 echo "HELLO, $USER"
test / [ ] 条件测试 test -f FILE.TXT && echo EXISTS
read 读取用户输入 read -p "ENTER NAME: " NAME
set 查看/设置 SHELL 选项 set -e 出错即停
source / . 在当前 SHELL 加载脚本 source ~/.zshrc
exit 退出 SHELL exit 0
printf 格式化输出 printf "%-10s %s\n" NAME VALUE
clear 清屏 clear
sleep 暂停指定秒数 sleep 5
type 判断命令类型(BUILTIN/ALIAS/EXTERNAL) type CD
which 查找可执行文件路径 which PYTHON3
unset 删除变量或函数 unset DEBUG
whereis 查找二进制/源码/MAN whereis LS
true-false-sleep / true-false-sleep 返回 0 / 非 0 退出码 while true; do ...; done
command 忽略别名直接执行 command ls -la
exec 替换当前 SHELL 进程 exec ZSH

🔗 实用管道组合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# IP 访问频率 Top 10
awk '{print $1}' access.log | sort | uniq -c | sort -nr | head -10

# 查找 100 MB 以上文件
find / -type f -size +100M -exec ls -lh {} \; 2>/dev/null | sort -k5 -h | head

# 实时监控错误日志
tail -f app.log | grep --color=auto "ERROR\|CRITICAL"

# 统计项目代码行数
find SRC/ -name "*.py" | xargs wc -l | tail -1

# 查看磁盘占用 Top 10
du -sh /home/* | sort -rh | head -10

# 批量替换文件内容
grep -rl "old_string" CONFIG/ | xargs sed -i 's/old_string/new_string/g'

# 查看所有监听端口
ss -tulnp | awk 'NR>1{print $1, $5, $7}' | column -t

# 检查系统负载
uptime && free -h && df -h /

⌨️ 终端常用快捷键

快捷键 作用
Ctrl + C 终止当前命令
Ctrl + D EOF / 退出 SHELL
Ctrl + Z 挂起(可 bg 后台执行)
Ctrl + L 清屏
Ctrl + A 光标到行首
Ctrl + E 光标到行尾
Ctrl + R 反向搜索历史
Ctrl + W 删除前一个词
Ctrl + U 删除到行首
Ctrl + K 删除到行尾
!! 重复上条命令
!$ 上条命令最后一个参数
!str 匹配最近的以 STR 开头的命令

提示: 每个命令的完整手册可通过 man <command> 查看,快速帮助用 <command> --help。每个命令的原子化文档参见对应分类目录。


📚 原子化命令文档

每个命令独立成一个文件,按分类存放:

编号 分类 目录 命令数
01 文件与目录管理 文件与目录管理/ 17
02 文件查看与文本处理 文件查看与文本处理/ 28
03 权限与用户管理 权限与用户管理/ 18
04 进程管理 进程管理/ 16
05 系统管理 系统管理/ 24
06 网络管理 网络管理/ 20
07 磁盘与存储管理 磁盘与存储管理/ 12
08 压缩与归档 压缩与归档/ 7
09 包管理 包管理/ 7
10 Shell 内置与杂项 Shell内置与杂项/ 12

🚀 Kubernetes 容器云 30 天学习路线

📜 计划公约

以下约定为学习计划的基础环境规范,每日操作基于此环境进行。违反约定可能导致环境不稳定或学习效果打折扣。

一、控制平面(Control Plane / Master 节点)

项目 最小规格 最佳规格 说明
vCPU 2 核 4 核 kube-apiserver、etcd 吃 CPU
内存 4 GB 8 GB etcd 需常驻 2GB+ 缓存
磁盘 40 GB 100 GB SSD etcd 对磁盘 I/O 敏感,SSD 必备
操作系统 CentOS Stream 9 CentOS Stream 9 内核 5.14+,RHEL 兼容生态
内核版本 ≥ 5.4 5.14+ 支持 cgroup v2、eBPF
主机名 k8s-master 部署后不可更改
网络 仅主机 / NAT 内网 IP 固定,不做 DHCP

为什么控制平面对磁盘敏感? etcd 是 K8s 的”大脑”,所有集群状态都存储在 etcd 中。etcd 使用 Raft 共识算法,每次写操作都需要 fsync 落盘。如果磁盘 I/O 不足(如使用 HDD 或云盘低 IOPS),etcd 的 fsync 延迟会飙升,导致:

  • kube-apiserver 响应超时(默认 3s)
  • 控制器反复重启
  • 集群”脑裂”风险增大

经验值: etcd 所在的磁盘建议 ≥ 500 IOPS,云环境选择 “SSD 云盘”或”性能型云盘”,切勿选”高效云盘”。

二、计算平面(Compute Plane / Worker 节点)

项目 最小规格(×2 台) 最佳规格(×2 台) 说明
vCPU 2 核 4 核 运行业务 Pod
内存 2 GB 8 GB 内存是 Pod 调度瓶颈
磁盘 40 GB 100 GB SSD 容器镜像 + 本地存储
操作系统 CentOS Stream 9 CentOS Stream 9 与 Master 保持一致
内核版本 ≥ 5.4 5.15+
主机名 k8s-worker1 / k8s-worker2 唯一标识

三、集群总资源预算

方案 Master Worker × 2 总计 月费用参考(大陆云厂商)
最小方案 2C4G40G 2C2G40G 6C8G120G 约 ¥200-300/月
推荐方案 4C8G100G 4C8G100G 12C24G300G 约 ¥500-800/月
竞赛模拟方案 4C8G100G 4C8G100G × 3 16C32G400G 约 ¥800-1200/月

省钱技巧:

  • 使用竞价实例/抢占式实例(价格低 60%-80%),学习时段避开竞价回收高峰
  • 不做实验时关机,云盘按量计费保留数据
  • 选择新用户首购优惠(通常 1C1G 起步的低配机型不合算,直接上 4C8G)

四、操作系统与环境公约

约定项 必须执行 原因
禁用 Swap swapoff -a + 注释 /etc/fstab kubelet 强制要求,Swap 会破坏 Pod 内存 QoS
关闭防火墙 systemctl stop firewalld && systemctl disable firewalld(学习环境) 简化网络配置;生产环境应开放特定端口
禁用 SELinux setenforce 0 + 编辑 /etc/selinux/configSELINUX=permissive 避免容器权限问题;CentOS 默认启用 SELinux
加载内核模块 br_netfilteroverlay 容器网络和存储驱动依赖
网络参数 net.bridge.bridge-nf-call-iptables = 1 桥接流量经 iptables 处理(Service 转发依赖)
容器运行时 containerd ≥ 1.6 更轻量,CKA/CKS 官方推荐
K8s 版本 v1.28 ~ v1.30 与大赛考纲对齐,不要追新
CNI 插件 Calico 支持 NetworkPolicy,大赛高频考点
Snap 卸载 不适用(CentOS 无 Snap) Snap 为 Ubuntu 专有,CentOS 无需处理
时区/NTP timedatectl set-timezone Asia/Shanghai 日志时间一致,排错不迷路

以上为环境规格约定,具体搭建步骤见 Day 01 动手实操

📋 适用对象

  • 起点:掌握 Docker 基础(Dockerfile、docker-compose、镜像构建)
  • 目标:职业技能大赛 Kubernetes 容器云方向
  • 时间:1-2 个月,每天约 4 小时
  • 环境:云服务器搭建 1 master + 2 worker 集群

🏗️ 学习方法论

1
2
3
4
5
6
7
8
9
每日节奏:
理论精讲(20%)→ 动手实操(50%)→ 排错练习(15%)→ 赛题模拟(15%)

具体时间分配(240 分钟/天):
├── 理论精讲 ~30 分钟
├── 演示示范 ~20 分钟
├── 动手实操 ~120 分钟
├── 排错练习 ~30 分钟
└── 赛题模拟 ~40 分钟

📦 模块总览

模块 主题 天数 入口 核心实操 权重
M1 集群架构与搭建 3 天 Day 01→03 手动部署 3 节点集群、etcd 备份、版本升级 🔵 基础
M2 Pod 与核心工作负载 4 天 Day 04→07 管理 Deployment/StatefulSet/DaemonSet/Job/CronJob 🔴 核心
M3 网络与服务发现 4 天 Day 08→11 Service/Ingress/NetworkPolicy/CNI 配置 🔴 核心
M4 存储与配置管理 4 天 Day 12→15 PV/PVC/ConfigMap/Secret/StorageClass 🔴 核心
M5 调度与资源管理 3 天 Day 16→18 亲和性/污点容忍/HPA/资源限制/QoS 🟡 进阶
M6 安全与认证 3 天 Day 19→21 RBAC/ServiceAccount/PodSecurity/镜像安全 🟡 进阶
M7 监控日志与排错 3 天 Day 22→24 Prometheus/EFK/故障注入/排错方法论 🟡 进阶
M8 综合实战与赛题模拟 6 天 Day 25→30 8 套完整赛题 + 限时挑战 + 全真模拟 🟢 冲刺

📁 文档目录

模块 Day 文章标题
M1 集群架构与搭建 Day 01 集群架构原理与环境准备
Day 02 多节点集群与节点管理
Day 03 集群运维与 kubectl 精通
M2 Pod 与核心工作负载 Day 04 Pod 生命周期与多容器模式
Day 05 Deployment 与 ReplicaSet
Day 06 DaemonSet、StatefulSet、Job、CronJob
Day 07 Pod 资源综合实战
M3 网络与服务发现 Day 08 Service 与集群内服务发现
Day 09 Ingress 与外部流量接入
Day 10 网络策略与 CNI 原理
Day 11 网络综合实战
M4 存储与配置管理 Day 12 ConfigMap 与 Secret
Day 13 Volume 与 PV/PVC
Day 14 StorageClass 与动态供给
Day 15 存储综合实战
M5 调度与资源管理 Day 16 调度策略与亲和性
Day 17 资源限制与 QoS
Day 18 调度综合实战
M6 安全与认证 Day 19 RBAC 权限控制
Day 20 ServiceAccount 与镜像安全
Day 21 安全综合实战
M7 监控日志与排错 Day 22 Prometheus 监控体系
Day 23 日志收集与 EFK
Day 24 故障排查实战
M8 综合实战与赛题模拟 Day 25 赛题模拟 1-3
Day 26 赛题模拟 4-5
Day 27 赛题模拟 6-7
Day 28 赛题模拟 8 + 限时挑战
Day 29 弱点回顾与强化
Day 30 全真模拟考试

📚 实践题目来源与参考

一级来源(官方权威)

来源 链接 说明
Kubernetes 官方文档 https://kubernetes.io/docs/home/ 所有概念的权威定义;每个资源都有 YAML 示例
Kubernetes 官方教程 https://kubernetes.io/docs/tutorials/ 从零到集群部署的分步教程
kubectl 命令参考 https://kubernetes.io/docs/reference/kubectl/ 每个命令的参数与用法
Kubernetes GitHub https://github.com/kubernetes/kubernetes 源码级理解,Issues 中有大量排错案例
Kubernetes Blog https://kubernetes.io/blog/ 新特性、版本变更说明

二级来源(考试与竞赛)

来源 说明
CNCF CKA 考纲 https://github.com/cncf/curriculum — K8s 管理员认证,实操题与大赛高度重叠
CNCF CKAD 考纲 https://github.com/cncf/curriculum — 应用开发者认证,侧重 Pod/Deploy/Config 实践
CNCF CKS 考纲 https://github.com/cncf/curriculum — 安全专家认证,M6 安全模块核心参考
Killer Shell (CKA/CKAD) https://killer.sh — 付费模拟器,题目风格与真实考试一致
全国职业院校技能大赛官网 历年赛题规程与样题(自行搜索”职业技能大赛 容器云”)

三级来源(练习平台)

来源 说明
Play with Kubernetes https://labs.play-with-k8s.com — 免费在线 K8s 沙箱(4 小时/次)
Katacoda → Killercoda https://killercoda.com — 在线交互式 K8s 场景练习
Minikube 本地环境 minikube start --cpus=4 --memory=8192 — 无云服务器时的本地替代
Kind (K8s in Docker) kind create cluster — Docker 里跑多节点集群,网络策略测试友好

四级来源(书籍与社区)

来源 说明
《Kubernetes in Action》第二版 最经典 K8s 书籍,概念讲得最透
《Kubernetes 权威指南》 中文版,实操性强
Kubernetes Slack (#kubernetes-users) 全球最大 K8s 社区,排错求助响应快
Stack Overflow (kubernetes 标签) 搜索错误信息,大概率已有答案
CNCF Landscape https://landscape.cncf.io — 了解 K8s 生态全貌

实践建议: CKA 模拟题是最接近大赛实操题的资源。按模块刷 CKA 真题,每题限时 5-10 分钟,重点训练命令行速度(kubectl 补全 + 别名 + 速记 YAML 模板)。大赛中 80% 的题都是”给一段描述 → 输出 YAML → 部署 → 验证”,与 CKA 完全一致。


📋 核心命令速查(命令 → 功能 → 注解)

以下命令按模块组织,每条命令附带详细功能注解。建议:

  • 日训 3-6 条,每条命令在终端执行并理解输出
  • 熟记 12 个最常用子命令(get/describe/create/apply/delete/logs/exec/explain/edit/scale/rollout/taint),它们是排错和赛题的骨架

kubectl 基础(M1)

命令 功能 注解
kubectl cluster-info 查看集群 Master 与 CoreDNS 地址 验证集群是否可用,输出 apiserver + DNS 地址即正常
kubectl version 查看客户端与服务端版本 客户端 kubectl 与 apiserver 版本偏差不超过 ±1 个小版本(v1.28+ 已移除 –short 标志)
kubectl get nodes 列出所有节点 STATUS 必须为 ReadyNotReady 意味节点失联或 CNI 未就绪
kubectl get nodes -o wide 节点列表 + 内网 IP/OS/内核/运行时 查看节点的网络可达性和运行时版本,排错第一步
kubectl describe node <node> 节点详细信息 查看 Conditions(内存/磁盘压力)、Taints、已分配资源;排错必用
kubectl get ns 列出所有命名空间 kube-system 存放集群组件;default 是用户默认空间
kubectl get pods -A 列出所有命名空间的 Pod -A = --all-namespaces,全局视图快速定位问题
kubectl get pods -n kube-system 查看系统组件 Pod etcd/apiserver/controller-manager/scheduler/coredns 的运行状态
kubectl get pods -o wide Pod 列表 + 节点 + IP 快速定位 Pod 运行在哪台节点,IP 是什么
kubectl describe pod <pod> Pod 详细信息 查看 Events(启动失败原因就在这里)、挂载卷、容器状态
kubectl logs <pod> 查看 Pod 日志(单容器) 最常用排错命令;-f 实时跟踪
kubectl logs <pod> -c <container> 查看指定容器日志 多容器 Pod 必须用 -c 指定容器名
kubectl logs <pod> --tail=50 查看最后 50 行日志 避免刷屏,快速看最新输出
kubectl logs <pod> --since=5m 查看最近 5 分钟日志 时间范围过滤,排查近期的异常
kubectl exec <pod> -- <cmd> 进入容器执行命令 -- 分隔 kubectl 参数和容器内命令
kubectl exec -it <pod> -- /bin/sh 交互式进入容器 相当于 docker exec -it,排错时进容器检查文件/网络
kubectl get all -n <ns> 查看某命名空间所有资源 包含 Pod/Service/Deploy/RS,快速了解某个 NS 的全貌
kubectl explain pod.spec.containers 查看资源字段文档 不需要翻官网,直接终端查字段含义和类型,写 YAML 神器
kubectl explain pod.spec --recursive 递归查看所有子字段 全面了解一个资源的 YAML 结构
kubectl api-resources 列出所有 API 资源类型 查看 K8s 支持哪些资源,包括 short name(如 svc/deploy/po
kubectl api-versions 列出所有 API 版本 了解当前集群支持的 API Group 和版本

YAML 管理(M1)

命令 功能 注解
kubectl create deploy nginx --image=nginx --dry-run=client -o yaml 生成 YAML 而不创建资源 --dry-run=client 本地校验不提交到集群;YAML 速成最佳技巧
kubectl apply -f file.yaml 声明式创建/更新资源 优先用 apply 而非 create;apply 会 diff 合并,幂等安全
kubectl create -f file.yaml 命令式创建资源 重复执行会报 “already exists”,非幂等
kubectl delete -f file.yaml 按 YAML 删除资源 删除该 YAML 中定义的所有资源
kubectl edit deploy <name> 直接编辑集群中的资源 实时生效;手快但危险,建议先 get -o yaml 备份
kubectl patch deploy <name> -p '{"spec":{"replicas":3}}' 部分更新资源(JSON Patch) 修改单个字段比 edit 更安全,适合脚本化操作
kubectl scale deploy <name> --replicas=5 快速扩缩副本数 等价于 kubectl edit 修改 replicas
kubectl rollout status deploy <name> 查看滚动更新进度 等待更新完成,常用于脚本中阻塞等待
kubectl rollout history deploy <name> 查看部署历史 查看 revision 号,配合 --revision 查看具体变更
kubectl rollout undo deploy <name> 回滚到上一个版本 回滚只回 deploy 模板,不回代码仓库
kubectl rollout undo deploy <name> --to-revision=2 回滚到指定版本 前提是该 revision 的历史还存在(默认保留 10 个)

Pod 与工作负载(M2)

命令 功能 注解
kubectl get deploy,rs,pod 同时查 Deploy/RS/Pod 逗号分隔多资源类型,一次看清层级关系
kubectl get deploy -o wide Deployment + 镜像/标签/副本数 快速确认当前部署用了哪个镜像
kubectl set image deploy/<name> <container>=<new-image> 更新 Deployment 的容器镜像 触发滚动更新,比 kubectl edit 效率高
kubectl get sts 列出 StatefulSet short name: sts
kubectl get ds 列出 DaemonSet short name: ds
kubectl get job,cronjob 列出 Job 和 CronJob short name: cj
kubectl delete pod <pod> --force --grace-period=0 强制立即删除 Pod 卡在 Terminating 时的救急操作
kubectl top pods -A 查看 Pod 实时资源用量 需要安装 metrics-server
kubectl top nodes 查看节点实时资源用量 判断节点是否资源紧张
kubectl cp <pod>:<path> <local-path> 从 Pod 拷贝文件到本地 双向可操作(本地 → Pod 也支持)
kubectl port-forward pod/<pod> 8080:80 本地端口转发到 Pod 无需 Service/Ingress 即可本地访问 Pod 端口

网络与服务发现(M3)

命令 功能 注解
kubectl get svc,endpoints Service + 后端 Endpoints endpoints 显示 Pod IP 列表;为空说明 Selector 没匹配到 Pod
kubectl expose deploy <name> --port=80 --target-port=8080 快速创建 Service 暴露 Deploy 一键生成 ClusterIP 类型的 Service
kubectl expose deploy <name> --type=NodePort --port=80 创建 NodePort Service 节点 IP:NodePort 可外部访问
kubectl get ingress 列出 Ingress 规则 需要安装 Ingress Controller(如 nginx-ingress)
kubectl get networkpolicy 列出网络策略 需要 CNI 支持(Calico 支持)
kubectl run test --image=busybox --rm -it -- wget -O- http://svc-name 临时 Pod 测试 Service 可达性 --rm 退出即删除;测试网络问题首选
kubectl exec <pod> -- nslookup <svc-name> 验证 DNS 解析 CoreDNS 故障导致 Service 不可用的首要排查
kubectl exec <pod> -- curl -s http://<svc-name>.<ns>.svc.cluster.local 验证全限定域名访问 FQDN 格式:<svc>.<namespace>.svc.cluster.local

存储与配置(M4)

命令 功能 注解
kubectl get pv,pvc 查看 PV 和 PVC STATUS: Bound 正常;Pending 说明没有 PV 能匹配
kubectl get sc 列出 StorageClass 动态供给的前提;默认 SC 标记为 (default)
kubectl get cm,secret 列出 ConfigMap 和 Secret Secret 值 base64 编码,get -o yamlecho <值> | base64 -d 解码
kubectl create cm <name> --from-file=<path> 从文件创建 ConfigMap 配置文件完整挂载为 ConfigMap
kubectl create cm <name> --from-literal=key=value 从键值对创建 ConfigMap 快速创建简单配置项
kubectl create secret generic <name> --from-literal=key=value 创建 Opaque Secret 值自动 base64 编码存储
kubectl create secret tls <name> --cert=cert.pem --key=key.pem 创建 TLS Secret Ingress TLS 终端必须用此类型 Secret

调度与资源管理(M5)

命令 功能 注解
kubectl taint node <node> key=value:NoSchedule 给节点添加污点 默认只有 Toleration 匹配的 Pod 才能调度上去
kubectl taint node <node> key=value:NoSchedule- 移除节点污点 末尾加 - 删除对应 Taint
kubectl cordon <node> 标记节点不可调度 等同于添加 node.kubernetes.io/unschedulable:NoSchedule
kubectl uncordon <node> 恢复节点可调度 取消 cordon 标记
kubectl drain <node> --ignore-daemonsets --delete-emptydir-data 驱逐节点上所有 Pod 安全下线节点前必执行;DaemonSet 管理的 Pod 用 --ignore-daemonsets 跳过
kubectl label node <node> key=value 给节点打标签 配合 nodeSelector/nodeAffinity 使用
kubectl get hpa 查看水平自动扩缩器 当前 CPU/内存使用率与目标值对比
kubectl autoscale deploy <name> --min=2 --max=10 --cpu=80% 创建 HPA 基于 CPU 使用率自动扩缩

安全与认证(M6)

命令 功能 注解
kubectl auth can-i create pods 检查当前用户是否有某权限 快速验证 RBAC 配置是否正确
kubectl auth can-i create pods --as=system:serviceaccount:ns:sa 检查某 SA 是否有权限 调试 ServiceAccount 权限问题
kubectl get role,rolebinding 列出命名空间级 RBAC Role 定义权限;RoleBinding 绑定到用户/SA
kubectl get clusterrole,clusterrolebinding 列出集群级 RBAC ClusterRole 全局权限(如节点、PV)
kubectl create role <name> --verb=get,list --resource=pods -n <ns> 快速创建 Role --verb--resource 即可,无需手写 YAML
kubectl create rolebinding <name> --role=<role> --serviceaccount=<ns>:<sa> 快速创建 RoleBinding 将 SA 与 Role 绑定
kubectl get sa 列出 ServiceAccount 每个 NS 有默认 default SA
kubectl get podsecuritykubectl get psa 查看 Pod Security Admission 1.25+ 替代 PSP 的机制

监控与排错(M7)

命令 功能 注解
kubectl describe pod <pod> | grep -A 10 Events 只查看 Pod Events Events 是排错第一入口
kubectl get events --sort-by=.metadata.creationTimestamp 按时间排序查看集群 Event 全局视角看哪些资源在出问题
kubectl get events -w 实时监听 Event -w = --watch,观察操作过程中触发的事件
kubectl get pods --field-selector=status.phase=Pending 按状态筛选 Pod 快速找到所有 Pending/Failed/Unknown Pod
kubectl get pods --field-selector=spec.nodeName=<node> 筛选某节点上的 Pod 节点故障时快速定位受影响 Pod
kubectl cluster-info dump | grep -A 20 "error|failed|Error" dump 集群诊断信息 输出包含所有组件的日志摘要
journalctl -u kubelet -f 查看 kubelet 日志(节点) kubelet 是节点代理,Pod 启停失败根因在 kubelet 日志
crictl ps -a 列出所有容器(含已退出) K8s 1.24+ 不再支持 docker,用 crictl 替代;排错 Pod 启动失败
crictl logs <container-id> 查看容器日志(crictl 方式) 在 kubectl logs 不可用时(如容器还没启动)的备选
kubectl -n kube-system logs kube-apiserver-<node> 查看 apiserver 日志 apiserver 是集群入口,大量 5xx 错误根因在此

集群运维(M1/M8)

命令 功能 注解
kubeadm token create --print-join-command 生成 Worker 加入命令 24h 有效;过期后重新执行
kubeadm token list 查看现有 Token 无 Token 时 Worker 无法加入集群
kubeadm certs check-expiration 查看证书过期时间 证书过期是生产常见故障,默认 1 年有效
kubeadm upgrade plan 查看可升级版本 升级前必做;版本偏差 ≤ 1 个小版本
kubectl taint node <node> node-role.kubernetes.io/control-plane- 去除 Master 污点以调度 Pod 3 节点以下集群可让 Master 也跑 Pod(学习环境)
ETCDCTL_API=3 etcdctl --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key snapshot save /backup/etcd-$(date +%F).db etcd 快照备份 必须指定 TLS 证书路径(kubeadm 部署的 etcd 标配 mTLS);设置 ETCDCTL_API=3 使用 v3 API
ETCDCTL_API=3 etcdctl --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key snapshot status /backup/etcd-xxx.db 查看快照状态 确认备份文件完整性和 etcd 版本信息

✅ 每日检查清单

  • 完成所有动手实操练习
  • 每道命令都在终端执行并理解输出
  • 排错练习先独立排查再对照答案
  • 赛题模拟严格限时,记录用时
  • 将当天遇到的问题和解决方案记录到笔记
  • 回顾前一天的笔记内容

💡 建议每天开始学习前,先花 5 分钟回顾前一天的笔记。每周日做一次周总结,梳理模块间的关联。

📘 Day 14:StorageClass 与动态供给

🎯 今日目标

  • 理解 StorageClass 如何实现”按需创建 PV”
  • 能部署 NFS Provisioner 实现动态供给
  • 掌握 default StorageClass 的设置
  • 能做 PVC 在线扩容
  • 理解 Immediate vs WaitForFirstConsumer

🧠 理论精讲(30 分钟)

为什么需要 StorageClass

静态 PV 的问题:每次创建 PVC 前都要手动创建 PV,管理员负担重。

1
2
动态供给:
PVC 创建 → StorageClass → Provisioner → 自动创建 PV → 绑定 PVC

StorageClass 关键参数

参数 含义
provisioner 供给驱动(如 nfs.csi.k8s.io)
volumeBindingMode Immediate(立即)/ WaitForFirstConsumer(延迟)
reclaimPolicy Delete(默认)/ Retain
allowVolumeExpansion 是否允许 PVC 扩容

volumeBindingMode

模式 行为
Immediate PVC 创建后立即绑定 PV(不考虑 Pod 调度)
WaitForFirstConsumer 等到 Pod 实际使用时才创建 PV(保证 PV 和 Pod 在同一可用区)

🔧 动手实操(120 分钟)

练习 14.1:NFS 动态供给环境准备

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# === 在 Master 或独立存储节点上安装 NFS Server ===

# 1. 安装 NFS 服务端
sudo dnf install -y nfs-utils

# 2. 创建共享目录
sudo mkdir -p /srv/nfs/k8s
sudo chown nobody:nobody /srv/nfs/k8s
sudo chmod 777 /srv/nfs/k8s

# 3. 配置 exports
echo "/srv/nfs/k8s *(rw,sync,no_subtree_check,no_root_squash)" | sudo tee -a /etc/exports
sudo exportfs -rav
sudo systemctl enable --now nfs-server

# 4. 验证 NFS 可用(在 worker 节点测试)
# sudo dnf install -y nfs-utils
# sudo mount -t nfs <master-ip>:/srv/nfs/k8s /mnt
# ls /mnt
# sudo umount /mnt

练习 14.2:部署 NFS Subdir External Provisioner

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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# 1. 创建 RBAC + Deployment
# 这是社区维护的 NFS 动态供给器

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-provisioner
namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: nfs-provisioner-runner
rules:
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch", "update"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["create", "update", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: nfs-provisioner-runner
subjects:
- kind: ServiceAccount
name: nfs-provisioner
namespace: default
roleRef:
kind: ClusterRole
name: nfs-provisioner-runner
apiGroup: rbac.authorization.k8s.io
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs-provisioner
spec:
replicas: 1
selector:
matchLabels:
app: nfs-provisioner
strategy:
type: Recreate
template:
metadata:
labels:
app: nfs-provisioner
spec:
serviceAccountName: nfs-provisioner
containers:
- name: nfs-provisioner
image: registry.cn-hangzhou.aliyuncs.com/google_containers/nfs-subdir-external-provisioner:v4.0.2
env:
- name: PROVISIONER_NAME
value: k8s-sigs.io/nfs-subdir-external-provisioner
- name: NFS_SERVER
value: "10.0.0.1" # 替换为你的 NFS 服务器 IP
- name: NFS_PATH
value: /srv/nfs/k8s
volumeMounts:
- name: nfs-root
mountPath: /persistentvolumes
volumes:
- name: nfs-root
nfs:
server: 10.0.0.1 # 替换为你的 NFS 服务器 IP
path: /srv/nfs/k8s
EOF

# 2. 创建 StorageClass
cat <<EOF | kubectl apply -f -
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-sc
annotations:
storageclass.kubernetes.io/is-default-class: "true"
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
reclaimPolicy: Delete
volumeBindingMode: Immediate
EOF

# 3. 验证
kubectl get sc
# NAME PROVISIONER RECLAIMPOLICY
# nfs-sc (default) k8s-sigs.io/nfs-subdir-external-provisioner Delete

kubectl get pod -l app=nfs-provisioner
# Running

练习 14.3:动态创建 PVC

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
# 1. 创建 PVC(不再需要手动创建 PV!)
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: dynamic-pvc
spec:
storageClassName: nfs-sc
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
EOF

# 2. 观察自动创建 PV
kubectl get pvc dynamic-pvc
# STATUS: Bound

kubectl get pv
# 看到自动创建的 PV(名称如 pvc-xxx-xxx-xxx)

# 3. 在 Pod 中使用
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: dynamic-pod
spec:
containers:
- name: app
image: busybox:1.36
command:
- sh
- -c
- |
echo "Dynamic provision test" > /data/test.txt
cat /data/test.txt
sleep 3600
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: dynamic-pvc
EOF

# 4. 验证 NFS 服务器上的实际文件
# ssh 到 NFS 服务器
ls /srv/nfs/k8s/
# 看到自动创建的目录(命名格式:<namespace>-<pvc-name>-<uuid>)

# 5. 清理
kubectl delete pod dynamic-pod
kubectl delete pvc dynamic-pvc
# PV 会自动删除(因为 reclaimPolicy: Delete)

练习 14.4:PVC 扩容

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
# 1. 首先确保 StorageClass 允许扩容
kubectl get sc nfs-sc
# 修改 StorageClass 允许扩容
kubectl patch sc nfs-sc -p '{"allowVolumeExpansion":true}'

# 2. 创建 PVC
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: expandable-pvc
spec:
storageClassName: nfs-sc
accessModes: ["ReadWriteMany"]
resources:
requests:
storage: 1Gi
EOF

# 3. 扩容 PVC(修改 requests.storage)
kubectl patch pvc expandable-pvc -p '{"spec":{"resources":{"requests":{"storage":"3Gi"}}}}'

# 4. 观察 PVC 状态
kubectl get pvc expandable-pvc -w
# CAPACITY 从 1Gi 逐渐变为 3Gi

# 5. 验证
kubectl get pvc expandable-pvc
kubectl get pv | grep expandable-pvc

# 6. 清理
kubectl delete pvc expandable-pvc

🐛 排错练习(30 分钟)

场景 1:PVC Pending — Provisioner 未运行

1
2
3
4
5
6
7
8
9
10
11
12
# 排查:
# 1. Provisioner Pod 是否运行?
kubectl get pod -l app=nfs-provisioner

# 2. 查看 Provisioner 日志
kubectl logs -l app=nfs-provisioner --tail=50

# 3. 检查 NFS 连通性
kubectl exec -it <provisioner-pod> -- sh -c "showmount -e <NFS_SERVER>"

# 4. 检查 StorageClass 的 provisioner 名称是否匹配
kubectl get sc nfs-sc -o yaml | grep provisioner

场景 2:扩容失败

1
2
3
4
5
6
7
8
# 原因 1:StorageClass 不允许扩容
kubectl get sc <name> -o yaml | grep allowVolumeExpansion

# 原因 2:请求的容量小于当前容量
# PVC 只能扩容不能缩容

# 原因 3:PVC 正在被 Pod 使用
# 某些 CSI 驱动要求在 Pod 运行时才能扩容

🏆 赛题模拟(40 分钟)

⚠️ 严格限时 40 分钟

题目:动态存储与扩容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
【前置条件】
NFS 服务器已部署(IP: 10.0.0.1),共享路径 /srv/nfs/k8s

【操作要求】

1. 部署 NFS Subdir External Provisioner
2. 创建 StorageClass nfs-retain(provisioner 指向 NFS,reclaimPolicy=Retain)
3. 将此 StorageClass 设为默认
4. 创建 PVC data-pvc:5Gi, ReadWriteMany
5. 验证自动创建了 PV
6. 创建 Pod data-app 使用此 PVC,挂载到 /app-data,写入测试数据
7. 将 PVC 扩容到 8Gi
8. 验证数据在扩容后仍然完整
9. 删除 Pod 和 PVC
10. 确认 PV 变为 Released 状态(因为 reclaimPolicy=Retain)

【评分标准】
- Provisioner 部署正确(25 分)
- StorageClass 配置正确(20 分)
- 动态供给工作正常(20 分)
- 扩容成功 + 数据完整(25 分)
- ReclaimPolicy 验证(10 分)

📋 命令速查

命令 功能 注解
kubectl get sc 列出 StorageClass 默认 SC 标记为 (default)
kubectl get sc -o yaml StorageClass 详细配置 查看 provisioner、parameters、reclaimPolicy、allowVolumeExpansion
kubectl describe sc <name> StorageClass 详情 包含创建事件和配置参数
kubectl patch sc <name> -p '{"metadata":{"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}' 设为默认 StorageClass 不指定 storageClassName 的 PVC 自动使用默认 SC
kubectl patch sc <name> -p '{"metadata":{"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}' 取消默认 StorageClass 防止误用不想要的 SC
kubectl patch sc <name> -p '{"allowVolumeExpansion":true}' 启用卷在线扩容 PVC spec.resources.requests.storage 允许增大
kubectl get pvc -o wide PVC + 绑定的 PV + SC 确认 PVC 使用了哪个 StorageClass
kubectl describe pvc <name> PVC 详情 Events 显示 Provisioning/FailedProvisioning 过程
kubectl delete pvc <name> && kubectl get pv -w 观察 PVC 删除后 PV 回收 Reclaim Policy: Delete 时 PV 自动消失;Retain 时 PV 变为 Released
kubectl patch pvc <name> -p '{"spec":{"resources":{"requests":{"storage":"2Gi"}}}}' 扩容 PVC 需要 SC 启用 allowVolumeExpansion;只能增大不能缩小

📚 参考来源

来源 链接 / 说明
Kubernetes 官方:StorageClass https://kubernetes.io/docs/concepts/storage/storage-classes/
Kubernetes 官方:动态卷供给 https://kubernetes.io/docs/concepts/storage/dynamic-provisioning/
Kubernetes 官方:卷扩容 https://kubernetes.io/docs/concepts/storage/persistent-volumes/#expanding-persistent-volumes-claims
Kubernetes 官方:CSI 驱动 https://kubernetes-csi.github.io/docs/
NFS Subdir External Provisioner https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner
Rancher Local Path Provisioner https://github.com/rancher/local-path-provisioner

📝 今日笔记模板

📘 Day 03:集群运维与 kubectl 精通

🎯 今日目标

  • 能灵活使用 -o wide-o yaml-o json-o jsonpath
  • 能用 --dry-run=client 快速生成任意资源 YAML 模板
  • 能用 kubectl explain 查阅 API 字段文档
  • 完成一次集群版本升级
  • 完成 etcd 快照备份并验证可恢复

🧠 理论精讲(30 分钟)

kubectl 命令分类

类别 命令 场景
CRUD creategetdescribeeditdeleteapplypatch 资源管理
调试 logsexecattachcpport-forwardtop 问题排查
集群管理 cordondrainuncordontaintlabelannotate 节点运维
配置 config viewconfig use-context kubeconfig 管理

输出格式速查

选项 用途
-o wide 追加列(如 Pod 显示 IP 和 Node)
-o yaml 完整 YAML 定义
-o json 完整 JSON 定义
-o jsonpath='{...}' 提取特定字段
-o name 只输出资源类型/名称
--sort-by='.metadata.creationTimestamp' 按字段排序

--dry-run=client 的威力

这是比赛中最常用的命令之一:

1
2
3
4
5
6
7
8
# 生成 Pod YAML 模板
kubectl run nginx --image=nginx:alpine --dry-run=client -o yaml

# 生成 Deployment YAML 模板
kubectl create deploy nginx --image=nginx:alpine --dry-run=client -o yaml

# 生成 Service YAML 模板
kubectl create service clusterip nginx --tcp=80:80 --dry-run=client -o yaml

💡 比赛中不需要从零手写 YAML,用 --dry-run=client 生成模板再编辑即可。


🔧 动手实操(120 分钟)

练习 3.1:kubectl explain 查阅 API 文档

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 查看 Pod 资源定义
kubectl explain pod

# 逐层深入
kubectl explain pod.spec
kubectl explain pod.spec.containers
kubectl explain pod.spec.containers.resources
kubectl explain pod.spec.containers.livenessProbe
kubectl explain pod.spec.containers.livenessProbe.httpGet

# 查看其他资源
kubectl explain deployment.spec.strategy
kubectl explain deployment.spec.strategy.rollingUpdate
kubectl explain ingress.spec.rules.http.paths.backend

# 递归查看所有字段
kubectl explain pod --recursive | head -100

练习 3.2:–dry-run=client 生成 YAML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 1. 生成 Pod YAML
kubectl run my-pod --image=nginx:alpine --dry-run=client -o yaml > pod-template.yaml

# 2. 生成 Deployment YAML
kubectl create deploy my-deploy --image=nginx:alpine --replicas=3 --dry-run=client -o yaml > deploy-template.yaml

# 3. 生成 Service YAML(ClusterIP)
kubectl create service clusterip my-svc --tcp=80:80 --dry-run=client -o yaml > svc-template.yaml

# 4. 生成 Service YAML(NodePort)
kubectl create service nodeport my-np --tcp=80:80 --dry-run=client -o yaml > np-template.yaml

# 5. 生成 ConfigMap YAML
kubectl create configmap my-config --from-literal=key1=val1 --from-literal=key2=val2 --dry-run=client -o yaml

# 6. 生成 Secret YAML
kubectl create secret generic my-secret --from-literal=password=123456 --dry-run=client -o yaml

# 7. 生成 Job YAML
kubectl create job my-job --image=busybox --dry-run=client -o yaml -- date

# 8. 生成 CronJob YAML
kubectl create cj my-cj --image=busybox --schedule="*/5 * * * *" --dry-run=client -o yaml -- date

练习 3.3:jsonpath 实战

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 前提:创建一些测试资源
kubectl create deploy nginx --image=nginx:alpine --replicas=3

# 1. 提取所有 Pod 名称
kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}'

# 2. 提取 Pod 名称:所在节点
kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{": "}{.spec.nodeName}{"\n"}{end}'

# 3. 提取 Pod IP
kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{": "}{.status.podIP}{"\n"}{end}'

# 4. 提取所有节点的 InternalIP
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{": "}{.status.addresses[?(@.type=="InternalIP")].address}{"\n"}{end}'

# 5. 提取所有 Deployment 的副本数
kubectl get deploy -o jsonpath='{range .items[*]}{.metadata.name}{": replicas="}{.spec.replicas}{", ready="}{.status.readyReplicas}{"\n"}{end}'

# 6. 提取所有 Service 的 ClusterIP
kubectl get svc -o jsonpath='{range .items[*]}{.metadata.name}{" -> "}{.spec.clusterIP}{":"}{.spec.ports[0].port}{"\n"}{end}'

练习 3.4:集群”体检”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 1. 查看所有命名空间的事件,按时间排序
kubectl get events --all-namespaces --sort-by='.lastTimestamp' | tail -20

# 2. 查看所有非 Running 的 Pod
kubectl get pods --all-namespaces --field-selector=status.phase!=Running

# 3. 查看节点资源使用(需要 metrics-server)
# 如果没有 metrics-server,先安装:
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

kubectl top nodes
kubectl top pods --all-namespaces

# 4. 查看集群版本信息
kubectl version

# 5. 检查证书到期时间
sudo kubeadm certs check-expiration

# 6. 检查所有组件的健康状态
kubectl get --raw='/healthz?verbose'

练习 3.5:集群版本升级(kubeadm upgrade)

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
# === 在 Master 节点上执行 ===

# 1. 查看当前版本和可升级版本
kubeadm upgrade plan

# 2. 解锁 kubeadm(如果之前 versionlock 了)
sudo dnf versionlock delete kubeadm
sudo dnf install -y kubeadm-1.29.5 # 替换为目标版本

# 3. 执行升级
sudo kubeadm upgrade apply v1.29.5

# 4. 升级 kubelet 和 kubectl
sudo dnf versionlock delete kubelet kubectl
sudo dnf install -y kubelet-1.29.5 kubectl-1.29.5
sudo dnf versionlock add kubelet kubectl

# 5. 重启 kubelet
sudo systemctl daemon-reload
sudo systemctl restart kubelet

# 6. 验证升级
kubectl get nodes
# Master 版本应变为 v1.29.5

# === 在每个 Worker 节点上执行 ===

# 7. 排空 worker
kubectl drain k8s-node1 --ignore-daemonsets --delete-emptydir-data

# 8. 在 worker 上升级
sudo dnf versionlock delete kubeadm
sudo dnf install -y kubeadm-1.29.5
sudo kubeadm upgrade node

# 9. 升级 kubelet
sudo dnf versionlock delete kubelet
sudo dnf install -y kubelet-1.29.5
sudo dnf versionlock add kubelet
sudo systemctl daemon-reload
sudo systemctl restart kubelet

# 10. 恢复 worker
kubectl uncordon k8s-node1

# 11. 对所有 worker 重复 7-10,最终验证
kubectl get nodes
# 所有节点版本一致

练习 3.6:etcd 备份与恢复

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
# === 备份 etcd ===

# 1. 查看 etcd 证书位置
ls /etc/kubernetes/pki/etcd/

# 2. 创建备份
sudo ETCDCTL_API=3 etcdctl snapshot save /opt/etcd-backup-$(date +%Y%m%d).db \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
--endpoints=127.0.0.1:2379

# 3. 验证备份
sudo ETCDCTL_API=3 etcdctl snapshot status /opt/etcd-backup-*.db
# 输出:hash、revision、total keys、total size

# 4. 验证备份内容
sudo ETCDCTL_API=3 etcdctl snapshot status /opt/etcd-backup-*.db --write-out=table

# === 恢复 etcd(模拟灾难恢复,请谨慎操作) ===

# 5. 创建恢复目录
sudo mkdir -p /var/lib/etcd-restore

# 6. 从快照恢复
sudo ETCDCTL_API=3 etcdctl snapshot restore /opt/etcd-backup-*.db \
--data-dir=/var/lib/etcd-restore \
--name=k8s-master \
--initial-cluster=k8s-master=https://127.0.0.1:2380 \
--initial-advertise-peer-urls=https://127.0.0.1:2380

# 7. 检查恢复的数据
sudo ls -la /var/lib/etcd-restore/

# ⚠️ 生产环境恢复需要修改 /etc/kubernetes/manifests/etcd.yaml 的 data-dir 指向恢复目录
# ⚠️ 练习环境请勿实际操作,理解流程即可

🐛 排错练习(30 分钟)

场景 1:kubectl 连接被拒

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 错误:
# The connection to the server localhost:8080 was refused

# 排查步骤:
# 1. 检查 kubeconfig 是否存在
ls -la ~/.kube/config

# 2. 检查环境变量
echo $KUBECONFIG

# 3. 检查当前 context
kubectl config current-context

# 4. 检查 api-server 是否运行
sudo crictl ps | grep kube-apiserver
# 或
sudo docker ps | grep kube-apiserver

# 5. 检查 6443 端口
sudo ss -tlnp | grep 6443

# 解决方案:
# - 如果 api-server 挂了 → systemctl restart kubelet
# - 如果 config 丢了 → sudo cp /etc/kubernetes/admin.conf ~/.kube/config

场景 2:操作集群时权限错误

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 错误:
# Error from server (Forbidden): pods is forbidden

# 排查步骤:
# 1. 检查当前使用的证书
kubectl config view --raw | grep client-certificate

# 2. 检查当前 context 的用户
kubectl config current-context
kubectl config view -o jsonpath='{.contexts[?(@.name=="<context-name>")].context.user}'

# 3. 确认是用的哪个 kubeconfig
# 可能用了错误的 context 或证书
kubectl config get-contexts

# 解决方案:
# 切换到 admin context
kubectl config use-context kubernetes-admin@kubernetes

🏆 赛题模拟(40 分钟)

⚠️ 严格限时 40 分钟完成下述全部操作

题目:集群运维综合

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
【初始环境】3 节点集群正常运行

【操作要求】

Part A: YAML 模板生成(15 分)
1. 用 --dry-run=client 生成以下 YAML 文件:
a. Deployment nginx-deploy,镜像 nginx:1.25,3 副本
b. Service nginx-svc,ClusterIP 类型,暴露 80 端口
c. ConfigMap nginx-config,包含键 index.html=<h1>Hello</h1>
d. Secret nginx-secret,包含键 api-key=sk-123456
2. 保存为 deploy.yaml、svc.yaml、cm.yaml、secret.yaml

Part B: 集群信息提取(25 分)
3. 用 jsonpath 提取所有节点的名称、IP、污点信息
4. 找出所有非 Running 的 Pod(不限命名空间)
5. 列出所有 Service 及其 ClusterIP、端口映射
6. 查看最近 20 条集群事件

Part C: etcd 备份(30 分)
7. 对 etcd 做一次快照备份
8. 验证快照状态(输出 hash、keys 数量)
9. 恢复快照到 /var/lib/etcd-restore 目录
10. 验证恢复数据的完整性(比较 key 数量)

Part D: 版本验证(20 分)
11. 检查集群证书到期时间
12. 生成一份"集群健康报告":节点状态、系统 Pod 状态、证书有效期

Part E: 新增节点(10 分)
13. 假设需要再添加一台 worker,写出 join 命令(不实际执行)

【评分标准】
- Part A: YAML 正确生成(15 分)
- Part B: 命令正确输出(25 分)
- Part C: etcd 备份恢复完整(30 分)
- Part D: 健康报告完整(20 分)
- Part E: join 命令正确(10 分)

📋 命令速查

命令 功能 注解
kubectl version 查看客户端与服务端版本 版本偏差不允许超过 ±1 个小版本
kubectl cluster-info dump 导出集群诊断信息 包含所有系统组件的日志摘要
kubectl get ns 列出所有命名空间 kube-system 存放集群组件,default 是用户默认空间
kubectl get pods -A 所有命名空间的 Pod -A = --all-namespaces,全局视角快速定位问题
kubectl get pods -o wide Pod + 节点 + IP 定位 Pod 在哪个节点、IP 是多少
kubectl describe pod <pod> Pod 详细信息 Events 段是排错第一入口,包含启动失败原因
kubectl logs <pod> 查看 Pod 日志(单容器) 最常用排错命令,-f 实时跟踪
kubectl logs <pod> -c <container> 指定容器日志 多容器 Pod 必须用 -c 指定容器名
kubectl logs <pod> --tail=50 最后 50 行日志 避免刷屏
kubectl logs <pod> --since=5m 最近 5 分钟日志 排查近期异常
kubectl exec <pod> -- <cmd> 容器内执行命令 -- 分隔 kubectl 参数和容器内命令
kubectl exec -it <pod> -- /bin/sh 交互式进入容器 排错时检查文件/网络/进程
kubectl get all -n <ns> 命名空间内所有资源 Pod/Service/Deploy/RS 一览
kubectl explain pod.spec.containers 查看资源字段文档 终端查 API 字段,写 YAML 神器
kubectl explain pod.spec --recursive 递归查看所有子字段 全面了解资源 YAML 结构
kubectl api-resources 列出所有 API 资源 包含 short name(svc/deploy/po)和 API Group
kubectl api-versions 列出所有 API 版本 了解支持的 API Group 和版本
kubectl apply -f file.yaml 声明式创建/更新 幂等安全,推荐优先使用
kubectl create -f file.yaml 命令式创建 重复执行报错”already exists”
kubectl delete -f file.yaml 按 YAML 删除 删除 YAML 中定义的所有资源
kubectl create deploy nginx --image=nginx --dry-run=client -o yaml > deploy.yaml 生成 YAML 不创建 YAML 速成技巧,--dry-run=client 仅本地校验
kubectl edit deploy <name> 直接编辑集群资源 实时生效;建议先 get -o yaml > backup.yaml
kubectl patch deploy <name> -p '{"spec":{"replicas":3}}' JSON Patch 部分更新 比 edit 更安全,适合脚本化
kubectl scale deploy <name> --replicas=5 快速扩缩副本 等价于修改 replicas 字段
kubectl rollout status deploy <name> 查看滚动更新进度 脚本中阻塞等待更新完成
kubectl rollout history deploy <name> 查看部署历史 revision 号配合 --revision 查看变更详情
kubectl rollout undo deploy <name> 回滚上一版本 仅回滚 deploy 模板,不涉及代码仓库
kubectl rollout undo deploy <name> --to-revision=2 回滚到指定版本 历史默认保留 10 个 revision
ETCDCTL_API=3 etcdctl --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key snapshot save /backup/etcd-$(date +%F).db etcd 快照备份 静态 Pod 管理的 etcd 需指定 TLS 证书路径(kubeadm 默认 mTLS);ETCDCTL_API=3 强制使用 v3 API
ETCDCTL_API=3 etcdctl --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key snapshot status /backup/etcd-xxx.db 查看快照完整性 输出快照的 etcd 版本、包含的 key 数量和文件大小
kubeadm certs check-expiration 查看证书过期时间 证书过期是生产常见故障,默认 1 年
kubeadm upgrade plan 查看可升级版本 升级前必做
kubectl config get-contexts 查看 kubeconfig 上下文 多集群切换
kubectl config use-context <name> 切换集群上下文 多集群管理

📚 参考来源

来源 链接 / 说明
kubectl 命令参考 https://kubernetes.io/docs/reference/kubectl/
kubectl 速查表 https://kubernetes.io/docs/reference/kubectl/quick-reference/
Kubernetes API 资源概览 https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/
kubeadm 升级指南 https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/
etcd 备份与恢复 https://kubernetes.io/docs/tasks/administer-cluster/configure-upgrade-etcd/#backing-up-an-etcd-cluster
kubectl explain 用法 https://kubernetes.io/docs/reference/kubectl/

📘 Day 02:多节点集群与节点管理

🎯 今日目标

  • 搭建 1 master + 2 worker 完整集群
  • 掌握节点标签的增删改查
  • 会用 cordon/drain 管理节点上/下线
  • 配置 Pod 的 Taint/Toleration 实现调度控制
  • 能处理节点 join 失败的问题

🧠 理论精讲(30 分钟)

Join 流程

1
2
3
4
5
6
7
8
9
10
Worker 节点                    Master 节点
│ │
│── kubeadm join ────────────→│ token 验证
│ (token + discovery-hash) │ TLS bootstrap
│ │ 颁发客户端证书
│←── 下发 kubeconfig ────────│
│ │
│── kubelet 启动 ────────────→│ 上报 Node 资源
│ │
│←── 分配 Pod (CNI IP) ──────│

关键参数:

  • --token:集群加入凭证,默认有效期 24 小时
  • --discovery-token-ca-cert-hash:CA 证书 hash,防中间人攻击

Node 生命周期

1
2
3
4
5
Register ──→ Ready ──→ NotReady(>5min) ──→ Pod 驱逐

├── cordon(标记不可调度,已有 Pod 不动)

└── drain(驱逐 Pod + cordon)

Taint / Toleration

概念 说明 类比
Taint(污点) 打在节点上,排斥 Pod “这节点只有特定 Pod 能用”
Toleration(容忍) 配置在 Pod 上,容忍节点污点 “我可以忍受这个节点的污点”
1
2
3
4
# 三个污点效果:
# NoSchedule — 不调度新 Pod
# PreferNoSchedule — 尽量不调度
# NoExecute — 不调度新 Pod + 驱逐已有 Pod

🔧 动手实操(120 分钟)

练习 2.1:搭建 3 节点集群

在所有 3 台服务器上执行 Day 01 的环境准备(不需要 kubeadm init):

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
# --- Worker 节点 1、2 都执行 ---

# 关闭 swap
sudo swapoff -a
sudo sed -i '/ swap / s/^/#/' /etc/fstab

# 内核模块
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter

# 内核参数
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system

# containerd
sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo dnf install -y containerd.io
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
sudo systemctl restart containerd
sudo systemctl enable containerd

# kubeadm/kubelet/kubectl
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.29/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.29/rpm/repodata/repomd.xml.key
EOF
sudo dnf install -y kubelet kubeadm kubectl
sudo dnf install -y dnf-plugins-core
sudo dnf versionlock kubelet kubeadm kubectl

在 Master 上获取 join 命令:

1
2
3
4
# 如果昨天的 token 过期了,重新生成
kubeadm token create --print-join-command
# 输出类似:
# kubeadm join 10.0.0.1:6443 --token abc123.xxx --discovery-token-ca-cert-hash sha256:yyy

在 Worker 1 和 Worker 2 上执行 join:

1
2
# 将上面输出的命令粘贴执行
sudo kubeadm join 10.0.0.1:6443 --token abc123.xxx --discovery-token-ca-cert-hash sha256:yyy

在 Master 上验证集群完整:

1
2
3
4
5
6
kubectl get nodes
# 预期输出:
# NAME STATUS ROLES AGE VERSION
# k8s-master Ready control-plane 1d v1.29.0
# k8s-node1 Ready <none> 30s v1.29.0
# k8s-node2 Ready <none> 30s v1.29.0

练习 2.2:节点标签管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 查看所有节点及其标签
kubectl get nodes --show-labels

# 给节点打标签
kubectl label node k8s-node1 role=worker
kubectl label node k8s-node2 role=worker
kubectl label node k8s-node1 disk=ssd
kubectl label node k8s-node2 disk=hdd

# 查看特定标签
kubectl get nodes -l role=worker
kubectl get nodes -l disk=ssd --show-labels

# 覆盖标签(--overwrite)
kubectl label node k8s-node1 disk=nvme --overwrite

# 删除标签(标签名后加 -)
kubectl label node k8s-node1 disk-

# 验证
kubectl get nodes k8s-node1 --show-labels

练习 2.3:cordon 与 uncordon

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 1. 先创建 Deployment 观察
kubectl create deploy nginx --image=nginx:alpine --replicas=6
kubectl get pod -o wide
# 观察 Pod 分布到两个 worker

# 2. 对 node1 执行 cordon(停止调度)
kubectl cordon k8s-node1

# 3. 验证 node1 状态
kubectl get nodes
# k8s-node1 Ready,SchedulingDisabled ...

# 4. 扩容,验证新 Pod 不调度到 node1
kubectl scale deploy/nginx --replicas=10
kubectl get pod -o wide
# 新 Pod 全部被调度到 node2

# 5. 解除 cordon
kubectl uncordon k8s-node1
kubectl get nodes
# k8s-node1 Ready ...

练习 2.4:drain 节点排空

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 1. 确定 node1 上有 Pod
kubectl get pod -o wide | grep k8s-node1

# 2. 对 node1 执行 drain
# --ignore-daemonsets:忽略 DaemonSet Pod(它们无法被驱逐)
# --delete-emptydir-data:删除使用 emptyDir 的 Pod
kubectl drain k8s-node1 --ignore-daemonsets --delete-emptydir-data

# 3. 观察 Pod 迁移过程
kubectl get pod -o wide -w
# Pod 被驱逐后在 node2 重建

# 4. 验证 node1 状态
kubectl get nodes
# k8s-node1 Ready,SchedulingDisabled ...

# 5. 恢复 node1
kubectl uncordon k8s-node1

练习 2.5:Taint 与 Toleration

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
# 1. 给 node1 添加污点(专用数据库节点)
kubectl taint node k8s-node1 db=only:NoSchedule

# 2. 创建普通 Deployment 验证不受影响
kubectl create deploy web --image=nginx:alpine --replicas=3
kubectl get pod -o wide
# 全部 Pod 应避开 node1

# 3. 创建带 Toleration 的 Pod 专门调度到 node1
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: db-pod
spec:
tolerations:
- key: "db"
operator: "Equal"
value: "only"
effect: "NoSchedule"
containers:
- name: db
image: nginx:alpine
EOF

kubectl get pod db-pod -o wide
# db-pod 可以调度到 node1(容忍了污点)

# 4. NoExecute 污点测试(驱逐已有 Pod)
kubectl taint node k8s-node2 test=evict:NoExecute
# 已有的普通 Pod 在 300 秒宽限期后会被驱逐

# 5. 移除污点(污点名后加 -)
kubectl taint node k8s-node1 db-
kubectl taint node k8s-node2 test-

# 6. 验证
kubectl describe node k8s-node1 | grep -A5 Taints
kubectl describe node k8s-node2 | grep -A5 Taints

练习 2.6:节点删除与重新加入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 1. 排空 node2
kubectl drain k8s-node2 --ignore-daemonsets --delete-emptydir-data

# 2. 从集群删除 node2
kubectl delete node k8s-node2

# 3. 在 node2 上重置 kubeadm
sudo kubeadm reset -f
sudo rm -rf /etc/cni/net.d

# 4. 重新加入集群
# 在 Master 上生成新 token
kubeadm token create --print-join-command
# 在 node2 上执行 join 命令

# 5. 验证节点回归
kubectl get nodes
# k8s-node2 Ready <none> 10s v1.29.0

🐛 排错练习(30 分钟)

场景 1:Token 过期

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 模拟:在 worker 上使用过期 token join 失败
# 错误信息:failed to parse token ...

# 排查步骤:
# 1. 查看现有 token 列表
kubeadm token list
# 如果没有有效 token,显示空

# 2. 创建新 token
sudo kubeadm token create

# 3. 获取 CA 证书 hash
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | \
openssl rsa -pubin -outform der 2>/dev/null | \
openssl dgst -sha256 -hex | sed 's/^.* //'

# 4. 使用新 token 和 hash 重新 join

场景 2:节点 NotReady — CNI 未初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 排查步骤:
# 1. 看节点状态
kubectl describe node k8s-node2 | grep -A10 Conditions
# 发现 KubeletNotReady,reason: ContainerNetworkNotReady

# 2. 登录 node2,检查 kubelet 日志
sudo journalctl -u kubelet -n 50 --no-pager
# 发现 "CNI plugin not initialized"

# 3. 检查 Calico Pod 是否已运行
kubectl get pods -n kube-system -l k8s-app=calico-node -o wide
# 如果 node2 上没有 Calico Pod,等待自动调度或检查 Calico DS 配置

# 4. 手动检查 CNI 配置
ls /etc/cni/net.d/
# 应有 calico 相关配置文件

🏆 赛题模拟(40 分钟)

⚠️ 严格限时 40 分钟完成下述全部操作

题目:节点管理与高可用

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
【初始环境】
1 master(k8s-master)+ 2 worker(k8s-node1, k8s-node2)集群就绪

【操作要求】
1. 给 node1 添加标签 env=production、zone=cn-east
2. 给 node2 添加标签 env=staging、zone=cn-east
3. 创建 Deployment app-prod(3副本),用 nodeSelector 限制到 env=production
4. 创建 Deployment app-staging(2副本),用 nodeSelector 限制到 env=staging
5. 对 node1 执行 drain 排空,要求:
- 忽略 DaemonSet
- 删除 emptyDir 数据
- 观察 app-prod Pod 迁移到哪个节点(预期迁移到 node2,但 node2 标签不匹配会怎样?)
6. 排空后 uncordon 恢复 node1
7. 给 node1 添加污点 maintenance=true:NoSchedule
8. 修改 app-prod Deployment,添加 Toleration 使之仍能调度到 node1
9. 移除 node1 污点
10. 验证全部 Pod 正常运行

【评分标准】
- 标签操作正确(10 分)
- nodeSelector 调度正确(25 分)
- drain 操作正确(20 分)
- uncordon 恢复(10 分)
- 污点与容忍配置正确(25 分)
- 最终验证全部 Running(10 分)

📋 命令速查

命令 功能 注解
kubeadm token create --print-join-command 生成 Worker 节点加入命令 Token 默认 24h 有效,过期需重新生成
kubeadm token list 查看现有 Token 无可用 Token 时 Worker 无法加入集群
kubeadm join <master-ip>:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash> Worker 加入集群 在 Worker 节点上执行,自动安装 kubelet 并注册节点
kubectl get nodes -o wide 节点列表 + 详细信息 显示内网 IP、OS、内核版本、容器运行时
kubectl describe node <node-name> 节点详细信息 查看 Conditions(MemoryPressure/DiskPressure/PIDPressure)、Taints、已分配资源
kubectl label node <node> key=value 给节点打标签 配合 nodeSelector/nodeAffinity 控制调度
kubectl label node <node> key- 删除节点标签 标签名后加 - 即可删除
kubectl taint node <node> key=value:NoSchedule 添加污点 无对应 Toleration 的 Pod 无法调度到此节点
kubectl taint node <node> key=value:NoSchedule- 移除污点 末尾加 - 删除对应 Taint
kubectl taint node <node> node-role.kubernetes.io/control-plane- 去除 Master 污点 3 节点以下集群可让 Master 也调度 Pod(学习环境常用)
kubectl cordon <node> 标记节点不可调度 不会驱逐已有 Pod,仅阻止新 Pod 调度
kubectl uncordon <node> 恢复节点可调度 取消 cordon 标记
kubectl drain <node> --ignore-daemonsets --delete-emptydir-data 安全驱逐节点上所有 Pod 节点维护/下线前必执行;DaemonSet Pod 需 –ignore-daemonsets
kubectl drain <node> --ignore-daemonsets --delete-emptydir-data --force 强制驱逐(含不受控制器管理的 Pod) 裸 Pod(无 ownerReference)需 –force
kubectl delete node <node> 删除节点对象 节点失联后从集群移除;需先 drain
systemctl status kubelet 查看 kubelet 状态 节点 NotReady 时首要排查命令
journalctl -u kubelet -f 实时查看 kubelet 日志 Pod 启停失败的根因通常在 kubelet 日志
journalctl -u kubelet --since "10 min ago" 查看最近 10 分钟 kubelet 日志 时间范围过滤,定位近期异常

📚 参考来源

来源 链接 / 说明
Kubernetes 官方:节点管理 https://kubernetes.io/docs/concepts/architecture/nodes/
Kubernetes 官方:kubeadm join https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm-join/
Kubernetes 官方:安全驱逐节点 https://kubernetes.io/docs/tasks/administer-cluster/safely-drain-node/
Kubernetes 官方:污点与容忍 https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/
Kubernetes 官方:节点标签 https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/

📝 今日笔记模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
日期:____年____月____日
用时:____小时____分

✅ 完成项:
□ 3 节点集群搭建
□ 练习 2.1-2.6
□ 排错练习 1-2
□ 赛题模拟

❓ 遇到的问题与解决方案:
1.
2.

📌 关键收获:
1. cordon vs drain 的区别
2. Taint/Toleration 的使用场景
3.

📘 Day 01:集群架构原理与环境准备

🎯 今日目标

  • 能画出 K8s 架构图并说出每个组件的作用
  • 能用 kubeadm 初始化单节点集群
  • 安装 Calico CNI 并使 CoreDNS 正常运行
  • 配置 kubectl 自动补全和常用别名
  • 能使用 kubectl 查看集群组件状态

🧠 理论精讲(30 分钟)

K8s 是什么

Kubernetes 是一个容器编排平台,它解决的问题:

问题 K8s 怎么解决
容器放哪台机器? 调度器(Scheduler)自动决策
容器挂了怎么办? 控制器(Controller)自动重建
服务怎么被发现? Service + DNS 自动注册与发现
配置怎么管理? ConfigMap/Secret 统一管理
流量怎么分发? Service/Ingress 负载均衡
存储怎么挂载? PV/PVC 抽象存储

控制平面组件(Master 节点)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
┌─────────────────────────────────────────────┐
│ Control Plane │
│ │
│ ┌──────────┐ ┌──────────┐ ┌───────────┐ │
│ │ API │ │ Scheduler│ │Controller │ │
│ │ Server │ │ │ │ Manager │ │
│ │ :6443 │ │ 决定 Pod │ │ 维持期望 │ │
│ │ │ │ 放哪台机 │ │ 状态一致 │ │
│ └────┬─────┘ └──────────┘ └───────────┘ │
│ │ │
│ ┌────┴─────┐ │
│ │ etcd │ ← 集群状态的唯一数据源 │
│ │ :2379 │ │
│ └──────────┘ │
└─────────────────────────────────────────────┘
组件 职责 关键端口
kube-apiserver 集群统一入口,所有操作必经之路 6443
etcd 分布式 KV 存储,保存集群所有状态 2379-2380
kube-scheduler 监听新 Pod,选择最优节点
kube-controller-manager 运行各种控制器(Deployment/Node/Service…)

数据平面组件(所有节点)

组件 职责
kubelet 节点代理,执行 Pod 创建/销毁,上报状态
kube-proxy 维护节点上的网络规则(iptables/IPVS),实现 Service
容器运行时 真正跑容器的东西(containerd / cri-o / docker)

一个 kubectl run nginx 请求的完整流程

1
2
3
4
kubectl → api-server(认证→鉴权→准入→写入 etcd)
→ scheduler(watch 到未调度 Pod → 打分选节点 → 更新 Pod.spec.nodeName)
→ 目标节点 kubelet(watch 到分配给自己 → 调 CRI 创建容器 → 上报状态)
→ api-server 更新 Pod 状态为 Running

🔧 动手实操(120 分钟)

前置环境准备

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
# 1. 关闭 swap(K8s 要求)
sudo swapoff -a
sudo sed -i '/ swap / s/^/#/' /etc/fstab

# 2. 加载内核模块
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter

# 3. 配置内核参数
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system

# 4. 安装 containerd(通过 Docker CE 仓库)
sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo dnf install -y containerd.io
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
# 修改 SystemdCgroup = true
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
sudo systemctl restart containerd
sudo systemctl enable containerd

安装 kubeadm/kubelet/kubectl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 5. 添加 K8s YUM 源
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.29/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.29/rpm/repodata/repomd.xml.key
EOF

# 6. 安装
sudo dnf install -y kubelet kubeadm kubectl
sudo dnf install -y dnf-plugins-core
sudo dnf versionlock kubelet kubeadm kubectl

# 7. 验证版本
kubeadm version
kubectl version --client
kubelet --version

练习 1.1:初始化单节点集群

1
2
3
4
5
6
7
8
9
# 初始化集群(关键参数)
sudo kubeadm init \
--pod-network-cidr=192.168.0.0/16 \
--kubernetes-version=v1.29.0 \
--apiserver-advertise-address=<你的云服务器内网IP> \
--image-repository=registry.aliyuncs.com/google_containers

# 记录 join 命令(后续 Day 02 用)
# 输出类似:kubeadm join <IP>:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>

验证集群初始化:

1
2
3
4
5
6
7
8
9
10
# 配置 kubectl
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

# 查看节点状态
kubectl get nodes
# 预期输出:
# NAME STATUS ROLES AGE VERSION
# k8s-master NotReady control-plane 30s v1.29.0

⚠️ 状态为 NotReady 是正常的,还没有安装网络插件。


练习 1.2:安装 Calico CNI 插件

1
2
3
4
5
6
7
8
9
10
11
12
13
# 下载并应用 Calico 清单
curl -O https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/calico.yaml
kubectl apply -f calico.yaml

# 等待所有系统 Pod 就绪
kubectl get pods -n kube-system --watch
# 等待 coredns 变为 Running,Calico Pod 也全部 Running

# Ctrl+C 退出 watch,验证节点 Ready
kubectl get nodes
# 预期输出:
# NAME STATUS ROLES AGE VERSION
# k8s-master Ready control-plane 2m v1.29.0

练习 1.3:配置 kubectl 自动补全与别名

1
2
3
4
5
6
7
8
9
# Bash 自动补全
echo 'source <(kubectl completion bash)' >> ~/.bashrc
echo 'alias k=kubectl' >> ~/.bashrc
echo 'complete -o default -F __start_kubectl k' >> ~/.bashrc
source ~/.bashrc

# 验证
k get no
# 预期输出:节点信息

练习 1.4:查看集群组件状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 查看所有命名空间
kubectl get namespaces

# 查看系统组件 Pod
kubectl get pods -n kube-system

# 查看各组件健康状态
kubectl get componentstatuses
# 或
kubectl get --raw='/readyz?verbose'

# 查看所有节点详细信息
kubectl describe node $(hostname)

# 查看集群信息
kubectl cluster-info

练习 1.5:探索 etcd 存储

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 进入 etcd 容器(如果是静态 Pod 运行的)
# 先确认 etcd 是以静态 Pod 方式运行
ls /etc/kubernetes/manifests/
# 应当看到 etcd.yaml

# 用 crictl(containerd 默认)查看容器
sudo crictl ps | grep etcd

# 进入 etcd 容器执行查询
sudo crictl exec -it <etcd-container-id> sh

# 在容器内:
ETCDCTL_API=3 etcdctl \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
get / --prefix --keys-only | head -30
# 退出:exit

🐛 排错练习(30 分钟)

场景 1:kubelet 停止后 Pod 状态变化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 1. 先创建一个测试 Pod
kubectl run test-pod --image=nginx:alpine

# 2. 停止 kubelet
sudo systemctl stop kubelet

# 3. 观察节点和 Pod 状态变化
kubectl get nodes
# 预期:节点变为 NotReady(需要等约 40 秒)

kubectl get pod test-pod
# 预期:Pod 仍然是 Running 但节点 NotReady

# 4. 恢复 kubelet
sudo systemctl start kubelet

# 5. 等待恢复
kubectl get nodes -w
# 预期:节点逐步恢复为 Ready

# 6. 清理
kubectl delete pod test-pod

场景 2:CoreDNS Pending 排错

1
2
3
4
5
6
7
8
9
10
11
12
13
# 模拟问题:使用错误的 pod-network-cidr 导致 Calico 不工作
# 排查思路:
kubectl get pods -n kube-system
# 看到 coredns-xxx 状态为 Pending

kubectl describe pod -n kube-system <coredns-pod-name>
# 查看 Events,通常会提示 "failed to allocate for range..."

# 根因:Calico 未正确配置,无法分配 Pod IP
# 检查 Calico Pod 日志:
kubectl logs -n kube-system -l k8s-app=calico-node --tail=50

# 解决方案:确认 Pod CIDR 正确,必要时重建集群

🏆 赛题模拟(40 分钟)

⚠️ 严格限时 30 分钟完成下述全部操作

题目:单节点集群部署

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
【环境】一台全新的 CentOS Stream 9 云服务器(2C4G)
【要求】
1. 安装 containerd、kubeadm、kubelet、kubectl(kubeadm 1.29)
2. 使用 kubeadm 初始化单节点集群,指定:
- Pod CIDR 为 192.168.0.0/16
- 镜像仓库使用 registry.aliyuncs.com/google_containers
3. 安装 Calico CNI 插件
4. 验证集群就绪:kubectl get nodes 显示 Ready
5. 验证系统 Pod:kube-system 命名空间下所有 Pod 均 Running
6. 配置 kubectl 别名 k=kubectl
7. 创建一个 nginx:alpine 测试 Pod,验证能正常运行

【评分标准】
- 集群初始化成功(30 分)
- Calico 安装正确(20 分)
- 节点状态 Ready(20 分)
- 系统 Pod 全部 Running(15 分)
- nginx 测试 Pod Running(10 分)
- 别名配置(5 分)

📋 命令速查

命令 功能 注解
sudo swapoff -a 关闭 Swap kubelet 强制要求,否则拒绝启动
sudo sed -i '/ swap / s/^/#/' /etc/fstab 永久禁用 Swap 注释 fstab 中 swap 行,重启后仍生效
sudo modprobe br_netfilter 加载 br_netfilter 模块 允许桥接流量经过 iptables 处理
sudo modprobe overlay 加载 overlay 模块 容器存储驱动依赖
sudo sysctl --system 应用所有 sysctl 配置 重新加载 /etc/sysctl.d/ 下所有配置
sudo dnf install -y containerd.io 安装 containerd 运行时 K8s 1.24+ 默认容器运行时,通过 Docker CE 仓库安装
containerd config default | sudo tee /etc/containerd/config.toml 生成 containerd 默认配置 必须修改 SystemdCgroup = true
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml 启用 SystemdCgroup 与 kubelet 的 cgroup 驱动保持一致
sudo systemctl restart containerd && sudo systemctl enable containerd 重启并开机自启 containerd 配置修改后必须重启
sudo dnf versionlock kubelet kubeadm kubectl 锁定 K8s 组件版本 防止 dnf upgrade 意外升级导致版本不一致
sudo kubeadm init --pod-network-cidr=192.168.0.0/16 --kubernetes-version=v1.29.0 初始化 K8s 集群 下载镜像、生成证书、启动控制平面组件为静态 Pod
mkdir -p $HOME/.kube && sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config 配置 kubectl 认证 将 admin 证书复制到用户目录
sudo chown $(id -u):$(id -g) $HOME/.kube/config 修改 kubeconfig 权限 让普通用户也能使用 kubectl
kubectl apply -f calico.yaml 安装 Calico CNI 提供 Pod 网络和 NetworkPolicy 支持
kubectl get pods -n kube-system --watch 实时监控系统 Pod 等待 CoreDNS 和 Calico Pod 就绪
kubectl get nodes 查看节点状态 STATUS 必须为 Ready
kubectl get componentstatuses 查看控制平面组件健康 检查 scheduler/controller-manager/etcd 状态
kubectl get --raw='/readyz?verbose' 查看 apiserver 就绪探测详情 比 componentstatuses 更准确(1.19+)
kubectl cluster-info 查看集群信息 输出 apiserver 和 CoreDNS 地址
sudo crictl ps 列出容器(containerd) K8s 1.24+ 替代 docker ps
sudo crictl ps | grep etcd 查找 etcd 容器 ID 静态 Pod 通过 crictl 管理
sudo crictl exec -it <etcd-id> sh 进入 etcd 容器 用于执行 etcdctl 命令探索存储
ETCDCTL_API=3 etcdctl --cacert=... --cert=... --key=... get / --prefix --keys-only | head -30 列出 etcd 中的 key 查看集群存储在 etcd 中的资源
echo 'source <(kubectl completion bash)' >> ~/.bashrc 启用 kubectl 自动补全 按 Tab 补全命令和资源名
alias k=kubectl 设置 kubectl 别名 减少输入量,赛题时间紧张时很有用

📚 参考来源

来源 链接 / 说明
Kubernetes 官方:安装 kubeadm https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/
Kubernetes 官方:创建集群 https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/
containerd 官方文档 https://github.com/containerd/containerd/blob/main/docs/getting-started.md
Calico 快速开始 https://docs.tigera.io/calico/latest/getting-started/kubernetes/quickstart
Linux 内核模块 overlay/br_netfilter https://kubernetes.io/docs/setup/production-environment/container-runtimes/
kubectl 安装与配置 https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/

📝 今日笔记模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
日期:____年____月____日
用时:____小时____分

✅ 完成项:
□ 架构原理理解
□ 练习 1.1 单节点初始化
□ 练习 1.2 Calico 安装
□ 练习 1.3 kubectl 配置
□ 练习 1.4 组件状态查看
□ 练习 1.5 etcd 探索
□ 排错练习 1-2
□ 赛题模拟

❓ 遇到的问题与解决方案:
1.
2.

📌 关键收获:
1.
2.
3.

⏭️ 明天重点:

📘 Day 29:弱点回顾与强化

🎯 今日目标

  • 通过自测识别薄弱模块
  • 针对性补强 2-3 个弱项
  • 整理个人速查手册

📊 自测评估(40 分钟)

快速自测题(每题用 kubectl 或手写 YAML 完成)

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
【M1 集群管理】
□ 初始化集群的命令是什么?(写出完整 kubeadm init 命令)
□ 如何生成 join token?
□ 如何备份 etcd?

【M2 Pod 与工作负载】
□ 写出 Deployment 的滚动更新回滚命令
□ StatefulSet 与 Deployment 的核心区别?
□ Job 的 completions 和 parallelism 含义?
□ InitContainer 有什么用?

【M3 网络】
□ 四种 Service 类型分别是什么?
□ Ingress 和 Service 的关系?
□ NetworkPolicy 默认行为是什么?
□ Headless Service 的 ClusterIP 是什么?

【M4 存储】
□ ConfigMap 的三种使用方式?
□ PV 的三种 reclaimPolicy?
□ PVC 一直 Pending 的常见原因?

【M5 调度】
□ nodeSelector vs nodeAffinity 的区别?
□ podAntiAffinity 的使用场景?
□ requests 和 limits 的区别?
□ HPA 公式是什么?

【M6 安全】
□ Role 和 ClusterRole 的区别?
□ ServiceAccount 的作用?
□ runAsNonRoot 的含义?

【M7 监控与排错】
□ kubectl logs --previous 的作用?
□ CrashLoopBackOff 的排查步骤?
□ Service Endpoint 为空的排查顺序?

评分标准

  • 每题 4 分,共 25 题,满分 100
  • ≥ 80 分:准备充分,明天模拟考后即可参赛
  • 60-79 分:基础扎实,需要补强标记为 □ 的模块
  • < 60 分:建议延期比赛,重点复习薄弱模块

🎯 针对性强化(150 分钟)

根据自测结果,从以下强化练习中选择 2-3 个最弱的模块 重点练习:

强化包 A:集群与工作负载

1
2
3
4
5
练习:在 30 分钟内完成
1. 用 kubeadm 重新初始化集群(销毁→重建)
2. 从零编写 Deployment + StatefulSet + DaemonSet + CronJob
3. 全部用 --dry-run=client 生成 YAML 后编辑
4. 执行至少 3 次滚动更新 + 回滚

强化包 B:网络

1
2
3
4
5
练习:在 30 分钟内完成
1. 创建 3 个 Service(ClusterIP/NodePort/Headless)
2. 创建 Ingress 规则(路径路由 + 域名路由)
3. 创建 Deny-All NetworkPolicy + 放行 DNS/Ingress
4. 验证跨 Namespace 网络隔离

强化包 C:存储与配置

1
2
3
4
5
练习:在 30 分钟内完成
1. 创建 ConfigMap(4 种方式各一次)
2. 创建 Secret(Opaque + TLS + dockerconfigjson)
3. 创建 PV + PVC 静态绑定
4. 创建 StorageClass + 动态 PVC(如有环境)

强化包 D:调度与资源

1
2
3
4
5
练习:在 30 分钟内完成
1. 打标签 + 污点
2. nodeAffinity + podAntiAffinity
3. ResourceQuota + LimitRange
4. HPA 配置并验证

强化包 E:安全

1
2
3
4
5
练习:在 30 分钟内完成
1. 创建 3 个 SA + 3 级 Role + 3 个 RoleBinding
2. 验证不同 SA 的权限差异
3. SecurityContext:runAsNonRoot + readOnlyRootFS + drop ALL
4. 创建受限 kubeconfig

强化包 F:排错

1
2
3
4
5
练习:在 30 分钟内完成
1. 故意制造 CrashLoopBackOff → 排查
2. 故意制造 Service selector 不匹配 → 排查
3. 故意制造 PVC Pending → 排查
4. 故意制造 Node NotReady → 排查

📝 个人速查手册模板(50 分钟)

花时间整理一份属于你自己的速查手册:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 我的 K8s 速查手册

## 最常用命令
kubectl get pods -A -o wide
kubectl describe pod <name>
kubectl logs <pod> --tail=50 -f
kubectl logs <pod> --previous
kubectl exec -it <pod> -- sh
kubectl create deploy <name> --image=<img> --dry-run=client -o yaml
kubectl expose deploy <name> --port=80 --dry-run=client -o yaml

## 排错套路
1. kubectl get pods -A | grep -v Running
2. kubectl describe pod <problem-pod>
3. kubectl logs <pod> --tail=50
4. kubectl get events -A --sort-by='.lastTimestamp'

## 我的易错点
1. Service selector 要匹配 Pod labels
2. ConfigMap envFrom 不会热更新(需 volume 方式)
3. ...

📊 今日检查清单

  • 完成自测评估,记录得分
  • 识别 2-3 个薄弱模块
  • 完成针对性强化练习
  • 整理个人速查手册
  • 准备好明天的全真模拟

📋 命令速查

弱点回顾中高频使用的验证与修复命令:

命令 功能 注解
kubectl auth can-i --list 列出当前用户全部权限 回顾 RBAC 配置是否正确
kubectl get events -A --sort-by=.lastTimestamp | tail -20 全集群最近事件 弱点排查第一步
kubectl get pods -A --field-selector=status.phase!=Running 找所有异常 Pod 一次性定位所有问题
kubectl describe pod <pod> | grep -E "State:|Exit Code|Restart" 容器状态摘要 快速判断容器状态和重启原因
kubectl top pods -A --sort-by=cpu 按 CPU 排序 找资源消耗大户
kubectl top pods -A --sort-by=memory 按内存排序 找内存泄漏 Pod
kubectl get pvc -A --field-selector=status.phase=Pending 未绑定的 PVC 存储问题排查
kubectl logs <pod> --previous | tail -30 上一次崩溃日志 CrashLoopBackOff 问题排查
kubectl exec <pod> -- nslookup <svc>.<ns>.svc.cluster.local 验证 DNS 网络问题必须先排除 DNS
kubectl -n kube-system logs kube-apiserver-<node> | grep -i error | tail -10 apiserver 错误日志 集群级故障溯源
journalctl -u kubelet --since "30 min ago" | grep -i error 节点 kubelet 错误 节点 NotReady 溯源

📚 参考来源

来源 链接 / 说明
Kubernetes 官方:排错指南 https://kubernetes.io/docs/tasks/debug/
Kubernetes 官方:排错 Pod https://kubernetes.io/docs/tasks/debug/debug-application/debug-pods/
Kubernetes 官方:排错集群 https://kubernetes.io/docs/tasks/debug/debug-cluster/
Kubernetes 常见问题 https://github.com/kubernetes/kubernetes/wiki/User-FAQ

📘 Day 30:全真模拟考试

🎯 今日目标

在严格限时的模拟比赛环境中,完成一套完整试卷,检验 30 天学习成果。


📋 考试规则

项目 要求
考试时长 180 分钟(3 小时)
总分 100 分
及格线 60 分
优秀线 85 分
环境 3 节点 K8s 集群(已就绪)
允许参考 个人速查手册(不允许联网搜索)
提交物 所有 YAML 文件 + 验证命令输出

📝 全真模拟试卷

第一部分:集群运维(15 分,25 分钟)

题目 1.1(5 分)

1
2
3
4
5
# 检查集群健康状态,输出以下信息:
# - 所有节点状态和版本
# - 所有命名空间中非 Running 的 Pod
# - 证书到期时间
# - 最近 10 条 Warning 事件

题目 1.2(5 分)

1
2
# 对 etcd 做一次快照备份,验证快照完整性
# 将备份文件存放到 /opt/etcd-backup/exam-$(date +%Y%m%d).db

题目 1.3(5 分)

1
2
3
4
# 现有节点 k8s-node1 需要维护,执行:
# - cordon 使其不再调度新 Pod
# - drain 排空已有 Pod
# - 维护完成后 uncordon 恢复

第二部分:工作负载编排(25 分,45 分钟)

题目 2.1:StatefulSet 数据库集群(10 分)

1
2
3
4
5
6
7
8
部署一个 redis 集群:
- 名称:redis-cluster
- 副本数:3
- 镜像:redis:7-alpine
- 启动命令:redis-server --appendonly yes --cluster-enabled yes
- Headless Service:redis-cluster-svc(端口 6379)
- 每个 Pod 独立 PVC:200Mi
- 限制资源:cpu 200m, memory 256Mi

题目 2.2:Deployment 应用层(10 分)

1
2
3
4
5
6
7
8
9
部署一个 API 服务:
- 名称:api-gateway
- 镜像:nginx:alpine
- 副本数:4
- 滚动策略:maxSurge=1, maxUnavailable=0
- livenessProbe: HTTP GET /health, 端口 80
- readinessProbe: HTTP GET /ready, 端口 80
- 资源:requests cpu=100m mem=128Mi, limits cpu=300m mem=256Mi
- Service:ClusterIP,端口 80

题目 2.3:DaemonSet + CronJob(5 分)

1
2
3
4
- DaemonSet node-monitor:busybox:1.36,每 10 秒输出主机名和时间
- CronJob cluster-health:每 5 分钟检查一次 DNS 解析,
命令:nslookup kubernetes.default
保留最近 3 个成功的 Job

第三部分:网络配置(20 分,35 分钟)

题目 3.1:Ingress 路由(10 分)

1
2
3
4
5
创建 Ingress 规则,路由到题 2.2 的 api-gateway:
- 域名:api.exam.com
- /v1/stats → api-gateway:80/stats
- /v1/health → api-gateway:80/health
- 配置 rewrite-target 注解

题目 3.2:NetworkPolicy 网络隔离(10 分)

1
2
3
4
5
6
在 exam 命名空间中创建网络策略:
- 默认拒绝所有入站流量
- 允许 Ingress Controller → api-gateway:80
- 允许 api-gateway → redis-cluster:6379
- 允许所有 Pod → CoreDNS(kube-system, UDP 53)
- 验证:从 api-gateway 可访问 redis,从外部 Pod 不可访问

第四部分:存储与配置(20 分,35 分钟)

题目 4.1:配置管理(8 分)

1
2
3
4
5
6
7
- ConfigMap api-config:
LOG_LEVEL=info, MAX_CONNECTIONS=500, TIMEOUT=30s
- Secret api-secret:
DB_PASSWORD=exam-secret-2024, JWT_KEY=jwt-key-exam
- 修改 Deployment api-gateway:
envFrom 注入 api-config
valueFrom 注入 DB_PASSWORD → DATABASE_PASSWORD

题目 4.2:持久存储(12 分)

1
2
3
4
5
6
- 创建 hostPath PV pv-exam(容器 2Gi, RWO, /data/exam-pv)
- 创建 PVC pvc-exam(请求 1Gi, RWO)
- 验证 PV 和 PVC 绑定
- 创建一个 Pod exam-storage 挂载 pvc-exam 到 /data:
写入验证文件 /data/exam.txt
删除 Pod 后验证文件仍存在

第五部分:安全与调度(20 分,40 分钟)

题目 5.1:RBAC(10 分)

1
2
3
4
5
6
7
8
9
创建以下权限体系:
- SA exam-admin:对 exam 命名空间全部权限
- SA exam-developer:对 Pod/Deploy/Service/ConfigMap
有 get/list/watch/create/update 权限
对 Secret 和 Pod/log 只有 get/list 权限
- SA exam-viewer:只读所有(get/list/watch)

每个 SA 创建对应的 Role + RoleBinding
验证:kubectl auth can-i --as=... 测试权限差异

题目 5.2:安全与调度(10 分)

1
2
3
4
5
6
7
8
修改 Deployment api-gateway 添加:
- SecurityContext:
runAsUser: 1001, runAsNonRoot: true
allowPrivilegeEscalation: false
drop ALL capabilities
- PodAntiAffinity: 同 app=api-gateway 的 Pod 不在同一节点
- topologySpreadConstraints: 按 hostname 均匀分布
- HPA: CPU 60%, min 2, max 8

📊 评分卡

部分 题目 满分 得分
第一部分 集群运维 15
第二部分 工作负载编排 25
第三部分 网络配置 20
第四部分 存储与配置 20
第五部分 安全与调度 20
总分 100

🏁 考后总结

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
得分:____ / 100
用时:____ 分钟

各模块得分情况:
- 集群运维:____ / 15
- 工作负载编排:____ / 25
- 网络配置:____ / 20
- 存储与配置:____ / 20
- 安全与调度:____ / 20

失分分析:
1. 最薄弱的模块:________
2. 主要失分原因:________
3. 时间分配是否合理?________

赛后提升计划:
1. ________
2. ________
3. ________

🎉 30 天学习完成

恭喜完成 Kubernetes 容器云 30 天学习计划!

1
2
3
4
5
6
7
8
9
回顾这段旅程:
- M1: 从零搭建了 K8s 集群
- M2: 掌握了 5 种工作负载
- M3: 构建了完整网络架构
- M4: 管理了配置和持久存储
- M5: 实现了智能调度和资源管理
- M6: 加固了集群安全
- M7: 建立了监控和排错体系
- M8: 完成了 8 套赛题模拟

后续建议

  1. 赛前 3 天:每天做一套限时模拟,保持手感
  2. 赛前 1 天:回顾速查手册,不再学新内容
  3. 比赛当天:先通读全部题目,按难度分配时间
  4. 长期:考取 CKA/CKAD 认证,深入源码和 Operator 开发

📋 命令速查

全真模拟考试必备命令速查(赛前 5 分钟默背):

命令 功能 注解
k=kubectl 设置别名 节省 80% 键盘输入量
kubectl create deploy <name> --image=<img> --dry-run=client -o yaml > deploy.yaml YAML 速成 赛题 80% YAML 用此方式生成再修改
kubectl expose deploy <name> --port=<p> --target-port=<tp> --dry-run=client -o yaml Service YAML 速成 不要手写 Service YAML
kubectl apply -f <file>.yaml 部署 优先 apply 而非 create
kubectl get all -n <ns> 全面审计 确认所有资源已创建
kubectl describe pod <pod> | tail -20 秒看 Event 排错第一步
kubectl logs <pod> --tail=20 日志速看 验证应用输出
kubectl exec <pod> -- curl -s http://<svc>:<port> 功能验证 证明服务可达
kubectl create cm <name> --from-literal=k=v --dry-run=client -o yaml ConfigMap 速成 配置注入
kubectl create secret generic <name> --from-literal=k=v --dry-run=client -o yaml Secret 速成 密钥注入
kubectl scale deploy <name> --replicas=<n> 副本调整 注意赛题要求的具体数量
kubectl rollout undo deploy/<name> 回滚 操作失误首选回滚
kubectl get events --field-selector type=Warning Warning 事件 致命错误秒定位
!khistory | grep kubectl 复用历史命令 一条命令多个任务使用

📚 参考来源

来源 链接 / 说明
Kubernetes 官方:kubectl 速查表(打印版) https://kubernetes.io/docs/reference/kubectl/quick-reference/
Kubernetes 官方:命令参考 https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands
kubectl 最佳实践 https://kubernetes.io/docs/reference/kubectl/conventions/

📘 Day 28:赛题模拟 8 + 限时挑战

🎯 今日目标

  • 完成最综合的赛题(120 分钟)
  • 完成限时挑战赛(60 分钟极限操作)

🏆 赛题 8:终极综合赛题(120 分钟)

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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
【场景】模拟职业技能大赛决赛场景:完整项目部署 + 运维 + 安全 + 排错。

【操作要求】(总分 100 分)

Part A: 集群准备(10 分)
1. 检查集群状态:所有节点 Ready
2. 确认 metrics-server 可用
3. 确认 NGINX Ingress Controller 已安装

Part B: 项目部署(40 分)
部署一个"在线商城"微服务系统:

4. 命名空间:online-mall

5. 用户服务(user-svc):
- Deployment user-api(3副本,nginx:alpine)
- ClusterIP Service user-svc
- ConfigMap user-config: DB=mysql, PORT=3306

6. 商品服务(product-svc):
- Deployment product-api(2副本,httpd:alpine)
- ClusterIP Service product-svc

7. 订单服务(order-svc):
- StatefulSet order-db(2副本,redis:7-alpine)
- Headless Service order-db-svc
- volumeClaimTemplates: 100Mi

8. 网关:
- Ingress: mall.example.com
- /api/users → user-svc:80
- /api/products → product-svc:80
- / → user-svc:80

9. 前端:
- Deployment mall-web(2副本,nginx:alpine)

Part C: 高级配置(25 分)
10. NetworkPolicy:
- 默认拒绝所有 ingress
- user-api → order-db:6379
- product-api → order-db:6379
- Ingress Controller → user-api:80
- Ingress Controller → product-api:80
- Ingress Controller → mall-web:80
- 所有 Pod → DNS

11. RBAC:
- SA mall-admin:对 online-mall 所有资源有全部权限
- SA mall-reader:对 Pod/Deploy/Service 有只读权限

12. HPA:
- user-api:CPU 50%, min 2, max 6
- product-api:CPU 60%, min 2, max 4

Part D: 安全加固(15 分)
13. 所有 Deployment 的 SecurityContext:
- runAsNonRoot
- allowPrivilegeEscalation: false
- drop ALL capabilities
14. 所有 Deployment 设置资源限制:
- requests: cpu=100m, mem=128Mi
- limits: cpu=300m, mem=256Mi

Part E: 故障演练与恢复(10 分)
15. 删除一个 user-api Pod,验证自愈
16. 回滚 product-api 到上一个版本
17. 手动触发 order-db 的缩容和扩容

【验证清单】
□ 所有 5 个微服务 Running
□ Ingress 路由正确
□ NetworkPolicy 隔离生效
□ RBAC 权限正确
□ HPA 生效
□ SecurityContext 加固

⚡ 限时挑战赛(60 分钟)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
【规则】60 分钟内尽可能多地完成以下任务,按完成度计分。

【挑战任务】(每题有对应分数,总分 100)

□ 任务 1(5 分):用 --dry-run=client 生成一个 Deploy + Service YAML
□ 任务 2(5 分):创建一个 Pod 带 InitContainer 等待 DNS 可用
□ 任务 3(10 分):配置一个 StatefulSet,3副本,每个独立 PVC
□ 任务 4(10 分):创建 Ingress 实现路径路由 /v1 → svc-a, /v2 → svc-b
□ 任务 5(10 分):创建 Deny-All NetworkPolicy + 逐层放行规则
□ 任务 6(10 分):配置 RBAC:dev 用户只能 get/list Pod
□ 任务 7(10 分):创建 ResourceQuota + LimitRange 并验证
□ 任务 8(10 分):配置 HPA,生成负载验证自动伸缩
□ 任务 9(10 分):排查并修复一个 CrashLoopBackOff Pod
□ 任务 10(10 分):创建带 SecurityContext 的安全 Pod
□ 任务 11(10 分):执行 etcd 备份并验证快照

【计分规则】
- 60 分钟内完成
- 每个任务:命令正确 = 满分,部分正确 = 一半
- 60 分以上及格,80 分以上优秀

📋 命令速查

该赛题涉及的核心命令速查(含限时挑战高频命令):

命令 功能 注解
kubectl create deploy <name> --image=<image> --dry-run=client -o yaml > deploy.yaml 生成 Deployment YAML 限时挑战中不手动写 YAML,用此生成后修改
kubectl create cm <name> --from-literal=key=value --dry-run=client -o yaml 生成 ConfigMap YAML 秒出模板,修改即可部署
kubectl expose deploy <name> --port=80 --dry-run=client -o yaml 生成 Service YAML 快速生成 Service 模板
kubectl apply -f <file>.yaml 声明式部署 一键部署所有资源
kubectl get all -n <ns> 查看所有资源 快速审计部署结果
kubectl describe pod <pod> | tail -20 Pod Events 摘要 出错时秒看原因
kubectl logs <pod> --tail=10 快速看日志 限时场景只看最后几行
kubectl exec <pod> -- <verify-cmd> 验证功能 curl/wget/cat 验证结果
kubectl rollout undo deploy/<name> 快速回滚 出错了不纠结,先回滚再改
kubectl delete pod <pod> --force --grace-period=0 强制删 Pod 卡 Terminating 时秒杀
kubectl get events --field-selector type=Warning | tail -10 只看 Warning 限时排错最佳实践

📚 参考来源

来源 链接 / 说明
Kubernetes 官方:kubectl 速查表 https://kubernetes.io/docs/reference/kubectl/quick-reference/
Kubernetes 官方:命令参考 https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands
CKA 模拟题(限时模式) https://killer.sh
kubectl 最佳实践 https://kubernetes.io/docs/reference/kubectl/conventions/
0%