注意CKA考试:
可以翻阅K8S官网,学会合理的利用官网文档,但是只能翻阅官网,翻阅其他网站会被判处作弊,
软件版本:Kubernetes v1.29
1.题目里设计到名称和路径之类,可以直接点击左侧进行复制,然后到粘贴到你的命令行窗口里
2.注意:考试环境有多个k8s集群,看题目要切换到要求的环境中进行答题
3.kubernetes.io中搜索题目关键字:左边题目上方也会给出一部分关键字,节省搜索时间
4.注意验证结果
5.kubernetes.io中举例说明,很多可以直接复制到自己yaml中,改几个参数就可以了,节约时间
一、考试权重
集群架构,安装和配置:25%
工作负载和调度:15%
服务和网络:20%
存储:10%
故障排除:30%
二、详细内容
集群架构,安装和配置:25%
• 管理基于角色的访问控制(RBAC)
• 使用Kubeadm安装基本集群
• 管理高可用性的Kubernetes集群
• 设置基础架构以部署Kubernetes集群
• 使用Kubeadm在Kubernetes集群上执行版本升级
• 实施etcd备份和还原
工作负载和调度:15%
• 了解部署以及如何执行滚动更新和回滚
• 使用ConfigMaps和Secrets配置应用程序
• 了解如何扩展应用程序
• 了解用于创建健壮的、自修复的应用程序部署的原语
• 了解资源限制如何影响Pod调度
• 了解清单管理和通用模板工具
服务和网络:20%
• 了解集群节点上的主机网络配置
• 理解Pods之间的连通性
• 了解ClusterIP、NodePort、LoadBalancer服务类型和端点
• 了解如何使用入口控制器和入口资源
• 了解如何配置和使用CoreDNS
• 选择适当的容器网络接口插件
存储:10%
• 了解存储类、持久卷
• 了解卷模式、访问模式和卷回收策略
• 理解持久容量声明原语
• 了解如何配置具有持久性存储的应用程序
故障排除:30%
• 评估集群和节点日志
• 了解如何监视应用程序
• 管理容器标准输出和标准错误日志
• 解决应用程序故障
• 对群集组件故障进行故障排除
• 排除网络故障
三、考试内容
题目类型基本一样,有的就是就改了名称而已
1、权限控制 RBAC
题目:
设置配置环境:
[candidate@node-1] $ kubectl config use-context k8s
Context
为部署流水线创建一个新的 ClusterRole 并将其绑定到范围为特定的 namespace 的特定 ServiceAccount。
Task
创建一个名为 deployment-clusterrole 且仅允许创建以下资源类型的新 ClusterRole:
Deployment
StatefulSet
DaemonSet
在现有的 namespace app-team1 中创建一个名为 cicd-token 的新 ServiceAccount。
限于 namespace app-team1 中,将新的 ClusterRole deployment-clusterrole 绑定到新的 ServiceAccount cicd-token。
解答:
更换 context
kubectl config use-context k8s
创建 ClusterRole
$ kubectl create clusterrole deployment-clusterrole --verb=create --resource=deployment,daemonset,statefulset
创建 ServiceAccount
$ kubectl create sa cicd-token -n app-team1
创建 rolebinding
rolebinding 后面的名字 cicd-token-rolebinding 随便起的,因为题目中没有要求,如果题目中有要求,就不能随便起了。
kubectl -n app-team1 create rolebinding cicd-token-rolebinding --clusterrole=deployment-clusterrole --serviceaccount=app-team1:cicd-token
检查
$ kubectl -n app-team1 describe rolebinding cicd-token-rolebinding
$ kubectl auth can-i create deployment --as system:serviceaccount:app-team1:cicd-token
no
$ kubectl auth can-i create deployment -n app-team1 --as system:serviceaccount:app-team1:cicd-token
yes
2、查看 pod 的 CPU
题目:
设置配置环境:
[candidate@node-1] $ kubectl config use-context k8s
Task
通过 pod label name=cpu-loader,找到运行时占用大量 CPU 的 pod,
并将占用 CPU 最高的 pod 名称写入文件 /opt/KUTR000401/KUTR00401.txt(已存在)。
解答:
更换 context
kubectl config use-context k8s
# 查看 pod 名称 -A 是所有 namespace
$ kubectl top pod -l name=cpu-loader --sort-by=cpu -A
# 将 cpu 占用最多的 pod 的 name 写入/opt/test1.txt 文件
$ echo "查出来的 Pod Name" > /opt/KUTR000401/KUTR00401.txt
检查
$ cat /opt/KUTR000401/KUTR00401.txt
3、配置网络策略 NetworkPolicy
题目:
设置配置环境:
[candidate@node-1] $ kubectl config use-context hk8s
Task
在现有的 namespace my-app 中创建一个名为 allow-port-from-namespace 的新 NetworkPolicy。
确保新的 NetworkPolicy 允许 namespace echo 中的 Pods 连接到 namespace my-app 中的 Pods 的 9000 端口。
进一步确保新的 NetworkPolicy:
不允许对没有在监听 端口 9000 的 Pods 的访问 不允许非来自 namespace echo 中的 Pods 的访问
双重否定就是肯定,所以最后两句话的意思就是:
仅允许端口为 9000 的 pod 方法。
仅允许 echo 命名空间中的 pod 访问。
解答:
更换 context
kubectl config use-context hk8s
创建 networkpolicy
vim networkpolicy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-port-from-namespace
namespace: my-app #被访问者的命名空间
spec:
podSelector: #这两行必须要写,或者也可以写成一行为 podSelector: {}
matchLabels: {} # 注意 matchLabels:与{}之间有一个空格
policyTypes:
- Ingress #策略影响入栈流量
ingress:
- from: #允许流量的来源
- namespaceSelector:
matchLabels:
project: echo #访问者的命名空间的标签 label
#- podSelector: {} #注意,这个不写。如果 ingress 里也写了- podSelector: {},则会导致 my-app 中的 pod 可以访问 my-app 中 pod 的 9000 了,这样不 满足题目要求不允许非来自 namespace echo 中的 Pods 的访问。
ports:
- protocol: TCP
port: 9000 #被访问者公开的端口
创建
kubectl apply -f networkpolicy.yaml
检查
kubectl describe networkpolicy -n my-app
4、暴露服务 service
题目:
设置配置环境:
[candidate@node-1] $ kubectl config use-context k8s
Task
请重新配置现有的 deployment front-end 以及添加名为 http 的端口规范来公开现有容器 nginx 的端口 80/tcp。
创建一个名为 front-end-svc 的新 service,以公开容器端口 http。
配置此 service,以通过各个 Pod 所在的节点上的 NodePort 来公开他们。
解答:
更换 context
kubectl config use-context k8s
修改 deployment
$ kubectl edit deployment front-end
......
spec:
containers:
- image: vicuu/nginx:hello
imagePullPolicy: IfNotPresent
name: nginx #找到此位置。下文会简单说明一下 yaml 文件的格式,不懂 yaml 格式的,往下看。
ports: #添加这 4 行
- name: http
containerPort: 80
protocol: TCP
......
暴露端口
$ kubectl expose deployment front-end --type=NodePort --port=80 --target-port=80 --name=front-end-svc
检查
kubectl get svc front-end-svc -o wide
5、创建 Ingress
题目:
设置配置环境:
[candidate@node-1] $ kubectl config use-context k8s
Task
如下创建一个新的 nginx Ingress 资源:
名称: ping
Namespace: ing-internal
使用服务端口 5678 在路径 /hello 上公开服务 hello
可以使用以下命令检查服务 hello 的可用性,该命令应返回 hello:
curl -kL <INTERNAL_IP>/hello
解答:
更换 context
kubectl config use-context k8s
创建 ingressclass
vim ingressclass.yaml
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
labels:
app.kubernetes.io/component: controller
name: nginx
annotations:
ingressclass.kubernetes.io/is-default-class: "true"
spec:
controller: k8s.io/ingress-nginx
kubectl apply -f ingressclass.yaml
创建 ingress
vim ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ping
namespace: ing-internal
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- http:
paths:
- path: /hello
pathType: Prefix
backend:
service:
name: hello
port:
number: 5678
kubectl apply -f ingress.yaml
检查
$ kubectl apply -f ingress.yaml
也可以 curl 一下 ingress 地址
6、扩容 deployment 副本数量
题目:
设置配置环境:
[candidate@node-1] $ kubectl config use-context k8s
Task
将 deployment presentation 扩展至 4 个 pods
解答:
更换 context
$ kubectl config use-context k8s
修改replicaset
$ kubectl scale deployment presentation --replicas=4
检查
$ kubectl get deployment presentation -oyaml
7、调度 pod 到指定节点
题目:
设置配置环境:
[candidate@node-1] $ kubectl config use-context k8s
Task
按如下要求调度一个 pod:
名称:nginx-kusc00401
Image:nginx
Node selector:disk=ssd
解答:
更换 context
$ kubectl config use-context k8s
创建 pod yaml
# 获取一个 pod 模版
$ kubectl run nginx-kusc00401 --image=nginx --dry-run -oyaml > 7.pod.yaml
$ cat 7.pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-kusc00401
spec:
nodeSelector: # 新增, 其余内容不需要
disk: ssd
containers:
- image: nginx
name: nginx-kusc00401
创建 pod
$ kubectl create -f 7.pod.yaml
pod/nginx-kusc00401 created
检查
$ kubectl get po -owide
8、查看可用节点数量
题目:
设置配置环境:
[candidate@node-1] $ kubectl config use-context k8s
Task
检查有多少 nodes 已准备就绪(不包括被打上 Taint:NoSchedule 的节点), 并将数量写入 /opt/KUSC00402/kusc00402.txt
解答:
更换 context
$ kubectl config use-context k8s
检查就绪 node
$ k describe no | grep -i taint
Taints: node-role.kubernetes.io/control-plane:NoSchedule
Taints: node-role.kubernetes.io/control-plane:NoSchedule
Taints: <none>
# 考试根据实际环境, 这里有 2 个节点被打上 NoSchedule
$ echo 1 > /opt/KUSC00402/kusc00402.txt
检查
$ cat /opt/KUSC00402/kusc00402.txt
9、创建多容器的 pod
题目:
设置配置环境:
[candidate@node-1] $ kubectl config use-context k8s
Task
按如下要求调度一个 Pod:
名称:kucc8
app containers: 2 container 名称/images:
⚫ nginx
⚫ consul
解答:
更换 context
$ kubectl config use-context k8s
创建 pod yaml
没指定 namespace 就是 default 不用填
# 获取一个 pod 模版
$ kubectl run kucc8 --image=nginx --dry-run=client -oyaml > 9.pod.yaml
$ cat 9.pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: kucc8
spec:
containers:
- image: nginx
name: nginx
- image: cousul
name: consul
创建 pod
$ kubectl create -f 9.pod.yaml
检查
$ kubectl get pod
10、创建 PV
题目:
设置配置环境:
[candidate@node-1] $ kubectl config use-context hk8s
Task
创建名为 app-config 的 persistent volume,容量为 1Gi,访问模式为 ReadWriteMany。 volume 类型为 hostPath,位于 /srv/app-config
解答:
更换 context
$ kubectl config use-context hk8s
创建 pv yaml
# 复制官网模版, 修改
$ cat 10.pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: app-config # 名
labels:
type: local
spec:
# storageClassName: manual 题目没指定
capacity:
storage: 1Gi # 容量
accessModes:
- ReadWriteMany # 读写权限
hostPath:
path: "/srv/app-config" # 题目有指定
创建 pv
$ kubectl create -f 10.pv.yaml
检查
$ kubectl describe pv app-config
11、创建 PVC
题目:
设置配置环境:
[candidate@node-1] $ kubectl config use-context ok8s
Task
创建一个新的 PersistentVolumeClaim:
名称: pv-volume
Class: csi-hostpath-sc
容量: 10Mi
创建一个新的 Pod,来将 PersistentVolumeClaim 作为 volume 进行挂载:
名称:web-server
Image:nginx:1.16
挂载路径:/usr/share/nginx/html
配置新的 Pod,以对 volume 具有 ReadWriteOnce 权限。
最后,使用 kubectl edit 或 kubectl patch 将 PersistentVolumeClaim 的容量扩展为 70Mi,并记录此更改。
解答:
更换 context
$ kubectl config use-context ok8s
创建 pvc
# 复制官网模版, 按题目修改响应字段
$ cat 11.pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pv-volume
spec:
storageClassName: csi-hostpath-sc
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Mi
$ kubectl create -f 11.pvc.yaml
创建 pod
# 获取 pod 模版
$ kubectl run web-server --image=nginx:1.16 --dry-run=client -oyaml > 11.pod.yaml
$ cat 11.pod.yaml # 挂载 pvc
apiVersion: v1
kind: Pod
metadata:
labels:
run: web-server
name: web-server
spec:
volumes:
- name: 11-pvc
persistentVolumeClaim:
claimName: pv-volume
containers:
- image: nginx:1.16
name: web-server
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: 11-pvc
$ kubectl create -f 11.pod.yaml
修改 pvc 并记录
$ kubectl edit pvc pv-volume --record
12、查看 pod 日志
题目:
设置配置环境:
[candidate@node-1] $ kubectl config use-context k8s
Task
监控 pod foo 的日志并:
提取与错误 RLIMIT_NOFILE 相对应的日志行 将这些日志行写入 /opt/KUTR00101/foo
解答:
$ kubectl logs foo | grep RLIMIT_NOFILE > /opt/KUTR00101/foo
检查
$ cat /opt/KUTR00101/foo
13、使用 sidecar 代理容器日志
题目:
设置配置环境:
[candidate@node-1] $ kubectl config use-context k8s
Context
将一个现有的 Pod 集成到 Kubernetes 的内置日志记录体系结构中(例如 kubectl logs)。 添加 streaming sidecar 容器是实现此要求的一种好方法。
Task
使用 busybox Image 来将名为 sidecar 的 sidecar 容器添加到现有的 Pod 11-factor-app 中。 新的 sidecar 容器必须运行以下命令:
/bin/sh -c tail -n+1 -f /var/log/11-factor-app.log
使用挂载在/var/log 的 Volume,使日志文件 11-factor-app.log 可用于 sidecar 容器。 除了添加所需要的 volume mount 以外,请勿更改现有容器的规格。
考题翻译成白话,就是:
添加一个名为 sidecar 的边车容器(使用 busybox 镜像),加到已有的 pod 11-factor-app 中。 确保 sidecar 容器能够输出 /var/log/11-factor-app.log 的信息。
使用 volume 挂载 /var/log 目录,确保 sidecar 能访问 11-factor-app.log 文件
解答:
更换 context
$ kubectl config use-context k8s
获取 pod yaml
$ kubectl get pod 11-factor-app -o yaml > varlog.yaml
# 备份 yaml 文件,防止改错了,回退。
$ cp varlog.yaml varlog-bak.yaml
修改 yaml
spec:
。。。。。。
volumeMounts: #在原配置文件,灰色的这段后面添加
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: default-token-4l6w8
readOnly: true
- name: varlog #新加内容
mountPath: /var/log #新加内容
- name: sidecar #新加内容,注意 name 别写错了
image: busybox #新加内容
args: [/bin/sh, -c, 'tail -n+1 -f /var/log/11-factor-app.log'] #新加内容,注意 文件名 别写错了。另外是用逗号分隔的,而题目里是空格。
volumeMounts: #新加内容
- name: varlog #新加内容
mountPath: /var/log #新加内容
dnsPolicy: ClusterFirst
enableServiceLinks: true
。。。。。。
volumes: #在原配置文件,灰色的这段后面添加。
- name: kube-api-access-kcjc2
projected:
defaultMode: 420
sources:
- serviceAccountToken:
expirationSeconds: 3607
path: token
- configMap:
items:
- key: ca.crt
path: ca.crt
name: kube-root-ca.crt
- downwardAPI:
items:
- fieldRef: apiVersion: v1
fieldPath: metadata.namespace
path: namespace
- name: varlog #新加内容,注意找好位置。
emptyDir: {} #新加内容
创建 pod
$ kubectl delete -f varlog.yaml
$ kubectl createe -f varlog.yaml
检查
$ kubectl exec 11-factor-app -c sidecar -- tail -f /var/log/11-factor-app.log
$ kubectl exec 11-factor-app -c count -- tail -f /var/log/11-factor-app.log
14、升级集群
题目:
设置配置环境:
[candidate@node-1] $ kubectl config use-context mk8s
Task
现有的 Kubernetes 集群正在运行版本 1.28.0。仅将 master 节点上的所有 Kubernetes 控制平面和节点组件升级到版本 1.28.1。
确保在升级之前 drain master 节点,并在升级后 uncordon master 节点。
可以使用以下命令,通过 ssh 连接到 master 节点:
ssh master01
可以使用以下命令,在该 master 节点上获取更高权限:
sudo -i
另外,在主节点上升级 kubelet 和 kubectl。
请不要升级工作节点,etcd,container 管理器,CNI 插件, DNS 服务或任何其他插件。
解答:
更换 context
$ kubectl config use-context mk8s
ssh 到 master01
$ ssh master01
$ sudo -i
排空节点
$ kubectl cordon master
$ kubectl drain master
升级 kubeadm
$ apt update
$ apt-cache madison kubeadm | grep 1.28.1
# apt 升级 kubeadm
$ apt-get install kubeadm=1.28.1-00 -y
# kubeadm 升级集群, 注意不要升级 etcd, 忘记怎么写, 可以 -h
$ kubeadm upgrade apply 1.28.1 --etcd-upgrade=false
升级 kubectl, kubelet
$ apt-get install kubectl=1.28.1-00 kubelet=1.28.1-00 -y
检查
$ kubeadm version
$ kubectl version
$ kubelet --version
# 记得使节点可重新调度
$ kubectl uncordon master01
$ exit # 退到 node01
15、备份还原 etcd
题目:
设置配置环境
此项目无需更改配置环境。但是,在执行此项目之前,请确保您已返回初始节点。
[candidate@master01] $ exit #注意,这个之前是在 master01 上,所以要 exit 退到 node01,如果已经是 node01 了,就不要再 exit 了。
Task
首先,为运行在 https://127.0.0.1:2379 上的现有 etcd 实例创建快照并将快照保存到 /var/lib/backup/etcd-snapshot.db
为给定实例创建快照预计能在几秒钟内完成。 如果该操作似乎挂起,则命令可能有问题。用 CTRL + C 来取消操作,然后重试。 然后还原位于/data/backup/etcd-snapshot-previous.db 的现有先前快照。
提供了以下 TLS 证书和密钥,以通过 etcdctl 连接到服务器。
CA 证书: /opt/KUIN00601/ca.crt
客户端证书: /opt/KUIN00601/etcd-client.crt
客户端密钥: /opt/KUIN00601/etcd-client.key
解答:
注意:
记得设置 ETCDCTL_API=3
如果文件没权限, 就 sudo -i
备份快照
$ sudo ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/opt/KUIN00601/ca.crt --cert=/opt/KUIN00601/etcd-client.crt --key=/opt/KUIN00601/etcd-client.key snapshot save /var/lib/backup/etcd-snapshot.db
恢复快照
$ sudo ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/opt/KUIN00601/ca.crt --cert=/opt/KUIN00601/etcd-client.crt --key=/opt/KUIN00601/etcd-client.key snapshot restore /data/backup/etcd-snapshot-previous.db
检查
# 没必要
$ etcdctl snapshot status /var/lib/backup/etcd-snapshot.db -wtable
16、排查集群中故障节点
题目:
设置配置环境:
[candidate@node-1] $ kubectl config use-context wk8s
Task
名为 node02 的 Kubernetes worker node 处于 NotReady 状态。
调查发生这种情况的原因,并采取相应的措施将 node 恢复为 Ready 状态,确保所做的任何更改永久生效。
可以使用以下命令,通过 ssh 连接到 node02 节点:
ssh node02
可以使用以下命令,在该节点上获取更高权限:
sudo -i
解答:
更换 context
$ kubectl config use-context wk8s
ssh 到 node02 查看 kubelet
$ ssh node02
$ sudo -i # root
# 查看 kubelet 状态
$ systemctl status kubelet
$ systemctl restart kubelet && systemctl enable kubelet
检查
$ systemctl status kubelet
# 考试时记得从 node2 退回到 node1
$ exit
$ exit
17、节点维护
题目:
设置配置环境:
[candidate@node-1] $ kubectl config use-context ek8s
Task
将名为 node02 的 node 设置为不可用,并重新调度该 node 上所有运行的 pods。
解答:
更换 context
$ kubectl config use-con排空节点
$ kubectl cordon node02
$ kubectl drain node02text ek8s
排空节点
$ kubectl cordon node02
$ kubectl drain node02
评论区