报名

中国区报名地址:https://training.linuxfoundation.cn 需要身份证购买

购买完成后在我的考试中查看考试券,去国外站点进行报名https://trainingportal.linuxfoundation.org

将考试码粘贴到如下进行注册

预约

访问https://trainingportal.linuxfoundation.org/learn/dashboard 考试界面讲解 提交试卷后24小时左右会出成绩,会发邮件让你下载证书,去官网可以查看分数。

CKA

CKA认证考试是由Linux基金会和云原生计算基金会(CNCF)创建的,以促进Kubernetes生态系统的持续发展。该考试是一种远程在线、有监考、基于实操的认证考试,需要在运行Kubernetes的命令行中解决多个任务。CKA认证考试是专为Kubernetes管理员、云管理员和其他管理Kubernetes实例的IT专业人员而设的。 CKA这个证书基本是个入门级的考试,有些同学听到通过考取证书,可以得到更多的工作机会,实际上技术好的同学有一张证书可以是锦上添花,如果是技术差的用一张证书去撑场面到最后跨的一定是自己。在国内大部分证书随着时间的推移,含金量都会变低,比如思科的CCIE等。因为很多证书都是批量生产的状态,背题就能过,所以通过证书并不能代表自己的实力。

1 RBAC

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。

官方文档搜索关键字:使用 RBAC 鉴权

切换集群

kubectl config use-context k8s

创建一个名为 deployment-clusterrole 的 ClusterRole 对象,允许对 Deployment、Daemonset、Statefulset 具有 create 权限

kubectl create clusterrole deployment-clusterrole --verb=create --resource=Deployment,StatefulSet,DaemonSet

创建sa

kubectl create serviceaccount cicd-token -n app-team1

绑定sa,题目中写了限于app-team1名称空间,所以用rolebinding。如果不限制名称空间则创建clusterrolebinding

kubectl create rolebinding rb-cicd-token(relebinding名字,随便起的,因为题目中没有要求) --clusterrole=deployment-clusterrole --serviceaccout=app-team1:cicd-token --namespace=app-team1

检查验证

root@cka-master1:~# kubectl describe rolebindings rb-cicd-token -n app-team1

Name: rb-cicd-token

Labels:

Annotations:

Role:

Kind: ClusterRole

Name: deployment-clusterrole

Subjects:

Kind Name Namespace

---- ---- ---------

ServiceAccount cicd-token app-team1

2 节点维护

将 ek8s-node-1 节点设置为不可用,然后重新调度该节点上的所有 Pod 官方文档搜索关键字:安全地清空一个节点

切换到指定集群

kubectl config use-context ek8s

将节点设置为不可调度

kubectl cordon ek8s-node-1

将该节点上的pod进行驱逐,重新调度

kubectl drain ek8s-node-1 --delete-emptydir-data --ignore-daemonsets --force

查看节点状态

kubectl get node

查看pod所在节点

kubectl get pod -owide

3 版本升级

Task 现有的 Kubernetes 集群正在运行版本 1.23.1。仅将 master 节点上的所有 Kubernetes 控制平面和节点组件升级到版本 1.23.2。(注意,考试时的集群可能为 1.23.0,会让你从 1.23.0 升级为 1.23.1。甚至是 1.22.1 升级为 1.22.2。所以敲命令时,具体要升级的版本,根据题目要求更改。) 确保在升级之前 drain master 节点,并在升级后 uncordon master 节点。

可以使用以下命令,通过 ssh 连接到 master 节点:ssh master01 可以使用以下命令,在该 master 节点上获取更高权限:sudo -i

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

官方文档搜索关键字:upgrade

考试时执行,切换集群

kubectl config use-context mk8s

查看节点信息

root@cka-master1:~# kubectl get nodes

NAME STATUS ROLES AGE VERSION

cka-master Ready control-plane,master 3h v1.23.1

cka-node1 Ready 175m v1.23.1

将节点标记为不可调度并驱逐所有负载,准备节点的维护

kubectl cordon k8s-master-1

kubectl drain k8s-master-1 --delete-emptydir-data --ignore-daemonsets --force

在考试环境中 ssh 到 master 节点,并切换到 root 下

ssh master

sudo -i

升级 kubeadm

$ apt-get update

# 找到题目要求升级到的指定版本

$ apt-cache madison kubeadm | grep 1.23.2

kubeadm | 1.23.2-00 | http://mirrors.ustc.edu.cn/kubernetes/apt kubernetes-xenial/main amd64 Packages

$ apt-get install kubeadm=1.23.2-00

验证下载操作正常,并且 kubeadm 版本正确

$ kubeadm version

kubeadm version: &version.Info{Major:"1", Minor:"23", GitVersion:"v1.23.2", GitCommit:"9d142434e3af351a628bffee3939e64c681afa4d", GitTreeState:"clean", BuildDate:"2022-01-19T17:34:34Z", GoVersion:"go1.17.5", Compiler:"gc", Platform:"linux/amd64"}

验证升级计划:此命令检查你的集群是否可被升级,并取回你要升级的目标版本。 命令也会显示一个包含组件配置版本状态的表格

kubeadm upgrade plan

# 排除 etcd,升级其他的

kubeadm upgrade apply v1.23.2 --etcd-upgrade=false

# 升级 kubelet 和 kubectl

apt-mark unhold kubelet kubectl

apt-get install kubelet=1.23.2-00 kubectl=1.23.2-00

apt-mark hold kubelet kubectl

systemctl daemon-reload

systemctl restart kubelet

# 考试环境中退出 root,退回到 student@master01

[root @master 01 ] # exit

# 考试环境中退出 master01,退回到 student@node-1

[student @master 01 ] $ exit

# 不要输入 exit 多了,否则会退出考试环境的。

# 解除节点的保护

root@cka-master1:~# kubectl uncordon cka-master1

# 检查 master1 是否为 Ready

root@cka-master1:~# kubectl get nodes

NAME STATUS ROLES AGE VERSION

cka-master1 Ready control-plane,master 3h40m v1.23.2

cka-node1 Ready 3h36m v1.23.1

如果报错如下:

root@cka-master1:~# rm /var/lib/apt/lists/lock

root@cka-master1:~# rm /var/cache/apt/archives/lock

root@cka-master1:~# rm /var/lib/dpkg/lock*

root@cka-master1:~# dpkg --configure -a

4 ETCD 备份恢复

注意:真实考试时,第 3 题是升级集群那道题。建议真正考试时,前 4 道题按照顺序做,特别是第 4 题,且做完后不要再修改,做完第 3 道题,如果没有 exit 退出到 student@node-1,则无法执行 etcdctl 命令,另外这道题没有切换集群,用的是第 3 道题的集群,所以,这道题做完就不要在回来检查或者操作了。etcd 不建议放到最后做,如果最后做,etcd 备份还原可能把所有 pod 都清空了,这个问题有可能会出现,所以前 4 道题按照顺寻做。

此项目无需更改配置环境,但是,在执行此项目之前,请确保您已返回初始节点。etcd 这道题真实考试为第 4 题,用的集群是真实考试时的上一题的集群,即真题第 3 题 mk8s,所以无需再切换集群了。

Task 首先,为运行在 https://127.0.0.1:2379 上的现有 etcd 实例创建快照并将快照保存到 /srv/data/etcd-snapshot.db 文件。 为给定实例创建快照预计能在几秒钟内完成。 如果该操作似乎挂起,则命令可能有问题。用 CTRL + C 来取消操作然后重试。

然后还原位于 /var/lib/backup/etcd-snapshot-previous.db 的现有先前快照。 提供了以下 TLS 证书和密钥,以通过 etcdctl 连接到服务器:

CA证书: /opt/KUIN00601/ca.crt 客户端证书: /opt/KUIN00601/etcd-client.crt 客户端密钥: /opt/KUIN00601/etcd-client.key

考试时确认一下 ssh 终端,是在 [student@node-1] $ 下

# 备份

# 如果不使用 export ETCDCTL_API=3,而使用 ETCDCTL_API=3,则下面每条 etcdctl 命令前都要加ETCDCTL_API=3

# 如果执行时,提示 permission denied,则是权限不够,命令最前面加 sudo 即可。

export ETCDCTL_API=3

# 先检查考试环境有没有题目说的目录 /srv/data/,没有的话则需要自己创建

root@cka-master1:~# mkdir -pv /srv/data/

# 下面的证书是模拟环境中的位置,考试时用题目给的三个证书

root@cka-master1:~# sudo 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

# 还原题目指定的 /var/lib/backup/etcd-snapshot-previous.db 文件

root@cka-master1:~# sudo 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 restore /var/lib/backup/etcd-snapshot-previous.db

5 NetworkPolicy

Task 在现有的 namespace my-app 中创建一个名为 allow-port-from-namespace 的新 NetworkPolicy。确保新的 NetworkPolicy 允许 namespace echo 中的 Pods 连接到 namespace my-app 中的Pods 的 9000 端口。 进一步确保新的NetworkPolicy: 不允许对没有在监听端口 9000 的 Pods 的访问 不允许非来自 namespace echo 中的 Pods 的访问

官方文档搜索关键字:网络策略

切换集群

kubectl config use-context hk8s

查看所有 ns 的标签 label

kubectl get ns --show-labels

如果访问者的 namespace 没有标签 label,则需要手动打一个。如果有一个独特的标签 label,则也可以直接使用。

kubectl label ns my-app project=my-app

参考官方文档,拷贝 yaml 文件内容,并修改。注意先输入 “:set paste”,防止复制时 yaml 文件空格错序。

root@cka-master1:~# vim networkpolicy.yaml

apiVersion: networking.k8s.io/v1

kind: NetworkPolicy

metadata:

name: allow-port-from-namespace

namespace: my-app # 被访问着的名称空间

spec:

podSelector: # 这两行必须要写,或者也可以写成一行为 podSelector: {}

matchLabels: {}

policyTypes:

- Ingress # 策略影响入栈流量

ingress:

- from: # 允许流量的来源

- namespaceSelector:

matchLabels:

project: my-app # 访问者的命名空间的标签 label

ports:

- protocol: TCP

port: 9000 # 被访问者公开的端口

创建网络策略资源

kubectl apply -f networkpolicy.yaml

检查

root@cka-master1:~# kubectl get networkpolicy -n my-app

NAME POD-SELECTOR AGE

allow-port-from-namespace 4m37s

root@cka-master1:~# kubectl describe networkpolicy allow-port-from-namespace -n my-app

Name: allow-port-from-namespace

Namespace: my-app

Created on: 2023-01-03 19:44:38 -0800 PST

Labels:

Annotations:

Spec:

PodSelector: (Allowing the specific traffic to all pods in this namespace)

Allowing ingress traffic:

To Port: 9000/TCP

From:

NamespaceSelector: project=echo

Not affecting egress traffic

Policy Types: Ingress

6 service

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

官方文档搜索关键字:服务

切换集群

kubectl config use-context k8s

参考官方文档,按照需要 edit deployment,添加端口信息

root@cka-master1:~# kubectl edit deployments front-end

······

imagePullPolicy: Always

name: nginx

ports:

- containerPort: 80

name: http

······

创建 service,以下两种方法二选一即可

# 命令行形式

root@cka-master1:~# kubectl expose deployment front-end --name=front-end-svc --port=80 --target-port=http --type=NodePort

# 编写 yaml 文件形式,复制官方文档的内容进行修改

root@cka-master1:~# vim service.yaml

apiVersion: v1

kind: Service

metadata:

name: front-end-svc # 题目指定的名称

spec:

type: NodePort # 题目指定的 service 类型

selector:

app: nginx # deployment 中 pod 的标签

ports:

- port: 80 # 题目指定暴露的端口

targetPort: http # 题目指定暴露的 http 端

root@cka-master1:~# kubectl apply -f service.yaml

查看 service 资源

root@cka-master1:~# kubectl get svc front-end-svc

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE

front-end-svc NodePort 10.98.31.4 80:30737/TCP 16s

7 ingress

在 ing-internal 名称空间下创建一个ingress,名字为pong,代理server hi,端口为5678,配置路径/hi 可以使用以下命令检查服务 hi 的可用性:curl -kL /hi 会返回hi

官方文档搜索关键字:ingress

切换集群

kubectl config use-context k8s

创建 ingress 资源。拷贝官网的 yaml 案例,修改相关参数即可。先输入 ":set paste",防止 yaml 文件空格错序

root@cka-master1:~# vim ingress.yaml

apiVersion: networking.k8s.io/v1

kind: Ingress

metadata:

name: pong # 题目指定名称

namespace: ing-internal # 题目指定的名称空间

spec:

ingressClassName: nginx

rules:

- http:

paths:

- path: /hi # 题目指定的 url

pathType: Prefix

backend:

service:

name: hi

port:

number: 5678 # 题目指定的端口

root@cka-master1:~# kubectl apply -f ingress.yaml

root@cka-master1:~# kubectl get ingress -n ing-internal

NAME CLASS HOSTS ADDRESS PORTS AGE

pong nginx * 80 10s

8 Deployment扩缩容

将名字为 loadbalancer 的 deployment 副本数扩容为 6

$ kubectl config use-context k8s

$ kubectl scale deployment loadbalancer --replicas=6

查看是否扩容成功,不用管pod的状态

kubectl get deployment loadbalancer

9 指定节点部署

创建一个 Pod,名字为 nginx-kusc00401,镜像地址是 nginx,调度到具有 disk=spinning 标签的节点上 官方文档搜索关键字:将 Pod 分配给节点

查看 node 节点标签

kubectl get nodes --show-labels

# 创建 pod

root@cka-master1:~# vim nodeselector.yaml

apiVersion: v1

kind: Pod

metadata:

name: nginx-kusc00401 # 题目指定的 pod 名称

spec:

containers:

- name: nginx # 题目指定的镜像

image: nginx

#imagePullPolicy: IfNotPresent

nodeSelector:

disk: spinning # 题目指定的被分配的节点标签

root@cka-master1:~# kubectl apply -f nodeselector.yaml

检查是否调度到对应的节点

root@cka-master1:~# kubectl get pods -o wide nginx-kusc00401

NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES

nginx-kusc00401 1/1 Running 0 13s 10.244.115.73 cka-node1

10 检查Node节点的健康状态

检查集群中有多少节点为 Ready 状态,并且去除包含 NoSchedule 污点的节点。之后将数字写到/opt/KUSC00402/kusc00402.txt 切换 k8s 集群环境:

$ kubectl config use-context k8s

记录Ready的总数A

kubectl get node | grep -i ready

记录所有节点状态为Ready并且包含 NoSchedule 污点的总数B

kubectl describe node node名 | grep NoSchedule

将 A 减 B 的值 x 导入到/opt/KUSC00402/kusc00402.txt

echo x >> /opt/KUSC00402/kusc00402.txt

kubectl describe node $(kubectl get node | grep Ready | awk ‘{print $1}’) | grep Taint | grep -vc NoSchedule > /opt/402.txt

查看结果

cat /opt/KUSC00402/kusc00402.txt

11 一个pod封装多个容器

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

切换集群

kubectl config use-context k8s

编写 yaml 文件

root@cka-master1:~# vim kucc1.yaml

apiVersion: v1

kind: Pod

metadata:

name: kucc1

spec:

containers:

- name: nginx

image: nginx

imagePullPolicy: IfNotPresent

- name: redis

image: redis

imagePullPolicy: IfNotPresent

- name: memcached

image: memcached

imagePullPolicy: IfNotPresent

- name: consul

image: consul

imagePullPolicy: IfNotPresent

创建pod

kubectl apply -f kucc1.yaml

查看pod,题目没有要求该pod必须启动,只需创建即可

root@cka-master1:~# kubectl get pods kucc1

NAME READY STATUS RESTARTS AGE

kucc1 4/4 Running 0 3s

12 PV

创建一个 pv,名字为app-config,大小为 2Gi,访问权限为 ReadWriteMany。Volume 的类型为 hostPath,路径为/srv/app-config 官方文档搜索关键字:PersistentVolume

切换集群

kubectl config use-context hk8s

考试环境路径已存在

ls /srv/app-config

编写yaml文件

root@cka-master1:~# vim pv.yaml

apiVersion: v1

kind: PersistentVolume

metadata:

name: app-config # 题目中指定的 pv 名称

spec:

capacity:

storage: 2Gi # 题目指定的 pv 大小

accessModes:

- ReadWriteMany # 题目指定的访问模式

hostPath:

path: "/srv/app-config" # 题目指定的路径

创建 pv

kubectl apply -f pv.yaml

查看pv

root@cka-master1:~# kubectl get pv

NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE

app-config 2Gi RWX Retain Available 6s

13 pvc

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

官方文档搜索关键字:PersistentVolume 1、考试时执行,切换集群

kubectl config use-context ok8s

2、编写yaml文件

root@cka-master1:~# vim pvc-pod.yaml

apiVersion: v1

kind: PersistentVolumeClaim

metadata:

name: pv-volume # 题目指定的 pvc 名称

spec:

storageClassName: csi-hostpath-sc # 题目指定的存储类名称

accessModes:

- ReadWriteOnce # 题目指定的访问模式

resources:

requests:

storage: 10Mi # 题目指定的 pvc 大小

---

apiVersion: v1

kind: Pod

metadata:

name: web-server # 题目指定的 pod 名称

spec:

volumes:

- name: pv-volume # 与 volumeMounts.name 一致

persistentVolumeClaim:

claimName: pv-volume # 使用的 pvc 名称

containers:

- name: nginx

image: nginx # 题目指定的镜像

volumeMounts:

- mountPath: "/usr/share/nginx/html" # 题目指定的挂载目录

name: pv-volume

3、创建

kubectl apply -f pvc-pod.yaml

4、查看是否创建成功。之所以是 pending 状态是模拟环境中没有存储类 storageClassName: csi-hostpath-sc,考试环境中存在,无需担心

root@cka-master1:~# kubectl get pvc pv-volume

NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE

pv-volume Pending csi-hostpath-sc 21s

root@cka-master1:~# kubectl get pods web-server

NAME READY STATUS RESTARTS AGE

web-server 0/1 Pending 0 31s

5、pvc 扩容。将 storage: 10Mi 修改为 70Mi

root@cka-master1:~# kubectl edit pvc pv-volume

······

resources:

requests:

storage: 70Mi

storageClassName: csi-hostpath-sc

······

14 监控pod日志

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

$ kubectl config use-context k8s

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

如果这个pod中有两个容器的话

$ kubectl logs pod名 -c 容器名

检查是否写入到对应的文件

cat /opt/KUTR00101/foobar

15 sidecar

添加一个名为 busybox 且镜像为 busybox 的 sidecar 到一个已经存在的名为 legacy-app 的 Pod上,这个 sidecar 的启动命令为 /bin/sh -c tail -n+1 -f /var/log/legacy-app.log 。并且这个sidecar 和原有的镜像挂载一个名为logs的volume,挂载的目录为/var/log/

1、切换答题环境(考试环境有多个,每道题要在对应的环境中作答)

kubectl config use-context k8s

2、将legacy-app的pod的yaml导出

kubectl get pod legacy-app -oyaml > c-sidecar.yaml

再此yaml中添加sidecar和volume

vi c-sidecar.yaml

apiVersion: v1

kind: Pod

metadata:

name: 11-factor-app

spec:

containers:

- name: count

image: busybox

args:

- /bin/sh

- -c

- >

i=0;

while true;

do

echo "$i: $(date)" >> /var/log/11-factor-app.log;

i=$((i+1));

sleep 1;

done

volumeMounts:

- 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

volumes:

- name: varlog

emptyDir: {}

3、删除原pod,创建新pod

kubectl delete pod 11-factor-app

kubectl apply -f factor-app.yaml

4、查看日志是否输出到控制台

16 查看cpu使用率最高的pod

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

$ kubectl config use-context k8s

$ kubectl top pod -A -l name=cpu-user --sort-by="cpu"

NAMESPACE NAME CPU(cores) MEMORY(bytes)

kube-system coredns-54d67798b7-hl8xc 7m 8Mi

kube-system coredns-54d67798b7-m4m2q 6m 8Mi

注意这里的 pod 名字以实际名字为准,按照 CPU 那一列进行选择一个最大的 Pod。如果CPU的数值是 1 2 3 不带m,不带m的数值是大于带 m的,因为 1 颗CPU等于 1000m 注意要用>>而不是>

$ echo "coredns-54d67798b7-hl8xc" >> /opt/KUTR00401/KUTR00401.txt

17 集群故障排查 – kubelet 故障

一个名为 wk8s-node-0 的节点状态为 NotReady,检查发生这种情况的原因,并采取相应措施将node 恢复为Ready 状态,确保所做的任何更改永久生效。 1、切换答题环境(考试环境有多个,每道题要在对应的环境中作答)

kubectl config use-context ek8s

2、查看节点状态

kubectl get node

3、切换到故障节点

ssh wk8s-node-0

sudo -i

4、检查节点状态并加入开机自启动

systemctl status kubelet

systemctl start kubelet

systemctl enable kubelet

5、退出故障节点

exit

好文推荐

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: