Akemi

CKA认证题目与解法(2024版)

2025/03/07

RBAC

使用 RBAC 鉴权 | Kubernetes

(拖到网页最下面有命令行操作的范例)

Context:
为部署流水线创建一个新的ClusterRole并将其绑定到范围为特定的 namespace 的特定ServiceAccount。

Task
创建一个名为deployment-clusterrole的clusterrole,该clusterrole只允许对Deployment、Daemonset、Statefulset具有create权限,在现有的 namespace app-team1中创建一个名为cicd-token的新 ServiceAccount。
限于 namespace app-team1中,将新的ClusterRole deployment-clusterrole绑定到新的 ServiceAccount cicd-token。

ClusterRolebinding无法指定名称空间,在整个Cluster内都生效。

Rolebinding可以指定在ns内生效

1
2
3
4
5
6
7
8
kubectl create clusterrole deployment-clusterrole \
--verb=create --resource=deployments,daemonsets,statefulsets

kubectl create serviceaccount cicd-token -n app-team1

kubectl create rolebinding deployment-binding -n app-team1 \
--clusterrole=deployment-clusterrole --serviceaccount=app-team1:cicd-token

节点维护-node节点不可用

安全地清空一个节点 | Kubernetes(搜索关键词 drain)

Task:
将ek8s-node-1节点设置为不可用,然后重新调度该节点上的所有Pod

1
2
3
4
5
6
7
设置节点不可用
kubectl cordon k8s-node

kubectl drain k8s-node --help 查看帮助

将node上的pod都驱逐走
kubectl drain k8s-node --delete-emptydir-data --ignore-daemonsets --force

k8s版本升级

升级 kubeadm 集群 | Kubernetes

关键词kubeadm —upgrade

Task

现有的Kubernetes 集群正在运行版本1.23.1。仅将master节点上的所有 Kubernetes控制平面和节点组件升级到版本1.23.2。
请不要升级工作节点,etcd,container 管理器,CNI插件, DNS服务或任何其他插件。

考点:如何离线主机,并升级控制面板和升级节点

(注意,考试时的集群可能为1.23.0,会让你从1.23.0升级为1.23.1。甚至是1.22.1升级为1.22.2。所以敲命令时,具体要升级的版本,要注意,根据题目要求更改。)

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
1.驱逐master节点的pod,保护起来
kubectl drain k8s-master --delete-emptydir-data --ignore-daemonsets --force

2.根据提示登录到控制节点
ssh k8s-master

3.查看要安装的版本的完整版本号 为1.23.2-00
apt-cache show kubeadm | grep 1.23.2
#Version: 1.23.2-00
#Filename: pool/kubeadm_1.23.2-00_amd64_f3593ab00d33e8c0a19e24c7a8c81e74a02e601d0f1c61559a5fb87658b53563.deb

4.根据官网命令执行,升级kubeadm
sudo apt-mark unhold kubeadm && \
sudo apt-get update && sudo apt-get install -y kubeadm='1.23.2-00' && \
sudo apt-mark hold kubeadm

sudo kubeadm upgrade plan 确认计划
kubeadm upgrade apply v1.23.2 --etcd-upgrade=false 排除升级etcd
kubeadm version 查看版本

5.根据官网 升级kubelet和kubectl
sudo apt-mark unhold kubelet kubectl && \
sudo apt-get update && sudo apt-get install -y kubelet='1.23.2-00' kubectl='1.23.2-00' && \
sudo apt-mark hold kubelet kubectl

或者直接升级
apt-get install kubelet=1.23.2-00
apt-get install kubectl=1.23.2-00

sudo systemctl daemon-reload
sudo systemctl restart kubelet

6.恢复master节点
kubectl uncordon k8s-master

etcd备份还原

https://kubernetes.io/docs/tasks/administer-cluster/configure-upgrade-etcd/

关键词 upgrade-etcd

Task:

首先,为运行在https://127.0.0.1:2379上的现有 etcd 实例创建快照并将快照保存到 /srv/data/etcd-snapshot.db文件

然后还原位于/var/lib/backup/etcd-snapshot-previous.db的现有先前快照。

提供了以下TLS证书和密钥,以通过etcdctl连接到服务器。

CA 证书: /opt/KUIN00601/ca.crt

客户端证书: /opt/KUIN00601/etcd-client.crt

客户端密钥: /opt/KUIN00601/etcd-client.key

为给定实例创建快照预计能在几秒钟内完成。 如果该操作似乎挂起,则命令可能有问题。用 CTRL + C 来取消操作,然后重试。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1.安装etcdctl命令
上传etcd的压缩包,将其复制到/bin下

2.根据官网给的命令操作
查看帮助
ETCDCTL_API=3 etcdctl -h

进行快照
ETCDCTL_API=3 etcdctl --endpoints=https://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 [/srv/data/etcd-snapshot.db](https://127.0.0.1:2379上的现有 etcd 实例创建快照并将快照保存到 /srv/data/etcd-snapshot.db)

3.还原
sudo etcdctl --endpoints="https://127.0.0.1:2379" \
--cacert=/opt/KUIN000601/ca.crt --cert=/opt/KUIN000601/etcd-client.crt \
--key=/opt/KUIN000601/etcd-client.key snapshot \
restore /var/lib/backup/etcd-snapshot-previous.db

NetworkPolicy

关键词Network Policy

https://kubernetes.io/docs/concepts/services-networking/network-policies/

Task

在现有的namespace my-app中创建一个名为allow-port-from-namespace的新NetworkPolicy。

确保新的NetworkPolicy允许namespace echo中的Pods连接到namespace my-app中的Pods的9000端口。

进一步确保新的NetworkPolicy:

不允许对没有在监听端口9000的Pods的访问

不允许非来自 namespace echo中的Pods的访问

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
1.给ns echo打一个标签echo,需要一个独特的标签来标记。考试的时候已经创建好了
kubectl label ns echo project=echo

2.创建一个NetworkPolicy
vim networkpolicy.yaml
先把官方的yaml文件复制下来然后修改
:set paste
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-port-from-namespace
namespace: default
spec:
podSelector:
matchLabels: my-app
policyTypes: #策略只留入栈
- Ingress
ingress:
- from: #允许流量来源
- namespaceSelector:
matchLabels:
project: echo #指定ns的标签
ports:
- protocol: TCP
port: 9000 # 指定端口
# 删除出栈设置
kubectl apply -f networkpolicy.yaml

创建service

Task

重新配置一个已经存在的front-end的deployment,在名字为nginx的容器里面添加一个端口配置,名字为http,暴露端口号为80,然后创建一个service,名字为front-end-svc,暴露该deployment的http端口,并且service的类型为NodePort。

1
2
3
4
5
6
7
1.修改一个已经创建的deploy资源
在template后面添加一个port,80端口,别名http

2.创建service,暴露http端口
可以直接用expose来快速创建service
kubectl expose deployment front-end --port=80 --target-port=http \
--name=front-end-svc --type=NodePort

创建ingress

http://kubernetes.io/docs/concepts/services-networking/ingress/#the-ingress-resource

关键词:ingress,找到default ingress class

Task

如下创建一个新的nginx Ingress资源:

名称: pong

Namespace: ing-internal

使用服务端口 5678在路径 /hello 上公开服务(service) hello

可以使用以下命令检查服务 hello的可用性,该命令应返回 hello:

curl -kL /hello

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
1.创建一个ingressclass类,在官网可以找到模板进行修改(只修改ns即可

apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
labels:
app.kubernetes.io/component: controller
namespace: ing-internal
annotations:
ingressclass.kubernetes.io/is-default-class: "true"
spec:
controller: k8s.io/ingress-nginx
kubectl apply -f

2.创建一个ingress
官网也有模板,ingressClassName要和上面的一致
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: pong
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
namespace: ing-internal
spec:
ingressClassName: nginx-example
rules:
- http:
paths:
- path: /hello
pathType: Prefix
backend:
service:
name: hello
port:
number: 5678
kubectl apply -f

deployment扩缩容

TASK:

扩容deployment的pod到6个

1
2
kubectl scale --replicas=6 deployment <dp名>
kubectl edit也可以

pod创建

Task:
创建一个Pod,名字为nginx-kusc00401,镜像地址是nginx,调度到具有disk=spinning标签的节点上

1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: v1
kind: Pod
metadata:
name: nginx-kusc00401
labels:
role: nginx-kusc00401
spec:
nodeSelector:
disk: spinning
containers:
- name: nginx
image: nginx

ready节点状态检查

TSAK

检查集群中有多少节点为Ready状态(不包括被打上 Taint:NoSchedule 的节点),之后将数量写到/opt/KUSC00402/kusc00402.txt

1
2
3
4
5
6
7
8

kubectl get nodes | grep -i ready | wc -l

kubectl describe nodes | grep -i taint | grep -vi nosch | wc -l

echo x > /opt/KUSC00402/kusc00402.txt
-v 排除在外
-c 统计条数

一个pod里封装多个容器

Task

创建一个Pod,名字为kucc1,这个Pod包含4容器,为nginx、redis、memcached、consul

1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: v1
kind: Pod
metadata:
name: kucc1
spec:
containers:
- image: nginx
name: nginx
- image: redis
name: redis
- image: memcached
name: memcached
- image: consul
name: consul

pv和pvc绑定

Task
创建一个pv,名字为app-config,大小为2Gi,访问权限为ReadWriteMany。Volume的类型为hostPath,路径为/srv/app-config

1
2
3
4
5
6
7
8
9
10
11
apiVersion: v1
kind: PersistentVolume
metadata:
name: app-config
spec:
capacity:
storage: 2Gi
accessModes:
- ReadWriteMany
hostPath:
path: "/srv/app-config"

Task:
创建一个名字为pv-volume的pvc,指定storageClass为csi-hostpath-sc,大小为10Mi
然后创建一个Pod,名字为web-server,镜像为nginx,并且挂载该PVC至/usr/share/nginx/html,挂载的权限为ReadWriteOnce。之后通过kubectl edit或者kubectl path将pvc改成70Mi,并且记录修改记录。

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
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pv-volume
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Mi
storageClassName: csi-hostpath-sc

apiVersion: v1
kind: Pod
metadata:
name: web-server
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: pv-volume
volumes:
- name: pv-volume
persistentVolumeClaim:
claimName: pv-volume

查看日志

Task:
监控名为foobar的Pod的日志,并过滤出具有unable-access-website 信息的行,然后将写入到 /opt/KUTR00101/foobar

1
kubectl logs foobar | grep unable-access-website > /opt/KUTR00101/foobar

Sidecar代理

Context:
将一个现有的 Pod 集成到 Kubernetes 的内置日志记录体系结构中(例如 kubectl logs)。
添加 streaming sidecar 容器是实现此要求的一种好方法。

Task:
使用busybox Image来将名为sidecar的sidecar容器添加到现有的Pod legacy-app上,新的sidecar容器必须运行以下命令:
/bin/sh -c tail -n+1 -f /var/log/legacy-app.log
使用volume挂载/var/log/目录,确保sidecar能访问/var/log/legacy-app.log文件

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.创建c-sidecar的容器(考试环境中不需要
kubectl apply -f c-sidecar.yaml

2.导出yaml文件,并删减
kubectl get pods legacy-app -oyaml > sidecar.yaml

annotations部分、creationTimestamp,status部分删除

3.添加新的容器
- name: sidecar
image: busybox
args: [/bin/sh, -c, 'tail -n+1 -F /var/log/legacy-app.log']
volumeMounts:
- name: logs
mountPath: /var/log
volumes:
- name: logs
emptyDir: {}

kubectl delete -f c-sidecar.yaml
kubectl apply -f sidecar.yaml

4.查看日志
sudo kubectl logs legacy-app -c sidecar

查看pod的cpu利用率

Task:
找出标签是name=cpu-user的Pod,并过滤出使用CPU最高的Pod,然后把它的名字写在已经存在的/opt/KUTR00401/KUTR00401.txt文件里(注意他没有说指定namespace。所以需要使用-A指定所以namespace)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1.模拟环境准备(考试中已经有了
kubectl apply -f cpu-1.yaml
kubectl apply -f cpu-2.yaml
kubectl apply -f metrics.yaml

kubectl top pod

2.
kubectl top pod -l name=cpu-user --sort-by=cpu -A
NAMESPACE NAME CPU(cores) MEMORY(bytes)
kube-system cpu-1 2m 90Mi
default cpu-2 0m 6Mi

echo "cpu-1" >> /opt/KUTR00401/KUTR00401.txt

kubelet故障排查

Task:
一个名为 wk8s-node-0 的 Kubernetes 工作节点处于 NotReady 状态。调查其原因,并执行适当的步骤使节点进入 Ready 状态,确保任何更改都是永久性的。

1
2
3
直接重启kubelet即可
systemctl daemon-reload && systemctl restart kubelet
systemctl enable kubelet --now

原文作者:王盛

原文链接:https://akemi.zj.cn/2025/03/07/CKA/

发表日期:March 7th 2025, 9:54:08 am

更新日期:March 7th 2025, 10:06:49 am

版权声明:本文采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可

CATALOG
  1. 1. RBAC
  2. 2. 节点维护-node节点不可用
  3. 3. k8s版本升级
  4. 4. etcd备份还原
  5. 5. NetworkPolicy
  6. 6. 创建service
  7. 7. 创建ingress
  8. 8. deployment扩缩容
  9. 9. pod创建
  10. 10. ready节点状态检查
  11. 11. 一个pod里封装多个容器
  12. 12. pv和pvc绑定
  13. 13. 查看日志
  14. 14. Sidecar代理
  15. 15. 查看pod的cpu利用率
  16. 16. kubelet故障排查