一、写这篇指南前,先说个惨案
2024年3月,我花2000块报了CKA考试,信心满满地刷完Udemy上所有题目,背了30个yaml模板。结果考试刚开始30分钟,我就在第7题卡住了——NetworkPolicy死活连不上DNS。
最后成绩:63分,离及格线就差2分。亏的不是2000块,是两周的晚上时间。
复盘时发现,问题不在于我背得不熟,而在于我没有在一台真实安装的Kubernetes集群上操作过。刷题时用的都是网页模拟器,点几个按钮就完事,跟真实环境差了十万八千里。
这篇指南是我第二次备考(86分通过)的完整记录,包含所有用到的工具、配置、脚本,以及花了几十个小时试错才总结出来的坑。
二、问题:CKA备考到底该用什么方式练?
CKA认证(Certified Kubernetes Administrator)由CNCF主办,考试时长2小时,17道题,全部在远程终端里操作。核心考察点:
- 集群架构、安装、配置
- 工作负载调度(Deployment、StatefulSet、DaemonSet)
- 服务与网络(Service、Ingress、NetworkPolicy)
- 存储(PV、PVC、StorageClass)
- 排障(cluster inspect、日志分析、资源诊断)
- 安全(RBAC、SecurityContext、ServiceAccount)
说白了,这考试就是看你能不能在黑乎乎的命令行里把事办成。所以备考方式必须满足两个条件:
- 动手:像考试一样真敲命令
- 接近真实:Kubernetes版本、环境限制、网络情况都要模拟到位
主流备考方案对比
| 方案 | 成本 | Kubernetes版本 | 全真环境 | 坏处 |
|---|---|---|---|---|
| 官方文档阅读 | 免费 | 最新 | 无 | 纯理论,无法验证 |
| 本地minikube | 免费 | 可指定 | 单节点 | 很多考题要多节点 |
| Killercoda | 免费 | v1.28/v1.29 | 2节点 | 环境限制某些操作 |
| KodeKloud模拟 | ~$79/年 | v1.29 | 2节点 | 题太简单 |
| 自建3节点 kubeadm集群 | 服务器费用 | 任意(我用1.29.2) | 完全可控 | 配置耗时,一次性 |
我的选择:Killercoda 免费环境 + 自建3节点集群做深度练习。原因后面展开。
三、两种备考路径的完整对比
方案A:Killercoda + 真题磨炼(我的主路线)
Killercoda地址:killercoda.com,搜索 CKA,会有多个模拟环境。我使用的是「CKA - Simulator」环境,版本是v1.29。启动后给你一个Web终端,里面是两节点集群(控制节点+工作节点)。
优点
- 免费,随时开干
- 环境跟考试非常接近(同样是远程SSH式的操作界面)
- 可以用来练习所有考题类型
缺点
- 资源有限,不能随便创建大负载的Pod
- 网络隔离不完全,某些操作会失败(比如loadbalancer类型的service)
我的做法
把Killercoda当「考试模拟器」,用计时器卡时间做整套题。做完以后录屏,回放分析哪一步卡壳,再针对性去自建集群里练。
方案B:自建3节点集群(吃透原理的核武器)
#!/bin/bash
# 在3台Ubuntu 22.04机器上执行(我用的是云厂商的按小时计费实例)
# 每台机器规格:2C4G,操作系统 Ubuntu 22.04.3 LTS
# 执行前先确保有root权限
# 步骤1:安装容器运行时(containerd 1.7.11)
cat <<EOF | sudo tee /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF
sudo sysctl --system
# 步骤2:安装containerd
sudo apt-get update
sudo apt-get install -y containerd
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
# 修改Sandbox镜像为阿里云镜像(国内环境加速)
sudo sed -i 's#sandbox_image = "registry.k8s.io/pause:3.8"#sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.9"#' /etc/containerd/config.toml
sudo systemctl restart containerd
sudo systemctl enable containerd
# 步骤3:安装kubeadm、kubelet、kubectl(1.29.2)
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl gpg
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubelet=1.29.2-1.1 kubeadm=1.29.2-1.1 kubectl=1.29.2-1.1
sudo apt-mark hold kubelet kubeadm kubectl
# 步骤4:在控制节点初始化集群(把下面IP换成实际IP)
sudo kubeadm init \
--pod-network-cidr=10.244.0.0/16 \
--apiserver-advertise-address=192.168.1.10 \
--kubernetes-version=v1.29.2
# 步骤5:配置kubectl
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
echo "source <(kubectl completion bash)" >> ~/.bashrc
echo "alias k=kubectl" >> ~/.bashrc
echo "complete -o default -F __start_kubectl k" >> ~/.bashrc
source ~/.bashrc
# 步骤6:安装Flannel网络插件
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
# 步骤7:工作节点加入集群(在工作节点上执行)
# kubeadm join 192.168.1.10:6443 --token your-token --discovery-token-ca-cert-hash sha256:your-hash
EOF
这套配置我踩过的坑:版本1.29.2的apt源需要gpg key,旧版教程里用的是apt-key,已经废弃了。还有containerd config default输出的默认配置里,SystemdCgroup默认是false,但Kubernetes官方要求必须是true,否则kubelet会报错。
# 修复SystemdCgroup问题
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
sudo systemctl restart containerd
四、核心代码与命令:考试必会的模板
CKA考试有个特点:速度就是一切。2小时17题,平均每题7分钟。如果你花2分钟去敲一个yaml的缩进,基本就挂了。
所以我把所有可能会用到的命令和模板整理成了脚本,每个都背到肌肉记忆。下面这些是全套模板,直接复制就能用。
1. kubectl命令快速模板
# 考试第一件事:设置别名和补全
# 同时按 Ctrl+Alt+T 打开终端,执行:
alias k=kubectl
source <(kubectl completion bash)
complete -o default -F __start_kubectl k
export ETCDCTL_API=3
# 创建Pod的最快方式
k run nginx --image=nginx
# 创建Deployment(生成yaml再修改,比手写快得多)
k create deploy web --image=nginx --replicas=3 --dry-run=client -o yaml > web.yaml
# 查看Pod的IP和节点分布(考试高频)
k get pods -o wide
# 查看所有资源
k get all -n kube-system
# 查看某Pod详细信息
k describe pod nginx-xxx
# 进入Pod内部排障
k exec -it nginx-xxx -- bash
# 查看日志(排障题必用)
k logs nginx-xxx --tail=20
# 导出已有资源为yaml(关键技巧)
k get deployment web -o yaml > web-backup.yaml
k get pod nginx-xxx -o yaml > pod-backup.yaml
# 创建service(ClusterIP)
k expose pod nginx --port=80 --target-port=80 --name=nginx-svc
# 创建NodePort service
k expose deployment web --type=NodePort --port=80 --target-port=80 --name=web-svc
# 给节点打标签
k label node worker1 disktype=ssd
# 给Pod设置资源限制(直接从命令行创建)
k run nginx-limited --image=nginx --dry-run=client -o yaml --limits='cpu=100m,memory=128Mi' --requests='cpu=50m,memory=64Mi' > limited.yaml
2. 高频yaml模板(考试前背熟)
# deployment.yaml —— Deployment完整模板
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
labels:
app: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.25-alpine
ports:
- containerPort: 80
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 200m
memory: 256Mi
# service-nodeport.yaml —— NodePort Service
apiVersion: v1
kind: Service
metadata:
name: web-svc
spec:
type: NodePort
selector:
app: web
ports:
- port: 80
targetPort: 80
nodePort: 30080
# pv-pvc.yaml —— 存储类题目(常考)
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-data
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /data/pv
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 500Mi
3. etcd备份与恢复(必考一题)
# 备份etcd(考试必考操作,用证书认证)
ETCDCTL_API=3 etcdctl --endpoints=127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
snapshot save /tmp/etcd-backup.db
# 验证备份
ETCDCTL_API=3 etcdctl --write-out=table snapshot status /tmp/etcd-backup.db
# 恢复etcd(前提:停掉kube-apiserver)
sudo systemctl stop kube-apiserver
sudo ETCDCTL_API=3 etcdctl --endpoints=127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
snapshot restore /tmp/etcd-backup.db \
--data-dir=/var/lib/etcd-backup
# 修改/etc/kubernetes/manifests/etcd.yaml里的hostPath指向新数据目录
# 重启kubelet
4. 网络策略(最容易丢分的题)
# networkpolicy.yaml —— 允许来自指定Pod的流量访问
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-web
spec:
podSelector:
matchLabels:
app: db
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: web
ports:
- protocol: TCP
port: 3306
5. RBAC(常考但很多人写不对)
# rbac.yaml —— 创建ServiceAccount+Role+RoleBinding
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-reader
namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects:
- kind: ServiceAccount
name: app-reader
namespace: default
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
6. 考试题实战:滚动更新与回滚
# 对Deployment进行滚动更新
k set image deployment/web nginx=nginx:1.26-alpine
# 查看滚动状态
k rollout status deployment/web
# 查看历史版本
k rollout history deployment/web
# 回滚到上一个版本
k rollout undo deployment/web
# 暂停/恢复滚动更新
k rollout pause deployment/web
k rollout resume deployment/web
# 修改更新策略(important:这题考过好几次)
k patch deployment web -p '{"spec":{"strategy":{"type":"Recreate"}}}'
7. 排障题速查命令
# Pod一直ContainerCreating?
k describe pod xxx
# Pod一直CrashLoopBackOff?
k logs xxx --previous
# 节点NotReady?
k get nodes
k describe node worker1
systemctl status kubelet
# Service不通?
k get endpoints
# 如果Endpoints为空,说明selector不匹配,检查标签
# 查看集群事件
k get events --sort-by='.lastTimestamp'
# 查看kubelet日志
journalctl -u kubelet -n 100 --no-pager
五、效果数据:这么练到底提升了多少?
第一次备考我用了KodeKloud的题,刷了3遍,考试63分。第二次我用Killercoda模拟+自建集群深练,86分通过。
具体的效率数据:
| 指标 | 第一次(纯刷题) | 第二次(模拟+实战) | 提升幅度 |
|---|---|---|---|
| 搭建一个Deployment+Service完整流程 | 4分30秒 | 1分40秒 | 63% |
| etcd备份+恢复完整流程 | 9分15秒 | 4分55秒 | 47% |
| RBAC创建完整流程 | 6分02秒 | 2分38秒 | 56% |
| 写在纸上的yaml出错率 | 40% | 10% | 75% |
| 网络策略题正确率 | 30%(模拟环境里) | 80%(真实环境验证) | 167% |
最明显的差别是NetworkPolicy。刷题时我从来没真正验证过「这个网络策略是不是真的生效了」,在Killercoda里也验证不了(环境网络限制)。直到我自己建了3节点集群,才发现之前的yaml有个字段写错了——podSelector和namespaceSelector的作用范围搞混了。这种错误在考试里直接丢7-10分。
六、考试当天的时间分配策略
CKA考试2小时17题,每题权重不同。我的策略:
- 0-10分钟:快速浏览全部题目,先把最简单的5题做掉(比如查看、创建Pod、查看日志这类),拿到基础分
- 10-60分钟:做中等难度题(工作负载、存储、RBAC),每题控制在5分钟左右
- 60-100分钟:做高危题(etcd备份恢复、网络策略、集群升级),这类题操作复杂,一旦卡住可能要10分钟以上
- 100-120分钟:检查。确认所有Pod都是Running状态,所有Service能访问,没有遗漏的题
我在真实考试中使用的时间分布(考试软件会自动记录):
- 第1-5题:总耗时14分钟,全部是基础操作题 —— 我直接复制粘贴提前准备好的模板
- 第6-10题(含etcd备份、升级节点):41分钟 —— 中间卡了一次证书路径,用了2分钟排查
- 第11-15题(含NetworkPolicy、Ingress、PV/PVC):32分钟 —— 网络策略一次过
- 第16-17题(排障+Service):18分钟
- 剩余检查:5分钟
七、避坑指南:我实际踩过的坑
坑1:kubectl run 创建的Pod不能直接修改部分字段
kubectl run创建出来的Pod,不可编辑(除了image等少数字段)。如果你想加一个nodeSelector,会报错:
# 错误做法:在已有Pod上修改
kubectl edit pod nginx
# 报错:pods "nginx" is invalid: spec: Forbidden: pod updates may not change fields other than...
正确做法:先导出yaml,删除再重建,或者直接用kubectl run ... --dry-run=client -o yaml生成完整模板再改。
坑2:别忘了kubectl补全功能
考试环境里的kubectl默认没有别名和补全。没有补全意味着你不能Tab出资源名,每个命令都得手打。我第二次考试第一件事就是设置别名,光这一步就帮我省了至少10分钟的敲错字时间。
坑3:yaml缩进错误是最常见的丢分点
考试编辑器里没有yaml语法校验工具。我试过在containers:下面少写一个空格,导致整个Pod创建失败。白白浪费5分钟。
解决方案:用kubectl create --dry-run=client -o yaml 生成基础yaml,然后在上面改,而不是从头手写。另外,每个yaml创建完以后,一定要用kubectl get验证实际状态。
坑4:etcd恢复的坑
etcd恢复是个大坑,我练习时卡了2小时。关键点:
- 恢复前必须停掉kube-apiserver,否则apiserver会不断尝试连接旧etcd
- 恢复时指定的
--data-dir必须和etcd.yaml里配置的hostPath一致 - 如果你改了数据目录,必须把
/etc/kubernetes/manifests/etcd.yaml里的volume挂载路径也改掉
# 恢复完成后重启kubelet让apiserver重新拉起etcd
sudo systemctl restart kubelet
# 然后检查etcd pod是否正常
k get pods -n kube-system | grep etcd
坑5:考试里的容器镜像下载慢
考试环境在中国大陆访问,官方镜像仓库没拉快(实际不是镜像慢,是考试环境的pull policy,但确实会卡)。缓解办法:考试题目里通常会给镜像地址,如果卡住,用docker pull或crictl pull提前把镜像拉下来,考试时直接指定已存在镜像。
另一个坑是:某些题目里的镜像可能不存在(比如nginx:1.99),这是故意设置的,目的就是看你能不能判断出Pod无法拉取镜像并排查问题。
八、CKA与版本的关系:为什么选1.29?
CKA考试是基于Kubernetes 1.29版本的(2024年)。但你本地练习建议用1.28或1.29,保证跟考试一致。特别注意:
- 1.28开始,
kubectl apply的--prune行为有变化 - 1.29里,
kubeadm init的--cri-socket参数要求更严格 - PriorityClass在1.29里改名为了
scheduling.k8s.io/v1
另外,CKA支持CSR(CertificateSigningRequest),这部分在1.29里有新增考题,务必练习。
九、参考资源与工具版本清单
| 工具 | 版本 | 用途 |
|---|---|---|
| Kubernetes | v1.29.2 | 集群环境 |
| Killercoda | 最新 | 免费模拟环境 |
| etcdctl | v3.5.12 | 备份恢复操作 |
| containerd | 1.7.11 | 容器运行时 |
| Ubuntu | 22.04.3 LTS | 节点操作系统 |
十、最后,关于刷题
不要只刷题。
我见过太多人把CKA当「背题库考试」,刷完一遍以为自己会了,结果上了考场发现题目稍一变就不会了。CKA的题目虽然来自题库,但考官的意图很清楚:你能不能在真实环境里把Kubernetes跑起来。
所以备考的结束标志不是「题刷完了」,而是「我能在60分钟内从零搭起一个2节点集群,能把etcd备份恢复,能写出一个正确的NetworkPolicy,且全程不查文档」。
达到这个标准,CKA也就是个及格线而已。