考题复习-2
自己当时考试前复习过的考题,做题笔记。
# 考题复习-2
# 题目一. RBAC
- [node]$ kubectl config use-context k8s
- 创建一个名为deployment-clusterrole的clusterrole,该clusterrole只允许创建deployment、daemonset、statefulset的create操作。
- 在名字为 app-team1的namespace下创建一个名为cicd-token的serviceAccount。
- 限于namespace app-team1,将新的clusterrole deployment-clusterrole绑定到新的serviceAccount cicd-token。
kubectl config use-context k8s # 切换集群
kubectl create clusterrole deployment-clusterrole --verb=create --resource=deployments,daemonsets,statefulsets
kubectl create sa cicd-token -n app-team1
kubectl create rolebinding cicd-token-binding --clusterrole=deployment-clusterrole --serviceaccount=app-team1:cicd-token
1
2
3
4
5
6
7
2
3
4
5
6
7
# 题目二. Top
- [node]$ kubectl config use-context k8s
- 通过pod label name=cpu-utilizer 直到运行占用大量cpu的pod,将pod名写入文件
- /opt/KUTR00401/KUTR00401.txt
kubectl config use-context k8s
kubectl top pods -l name=cpu-utilizer --sort-by=cpu -A
# echo <podname> >/opt/KUTR00401/KUTR00401.txt #注意:这里由于翻译问题可能文件名字不存在,可以先进去/opt下,确认这个文件具体目录在写入进去,别新建文件目录,否则没分。
1
2
3
4
2
3
4
# 题目三. Networkpolicy
- [node]$ kubectl config use-context hk8s
- 在namespace my-app中创建一个allow-port-from-namespace的新networkpolicy,确保新的NetwoekPolicy允许namespace big-corp中的Pods连接到namespace my-app中的Pod的端口8080。
- 进一步确认Networkolicy:
- 不允许对没有监听 8080 的Pods访问
- 不允许不来自namespace my-app 的Pods访问
kubectl config use-context k8s
kubectl label ns big-corp name=big-corp
1
2
3
2
3
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-port-from-namespace
namespace: my-app
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: big-corp
ports:
- protocol: TCP
port: 8080
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 题目四: Service
- [node]$ kubectl config use-context k8s
- 重新配置现有的front-end以及添加http的端口规范来公开现有的容器nginx的端口80/tcp
- 创建一个名叫front-end-svc服务,公开容器端口http。使用NodePort来公开各个Pods。
kubectl config use-context k8s
kubectl edit deploy front-end
ports:
- name: http
containerPort: 80
protocol: TCP
kubectl expose deploy front-end --name=front-env-svc --port=80 --target-port=80 --type=NodePort
# curl service:xxx
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 题目五. Ingress
- [node]$ kubectl config use-context k8s
- 创建一个新的nginx Ingress资源:
- 名称: pong
- Namespace: ing-internal
- 使用服务端口 5678 在路径 /hello上公开服务 hello
- 可以使用curl -kl
/hello
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: pong
namespace: ing-internal
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /hello
pathType: Prefix
backend:
service:
name: hello
port:
number: 5678
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
curl ip/hello
1
# 题目六. 副本扩容
- [node]$ kubectl config use-context k8s
- 将deployment 从 loadbalancer 扩展至 5 pods
kubectl config use-context k8s
kubectl scale deploy loadbalancer --replicas=5
1
2
3
2
3
# 题目七. 分配Pod
- 按照要求调度一个Pod:
- 名称: nginux-kusc00401
- Image: nginx
- Node selector: disk=ssd
kubectl run nginux-kusc00401 --image=nginx --image-pull-policy=IfNotPresent --dry-run=client
-o yaml > x.yaml
1
2
2
apiVersion: v1
kind: Pod
metadata:
name: nginux-kusc00401
spec:
nodeSelector:
disk: ssd
containers:
- name: nginux-kusc00401
image: nginx
imagePullPolicy: IfNotPresent
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 题目八: 统计污点
- [node]$ kubectl config use-context k8s
- 统计有多少个worker nodes 以准备就绪(不包括被打上Taint:NoSchedule的节点),并将数量写入到/opt/KUSC00402/kusc00402.txt
kubectl config use-context k8s
# 方法1
kubectl describe node | grep -i Taints | grep -vci NoSchedule > /opt/KUSC00402/kusc00402.txt
# -i 忽略大小写 -c 统计 -v 取反
# 方法2
kubectl describe node | grep Taints | grep -i NoSchedule | wc -l # 统计污点和不允许调度
kubectl get node | grep -w Ready | wc -l # 统计启动状态
# 指令2数字-指令1数字
# echo 数量 > /opt/KUSC00402/kusc00402.txt
# 方法3
kubectl describe nodes $(kubectl get node | grep Ready | awk '{print $1}') | grep Taints | grep -vc NoSchedule
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 题目九:多容器运行一个Pod
- [node]$ kubectl config use-context k8s
- 创建一个名叫kucc4的pod,在pod里面分别为每个images单独运行一个app container Nginx+redis+memcached
apiVersion: v1
kind: Pod
metadata:
name: kucc4
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
- name: redis
image: redis
imagePullPolicy: IfNotPresent
- name: memcached
image: memcached
imagePullPolicy: IfNotPresent
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 题目十. PV
- [node]$ kubectl config use-context hk8s
- 创建名叫app-data 的pv,容量为2Gi,访问模式为ReadWriteOnce。 Volume类型为hostPath,位于/srv/app-data
kubectl config use-context hk8s
1
apiVersion: v1
kind: PersistentVolume
metadata:
name: app-data
spec:
capacity:
storage: 2Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/srv/app-data"
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 题目十一. PVC
- [node]$ kubectl config use-context ok8s
- 创建一个新的PersistentVolumeClaim:
- 名称: pv-volume
- Class: csi-hostpath-sc
- 容量: 10Mi
- 创建一个新的Pod,这个Pod将volume挂在到 PersistentVolumeClaim:
- 名称: web-server
- Image: nginx
- 挂载路径: /usr/share/nginx/html
- 配置新的Pod,对volume具有 ReadWriteOnce 权限
- 最后,使用kubectl edit 或 kubectl patch将pvc容量扩展到70Mi,并记录更改。
kubectl config use-context ok8s
# kubectl get pvc #注意,这里因为没有csi这个类,所以状态处于pending是正常的。考试会有csi这个类,csi这个类需要安装对应插件才能使用
# kubectl edit pvc pv-volume --save-config #我们修改会保存不了,因为上面pvc,pending状态,记住在那里修改即可。或--save-config也可以用--record替换。
1
2
3
4
2
3
4
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pv-volume
spec:
# storageClassName: csi-hostpath-sc
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Mi
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
apiVersion: v1
kind: Pod
metadata:
name: web-server
spec:
volumes:
- name: pvc
persistentVolumeClaim:
claimName: pv-volume
containers:
- name: web-server
image: nginx
imagePullPolicy: IfNotPresent
volumeMounts:
- name: pv
mountPath: "/usr/share/nginx/html"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 题目十二. Logs
- [node]$ kubectl config use-context k8s
- 监控 pod bar的日志并:提取与错误 file-not-found 相对应的日志行,将这些日志写入到/opt/KUTR00101/bar
kubectl config use-context k8s
kubectl logs bar | grep file-not-found >/opt/KUTR00101/bar
#注意pod/bar格式。可以先logs看有没有信息在输出,注意权限问题,必要加sudo
# cat /opt/KUTR00101/bar #验证
1
2
3
4
5
2
3
4
5
# 题目十三. Sidecar边车(遇到可以先做后面,我考试第5题出现)
- [node]$ kubectl config use-context k8s
- 现有一个Pod legacy-app 内置日志,使用busybox Image添加一个 sidecar 容器添加到现有Pod legacy-app中新sidecar容器必须运行一下指令
- /bin/sh, -c, 'tail -n+1 -f /var/log/legacy-app.log'。
- 并且这个 sidecar 和原有的镜像挂载一个名为 logs 的 volume,挂载的目录为/var/log/
- 除了添加volume mount 外,请不要更改现有容器的规格。
kubectl config use-context k8s
# 注意 不能对原有pod修改, 只能新增辅助sidecar
kubectl get pods leagcy-app -o yaml > 13.yaml # 导出旧pod配置
cp 13.yaml 13.bak.yaml # 备份
kubectl delete pod legacy-app # 删除旧pod
vim 13.yaml
kubectl apply -f 13.yaml # 重新部署
# 验证是否使用同一个log
kubectl exec legacy-app -c legacy-app -- tail -f /var/log/legacy-app.log
kubectl exec legacy-app -c sidecar -- tail -f /var/log/legacy-app.log
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
...
volumes:
# 插入↓
- name: varlog
emptyDir: {}
# 插入↑
...
volumeMounts:
- mountPath: /var/log
name: varlog
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: default-token-h2tqr
readOnly: true
# 插入↓
- name: varlog
mountPath: /var/log
- name: sidecar
image: busybox
args: [/bin/sh, -c, 'tail -n+1 -F /var/log/legacy-app.log']
volumeMounts:
- name: varlog
mountPath: /var/log
# 插入↑
dnsPolicy: ClusterFirst
enableServiceLinks: true
nodeName: node01
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 题目十四. 升级(升级需要时间,建议最后做)
- [node]$ kubectl config use-context mk8s
kubectl config use-context mk8s
kubectl cordon mk8s-master-0
kubectl darin mk8s-master-0 --ignore-daemonsets
ssh mk8s-master-0
sudo -i
api install kubeadm=1.20.1-00 -y
kubeadm upgrade plan
kubeadm upgrade apply v1.20.1 --etcd-upgrade=false
apt install kubelet=1.20.1-00 kubectl=1.20.1-00 -y
systemctl restart kubelet
exit # sudo
exit # ssh
kubectl uncordon mk8s-master-0
# 验证
kubectl get node -o wide
kubectl --version
kubelet --version
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 题目十五. Etcd备份
- 备份文件名:/data/backup/etcd-snapshot.db
- 还原文件名:/data/backup/etcd-snapshot-previous.db
# 确定当前环境, 已经返回初始点
kubectl get node
# 配置
ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 \
--cacert=<CA-FILE> --cert=<CERT-FILE> --key=<KEY-FILE> \
snapshot save /data/backup/etcd-snapshot.db
# 还原
sudo -i
systemctl stop etcd
systemctl cat etcd # 确认数据目录
mv /var/lib/etcd/default.etcd /var/lib/etcd/default.etcd.bak # 备份
sudo ETCDCTL_API=3 etcdctl restore /data/backup/etcd-snapshot-previous.db --data-dir=/var/lib/etcd/default.etcd
chown -R etcd:etcd /var/lib/etcd # 注意 不要忘记
systemctl start etcd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 题目十六. Node 状态排错(送分题)
kubectl config use-context wk8s
ssh wk8s-node-0
sudo -i
kubectl describe node wk8s-node-0
systemctl enable kubelet --now
systemctl status kubelet
# journalctl -u kubelet # 如果没有起来, 查看原因
exit # sudo
exit # ssh
kubectl get nodes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 题目十七. Node驱逐Pod
- [node]$ kubectl config use-context ek8s
- 将名叫ek8s-node-1的node设置为不可用,并重新调度该node上的所有pods。
kubectl config use-context ek8s
# kubectl cordon ek8s-node-1 # 不可调度
kubectl drain ek8s-node-1 --ignore-daemonsets # 不可调度, 并且排空节点
# 如果上面命令报错, 加上--delete-local-data 或 --delete-emptydir-data
# 验证
kubectl get nodes
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
编辑 (opens new window)