K8S认证工程师(CKA)考试(最新版,实测可靠)

k8s的全部考试答案,亲测可靠,博主CKA,CKS已过,欢迎交流。(求个关注吧)

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

kubectl create clusterrole -h
kubectl create rolebinding -h
kubectl create clusterrole deployment-clusterrole --verb=create --resource=deployments,statefulsets,daemonsets

kubectl -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 k8s

Task

通过 pod label name=cpu-loader,找到运行时占用大量 CPU 的 pod,

并将占用 CPU 最高的 pod 名称写入文件 /opt/KUTR000401/KUTR00401.txt(已存在)。

kubectl top pod -h

# 查看 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 访问。

Concepts → Services, Load Balancing, and Networking → Network Policies

查看所有 ns 的标签 label
kubectl get ns --show-labels
如果访问者的 namespace 没有标签 label,则需要手动打一个。如果有一个独特的标签 label,则也可以直接使用。
kubectl label ns echo project=echo
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 来公开他们。

考点:将现有的 deploy 暴露成 nodeport 的 service。

解答

检查 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: http
       containerPort: 80
       protocol: 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 wide

如果你 kubectl expose 暴露服务后,发现 service 的 selector 标签是空的<none>,或者不是 deployment 的。

则需要编辑此 service,手动添加标签。(模拟环境里暴露服务后,selector 标签是正确的。但是考试时,有时 service 的 selector 标签是 none)

kubectl edit svc front-end-svc
在 ports 这一小段下面添加 selector 标签
 selector:
 app: front-end #注意 yaml 里是写冒号,而不是等号,不是 app=front-end。

确保 service 的 selector 标签与 deployment 的 selector 标签一致。

最后 curl 检查 kubectl get pod,svc -o wide

curl 所在的 node 的 ip 或主机名:30938

curl svc 的 ip 地址:80

(注意,只能 curl 通 svc 的 80 端口,但是无法 ping 通的。)

考试时,如果 curl 不通,简单排错后也不通,就不要过于纠结,继续往下做题即可。因为部分同学反馈 curl 不通,不清楚是否为考试集群环境的问题。 只要确保都做对了,即使 curl 不通,也最多扣几分而已,是有其他步骤分的。

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

考点:Ingress 的创建

依次点击 Concepts → Services, Load Balancing, and Networking → Ingress

vim ingress.yaml
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  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/v1
kind: Ingress
metadata:
  name: ping
  namespace: ing-internal
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx-example
  rules:
  - http:
      paths:
      - path: /hello
        pathType: Prefix
        backend:
          service:
            name: hello
            port:
              number: 5678
创建
kubectl apply -f ingress.yaml
最后 curl 检查
# 通过 get ingress 查看 ingress 的内外 IP,然后通过提供的 curl 测试 ingress 是否正确。
# 做完题后,略等 3 分钟,再检查,否则可能还没获取 IP 地址。或者可以先去做别的题,等都做完了,再回来检查这道题,一下,记得回来检查时,先使用 kubectl 
config use-context k8s 切换到此集群。
kubectl get ingress -n ing-internal
curl ingress 的 ip 地址/hello

6、扩容 deployment 副本数量

设置配置环境: [candidate@node-1] $ kubectl config use-context k8s

Task

将 deployment presentation 扩展至 4 个 pods

kubectl scale deployment -h

扩展成 4 个
kubectl scale deployment presentation --replicas=4
candidate@node01:~$ kubectl get deployments presentation -o wide
NAME           READY   UP-TO-DATE   AVAILABLE   AGE    CONTAINERS   IMAGES              SELECTOR
presentation   4/4     4            4           251d   nginx        vicuu/nginx:hello   app=presentation
candidate@node01:~$ kubectl get pod -l app=presentation
NAME                           READY   STATUS    RESTARTS      AGE
presentation-78777866b-8v7p5   1/1     Running   0             39s
presentation-78777866b-dvpm9   1/1     Running   0             39s
presentation-78777866b-lbvk2   1/1     Running   0             39s
presentation-78777866b-n855j   1/1     Running   4 (63m ago)   251d

7、调度 pod 到指定节点

设置配置环境: [candidate@node-1] $ kubectl config use-context k8s

Task

按如下要求调度一个 pod:

名称:nginx-kusc00401

Image:nginx

Node selector:disk=ssd

依次点击 Tasks → Configure Pods and Containers → Assign Pods to Nodes

kubectl get nodes --show-labels|grep 'disk=ssd'
kubectl label nodes node01 disk=ssd
vim pod-disk-ssd.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-kusc00401
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  nodeSelector:
    disk: ssd
kubectl apply -f pod-disk-ssd.yaml
candidate@node01:~$ kubectl get pod nginx-kusc00401 -o wide
NAME              READY   STATUS    RESTARTS   AGE   IP               NODE     NOMINATED NODE   READINESS GATES
nginx-kusc00401   1/1     Running   0          6s    10.244.196.182   node01   <none>           <none>

8、查看可用节点数量

设置配置环境: [candidate@node-1] $ kubectl config use-context k8s

Task

检查有多少 nodes 已准备就绪(不包括被打上 Taint:NoSchedule 的节点),

并将数量写入 /opt/KUSC00402/kusc00402.txt

kubectl -h

candidate@node01:~$ kubectl describe nodes |grep -i Taint |grep -vc NoSchedule
2
candidate@node01:~$ echo "2" > /opt/KUSC00402/kusc00402.txt

9、创建多容器的 pod

设置配置环境: [candidate@node-1] $ kubectl config use-context k8s

Task

按如下要求调度一个 Pod:

名称:kucc8

app containers: 2

container 名称/images:

  • nginx
  • consul

依次点击 Concepts → Workloads → Pods

apiVersion: v1
kind: Pod
metadata:
  name: kucc8
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  - name: consul
    image: consul
    imagePullPolicy: IfNotPresent
kubectl apply -f pod-kucc.yaml
kubectl get pod kucc8

10、创建 PV

设置配置环境: [candidate@node-1] $ kubectl config use-context hk8s

Task

创建名为 app-configpersistent volume,容量为 1Gi

访问模式为 ReadWriteMany。 volume 类型为 hostPath,位于 /srv/app-config

依次点击 Tasks → Configure Pods and Containers → Configure a Pod to Use a PersistentVolume for Storage

vim pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: app-config
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteMany
  hostPath:
    path: "/srv/app-config"
candidate@node01:~$ kubectl apply -f pv.yaml 
persistentvolume/app-config created
candidate@node01:~$ kubectl get 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 editkubectl patchPersistentVolumeClaim 的容量扩展为 70Mi,并记录此更改。

依次点击 Tasks → Configure Pods and Containers → Configure a Pod to Use a PersistentVolume for Storage

vim pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pv-volume
spec:
  storageClassName: csi-hostpath-sc
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Mi
kubectl apply -f pvc.yaml
kubectl get pvc
pv-volume   Bound
vim pvc-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: web-server
spec:
  volumes:
    - name: task-pv-storage
      persistentVolumeClaim:
        claimName: pv-volume
  containers:
    - name: nginx
      image: nginx:1.16
      volumeMounts:
        - mountPath: "/usr/share/nginx/html"
          name: task-pv-storage
kubectl apply -f pvc-pod.yaml 
kubectl get pod web-server
web-server   1/1     Running

将 storage: 10Mi 改为 storage: 70Mi

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/foocat /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 以外,请勿更改现有容器的规格。

依次点击 Concepts → Cluster Administration → Logging Architecture

kubectl get pod 11-factor-app -o yaml > varlog.yaml
cp varlog.yaml varlog-bak.yaml 
vim varlog.yaml
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: kube-api-access-xhzsg
      readOnly: true
    - name: varlog
      mountPath: /var/log
  - name: sidecar
    image: busybox
    args: [/bin/sh, -c, 'tail -n+1 -F /var/log/11-factor-app.log']
    volumeMounts:
    - name: varlog
      mountPath: /var/log
  dnsPolicy: ClusterFirst
...
  - name: varlog
    emptyDir: {}         
status:
  conditions:
# 删除原先的 pod
kubectl delete pod 11-factor-app
kubectl get pod 11-factor-app
# 新建这个 pod
kubectl apply -f varlog.yaml
kubectl apply -f varlog.yaml 
kubectl get pod 11-factor-app
kubectl logs 11-factor-app sidecar

14、升级集群

设置配置环境: [candidate@node-1] $ kubectl config use-context mk8s

Task

现有的 Kubernetes 集群正在运行版本 1.29.1仅将 master 节点上的所有 Kubernetes 控制平面和节点组件升级到版本 1.29.2

确保在升级之前 drain master 节点,并在升级后 uncordon master 节点。

可以使用以下命令,通过 ssh 连接到 master 节点: ssh master01 可

以使用以下命令,在该 master 节点上获取更高权限: sudo -i

另外,在主节点上升级 kubeletkubectl。 请不要升级工作节点,etcd,container 管理器,CNI 插件, DNS 服务或任何其他插件。

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

依次点击 Tasks → Administer a Cluster → Administration with kubeadm → Upgrading kubeadm clusters

kubectl get nodes
kubectl cordon master01     ##cordon 停止调度
kubectl drain master01 --ignore-daemonsets  ##drain 驱逐节点
# ssh 到 master 节点,并切换到 root 下
ssh master01
sudo -i
apt-get update
apt-cache show kubeadm|grep 1.29.2
apt-get install kubeadm=1.29.2-00
kubeadm version
# 验证升级计划,会显示很多可升级的版本,我们关注题目要求升级到的那个版本。
kubeadm upgrade plan
# 排除 etcd,升级其他的,提示时,输入 y。
kubeadm upgrade apply v1.29.2 --etcd-upgrade=false
升级 kubelet
apt-get install kubelet=1.29.2-00
kubelet --version
升级 kubectl
apt-get install kubectl=1.29.2-00
kubectl version

exit exit

kubectl uncordon master01 ##恢复 master01 调度
kubectl get node

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

export ETCDCTL_API=3etcdctl -h

etcdctl --endpoints=https://11.0.1.111: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

Snapshot saved at /var/lib/backup/etcd-snapshot.db

etcdctl snapshot status /var/lib/backup/etcd-snapshot.db -wtable #检查

sudo ETCDCTL_API=3 etcdctl --endpoints=https://11.0.1.111: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

restored snapshot        {"path": "/data/backup/etcd-snapshot-previous.db",

16、排查集群中故障节点

设置配置环境: [candidate@node-1] $ kubectl config use-context wk8s

Task

名为 node02 的 Kubernetes worker node 处于 NotReady 状态。

调查发生这种情况的原因,并采取相应的措施将 node 恢复为 Ready 状态,确保所做的任何更改永久生效

可以使用以下命令,通过 ssh 连接到 node02 节点: ssh node02

可以使用以下命令,在该节点上获取更高权限: sudo -i

记住先 restart 再 enable 就行

在 candidate@node01 上执行模拟环境
sudo sh /opt/sh/a.sh
kubectl get nodes
node02     NotReady
ssh node02
sudo -i
systemctl status kubelet
systemctl start kubelet
systemctl enable kubelet
systemctl status kubelet

exit exit

kubectl get nodes
node02     Ready

17、节点维护

设置配置环境: [candidate@node-1] $ kubectl config use-context ek8s

Task

将名为 node02 的 node 设置为不可用,并重新调度该 node 上所有运行的 pods。

kubectl -h
kubectl drain -h
kubectl get node
kubectl cordon node02
kubectl get node

kubectl drain node02 --ignore-daemonsets --delete-emptydir-data --force

kubectl get node
kubectl get pod -A -o wide|grep node02

  • 35
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值