导航菜单
首页 >  nginx考试题  > Kubernetes考试题(CKA)

Kubernetes考试题(CKA)

CKA题目

每次还原初始化快照后,开机后等5分钟,ssh登录node01(11.0.1.112)检查一下所有的pod,确保都为Running,再开始练习。

kubectl get pod -A 1、权限控制RBAC 问题 设置配置环境: [candidate@node-1] $ kubectl config use-context k8sContext 为部署流水线创建一个新的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。

考点:RBAC授权模型的理解。

没必要参考网址,使用-h帮助更方便。 kubectl create clusterrole -h kubectl create rolebinding -h

解答 kubectl create clusterrole deployment-clusterrole --verb=create --resource=deployments,statefulsets,daemonsetskubectl -n app-team1 create serviceaccount cicd-token # 题目中写了“限于namespace app-team1中”,则创建rolebinding。没有写的话,则创建clusterrolebinding。 kubectl -n app-team1 create rolebinding cicd-token-rolebinding --clusterrole=deployment-clusterrole --serviceaccount=app-team1:cicd-token # rolebinding后面的名字cicd-token-rolebinding随便起的,因为题目中没有要求,如果题目中有要求,就不能随便起了。检查(考试时,可以不检查的) kubectl -n app-team1 describe rolebinding cicd-token-rolebinding

2、查看pod的CPU 问题 设置配置环境: [candidate@node-1] $ kubectl config use-context k8sTask 通过 pod label name=cpu-loader,找到运行时占用大量 CPU 的 pod,并将占用 CPU 最高的 pod 名称写入文件 /opt/KUTR000401/KUTR00401.txt(已存在)。

考点:kubectl top --l 命令的使用

没必要参考网址,使用-h帮助更方便。 kubectl top pod -h

解答 考试时务必执行,切换集群。模拟环境中不需要执行。 # 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.txt3、配置网络策略 NetworkPolicy

问题 设置配置环境: [candidate@node-1] $ kubectl config use-context hk8sTask 在现有的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访问。

考点:NetworkPolicy 的创建

解答

参考官方文档,拷贝yaml文件内容,并修改。 这里要注意,模拟题和真题截图里都有提到echo这个namespace,但是和真题的截图比较,你会发现,两个echo出现的位置不同,一个作为访问者,一个作为 被访问者。 所以不要搞混了。他们其实只是个名字而已,叫什么都无所谓,但要分清访问和被访问。

podSelector:每个 NetworkPolicy 都包括一个 podSelector​, 它对该策略所适用的一组 Pod 进行选择。示例中的策略选择带有 " role (作用) =db" 标签的 Pod。 空的 podSelector​ 选择名字空间下的所有 Pod。

开始操作查看所有ns的标签label kubectl get ns --show-labels 如果访问者的namespace没有标签label,则需要手动打一个。如果有一个独特的标签label,则也可以直接使用。 kubectl label ns echo project=echo编写一个yaml文件 vim networkpolicy.yaml #注意 :set paste,防止yaml文件空格错序。 apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: allow-port-from-namespace namespace: my-appspec: podSelector:matchLabels: {} policyTypes:- Ingress ingress:- from:- namespaceSelector:matchLabels: project: echo ports:- protocol: TCP port: 9000

检查

kubectl describe networkpolicy -n my-app4、暴露服务 service 问题 设置配置环境: [candidate@node-1] $ kubectl config use-context k8sTask 请重新配置现有的deployment front-end 以及添加名为http的端口规范来公开现有容器 nginx 的端口80/tcp。创建一个名为front-end-svc的新service,以公开容器端口http。 配置此service,以通过各个Pod所在的节点上的 NodePort 来公开他们。

解答 # kubectl config use-context k8s开始操作检查deployment信息,并记录SELECTOR的Lable标签,这里是app=front-end kubectl get deployment front-end -o wide 参考官方文档,按照需要edit deployment,添加端口信息 kubectl edit deployment front-end #注意 :set paste,防止yaml文件空格错序。 spec:containers:- image: vicuu/nginx:hello imagePullPolicy: IfNotPresent name: nginx #找到此位置。下文会简单说明一下yaml文件的格式,不懂yaml格式的,往下看。 ports: #添加这4行 - name: httpcontainerPort: 80protocol: TCP 暴露对应端口 kubectl expose deployment front-end --type=NodePort --port=80 --target-port=80 --name=front-end-svc #注意考试中需要创建的是NodePort,还是ClusterIP。如果是ClusterIP,则应为--type=ClusterIP #--port是service的端口号,--target-port是deployment里pod的容器的端口号。 暴露服务后,检查一下service的selector标签是否正确,这个要与deployment的selector标签一致的。 kubectl get svc front-end-svc -o wide kubectl get deployment front-end -o wide5、创建 Ingress 问题 设置配置环境: [candidate@node-1] $ kubectl config use-context k8sTask 如下创建一个新的nginx Ingress 资源: 名称: ping Namespace: ing-internal 使用服务端口 5678在路径 /hello 上公开服务 hello可以使用以下命令检查服务 hello的可用性,该命令应返回 hello: curl -kL /hello解答

vim ingress.yaml #注意 :set paste,防止yaml文件空格错序。 apiVersion: networking.k8s.io/v1kind: IngressClassmetadata: labels:app.kubernetes.io/component: controller name: nginx-example annotations:ingressclass.kubernetes.io/is-default-class: "true"spec: controller: k8s.io/ingress-nginx---apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: ping namespace: front-end annotations:nginx.ingress.kubernetes.io/rewrite-target: /spec: ingressClassName: nginx-example #这里调用上面新建的ingressClassName 为nginx-examplerules: - http: paths: - path: /hellopathType: Prefixbackend: service:name: helloport: number: 80

最后curl检查

通过get ingress 查看ingress 的内外IP,然后通过提供的 curl 测试 ingress 是否正确。

另一种方法

kubectl create ingress ping --rule=/hello=hello:5678 --class=nginx --annotation=nginx.ingress.kubernetes.io/rewrite-target=/ -n ing-internal

6、扩容 deployment副本数量 问题 设置配置环境: [candidate@node-1] $ kubectl config use-context k8sTask 将 deploymentpresentation 扩展至 4个 pods

kubectl scale deployment -h

解答 先检查一下现有的pod数量(可不检查) kubectl get deployments presentation -o wide kubectl get pod -l app=presentation扩展成4个 kubectl scale deployment presentation --replicas=47、调度 pod 到指定节点 问题 设置配置环境: [candidate@node-1] $ kubectl config use-context k8sTask 按如下要求调度一个 pod: 名称:nginx-kusc00401 Image:nginx Node selector:disk=ssd

考点:nodeSelect属性的使用

解答 开始操作 先检查一个是否有这个pod,应该是没有创建的,所以需要创建 kubectl get pod -A|grep nginx-kusc00401 # 确保node有这个labels,考试时,检查一下就行,应该已经提前设置好了labels。 kubectl get nodes --show-labels|grep 'disk=ssd' node02 添加标签kubectl label nodes node02 disk=ssdcat pod_nginx_ssd.yamlapiVersion: v1kind: Podmetadata: name: nginx labels:env: appspec: containers: - name: nginximage: nginximagePullPolicy: IfNotPresent nodeSelector:disk: ssdkubectl get pod nginx -o wide 8、查看可用节点数量 问题 [candidate@node-1] $ kubectl config use-context k8sTask 检查有多少 nodes 已准备就绪(不包括被打上 Taint:NoSchedule 的节点),并将数量写入 /opt/KUSC00402/kusc00402.txt

考点:检查节点角色标签,状态属性,污点属性的使用

kubectl -h

解答 # grep的-i 是忽略大小写,grep -v是排除在外,grep -c是统计查出来的条数。 kubectl describe nodes | grep -i Taints | grep -vc NoSchedule echo "查出来的数字" > /opt/KUSC00402/kusc00402.txt 其实你直接使用如下命令,就能一眼看出来,几个没有的。 kubectl describe nodes | grep -i Taints9、创建多容器的 pod 问题 设置配置环境: [candidate@node-1] $ kubectl config use-context k8sTask 按如下要求调度一个Pod: 名称:kucc8 app containers: 2 container 名称/images: ⚫ nginx ⚫ consul解答 # kubectl config use-context k8s可以参考上一题“调度pod到指定节点”的yaml配置文件。开始操作vim pod-kucc.yaml #注意 :set paste,防止yaml文件空格错序。apiVersion: v1kind: Podmetadata: name: nginx-consul labels:env: appspec: containers: - name: nginximage: nginximagePullPolicy: IfNotPresent - name: consulimage: consulimagePullPolicy: IfNotPresentkubectl get pod nginx-consul 10、创建 PV 问题 Task 创建名为 app-config 的 persistent volume,容量为 1Gi,访问模式为 ReadWriteMany。volume 类型为 hostPath,位于 /srv/app-config

考点:hostPath类型的pv

解答

https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/configure-persistent-volume-storage/

直接从官方复制合适的案例,修改参数,然后设置 hostPath 为 /srv/app-config 即可。开始操作vim pv.yaml #注意 :set paste,防止yaml文件空格错序。 [root@bt cka]# cat pv_config_app.yaml apiVersion: v1kind: PersistentVolumemetadata: name: app-configspec: capacity:storage: 1GiaccessModes:- ReadWriteMany hostPath:path: "/srv/app-config"kubectl get pv # RWX是ReadWriteMany,RWO是ReadWriteOnce。11、创建 PVC 问题 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,并记录此更改。

考点:pvc的创建class属性的使用,–record记录变更

解答 根据官方文档复制一个PVC配置,修改参数,不确定的地方就是用 kubectl 的 explain 帮助。开始操作vim pvc.yaml #注意 :set paste,防止yaml文件空格错序。[root@bt cka]# cat pvc_storgae.yamlapiVersion: v1kind: PersistentVolumeClaimmetadata: name: pv-volumespec: storageClassName: nfs-client accessModes:- ReadWriteOnce resources:requests: storage: 10Mi创建PVC kubectl apply -f pvc.yaml检查 kubectl get pvcvim pvc-pod.yaml #注意 :set paste,防止yaml文件空格错序apiVersion: v1 kind: Pod metadata:name: web-server spec:volumes: - name: task-pv-storage#绿色的两个name要一样。persistentVolumeClaim: claimName: pv-volume #这个要使用上面创建的pvc名字containers: - name: nginximage: nginx:1.16volumeMounts: - mountPath: "/usr/share/nginx/html"name: task-pv-storage#绿色的两个name要一样。 创建 kubectl apply -f pvc-pod.yaml检查 kubectl get pod web-server 改大小,并记录过程。 # 将storage: 10Mi改为storage: 70Mi(模拟环境里会报错,下面有解释。) # 注意是修改上面的spec:里面的storage: kubectl edit pvc pv-volume --record #模拟环境是nfs存储,操作时,会有报错忽略即可。考试时用的动态存储,不会报错的。模拟环境使用的是nfs做后端存储,是不支持动态扩容pvc的(:wq保存退出时,会报错)。 所以最后一步修改为70Mi,只是操作一下即可。换成ceph做后端存储,可以,但是集群资源太少,无法做ceph。

12、查看 pod 日志 问题 [candidate@node-1] $ kubectl config use-context k8sTask 监控 pod foo 的日志并: 提取与错误 RLIMIT_NOFILE相对应的日志行 将这些日志行写入 /opt/KUTR00101/foo

考点:kubectl logs命令

解答 kubectl logs foo | grep "RLIMIT_NOFILE" > /opt/KUTR00101/foo检查 cat /opt/KUTR00101/foo13、使用 sidecar 代理容器日志 问题 [candidate@node-1] $ kubectl config use-context k8sContext 将一个现有的 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 文件

考点:pod两个容器共享存储卷

https://kubernetes.io/zh-cn/docs/concepts/cluster-administration/logging/

解答 通过 kubectl get pod -o yaml 的方法备份原始 pod 信息,删除旧的pod 11-factor-app copy 一份新 yaml 文件,添加 一个名称为 sidecar 的容器 新建 emptyDir 的卷,确保两个容器都挂载了 /var/log 目录 新建含有 sidecar 的 pod,并通过 kubectl logs 验证 apiVersion: v1kind: Podmetadata: name: counterspec: containers: - name: leagcy-appimage: busyboxargs:- /bin/sh- -c- > i=0; while true; doecho "$i: $(date)" >> /var/log/legacy-app.log;i=$((i+1));sleep 1; donevolumeMounts:- name: varlog mountPath: /var/log - name: sidecarimage: busyboxargs: [/bin/sh, -c, 'tail -n+1 -F /var/log/legacy-app.log']volumeMounts:- name: varlog mountPath: /var/log volumes: - name: varlogemptyDir: {}验证:kubectl exec counter-log -c sidecar -- tail -f /var/log/legacy-app.log 14、升级集群 问题 Task 现有的Kubernetes 集群正在运行版本1.25.1。仅将master节点上的所有 Kubernetes控制平面和节点组件升级到版本1.25.2。确保在升级之前 drain master节点,并在升级后 uncordon master节点。 可以使用以下命令,通过ssh连接到master节点: ssh master01 可以使用以下命令,在该master节点上获取更高权限: sudo -i另外,在主节点上升级kubelet和kubectl。 请不要升级工作节点,etcd,container 管理器,CNI插件, DNS服务或任何其他插件。

(注意,考试敲命令时,注意要升级的版本,根据题目要求输入具体的升级版本!!!)

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

解答

1、切换环境kubectl config use-context mk8s2、配置#升级kueadmkubectl cordon master01 kubectl drain mk8s-master-0 --ignore=daemonsets连接master机器 提权ssh mk8s-master-0sudo -i 升级kubeadmapt-get update apt-cache show kubeadm|grep 1.25.2 apt install kubeadm=1.25.2-ykubeadm upgrade plan#这里可以先查下的:apt-cache show|grep kubeadm#kubeadm upgrade install v1.20.1 #。。。淦,这个写错了。。。。。。。是apply,并且要加上--ectd-ugrade=false。。。。。。题目要求不升级 etcd; 注意下这2个版本号写法的区别。。。。kubeadm upgrade apply v1.20.1 --etcd-upgrade=false#升级kubelt 和 kubectlapt install kubelet=1.20.1-00 kubectl=1.20.1-00 -ysystemctl restart kubelet #这里要重启下kubelt的,切记。。。exitexitkubectl uncordon mk8s-master-03、验证kubectl get node -owidekubectl --versionkubelet --version 15、备份还原 etcd 问题 此项目无需更改配置环境。但是,在执行此项目之前,请确保您已返回初始节点。 [candidate@master01] $ exit#注意,这个之前是在master01上,所以要exit退到node01,如果已经是node01了,就不要再exit了。Task 首先,为运行在https://11.0.1.111:2379 上的现有 etcd 实例创建快照并将快照保存到 /var/lib/backup/etcd-snapshot.db (注意,真实考试中,这里写的是https://127.0.0.1:2379) 为给定实例创建快照预计能在几秒钟内完成。 如果该操作似乎挂起,则命令可能有问题。用 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

考点:etcd的备份和还原命令

解答 # 备份ETCDCTL_API=3 etcdctl snapshot save /data/backup/etcd-snapshot.db --endpoints=https://127.0.0.1:2379 --cacert=/opt/KUIN00601/ca.crt --cert=/opt/KUIN00601/etcd-client.crt --key=/opt/KUIN00601/etcd-client.key# 恢复 systemctl stop etcd systemctl cat etcd # 确认下数据目录(--data-dir值) mv /var/lib/etcd /var/lib/etcd.bak ETCDCTL_API=3 etcdctl snapshot restore /data/backup/etcd-snapshot-previous.db --data-dir=/var/lib/etcd chown -R etcd:etcd /var/lib/etcd systemctl start etcd

16、排查集群中故障节点 问题 名为node02的Kubernetes worker node处于NotReady状态。 调查发生这种情况的原因,并采取相应的措施将node恢复为Ready状态,确保所做的任何更改永久生效。可以使用以下命令,通过ssh连接到node02节点: ssh node02 可以使用以下命令,在该节点上获取更高权限: sudo -i 解答 过 get nodes 查看异常节点,登录节点查看 kubelet 等组件的 status 并判断原因。 真实考试时,这个异常节点的kubelet服务没有启动导致的,就这么简单。执行初始化这道题的脚本a.sh,模拟node02异常。 (考试时,不需要执行的!考试时切到这道题的集群后,那个node就是异常的。)1、切换环境kubectl config use-context wk8s #考试时切到这道题的集群后,那个 node 就是异常的。 真实考试时,这个异常节点的 kubelet 服务没有启动导致的,就这么简单。2、配置kubectl get node #查看Not Ready的node节点ssh wk8s-node-0sudo -isystemctl status kubeletsystemctl start kubeletsystemctl enable kubeletexit #退出root用户exit #退出故障节点3、验证kubectl get node#jounarlctl -u kubelet 查看kubelet日志 17、节点维护 问题 Task 将名为 node02 的 node 设置为不可用,并重新调度该 node 上所有运行的 pods。

考点:cordon和drain 命令的使用

解答 1、切换环境kubectl config use-context ek8s2、配置kubectl cordon ek8s-node-1 #设置次节点为不可调度skubectl drain ek8s-node-1 --ignore-daemonsets #设置次节点为不可调度,并且排空次节点#如果上面命令报错就加上一个 --delete-local-data --forcekubectl drain ek8s-node-1 --ignore-daemonsets --delete-local-data --forcekubectl drain ek8s-node-1 --ignore-daemonsets --delete-emptydir-data --force3、验证kubectl get node

相关推荐: