1、 权限控制RBAC:
创建名称 deployment-clusterrole 的 ClusterRole,该⻆⾊具备创建 Deployment、Statefulset、
Daemonset 的权限,在命名空间 app-team1 中创建名称为 cicd-token 的 ServiceAccount,绑定
ClusterRole 到 ServiceAccount,且限定命名空间为 app-team1。
考题解析:
需要熟悉创建 serviceaccount、clusterrole 和 rolebinding 的⽅法,需要限定在 ns 级别,因此最好使⽤ rolebinding
参考:https://kubernetes.io/zh/docs/reference/access-authn-authz/rbac/
kubectl create clusterrole deploymengt-clusterrole --verb=create --resource=deployments,daemonsets,statefulsets
kubectl -n app-team1 create serviceaccount cicd-token
kubectl create rolebinding cicd-token-binding --clusterrole=deployment-clusterrole --serviceaccount=app-team1:cicd-token -n app-team1
2、 节点维护-指定 node 节点不可用
将 ek8s-node-1 节点设置为不可用,然后重新调度该节点上的所有 Pod
参考:https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#drain
https://kubernetes.io/zh/docs/concepts/architecture/nodes/
#标记节点为不可调度
kubectl cordon k8s-node1
#驱逐pod
kubectl drain k8s-node1 --delete-emptydir-data --ignore-daemonsets --force
3、版本升级
参考:https://kubernetes.io/zh-cn/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/
切换 context
kubectl get nodes
ssh mk8s-master-0
kubectl cordon mk8s-master-0
kubectl drain mk8s-master-0 --ignore-daemonsets --force
apt-mark unhold kubeadm kubectl kubelet
apt-get update && apt-get install -y kubeadm=1.22.2-00 kubelet=1.22.2-00
kubectl=1.22.2-00
apt-mark hold kubeadm kubectl kubelet
kubeadm upgrade plan
kubeadm upgrade apply v1.22.2 --etcd-upgrade=false
systemctl daemon-reload && systemctl restart kubelet
kubectl uncordon mk8s-master-0
4、 Etcd 数据库备份恢复
参考:https://kubernetes.io/zh-cn/docs/tasks/administer-cluster/configure-upgrade-etcd/
#安装命令
apt-get install etcd-client
#保存快照
ETCDCTL_API=3 etcdctl --endpoints="https://127.0.0.1:2379" \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/healthcheck-client.crt \
--key=/etc/kubernetes/pki/etcd/healthcheck-client.key \
snapshot save /data/etcd-snapshot.db
#验证快照
ETCDCTL_API=3 etcdctl --write-out=table snapshot status /data/etcd-snapshot.db
#还原快照
mkdir /data/backup/ -p
cd /etc/kubernetes/manifests && mv kube-* /data/backup
ETCDCTL_API=3 etcdctl --endpoints="https://127.0.0.1:2379" \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/healthcheck-client.crt \
--key=/etc/kubernetes/pki/etcd/healthcheck-client.key \
snapshot restore /data/etcd-snapshot.db \
--data-dir=/var/lib/etcd-restore
#修改etcd配置文件
vim /etc/kubernetes/manifests/etcd.yaml
# 将 volume 配置的 path: /var/lib/etcd 改成/var/lib/etcd-restore
volumes:
- hostPath:
path: /etc/kubernetes/pki/etcd
type: DirectoryOrCreate
name: etcd-certs
- hostPath:
path: /var/lib/etcd
type: DirectoryOrCreate
name: etcd-data
status: {}
#还原配置
cd /data/backup && mv *.yaml /etc/kubernetes/manifests
systemctl restart kubelet
kubectl get nodes
5、 网络策略 NetworkPolicy
在命名空间 fubar 中创建⽹络策略 allow-port-from-namespace,只允许 ns my-app 中的 pod 连上fubar 中 pod 的 80 端⼝,注意:这⾥有 2 个 ns ,⼀个为 fubar(⽬标pod的ns),另外⼀个为 my-app(访问源pod的ns)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-port-from-namespace
namespace: echo #目的命名空间
spec:
podSelector: {} # 注意这里我敲加matchLabels会出错,删了matchLabels这么写可以过
policyTypes:
- Ingress #策略影响入栈流量
ingress:
- from: #允许流量的来源
- namespaceSelector:
matchLabels:
project: my-app
ports:
- protocol: TCP
port: 9000 #允许访问的端口
6、 四层负载均衡 service
重新配置一个已经存在的 deployment front-end,在名字为 nginx 的容器里面添加一个端口配置, 名字为 http,暴露端口号为 80,然后创建一个 service,名字为 front-end-svc,暴露该 deployment 的 http 端口,并且 service 的类型为 NodePort。
参考:https://kubernetes.io/zh-cn/docs/concepts/services-networking/service/
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: front-end
name: front-end
spec:
replicas: 1
selector:
matchLabels:
app: front-end
template:
metadata:
labels:
app: front-end
spec:
containers:
- image: nginx:1.21
name: nginx
ports:
- containerPort: 80
name: http
protocol: TCP
kubectl expose deploy front-end --name=front-end-svc --port=80 --target-port=http -- type=NodePort
以上ports为考试部分
7、 七层负载均衡 Ingress
在 ing-internal 命名空间下创建一个 ingress,名字为 pong,代理的 service hi,端口为 5678,配 置路径/hi。 验证:访问 curl -kL
参考:https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress/#the-ingress-resource
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: pong
namespace: ing-internal
spec:
rules:
- http:
paths:
- path: /hi
pathType: Prefix
backend:
service:
name: hi
port:
number: 5678
8 、Deployment 管理 pod 扩缩容
扩容名字为 loadbalancer 的 deployment 的副本数为 6
kubectl scale --replicas=5 deployment loadbalancer
或
kubectl edit deployment loadbalancer
9、 pod 指定节点部署
创建一个 Pod,名字为 nginx-kusc00401,镜像地址是 nginx,调度到具有 disk=spinning 标签的 节点上
参考:https://kubernetes.io/zh/docs/tasks/configure-pod-container/assign-pods-nodes/
kubectl label node k8s-node1 disk=spinning
#验证
kubectl get nodes --show-labels
#查看配置文件
cat assign-pods-nodes.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-kusc00401
labels:
role: nginx-kusc00401
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
nodeSelector:
disk: spinning
10、 检查 Node 节点的健康状态
检查集群中有多少节点为 Ready 状态,并且去除包含 NoSchedule 污点的节点。之后将数字写到 /opt/KUSC00402/kusc00402.txt
参考:https://kubernetes.io/zh-cn/docs/concepts/scheduling-eviction/taint-and-toleration/
#查看ready节点
kubectl get node | grep -i ready # 记录总数为 A
#查看NoSchedule节点
kubectl describe node | grep Taint | grep NoSchedule # 记录总数为 B
# 将 A 减 B 的值 x 导入到/opt/KUSC00402/kusc00402.txt
$ echo x >> /opt/KUSC00402/kusc00402.txt
11、 一个 Pod 封装多个容器
创建一个 Pod , 名 字 为 kucc1 ,这个 Pod 可 能 包 含 1-4 容 器 , 该 题 为 四 个 : nginx+redis+memcached+consul
参考:https://kubernetes.io/zh-cn/docs/concepts/services-networking/service/
apiVersion: v1
kind: Pod
metadata:
name: kucc1
spec:
containers:
- name: nginx
image: nginx
- name: redis
image: redis
- name: consul
image: consul
- name: memcached
image: memcached
imagePullPolicy: IfNotPresent
12、 持久化存储卷 PersistentVolume
创建一个 pv,名字为 app-config,大小为 2Gi,访问权限为 ReadWriteMany。Volume 的类型为 hostPath,路径为/srv/app-config
参考:https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/configure-persistent-volume-storage/
apiVersion: v1
kind: PersistentVolume
metadata:
name: app-config
labels:
type: local
spec:
capacity:
storage: 2Gi
accessModes:
- ReadWriteMany
hostPath:
path: "/srv/app-config"
13、 PersistentVolumeClaim
创建一个名字为 pv-volume 的 pvc,指定 storageClass 为 csi-hostpath-sc,大小为 10Mi 然后创建一个 Pod,名字为 web-server,镜像为 nginx,并且挂载该 PVC 至/usr/share/nginx/html,挂 载的权限为 ReadWriteOnce。之后通过 kubectl edit 或者 kubectl path 将 pvc 改成 70Mi,并且记录修 改记录。
参考:https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/configure-persistent-volume-storage/
pvc
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pv-volume
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Mi
storageClassName: csi-hostpath-sc
pod
apiVersion: v1
kind: Pod
metadata:
name: web-server
spec:
volumes:
- name: pv-volume
persistentVolumeClaim:
claimName: pv-volume
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
name: "http-server"
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: pv-volume
扩容
kubectl edit pvc pv-volume
14、 监控 Pod 日志
监控名为 foobar 的 Pod 的日志,并过滤出具有 unable-access-website 信息的行,然后将写入到 /opt/KUTR00101/foobar
kubectl logs foobar | grep unable-access-website > /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/
apiVersion: v1
kind: Pod
metadata:
name: legacy-app
spec:
containers:
- name: count
image: busybox
args:
- /bin/sh
- -c
- >
i=0;
while true;
do
echo "$i: $(date)" >> /var/log/1.log;
echo "$(date) INFO $i" >> /var/log/2.log;
i=$((i+1));
sleep 1;
done
volumeMounts:
- name: varlog
mountPath: /var/log
- name: count-log-1
image: busybox
args: [/bin/sh, -c, 'tail -n+1 -F /var/log/1.log']
volumeMounts:
- name: varlog
mountPath: /var/log
volumes:
- name: varlog
emptyDir: {}
16、 监控 Pod 度量指标
找出具有 name=cpu-user 的 Pod,并过滤出使用 CPU 最高的 Pod,然后把它的名字写在已经存在 的/opt/KUTR00401/KUTR00401.txt 文件里(注意他没有说指定 namespace。所以需要使用-A 指定所 以 namespace)
kubectl top pod -A -l name=cpu-user
echo "coredns-54d67798b7-hl8xc" >> /opt/KUTR00401/KUTR00401.txt
17、 集群故障排查 – kubelet 故障
一个名为 wk8s-node-0 的节点状态为 NotReady,让其他恢复至正常状态,并确认所有的更改开机
ssh wk8s-node-0
sudo -i
systemctl status kubelet
systemctl start kubelet
systemctl enable kubelet