一.一些省时技巧
1.复制粘贴。
终端:ctrl+shift+c/v
除终端外的其他地方:ctrl+c/v
2.alias设置别名。
alias k=kubectl
3.kubectl 自动补全(已经不需要手动设置了,默认已有)。
echo "source <(kubectl completion bash)" >> ~/.bashrc
source ~/.bashrc
4.善用 --dry-run=client -o yaml
生成yaml文件模板,更简洁的办法是直接将这一串字符设为环境变量,直接引用环境变量。
k run --dry-run=client -o yaml > *.yaml
export do="--dry-run=client -o yaml"
k create deploy nginx --image=nginx $do
5.善用 kubectl explain [resource[.field]]
。
6.善用强制停止pod,避免默认优雅停止占用太多时间。
export now="--force --grace-period 0"
k delete pod x $now
7.善用一切 --help
,避免搜索文档浪费时间。
k create clusterrole --help
k create rolebinding --help
k scale --help
k top pods --help
k logs --help
k drain --help
8.可以打开一个mousepad记事本,yaml粘完修改后再复制到vim中。
二.注意事项
1.黑色星期五(或Cyber Monday)时购买考试是全年价格最低的时候,推荐预算充足的同学购买CKA+CKS,性价比最高,相关课程不推荐买,video和课件都是纯英语,对英语一般的人不够友好,买后用处不大。
2.规定的是考试购买后1个月内需要兑换考试券(我超过1个月后兑换的虽然也成功了,但不建议卡时间)。
3.考试时间的选择,最好选择凌晨和清晨,比如早上7点左右,亲测网络不会卡顿。
4.浏览器和PSI插件按照指南说明准备,考前最好多测试多运行几次,确保系统环境一定没问题,比如我考时windows系统不能用win10企业版,所以需要重装系统或换个电脑。
5.关于网络,不建议在办公室等有公司防火墙的WiFi环境考试,很可能会看不到题目,可以选择在家或酒店,或者自己手机开热点这些方式。
三.考试题目
第1题.基于角色的访问控制-RBAC
第2题.节点维护—指定node节点不可用
第3题.K8s版本升级
第4题.Etcd数据库备份恢复
第5题.网络策略NetworkPolicy
第6题.四层负载均衡service
第7题.七层负载均衡Ingress
第8题.Deployment管理pod扩缩容
第9题.pod指定节点部署
第10题.检查Node节点的健康状态
第11题.一个Pod封装多个容器
第12题.持久化存储卷PersistentVolume
第13题.PersistentVolumeClaim
第14题.监控Pod日志
第15题.Sidecar代理
第16题.监控Pod度量指标
第17题.集群故障排查——kubelet故障
下面按照考试可能的顺序排序。
1.RBAC(4分)
中文解释:
创建一个名为deployment-clusterrole的clusterrole,该clusterrole只允许创建Deployment、Daemonset、Statefulset的create操作
在名字为app-team1的namespace下创建一个名为cicd-token的serviceAccount,并且将上一步创建clusterrole的权限绑定到该serviceAccount
参考:
https://kubernetes.io/zh/docs/reference/access-authn-authz/rbac/
https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/configure-service-account/
解题:
# 创建clusterrole
kubectl create clusterrole deployment-clusterrole --verb=create --resource=deployments,statefulsets,daemonsets
# 或者
[root@k8s-master01 ~]# cat dp-clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: deployment-clusterrole
rules:
- apiGroups: ["extensions", "apps"]
resources: ["deployments","statefulsets","daemonsets"]
verbs: ["create"]
[root@k8s-master01 ~]# kubectl create -f dp-clusterrole.yaml
clusterrole.rbac.authorization.k8s.io/deployment-clusterrole created
# 创建serviceAccount
kubectl create sa cicd-token -n app-team1
serviceaccount/cicd-token created
# 绑定权限(推荐,节省时间)
kubectl create rolebinding deployment-rolebinding --clusterrole=deployment-clusterrole --serviceaccount=app-team1:cicd-token -n app-team1
或者
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: deployment-rolebinding
namespace: app-team1
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: deployment-clusterrole
subjects:
- kind: ServiceAccount
name: cicd-token
namespace: app-team1
# 验证:
[root@k8smaster /opt/cka]# kubectl auth can-i create deployment --as system:serviceaccount:app-team1:cicd-token -n app-team1
yes
[root@k8smaster /opt/cka]# kubectl auth can-i create daemonset --as system:serviceaccount:app-team1:cicd-token -n app-team1
yes
[root@k8smaster /opt/cka]# kubectl auth can-i create statefulset --as system:serviceaccount:app-team1:cicd-token -n app-team1
yes
[root@k8smaster /opt/cka]# kubectl auth can-i create pod --as system:serviceaccount:app-team1:cicd-token -n app-team1
no
2.节点维护(4分)
中文解释:
将ek8s-node-1节点设置为不可用,然后重新调度该节点上的所有Pod
参考:
https://kubernetes.io/zh/docs/tasks/configure-pod-container/
https://kubernetes.io/zh-cn/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/
https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#drain
解题:
kubectl config use-context ek8s
kubectl cordon ek8s-node-1
# 测试执行
kubectl drain ek8s-node-1 --delete-emptydir-data --ignore-daemonsets --force --dry-run=server
# 腾空节点
kubectl drain ek8s-node-1 --delete-emptydir-data --ignore-daemonsets --force
3.1K8S组件升级1.18.8升级为1.19.0(7分)
参考:
https://kubernetes.io/zh/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/
https://kubernetes.io/zh-cn/docs/tasks/administer-cluster/safely-drain-node/
解题:
首先腾空节点:
# 设置为维护状态
kubectl cordon k8s-master
# 驱逐Pod
kubectl drain k8s-master --delete-emptydir-data --ignore-daemonsets --force
# 之后需要按照题目提示ssh到一个master节点
ssh master01
sudo su -
apt update
apt-cache policy kubeadm | grep 1.19.0 # (注意版本的差异,有可能并非1.18.8升级到1.19)
apt-get install kubeadm=1.19.0-00 [--allow-change-held-packages] -y
# 验证升级计划
kubeadm upgrade plan
# 看到如下信息,可升级到指定版本
You can now apply the upgrade by executing the following command:
kubeadm upgrade apply v1.19.0
_____________________________________________________________________
# 开始升级Master节点,注意看题目是否需要升级etcd
kubeadm upgrade apply v1.19.0 --etcd-upgrade=false
[upgrade/successful] SUCCESS! Your cluster was upgraded to "v1.19.0". Enjoy!
[upgrade/kubelet] Now that your control plane is upgraded, please proceed with upgrading your kubelets if you haven't already done so.
# 升级kubectl和kubelet
apt-get install -y kubelet=1.19.0-00 kubectl=1.19.0-00 [--allow-change-held-packages]
systemctl daemon-reload
systemctl restart kubelet
# 恢复master为可调度节点
kubectl uncordon k8s-master
node/k8s-master uncordoned
kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master01 NotReady control-plane,master 11d v1.19.0
k8s-node01 Ready <none> 8d v1.18.8
k8s-node02 Ready <none> 11d v1.18.8
kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master01 Ready control-plane,master 11d v1.19.0
k8s-node01 Ready <none> 8d v1.18.8
k8s-node02 Ready <none> 11d v1.18.8
3.2K8S组件升级1.20.1升级到1.21.1(7分)
参考:
https://kubernetes.io/zh/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/
解题:
首先腾空节点:
# 设置为维护状态
kubectl cordon k8s-master
# 驱逐Pod
kubectl drain k8s-master --delete-emptydir-data --ignore-daemonsets --force
# 之后需要按照题目提示ssh到一个master节点
apt update
apt-cache policy kubeadm | grep 1.21.1
# 注意版本的差异,有可能并非1.20.1升级到1.21.1
apt-get install kubeadm=1.21.1-00
# 验证升级计划
kubeadm upgrade plan
# 看到如下信息,可升级到指定版本
# 开始升级Master节点,注意看题需不需要升级etcd
kubeadm upgrade apply v1.21.1 --etcd-upgrade=false -f
# 注意:自己的环境升级,可能会报找不到coredns的镜像,可以使用如下方法解决:
所有节点docker pull coredns/coredns:1.8.0 ; docker tag coredns/coredns:1.8.0
registry.cn-hangzhou.aliyuncs.com/google_containers/coredns/coredns:v1.8.0
然后继续就行。1.8.0改成你自己CoreDNS 报错的版本
# 升级kubectl和kubelet
apt-get install -y kubelet=1.21.1-00 kubectl=1.21.1-00
systemctl daemon-reload
systemctl restart kubelet
# 恢复master可调度
kubectl uncordon k8s-master
node/k8s-master uncordoned
kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master01 NotReady control-plane,master 11d v1.21.1
k8s-node01 Ready <none> 8d v1.12.1
kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master01 Ready control-plane,master 11d v1.21.1
k8s-node01 Ready <none> 8d v1.20.1
k8s-node02 Ready <none> 11d v1.20.1
4.Etcd备份与恢复(7分)
中文解释:
针对etcd实例https://127.0.0.1:2379
创建一个快照,保存到 /srv/data/etcd-snapshot.db
。在创建快照的过程中,如果卡住了,就键入ctrl+c终止,然后重试。
然后恢复一个已经存在的快照:/var/lib/backup/etcd-snapshot-previous.db
执行etcdctl命令的证书存放在:
ca证书:/opt/KUIN00601/ca.crt
客户端证书:/opt/KUIN00601/etcd-client.crt
客户端密钥:/opt/KUIN00601/etcd-client.key
参考:
https://kubernetes.io/zh/docs/tasks/administer-cluster/configure-upgrade-etcd/
解题:
kubernetes的所有数据记录在etcd中,对etcd进行备份就是对集群进行备份。连接etcd需要证书,证书可以从apiserver获取,因为apiserver可以去连etcd。新版本的apiserver都是以static pod方式运行,证书通过volume挂载到pod中。
具体的证书路径和备份到的路径按题目要求设置。ssh到master节点很快,长时间没连上,可以中断重连。
恢复部分据说很容易卡住,不要花太多时间。
# 路径不存在的话要提前建出来
export ETCDCTL_API=3
etcdctl --endpoints="https://127.0.0.1:2379" --cacert=/opt/KUIN000601/ca.crt --cert=/opt/KUIN000601/etcd-client.crt --key=/opt/KUIN000601/etcd-client.key snapshot save /srv/data/etcd-snapshot.db
# 还原
还原前最好关掉etcd服务,还原后重新开启etcd服务,
还原后etcd的状态可能有问题,最好不要去赌,失分可能性很大。
systemctl stop etcd
mkdir /opt/backup/ -p
cd /etc/kubernetes/manifests
mv kube-* /opt/backup
export ETCDCTL_API=3
etcdctl --endpoints="https://127.0.0.1:2379" --cacert=/opt/KUIN000601/ca.crt --cert=/opt/KUIN000601/etcd-client.crt --key=/opt/KUIN000601/etcd-client.key snapshot restore /var/lib/backup/etcd-snapshot-previous.db --data-dir=/var/lib/etcd-restore
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-restore
# 修改数据目录权限
chown -R etcd.etcd /var/lib/etcd-restore
# 还原k8s组件
mv /opt/backup/* /etc/kubernetes/manifests
systemctl restart kubelet
systemctl start etcd
# 其他答案:
# 不需要进行集群的切换,etcdctl 工具主机上已存在,无需进行安装
ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1: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_API=3 etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/opt/KUIN00601/ca.crt --cert=/opt/KUIN00601/etcd-client.crt --key=/opt/KUIN00601/etcd-client.key snapshot restore /var/lib/backup/etcd-snapshot-previous.db
注意:
如果是二进制安装的etcd,考试环境的etcd可能并非root用户启动的,所以可以先切换到root用户(sudo su -)
然后使用ps aux | grep etcd查看启动用户是谁和启动的配置文件是谁config-file字段指定,假设用户是etcd。所以如果是二进制安装的etcd,执行恢复时需要root权限,所以在恢复数据时,可以使用root用户恢复,之后更改恢复目录的权限:sudo chown -R etcd.etcd /var/lib/etcd-restore,
然后通过systemctl status etcd(或者ps aux | grep etcd)找到它的配置文件
(如果没有配置文件,就可以直接在etcd的service 通过systemctl status etcd即可看到文件中找到data-dir的配置),然后更改data-dir配置后,执行systemctl daemon-reload,最后使用etcd用户systemctl restart etcd即可。
5.1NetworkPolicy(7)
中文解释:
创建一个名字为allow-port-from-namespace的NetworkPolicy,这个NetworkPolicy允许internal命名空间下的Pod访问该命名空间下的9000端口。
并且不允许不是internal命令空间的下的Pod访问
不允许访问没有监听9000端口的Pod。
参考:
https://kubernetes.io/zh/docs/concepts/services-networking/network-policies/
解题:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-port-from-namespace
namespace: internal
spec:
ingress:
- from:
- podSelector: {}
ports:
- port: 9000
protocol: TCP
podSelector: {}
policyTypes:
- Ingress
5.2(7)
上述的题目是只限制在internal命名空间下的,该题可能存在更新。更新如下:
在现有的namespace my-app中创建一个名为allow-port-from-namespace的NetworkPolicy
确保这个NetworkPolicy允许namespace my-app中的pods可以连接到namespace big-corp中的8080。
并且不允许不是my-app命令空间的下的Pod访问,不允许访问没有监听8080端口的Pod。
所以可以拿着上述的答案,进行稍加修改(注意namespaceSelector的labels配置,首先需要查看big-corp命名空间有没有标签:kubectl get ns big-corp --show-labels
如果有,可以更改 name: big-corp
为查看到的即可。如果没有需要添加一个label:kubectl label ns big-corp name=big-corp
):
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-port-from-namespace
namespace: my-app
spec:
egress:
- to:
- namespaceSelector:
matchLabels:
name: big-corp
ports:
- protocol: TCP
port: 8080
ingress:
- from:
- podSelector: {}
ports:
- port: 8080
protocol: TCP
podSelector: {}
policyTypes:
- Ingress
- Egress
5.3(7)
参考:
https://kubernetes.io/zh/docs/concepts/services-networking/network-policies/
此题和上题比较比较简单,只需要允许internal命名空间即可。
解题:
注意namespace选择器
# 切换到指定集群
kubectl config use-context [NAME]
# 查看 namespace corp-bar 的标签,如:kubernetes.io/metadata.name=corp-bar
kubectl get ns --show-labels
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-port-from-namespace
namespace: big-corp
spec:
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: internal
ports:
- port: 9200
protocol: TCP
podSelector: {}
policyTypes:
- Ingress
6.Service(7)
中文解释:
重新配置一个已经存在的deployment front-end,在名字为nginx的容器里面添加一个端口配置,名字为http,暴露端口号为80/TCP,然后创建一个service,名字为front-end-svc,暴露该deployment的http端口,并且service的类型为NodePort。
参考:
https://kubernetes.io/docs/concepts/services-networking/connect-applications-service/
https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/deployment/
https://kubernetes.io/zh-cn/docs/concepts/services-networking/service/
解题:
kubectl edit deploy front-end
spec:
containers:
- name: nginx
image: nginx
# 需要加这四行
ports:
- name: http
containerPort: 80
protocol: TCP
添加如下配置,主要是在name为nginx的容器下
# 添加service:
kubectl expose deploy front-end --name=front-end-svc --port=80 --target-port=http --type=NodePort
# 或者通过文件方式创建service:
apiVersion: v1
kind: Service
metadata:
name: front-end-svc
labels:
app: front-end
spec:
type: NodePort
selector:
app: front-end # label需要匹配,否则访问不到。
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
7.Ingress(7)
中文解释:
在ing-internal 命名空间下创建一个ingress,名字为pong,代理的service hi,端口为5678,配置路径/hi。
验证:访问curl -kL <INTERNAL_IP>/hi
会返回hi。
参考:
https://kubernetes.io/zh/docs/concepts/services-networking/ingress/
https://kubernetes.io/zh-cn/docs/concepts/services-networking/service/
解题:
# ingressClassName需指定为nginx
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: pong
namespace: ing-internal
spec:
ingressClassName: nginx
rules:
- http:
paths:
- path: /hi
pathType: Prefix
backend:
service:
name: hi
port:
number: 5678
kubectl get ingress -n ing-internal 获取ip后curl验证
# 如果考试环境没出ip需要在annotations下加一行
cat ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: pong
namespace: ing-internal
annotations:
nginx.ingress.kubernetes.io
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /hi
pathType: Prefix
backend:
service:
name: hi
port:
number: 5678
ingressclassname如果不指定,则会使用集群默认的指定的ingress。
8.Deployment扩缩容(4)
中文解释:
扩容名字为loadbalancer的deployment的副本数为6
参考:
https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/deployment/
解题:
kubectl config use-context k8s
kubectl scale --replicas=6 deployment loadbalancer
kubectl edit deploy loadbalancer
9.指定节点部署(4)
中文解释:
创建一个Pod,名字为nginx-kusc00401,镜像地址是nginx,调度到具有disk=spinning标签的节点上
参考:
https://kubernetes.io/zh/docs/concepts/scheduling-eviction/assign-pod-node/
https://kubernetes.io/zh/docs/tasks/configure-pod-container/assign-pods-nodes/
解题:
vim pod-ns.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-kusc00401
labels:
role: nginx-kusc00401
spec:
nodeSelector:
disk: spinning
containers:
- name: nginx
image: nginx
kubectl create -f pod-ns.yaml
# 省时
kubectl run nginx-kusc00401 --image=nginx --dry-run=client -o yaml > 9.yaml
10.检查Node节点健康状态(4)
中文解释:
检查集群中有多少节点为Ready状态,并且去除包含NoSchedule污点的节点。之后将数字写到/opt/KUSC00402/kusc00402.txt
参考:
https://kubernetes.io/zh-cn/docs/concepts/scheduling-eviction/taint-and-toleration/
解题:
kubectl config use-context k8s
# 记录总数为A
kubectl get node|grep -i ready|wc -l
# 记录总数为B
kubectl describe node|grep Taints|grep NoSchedule|wc -l
# 将A减B的值x导入到/opt/KUSC00402/kusc00402.txt
echo x >> /opt/KUSC00402/kusc00402.txt
# 切换到指定集群
kubectl config use-context [NAME]
# Ready 状态的节点数减去 NoSchedule 状态的节点数
kubectl get node |grep -i ready
kubectl describe node |grep -i 'taints'
echo '2' >> /opt/KUSC00402/kusc00402.txt
11.一个Pod多个容器(4)
中文解释:
创建一个Pod,名字为kucc1,这个Pod可能包含1-4容器,该题为四个:nginx+redis+memcached+consul
参考:
https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/
解题:
apiVersion: v1
kind: Pod
metadata:
name: kucc1
spec:
containers:
- image: nginx
name: nginx
- image: redis
name: redis
- image: memchached
name: memcached
- image: consul
name: consul
# 或者用dry-run=client的命令快速生成yaml模板,修改yaml,加入新容器进去
kubectl run kucc1 --image=nginx --dry-run=client -o yaml > 11.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
run: kucc1
name: kucc1
spec:
containers:
- image: nginx
name: nginx
- image: redis
name: redis
- image: memcached
name: memcached
- image: consul
name: consul
dnsPolicy: ClusterFirst
restartPolicy: Always
12.PersistentVolume(4)
中文解释:
创建一个pv,名字为app-config,大小为2Gi,访问权限为ReadWriteMany。Volume的类型为hostPath,路径为/srv/app-config
参考:
https://kubernetes.io/docs/tasks/configure-pod-container/configure-persistent-volume-storage/
https://kubernetes.io/zh-cn/docs/concepts/storage/persistent-volumes/
可以ctrl+F 搜003,会直接跳转到创建pv
https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/configure-persistent-volume-storage/#create-a-persistentvolume
解题:
apiVersion: v1
kind: PersistentVolume
metadata:
name: app-config
labels:
type: local
spec:
storageClassName: manual # 需要有这一项吗?题目没有要求,(可以不写)
volumeMode: Filesystem
capacity:
storage: 2Gi
accessModes:
- ReadWriteMany
hostPath:
path: "/srv/app-config"
kubectl get pv app-config
13.监控Pod度量指标(5)
中文解释:
找出具有name=cpu-user
的Pod,并过滤出使用CPU最高的Pod,然后把它的名字写在已经存在的 /opt/KUTR00401/KUTR00401.txt
文件里(注意他没有说指定namespace。所以需要使用-A指定所以namespace)
参考:
https://kubernetes.io/zh-cn/docs/reference/kubectl/
解题:
kubectl config use-context k8s
kubectl top pod -A -l name=cpu-user
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这样的,因为1颗CPU等于1000m
注意要用">>"而不是">"
echo "coredns-54d67798b7-hl8xc" >> /opt/KUTR00401/KUTR00401.txt
# 其他解法:
kubectl get pods -A --show-labels
kubectl top pods -A -l name=cpu-user --sort-by="cpu"
echo "[podname]" >> /opt/KUTR00401/KUTR00401.txt
14.监控Pod日志(5)
中文解释:
监控名为foobar的Pod的日志,并过滤出具有unable-access-website信息的行,然后将写入到 /opt/KUTR00101/foobar
参考:
https://kubernetes.io/zh-cn/docs/reference/kubectl/
解题:
kubectl config use-context k8s
kubectl logs foobar|grep 'unable-access-website' >> /opt/KUTR00101/foobar
15.CSI & PersistentVolumeClaim(7)
中文翻译:
创建一个名字为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/docs/tasks/configure-pod-container/configure-persistent-volume-storage/
https://kubernetes.io/zh-cn/docs/concepts/storage/persistent-volumes/
解题:
# 创建PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pv-volume
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 10Mi
storageClassName: csi-hostpath-sc
# 创建Pod
apiVersion: v1
kind: Pod
metadata:
name: web-server
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: pv-volume # 名字不是必须和pvc一直,也可以为my-volume
volumes:
- name: pv-volume # 名字不是必须和pvc一直,也可以为my-volume
persistentVolumeClaim:
claimName: pv-volume
# 扩容
# 方式一patch命令:
kubectl patch pvc pv-volume -p '{"spec":{"resources":{"requests":{"storage": "70Mi"}}}}' --record
# 方式二edit:
kubectl edit pvc pv-volume
# 记录修改记录,需要加--record参数或--save-config
kubectl edit pvc pv-volume --record
kubectl edit pvc pv-volume --save-config
将两处10Mi都改为70Mi,如果是nfs,会因为不支持动态扩容而失败。
edit完需要稍等一会儿,容量才会变为70Mi
16.Sidecar(7)
中文解释:
添加一个名为busybox且镜像为busybox的sidecar到一个已经存在的名为legacy-app的Pod上,这个sidecar的启动命令为 /bin/sh, -c, 'tail -n+1 -f /var/log/legacy-app.log'
。
并且这个sidecar和原有的镜像挂载一个名为logs的volume,挂载的目录为/var/log/
。
参考:
https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/configure-volume-storage/
https://kubernetes.io/zh-cn/docs/concepts/cluster-administration/logging/
解题:
首先将legacy-app的Pod的yaml导出,大致如下:
kubectl get pod legacy-app -o yaml > c-sidecar.yaml
apiVersion: v1
kind: Pod
metadata:
name: legacy-app
spec:
containers:
- name: count
image: busybox
args:
- /bin/sh
- -c
- >
i=0;
while true;
do
echo "$(date) INFO $i" >> /var/log/legacy-ap.log;
i=$((i+1));
sleep 1;
done
# 在此yaml中添加sidecar和volume
vim c-sidecar.yaml
apiVersion: v1
kind: Pod
metadata:
name: legacy-app
spec:
containers:
- name: count
image: busybox
args:
- /bin/sh
- -c
- >
i=0;
while true;
do
echo "$(date) INFO $i" >> /var/log/legacy-ap.log;
i=$((i+1));
sleep 1;
done
# 加上下面部分
volumeMounts:
- name: logs
mountPath: /var/log
- name: busybox
image: busybox
args: [/bin/sh, -c, 'tail -n+1 -f /var/log/legacy-ap.log']
volumeMounts:
- name: logs
mountPath: /var/log
volumes:
- name: logs
emptyDir: {}
kubectl delete -f c-sidecar.yaml
kubectl create -f c-sidecar.yaml
# 检查
[root@k8smaster /opt/cka]# kubectl logs legacy-app -c busybox
17.1集群故障排查——kubelet故障(13)
中文解释:
一个名为wk8s-node-0的节点状态为NotReady,让其他恢复至正常状态,并确认所有的更改开机自动完成
解题:
# 检查wk8s-node-0 kubelet服务状态
ssh wk8s-node-0
sudo su -
systemctl status kubelet
systemctl start kubelet
systemctl enable kubelet
其实这题没这么简单,一般启动kubelet后大概率是启动失败的
可能的原因:
1.kubelet二进制文件路径不对,which kubelet后和服务启动文件kubelet systemd service做个对比,看是否是这个原因
2.service文件路径和它启动的路径不一致,在启动目录下找不到service文件,可以全局搜下并做个软链接。
3.其他原因。
# 再次检查wk8s-node-0是否在ready
ssh master01
kubectl get nodes
17.2集群故障排查——主节点故障(13)
这是之前的考题,现在应该没有这个题了。
参考:
https://kubernetes.io/zh/docs/tasks/configure-pod-container/static-pod/
四.可能会考的题
题目1:nginx打标签
labels key1=rw01 key2=rw02
思路:
label pod/deployment
参考:
https://kubernetes.io/zh-cn/docs/concepts/cluster-administration/manage-deployment/#using-labels-effectively
步骤:
kubectl run hwcka-005 --image=nginx --labels key1=rw01,key2=rw02
kubectl apply -f name.yaml
题目2:deployment版本升级回退
1.创建deployment版本nginx
2.修改镜像1.12.0,并记录这个更新
3.回退到上个版本
思路:
1.deployment rollout
2.--record
参考:
https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/deployment/
https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/deployment/#rolling-back-a-deployment
步骤:
kubectl create deployment hwcka-07 --image=nginx --dry-run=client -o yaml > 7.yaml
kubectl apply -f 7.yaml
kubectl edit deployments.apps hwcka-07 --record # 修改nginx镜像为nginx:1.12.0
kubectl rollout history deployment hwcka-07
kubectl rollout undo deployment hwcka-07 --to-revision=1
# 回退前和回退后都需要edit查看下image的版本