K8S 考试相关笔记

考试时,环境设置

设置环境,可以操作效率,考试环境默认都弄好了。vim 考试时候可以直接 :set paste 处理下。

alias k=kubectl
export do="--dry-run=client -o yaml" # k create deploy nginx --image=nginx $do
export now="--force --grace-period 0" # k delete pod x $now

修改 vim 设置,设置文件在 ~/.vimrc

set tabstop=2
set expandtab
set shiftwidth=2

需要熟悉命令

grep
tr
sed

ip
netstat -anp | grep etcd
netstat -nplt
ps -aux

熟悉以上命令可以提高操作效率

备考资料

https://github.com/David-VTUK/CKA-StudyGuide/tree/master

题目操作:

一、权限控制 RBAC

kubectl config use-context k8s

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

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

二、查看 pod 的 CPU

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

三、配置网络策略 NetworkPolicy

# kubectl config use-context hk8s

# 拷贝官方文档设置 Concepts → Services, Load Balancing, and Networking → Network Policies

# 查看所有 ns 的标签 label
kubectl get ns --show-labels

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

# 编写一个 yaml 文件
vim networkpolicy.yaml

# 创建
kubectl apply -f networkpolicy.yaml

# 检查
kubectl describe networkpolicy -n my-app

四、暴露服务 service

kubectl config use-context 

# 检查 deployment 信息,并记录 SELECTOR 的 Lable 标签,这里是 app=front-end
kubectl get deployment front-end -o wide

# 参考官方文档,按照需要 edit deployment,添加端口信息
# Concepts → Workloads → Workload Resources → Deployments
kubectl edit deployment front-end

# 暴露对应端口
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,手动添加标签。
kubectl edit svc front-end-svc

# selector:
# app: front-end


# 最后 curl 检查
kubectl get pod,svc -o wide
curl 所在的 node 的 ip 或主机名:30938
curl svc 的 ip 地址:80
#(注意,只能 curl 通 svc 的 80 端口,但是无法 ping 通的。)

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


五、创建 Ingress

Concepts → Services, Load Balancing, and Networking → Ingress

kubectl config use-context k8s

# 拷贝官文的 yaml 案例,修改相关参数即可
vim ingressclass.yaml
kubectl apply -f ingressclass.yaml

# 再编写 ingress 的 yaml
vim ingress.yaml
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

六、扩容 deployment 副本数量

kubectl scale deployment -h

kubectl config use-context k8s


kubectl get deployments presentation -o wide
kubectl get pod -l app=presentation

kubectl scale deployment presentation --replicas=4

# 检查
kubectl get deployments presentation -o wide
kubectl get pod -l app=presentation

七、调度 pod 到指定节点

Tasks → Configure Pods and Containers → Assign Pods to Nodes

kubectl config use-context k8s

# 先检查一下是否有这个 pod,应该是没有创建的,所以需要创建
kubectl get pod -A|grep nginx-kusc00401
# 确保 node 有这个 labels,考试时,检查一下就行,应该已经提前设置好了 labels。
kubectl get nodes --show-labels|grep 'disk=ssd'

# 如果没有设置,则使用 kubectl label nodes node01 disk=ssd 命令来手动自己设置。
# 拷贝官文案例,修改下 pod 名称和镜像,删除多余的部分即可

vim pod-disk-ssd.yaml
#注意 :set paste,防止 yaml 文件空格错序。

kubectl apply -f pod-disk-ssd.yaml

# 检查
kubectl get pod nginx-kusc00401 -o wide

# 还有一个方法:
# 可以先生成 yaml,然后再修改 yaml,在创建
kubectl run nginx-kusc00401 --image=nginx --dry-run=client -o yaml > pod.yaml
vi pod.yaml

八、查看可用节点数

kubectl config use-context k8s

kubectl get nodes

# 因为题目要求,不包括被打上 Taint:NoSchedule 的就绪节点,所以要排除 NoSchedule 的。
# 然后使用如下命令,就能一眼看出来,几个打了 NoSchedule,几个没有打的。
# 下图可见 1 个 master01 打了 NoSchedule,所以 3-1=2

kubectl describe nodes | grep -i Taints
echo "查出来的数字" > /opt/KUSC00402/kusc00402.txt

# 还有一个方法:
# grep 的-i 是忽略大小写,grep -v 是排除在外,grep -c 是统计查出来的条数。
kubectl describe nodes | grep -i Taints | grep -vc NoSchedule
echo "查出来的数字" > /opt/KUSC00402/kusc00402.txt

# 检查
cat /opt/KUSC00402/kusc00402.txt

九、创建多容器的 pod

Concepts → Workloads → Pods

在 Yaml 配置文件里面写两个 -name 和 image

kubectl config use-context k8s

vim pod-kucc.yaml
kubectl apply -f pod-kucc.yaml

# 检查
kubectl get pod kucc8

十、创建 PV

Tasks → Configure Pods and Containers → Configure a Pod to Use a PersistentVolume for Storage

kubectl config use-context k8s

vim pv.yaml

kubectl apply -f pv.yaml

kubectl get pv

十一、创建 PVC

Tasks → Configure Pods and Containers → Configure a Pod to Use a PersistentVolume for Storage

kubectl config use-context ok8s

vim pvc.yaml

kubectl apply -f pvc.yaml

kubectl get pvc

vim pvc-pod.yaml

kubectl apply -f pvc-pod.yaml

kubectl get pod web-server

kubectl edit pvc pv-volume --record

# 修改 storage 便签改为 70m

十二、查看 pod 日志

kubectl config use-context k8s

kubectl logs foo | grep "RLIMIT_NOFILE" > /opt/KUTR00101/foo

cat /opt/KUTR00101/foo # 检查

十三、使用 sidecar 代理容器日志

Concepts → Cluster Administration → Logging Architecture

kubectl config use-context k8s

# 通过 kubectl get pod -o yaml 的方法备份原始 pod 信息,删除旧的 pod 11-factor-app
# copy 一份新 yaml 文件,添加 一个名称为 sidecar 的容器
# 新建 emptyDir 的卷,确保两个容器都挂载了 /var/log 目录
# 新建含有 sidecar 的 pod,并通过 kubectl logs 验证

kubectl get pod 11-factor-app -o yaml > varlog.yaml

cp varlog.yaml varlog-bak.yaml # 备份,防止改错

vim varlog.yaml

# 通过官方文档拷贝 sidecar 的 yaml 并修改

kubectl delete pod 11-factor-app # 执行需等待 2 分钟

kubectl get pod 11-factor-app # 检查

kubectl apply -f varlog.yaml

kubectl log 11-factor-app sidecar

# 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

十四、升级集群

Tasks → Administer a Cluster → Administration with kubeadm → Upgrading kubeadm clusters

kubectl config use-context mk8s

kubectl get nodes

kubectl cordon master01

kubectl drain master01 --ignore-deamonsets

ssh master01

sudo -i

apt-get update

apt-cache show kubeadm|grep 1.28.1

apt-get insatll=1.28.1-00

kubeadm version

kubectl upgrade apply v1.28.1 --etcd-upgrade=flase

# 升级 kubelet

apt-get install kubelet=1.28.1-00

kubectl version

# 退出 root,退回到 candidate@master01
exit

# 退出 master01,退回到 candidate@node01
exit

kubectl uncordon master01

kubectl get node

十五、备份还原 etcd

Tasks → Administer a Cluster → Operating etcd clusters for Kubernetes

kubectl config use-context xxxx

# 如果不使用 export ETCDCTL_API=3,而使用 ETCDCTL_API=3,则下面每条 etcdctl 命令前都要加 ETCDCTL_API=3。
# 如果执行时,提示 permission denied,则是权限不够,命令最前面加 sudo 即可。
export 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 save /var/lib/backup/etcd-snapshot.db

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

# 还原

# 考试时,/data/backup/etcd-snapshot-previous.db 的权限应该是只有 root 可读,所以需要使用 sudo 命令。
# 可以 ll /data/backup/etcd-snapshot-previous.db 检查一下读写权限和属主。


# 不加 sudo 会报错 permission denied,上面执行了 export ETCDCTL_API=3 了,下面就可以不写 ETCDCTL_API=3d 的,另外还原也是可以不写证书的(--cacert --cert --key)。
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

十六、排查集群中故障节点

# kubectl config use-context wk8s

# 通过 get nodes 查看异常节点,登录节点查看 kubelet 等组件的 status 并判断原因。真实考试时,这个异常节点的 kubelet 服务没有启动导致的,就这么简单。

kubectl get nodes

# ssh 到 node02 节点,并切换到 root 下
ssh node02
sudo -i

systemctl status kubelet

# 启动服务,并设置为开机启动
systemctl start kubelet
systemctl enable kubelet

# 检查
systemctl status kubelet

# 退出 root,退回到 candidate@node02
exit
# 退出 node02,退回到 candidate@node01
exit
# 再次检查节点, 确保 node02 节点恢复 Ready 状态
kubectl get nodes

十七、节点维护

# kubectl config use-context ek8s

kubectl get node

kubectl cordon node02
kubectl get node


kubectl drain node02 --ignore-daemonsets
# 注意,还有一个参数--delete-emptydir-data --force,这个考试时不用加,就可以正常 draini node02 的。
# 但如果执行后,有跟测试环境一样的报错(如下截图),则需要加上--delete-emptydir-data --force,会强制将 pod 移除。
# kubectl drain node02 --ignore-daemonsets --delete-emptydir-data --force

# 检查
kubectl get node
kubectl get pod -A -o wide|grep node02
# 正常已经没有 pod 在 node02 上了。但测试环境里的 ingress、calico、kube-proxy 是 daemonsets 模式的,所以显示还在 node02 上,忽略即可。