nginx跨域
#!/bin/bash LOG_DIR="/path/to/kownstreaming/logs" RETENTION_DAYS=7 # 获取当前日期 CURRENT_DATE=$(date +%Y-%m-%d) # 计算要删除的日期 DELETE_DATE=$(date -d "$CURRENT_DATE - $RETENTION_DAYS days" +%Y-%m-%d) # 删除早于删除日期的日志文件 find "$LOG_DIR" -type f -name "*.log" -mtime +$RETENTION_DAYS -exec rm -f {} \; echo "已删除 $RETENTION_DAYS 天前的日志文件"
if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' '*' always; add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE' always; add_header 'Access-Control-Allow-Headers' '*' always; add_header 'Access-Control-Max-Age' 1728000 always; add_header 'Content-Length' 0; add_header 'Content-Type' 'text/plain; charset=utf-8'; return 204;
k8s常见故障排查-51cto课程
1.目录
1章—k8s之连接异常(集群故障)
2章—k8s之通信异常(网络故障)
3章—k8s之内部异常(节点异常)
4章—k8s之应用故障(应用异常)
第一章 k8s之连接异常(集群故障)
1.k8s集群的能力供应站(pod)的详解
Pod是k8s中的最小调度单元,当指派容器时,容器实际上并不会指派到物理硬件上,容器会被分配到一个pod里,pod代表集群上正在运行的一个进程,一个pod封装一个容器(也可以封装多个容器),pod里的容器共享存储、网络等。也就是说,应该把整个pod看作虚拟机,然后每个容器相当于运行在虚拟机的进程。
示意图如下:
2.k8s集群中的pod的用途
运行单个容器的pod:
Pod里封装单个容器,k8s直接管理pod,pod调度到哪个物理节点,pod里的容器就跟随pod调度到哪个节点。
运行多个协同工作的容器的pod:
Pod里可以运行多个容器,如初始化容器、业务容器,这些容器之间的互相作用,共享资源。
3.k8s集群中pod一般哪些方面容易出现问题
1).k8s资源配置错误
例如部署deployment和statefuset时,资源清单书写有问题,导致pod无法正常创建。
2).代码问题
应用程序代码在容器启动后失败,那就需要通过检查代码找错误。
3).网络问题
网络插件部署有问题,导致pod启动之后无法相互通信。
4).存储问题
Pod挂载存储,但是需要共享的存储连接不上导致pod启动异常。
4.pod的状态为ContainerCreating状态的故障
一般原因是:后面node节点故障不能工作或网络ip已被注册、也可能是没有挂载到pv的存储卷。
诊断方法流程:
# kubectl get pod -o wide |grep pod名 #查看pod在哪个节点
# kubectl describe pod pod名 #查看pod的详细信息
# kubectl logs pod pod名 [-c 容器名] #查看pod的日志或某个容器日志
# systemctl status kubelet #查看pod所在节点的kubelet服务状态
# tailf /…/kubelet.xx.log #查看pod所在节点的kubelet服务日志
1).后面node节点故障不能工作的处理:
创建一个别的新的pod,看能否运行在该node1节点上,如果其他pod能创建在node1节点,说明可能只是无法创建的pod本身有问题,如果所有其他pod都无法在node1节点创建(所有在node节点创建的pod状态都是:ContainerCreating),说明node1节点有问题。
如果已经确定某个node节点有问题不能使用时,需要将node节点重置后重新加入集群:
步骤如下:
(1).先将该node节点上正在运行的pod驱逐到其他node节点
(2).#kubeadm reset 在故障node节点上重置k8s集群,执行完相当于这个节点所有东西都清空了(操作需要慎重,将pod全部驱逐后再操作)
(3).#systemctl stop kueblet
(4).#systemctl stop docker
(5).#rm -rf /var/lib/kubelet/*
(6).#rm -rf /etc/cni/
(7).#ifconfig cni0 down
(8).#ifconfig flannel.1 down (如果安装的是flannel网络)
(9).#ip link delete cni0
(10).#ip link delete flannel.1
(11).#systemctl start docker
(12).#systemctl start kubelet
(13)#kubeadmin join … 把node节点重新加入加入k8s集群
视频步骤如下:
2).也可能是没有挂载到pv的存储卷的处理:
查看pv绑定的情况和需求。
步骤如下:
# kubectl get pod -o wide |grep pod名 #查看pod所在node节点
# kubectl describe pod pod名 #查看pod的详细信息
若后台存储是ceph相关报错,可能是没有安装相关程序
# yum -y install ceph-common #再相应节点安装ceph相关程序
安装ceph-common程序后,删除pod: test-ceph后重新运行pod,再查看状态。
如后台存储是nfs或其他,则查看相关服务是否正常,是否能手动正常挂载。
3).重要错误截图:
安装ceph-common程序后,删除pod: test-ceph后重新运行pod,再查看状态。
处理思路总结:
查看日志时候也可 -c 容器名
5.pod的状态为pending状态的故障
Pending状态:是挂起状态。表示创建的pod找不到可以运行它的物理节点,不能调度到相应的节点上运行。
1).从两个层面分析问题:
(1).物理节点层面分析:
查看节点资源使用情况: 如free -m查看内存、top查看cpu使用率、df -h查看磁盘使用情况,这样可以定位节点资源情况,判断是不是节点有问题。
查看节点污点:#kubectl describe node node节点名字 ,如果节点定义了污点,那么pod不能容忍污点,就会调度失败,可以在yaml文件里定义容忍度,则可以试下调度。
(2).pod本身分析:
在定义pod时,如果指定了nodeName或nodeSelector选择器是不存在的,那么也会调度失败。
在定义pod时,如果定义的资源请求比较大,导致物理节点资源不够也是不会调度的。
2).查看node节点是否有污点的方法:
# kubectl describe node node名称 |grep Taints
Taints xxx (看有没有,没有就是空)
重要视频截图:
7.pod的状态为ImagePullBackOff状态的故障
1).ImagePullBackOff状态的原因:
(1).拉取镜像时间长导致超时.
(2).配置的镜像有错误:如镜像名字不存在等.
(3).配置的镜像无法访问:如网络限制无法访问hub上的镜像.
(4).配置的私有镜像仓库参数错误:如imagePullSecret没有配置或者配置错误.
(5).dockerfile打包的镜像不可用.
2).ImagePullBackOff状态的排查思路:
# kubectl get pod -o wide 查看pod在哪个节点
# kubectl describe pod pod名 查看pod的详细信息
查看到时镜像拉不下来问题时,可以手动拉一下看看
重要视频截图如下:
8.pod的状态为CrashLoopBackOff状态的故障
1).CrashLoopBackOff状态的原因:
pod里面的容器退出、多次重启或准备删除。
k8s中的pod正常运行,但是里面的容器可能退出或者多次重启或者准备删除,导致出现这个状态,这个状态具有偶发性,可能上一步还是running状态,但是突然就变成CrashLoopBackOff状态了。
2).CrashLoopBackOff状态的排查思路:
# kubectl logs pod名 [-c 容器名] 查看pod日志,代码或环境变量
查看日志,查看构建镜像用的代码是否有问题,如果代码没问题,再看环境变量是否有问题。
# kubectl describe pod pod名 查看pod的详细信息,limit资源限制
查看yaml文件里的limit资源限制,是否跟资源限制有关。
9.pod的状态为Error状态的故障
原因分析:
(1).依赖的configmap、secret、pv、storageClass等不存在.
(2).请求的资源超过了管理员设置的限制,比如超过了limits等.
(3).无法操作集群内的资源,比如:开启rbac后,需要为serviceAccount配置权限.
排查思路:
# kubectl describe pod pod名 #查看pod详细信息
# kubectl logs pod pod名 [-c 容器名] #查看pod或容器日志
# kubectl -f -u kubelet #查看kubelet服务日志
# tail -f /var/log/messages #查看主机日志
重要截图如下:
10.pod的状态为Terminating或Unknown状态的故障
原因分析:
Terminating故障是因为容器里的应用挂了或node节点失联。
从k8s1.5开始,k8s不会因为node失联而删除其上正在运行的pod,而是将其标记为Terminating或Unknown状态。
相应删除这些状态的pod有4种方法:
1).手动删除node节点(确定节点不能用再删) # kubectldelete node node节点名称
2).恢复正常可选择性删除
若node节点恢复正常,kubelet会重新跟kube-apiserver通信确认这些pod的期待状态,进而再决定删除或者继续运行这些pod,如果删除可以通过# kubectl deletepod pod名 –grace-period=0 --force强制删除
3).使用参数重建容器 (了解)
4).自动重建pod (了解)
注意:节点确实不能用了再删node节点。删除node节点前,先将部署的pod服务驱逐到其他node节点。
如果node节点已经删除了,但是使用命令kubectl getpod查看时该node节点上还显示有pod,呈现terminating状态,可以用命令: # kubectl delete pod pod名 –grace-period --force 强制删除该pod。
解决思路:
1).# systemctl status kubectl #查看kubectl状态
2).# kubectl get node #查看节点状态和节点资源是否还充足,df -h free -m
3).# kubectl get pod -n kube-system |grep apiserver #查看apiserver是否异常
4).查看kubelet日志,查看相应node节点的kubelet错误日志
重要截图如下:
11.pod的健康检查(存活性探测和就绪性探测)
1).为什么需要探针?
如果没有探针,k8s无法知道应用是否还活着,只要pod还在运行,k8s则认为容器时健康的。但实际上,pod虽然运行了,但里面容器中的应用可能还没提供服务,那就需要做健康检查,健康检查就需要探针。
2).常见的探针有以下几种:
(1).httpGet
对容器的ip地址(指定的端口和路径)执行http get请求,如果探测器收到响应,并且响应码是2xx,则认为探测成功。如果服务器没有响应或者返回错误响应码则说明探测失败,容器将重启。
(2).tcpSocket
探针与容器指定端口建立tcp连接,如果连接建立则探测成功,否则探测失败容器重启。
(3).exec
在容器内执行任意命令,并检查命令退出状态码,如果状态码为0,则探测成功,否则探测失败容器重启。
3).健康检查的两种方式: (livenessProbe和ReadinessProbe)
(1).LivenessProbe(存活探测):
探测pod里的容器是否启动成功,如果pod里的容器启动成功那pod的状态就是Running.
(2).ReadinessProbe(就绪探测):
Pod是Running的前提下,看pod里容器部署的应用是否就绪,是否可以对外提供服务,如果应用正常,可以接受客户端的请求,则ready是就绪的。
4).LivenessProbe和ReadinessProbe区别:
LivenessProbe决定是否重启容器、ReadinessProbe主要来确定容器是否已经就绪,只有当pod里的容器部署的应用都处于就绪状态,才会将请求转发给容器。
重要截图如下: 容器启动后15后再探测,否认容器还没起来呢就探测,肯定是探测失败的。
12.token验证问题:(添加节点token过期)
token过期的处理,如下截图
13.kubectl执行异常,无权限连接到k8s问题定位
kubectl执行异常的排查,如下截图:
14.总结pod的各种状态
第二章.k8s之通信异常(网络故障)
1.k8s中的网络通信类型
K8s中的网络是非常重要的,整个k8s集群的通信调度都是通过网络插件实现的。
网络通信主要有以下几种:
1).容器间的通信: 同一个pod内的多个容器间的通信。
2).pod通信: 从一个pod的ip到另一个pod的ip。
3).pod与service通信: pod的ip到cluster ip。
4).外部通信: service与集群外部客户端的通信。
2.k8s中的网络插件和各自特点
1).常用的网络插件:calico、flannel、canel
(1).calico 既能够提供ip,又能够配置网络策略
提供ip: 给pod提供ip地址
配置网络策略:指定某一个pod允许哪一个网段的ip访问,限制哪个网段能访问,哪个不能.
(2).flannel: 也能够提供ip,但不能配置网络策略。
(3).canel: 既能提供ip,也能够配置网络策略(是calico和flannel的结合)
2).网络插件哪个性能好?
calico和flannel的性能差不多,因为flannel支持很多种后端模式,默认是vxlan叠加的网络模式,还有一个Director routing(直接路由模式)、host-gw(以宿主机充当网关)模式,
calico的优势在于能配置网络策略。如果论性能,flannel的直接路由模式和calico性能差不多。
重要截图:
3.pod网络连接超时的几种情况和排查思路
1).pod网络连接超时的几种情况:
(1).pod和pod连接超时
(2).pod和虚拟主机上的服务器连接超时
(3).pod和云主机或外网连接超时
2).排查思路:
(1).pod和pod连接超时:
查看calico或flannel是否是running状态,查看日志提取重要信息。(网络层面)
(2).pod和虚拟主机上的服务器连接超时:
检查pod网络,测试pod是否可以ping通同网段其他pod的ip。(pod层面)
(3).pod和外网连接超时:
检查物理网络,测试ping www.baidu.com或其他pod的ip,可以抓包测试有无异常,通过抓包修改内核参数(物理机层面)
当pod内部ping不通外网,如:www.baidu.com
解题思路: centos系统中
查看/etc/sys/net/bridge/bridge-nf-call-iptables的值是不是1,若不是则修改成1.(开启桥接模式)
当pod中连接集群之外的数据库超时:
解题思路:
(1).检查pod配置数据库地址是否正确
(2).检查网络状态,进入到容器对数据库ip地址telnet测试端口
(3).检查数据库是不是拒绝pod网段ip访问,是否已经开放了访问权限
(4).检查是否出现慢查询和数据库连接数问题
重要截图如下:
上面1: 是表示开启桥接模式。
4.访问pod的ip:端口或者service时候显示超时的故障排查(可以到宿主机上抓包查看)
处理思路和故障现象:
用tcpdump在相应宿主机上抓包,可以显示发送了大量重复的SYN数据包,但是没有收到ack.
诊断: 检查ipv4是否开启. #vim /etc/sysctl.conf 添加或修改: net.ipv4.ip_forward=1,sysctl -p生效
5.pod的生命周期阶段状态划分
(1).pending: 挂起状态,表示pod已经开始创建,内部的容器正在创建,包括拉取镜像、调度到node节点、可能需要一段时间。
(2).Running: 运行状态,pod成功创建并且正常调度到node节点,里面的容器已经被创建了。
(3).Teminated: 终止状态。
重要截图如下:
6.Pod的状态是running,但是容器已经退出的几种情况
1).pod是running,容器成功exit.
2).pod是running, 容器OOM退出(内存泄露的退出),容器自启拉取,pod持续保持running.
重要截图如下:
7.coredns或者kube-dns经常重启和报错的故障
1).故障现象:
在k8s中部署服务,服务之间无法通过dns解析,coredns一直处于CrashLoopBackOff状态,查看日志,报错如下: Loop (127.0.0.1:44222 -> :53) detected for zone。
2).解决思路:
coredns主要和相关node节点的宿主机上dns文件resolv.conf打交道,会读取宿主机的/etc/resolv.conf中的nameserver内容,查询resolv.conf文件,如果里面存在本地回环,如:127.0.0.1或127.0.0.53,那么就容易造成死循环。
3).解决步骤:
(1).修改相关node节点宿主机的resolv.conf文件,将nameserver临时改成114.114.114.114;
(2).之后,编辑coredns相关的deployment的yaml文件,将副本数改为0,停止已经启动的coredns 的pod。
(3).再编辑coredns相关的deployment的yaml文件,将副本数改为2或原来的数量,这样会触发coredns重新读取系统配置,此时服务的状态为running
上述一般能解决该问题。
重要截图如下:
总结:先将宿主机的dns文件/etc/resolv.conf的dns修改,然后重建coredns的pod,新建的pod就会重新读取宿主机上的/etc/resolv.conf文件。(进入不到coredns的pod查看,可能环境有问题)
8.k8s中calico或flannel网络插件的pod会挂载相应node节点宿主机本地dns文件案例
网络插件pod和coredns的pod里会挂载宿主机的dns文件,应用pod不会。
# cat /etc/resolv.conf #查看宿主机本地的dns文件
# Generated by NetworkManager
nameserver 192.168.5.200
# kubectl get pod -n kube-system -o wide |grep calico #查看calico网络的pod(也可flannel)
calico-kube-controllers-84445dd79f-7wjlk 1/1 Running 3 182d 100.80.33.27 dev-core-master-6-51 <none> <none>
calico-node-6rx6m 1/1 Running 10 132d 192.168.6.76 dev-core-node-6-76 <none> <none>
calico-node-84hbx 1/1 Running 6 286d 192.168.6.51 dev-core-master-6-51 <none> <none>
calico-node-8mcv7 1/1 Running 7 286d 192.168.6.52 dev-core-master-6-52 <none> <none>
…
# kubectl exec -it calico-node-84hbx bash -n kube-system -- cat /etc/resolv.conf #查看网络插件pod的dns文件
nameserver 192.168.5.200
# kubectl get pod -n dev00-th-ffm -o wide |grep wms-boss
wms-boss-api-5b547957fc-hpdcv 1/1 Running 0 27h 100.105.200.204 dev-ard-node-7-93 <none> <none>
wms-boss-ui-b85d49595-7h27c 1/1 Running 0 27h 100.105.200.226 dev-ard-node-7-93 <none> <none>
# kubectl exec -it wms-boss-api-5b547957fc-hpdcv -n dev00-th-ffm -- cat /etc/resolv.conf |grep nameserver #普通pod
nameserver 10.96.0.10
# kubectl exec -it wms-boss-ui-b85d49595-7h27c -n dev00-th-ffm -- cat /etc/resolv.conf |grep nameserver
nameserver 10.96.0.10
coredns的pod也会挂载本地的/etc/resolv.conf文件,看看这个文件里的nameserver是不是114.114.114.114
(进入不到coredns的pod查看,可能环境有问题)
9.pod之间,跨主机通信中断的故障
k8s中pod有调度到node1节点,有调度到node2节点,pod之间跨主机通信中断的错误.
1).故障现象:
在k8s集群部署pod后,pod之间无法跨节点访问。登录到一个node节点的pod,ping另一个node节点的pod,报错:无路由,No route to host。
2).排查思路:
查看网络插件如calico或flannel插件的pod日志,如果发下pod网段和物理机网段重合,则需要修改pod网段的ip地址,不能让pod网段的ip和宿主机网段的ip网段重合。
3).若pod网段和物理机网段重合,导致的网络故障,解决步骤如下:
(1).# kubectl get ippool default-ipv4-ippool -o yaml> default-ipv4-ippool.yaml #导出yaml
(上面default-ipv4-ippool是集群中默认的名字)
(2).# vim default-ipv4-ippool.yaml #修改pod的网段为新的和宿主机不同的网段
………
spec:
blockSize: 26
cidr: 100.64.0.0/10
ipipMode: Always
(3).# kubectl delete -f default-ipv4-ippool.yaml #删除现有ip pool
(4).# kubectl apply -f default-ipv4-ippool.yaml #创建新的ip pool
(5)然后依次删除calico或flannel网络pod
重要截图如下:
10.k8s集群内部域名解析困难故障
1). k8s的pod容器内部无法解析集群外的域名
安装coredns后,容器内部无法解析集群外的域名。
解决思路:
查看coredns是否正常运行
查看coredns日志
查看coredns会挂载本地的/etc/resolv.conf文件,看看这个文件里的nameserver是不是114.114.114.114
2).公司的k8s的基础服务mysql或redis是基于域名访问的,但是应用pod访问基础服务的域名时报错dns超时相关的故障
解决思路:
(1).出现k8s内部域名解析问题,最多的就是查看pod内部resolv.conf文件是否有问题,需要先登录pod查看resolv.conf有没有问题。
(2).如果pod的内部resov.conf文件没有问题, 尝试ping 基础服务的全域名(如:redis.svc.cluster.local),可能是跨命名空间等,需要用全域名,如果全域名能ping通,在yaml文件里配置域名为全域名地址。
重要截图:
第三章 k8s之内部异常(节点异常)
1.k8s集群节点notready状态的几种情况
情况1: 刚安装好k8s集群的node节点notready
现象:node节点notready,查看coredns的pod状态为pending
可能原因: 可能是没有部署网络插件(calico或flannel),需要安装网络插件
情况2: k8s运行一段时间后,node节点notready
可能原因:
(1).查看node节点宿主机的磁盘情况、内存情况、cpu情况,查看资源是否足够
(2).查看node节点的kubelet服务是否正常
如果node节点的kubelet服务不正常,也会显示notready状态
(3).查看node节点的详细信息排查原因
# kubectl describe node node名
重要截图如下:
2.pod的几种调度方式
当我们发送请求创建pod,调度器就会把pod调度到合适的物理节点,大致分为以下过程:
1).Scheduler根据预选策略和优选函数,选择合适node节点调度。
a).预选阶段(Predicates):过滤节点,调度器用一组规则过滤掉不符合要求的node节点,比如pod设置了资源的request,那么可用资源比pod需要资源少的主机显然就会被过滤掉
b).优选阶段(Priorities):为节点的优先级打分,将上一阶段过滤出来的node列表进行打分,调度器会考虑一些整体的优化策略,比如把deployment控制的多个pod 副本尽量分布到不同的主机上,使用最低负载的主机等等策略
2).可以通过定义nodeName(一般不经过调度器,使用很少)或nodeSelector进行调度。
3).可以根据节点亲和性进行调度。
nodeAffinity: 节点亲和性,与nodeSelector作用一样,但相比更灵活,满足更多条件:
-匹配有更多的逻辑组合,不只是字符串的完全相等。
-调度分为软策略和硬策略,而不是硬性要求。
a).硬(required): 必须满足
b).软(preferred):尝试满足,但不保证
操作符:In、NotIn、Exists、DoesNotExist、Gt、Lt (操作符支持这些,标签选择不一定等于,也可是包含或其他等操作)
节点选择器2:nodeAffinity分两种:硬性需求:必须满足。软性需求:尝试满足,但不保证。
硬性需求应用场景: 创建pod资源或其他资源时候,yaml文件里指定在打了具体标签的node节点上,就必须只能在该node节点上创建资源,如果node节点上没有符合的标签,就不会被调度。所有node节点都不满足,就都不调度创建资源。
软性需求应用场景: 创建pod资源或其他资源时候,yaml文件里指定在打了具体标签的node节点上,则尽可能在该node节点上创建资源,如果所有node节点上都没有符合的标签,就再按其他调度算法创建在相应的node节点上
注意:pod在调度的时候会找到一个合适的节点,所以如果节点资源不足;pod定义了指定的节点,但是指定的节点出现故障;或者pod定义了亲和性,但是节点没有满足的条件,都会导致调度失败。
解释:亲和性和反亲和性概念:
pod 亲和性(podAffinity)主要解决pod可以和哪些pod部署在同一个拓扑域中的问题(其中拓扑域用主机标签实现,可以是单个主机,也可以是多个主机组成的 cluster、zone 等等),而 pod 反亲和性主要是解决 pod 不能和哪些pod部署在同一个拓扑域中的问题,它们都是处理的 pod 与pod 之间的关系,比如一个Pod在一个节点上了,那么我这个也得在这个节点,或者你这个Pod在节点上了,那么我就不想和你待在同一个节点上。
重要截图:
3.k8s中一个node节点突然断电,恢复后上面的pod无法启动故障
1).故障现象:
k8s中pod一直正常运行,偶尔一次node节点突然断电,恢复之后,发现pod无法启动
报错日志: node节点包含污点,但是没有配置容忍度
2).排查思路:
(1).首先查看node节点是否有污点存在
当node节点宕机,k8s会自动为这个节点加上不可调度污点。有可能开机后,污点没有自动消失,导致有污点,让pod调度不过去。
(2).检查node节点的主机名是否更改,主机名更改后连接不到集群,也会添加污点
如果初始化后的集群的某个node节点的主机名更改后,重启kubelet服务后,该node节点就注册不到k8s集群了,这是该node节点也显示notready状态。即使将该node节点和master的hosts解析改成新主机名,也不行,kubelet还是按最初初始化集群时定义的主机名注册,除非再将node节点的主机名改成原来初始化时候的主机名才能恢复。所以,初始化时候一般要定义好主机名,后面不要随意修改主机名。
(3).检查node节点的kubelet服务是否正常
如果node节点的kubelet服务不正常,也会使node节点notready状态。
注意:只要node节点的状态为notready状态,k8s就会给该node节点打上一个污点,如果node节点恢复了,污点一般会自动消失,但也有可能没消失,这时候可以手动删除污点或看看别的原因。
3).解决思路:
(1).在相应node节点查看kubelet服务状态,如果不行,重启kubelet服务。
(2).将相应node节点上的污点手动删除。
# kubectl taint node node名 污点-
重要截图如下:
4.常见的k8s调度失败的内置污点
重要截图:
5.pod超过节点资源限制
1).pod数量太多超过物理节点限制
故障现象: 监控系统大量报警,大量pod在批量重启,还有pod一直处于pending状态
处理思路:
(1).查看pod详细信息,看有没有报错,污点:xx:NoExecute。(当pod数量太多不可调度时也会自动加污点)
# kubectl describe pod pod名
(2).查看相应node节点详细信息,有没有报错: OOM内存泄露。
# kubectl describe node node名
(3).到相应node节点,查看磁盘、cpu、内存等资源情况是否足够。 #df -h free top
(4).到相应node节点查看kubelet的状态,看有没有报错。
# systemctl status kubelet
(5).查看相应node节点数量是否超出了默认的110个
# kubectl get pod | wc -l |grep node名
当node节点上pod数量太多,超过默认110个后,无法再运行pod的处理:
(1).给相应node节点增加资源,磁盘/内存/cpu,在kubelet服务中增加启动参数,调大node节点运行pod数量,如:--max-pods=300
(2).增加node节点数量。
2).pod资源超过物理节点资源限制
故障现象: 在k8s中部署pod,发现一直处于pending状态
处理思路:
(1).查看pod详细信息,看有没有污点报错,在查看有没有资源限制报错、内存/cpu/磁盘等.
# kubectl describe pod pod名
(2).查看pod的yaml文件中limit相关的资源限制,看定义资源范围node节点是否能满足。
解决方法:
(1).扩容相应的node宿主机节点的资源。
(2).增加一个新的node节点。
(3).缩小部署的pod相关的limit的资源限制,资源参数改小一点。
重要截图:
6.pod 的自动扩容和缩容方法
重要截图如下:
第四章. k8s之应用故障(应用异常)
1.k8s中的service概念和pod的匹配情况
重要截图如下:
2.k8s中service访问异常的常见问题
1).service没有正确匹配到后端的pod标签
(1).service匹配的label标签没有匹配上后面的pod(导致访问不到界面)
(2).service匹配的label标签匹配到后面其他错误的pod(导致访问的别的界面)
2).kube-proxy服务故障导致service无法提供服务
kube-proxy是什么:
Service为一组相同的pod提供了统一的入口,起到负载均衡的效果。Service具有这样的功能,真是kube-proxy的功劳,kube-proxy是一个代理,安装在每一个k8s节点,当我们暴露一个service的时候,kube-proxy会在iptables中追加一些规则,为我们实现路由与负载均衡的功能。
kube-proxy的两种转发规则: iptables(DNAT规则转发到后台pod)和ipvs
故障现象:
service的标签选择器正常,pod也正常,但是访问service的ip时,还是代理不到pod,就需要检查kube-proxy组件。
解决思路:
(1).查看相应node节点kube-proxy服务是否正常。
(2).查看相应node节点上kube-proxy相关日志,有没有报错,资源不足,如:cpu/内存/磁盘
(3)查看相应node节点上系统日志中有没有关于kube-proxy的日志报错.
# cat /var/log/messages[kube-proxy] |grep kube-proxy或 kubectl logs pod名 |grep kube-proxy
解决方法:
(1).扩容节点资源,增加服务器或者虚拟机的cpu和内存。
(2).修改kube-proxy的yaml中的limit资源限制,限制可使用的cpu和内存。
重要截图如下:
3.k8s中pod删除失败的解决
故障现象:在k8s中,可能会产生很多垃圾pod,也就是有些pod虽然是running状态,可是其所调度到的k8s的node节点已经从k8s集群删除了,但是pod还是在这个node上,没有被驱逐,针对这种情况就需要把pod删除。
故障问题:删除pod时候,pod一直处于terminate状态,很长时间无法删除。
解决方案:
可以通过如下方法添加参数强制删除pod,--force --grace-period=0, grace-period表示过渡存活期,默认30s,在删除pod之前运行pod慢慢终止其上的容器进程,从而优雅退出,0表示立即终止pod.
# kubectl delete pod pod名 --force --grace-period=0
重要截图:
4.k8s中命名空间的强制删除
虽然pod可以强制删除,但是可能命名空间还是处于terminate状态,无法删除。
解决方法:
(1).强制删除命名空间
# kubectl delete ns 命名空间 --force --grace-period=0
(2).获取namespace的json文件,删除相关内容
# kubectl get ns 命名空间 -o json > /root/xx.json
# vim /root/xx.json
删除spec下的”finalizers”:[ 和”kubernetes” 内容
调用api-server接口进行删除:
打开一个新的终端,或者把下面的命令放到后台执行: # kubectl proxy --port=8081
调用接口删除:
# curl -k -H “Content-Type: application/json” -X PUT --data-binary @xx.json
http://127.0.0.1:8081/api/v1/namespaces/命名空间名/finalize
如果kubectl get ns 命名空间 -o json的结果中”spec”:{}中为空了,但是metadata部分还有finalizers字段,需要将里面相关finalizers的内容也删除。
# kubectl edit ns 命名空间
进去后,直接删除相关finalizers的内容即可,保存退出后,出入Terminating状态的ns便没有了。
重要截图:
5.k8s中跨主机连接不通(pod和pod)
1).pause容器概念:
Pause容器,又叫Infra容器,Pause容器对应的镜像属于k8s平台的一部分,除了pause容器,每个pod还包含一个或者多个紧密相关的用户业务容器。
2).pause容器的作用:
(1).pod里的多个业务容器共享pause容器的ip,共享pause容器挂载的volume,这样简化了业务容器之间的通信问题,也解决了容器之间的问题件共享问题。
(2).pod中的容器共享同一个ip地址。故同一个pod中container可以做到直接通过localhost直接通信。
3).同一个节点多个pod通信机制:
pause容器启动之前,会为容器创建虚拟一对ethernet接口,一个保留在宿主机vethxxx(插在网桥上),一个保留在容器网络命名空间内,并重命名为eth0。两个虚拟接口的两端,从一端进入,从另一端出来。任何pod连接到该网桥的pod都可以收发数据。
4).跨节点pod通信机制:
跨节点pod通信,相当于创建一个整个集群公用的 [网桥] ,然后把集群中所有的pod连接起来,就可以通信了。
5).跨主机连接不通(pod和pod)的故障排查方法:
(1).排查宿主机网络是否正常,在宿主机上ping www.baidu.com,或tcpdump抓包看是否丢包.
(2).查看k8s中的网络插件是否正常,查看网络组件calico或flannel的日志。
重要截图:
https://www.qikqiak.com/k3s/logging/efk/
}
if ($request_method ~* '(GET|POST|DELETE|PUT)') { add_header 'Access-Control-Allow-Origin' '*' always; }
1 2 3 4 | location / { return 200 "200" ; add_header Content-Type text /plain ; } |
1 2 3 4 5 6 7 8 9 | pvcreate /dev/sdb vgcreate vg_data0 -s 32m /dev/sdb lvcreate -l 98%VG -n lv02 vg_data0 mkfs.xfs /dev/vg_data0/lv02 mkdir /data cat >> /etc/fstab <<EOF /dev/vg_data0/lv02 /data xfs defaults 0 0 EOF mount /datalive :.cid.b2705c07a5efd070 |
curl -I --resolve a.com:443: ip https://a.com
嗯,这个命令,看响应Header里有没有access-control-allow系列就可以
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | < html > < head > < title >URL 管理页面</ title > </ head > < body > < h1 >URL 管理页面</ h1 > < ul > < li >< a href="https://www.example.com">Example Website</ a ></ li > < li >< a href="https://www.openai.com">OpenAI</ a ></ li > < li >< a href="https://www.google.com">Google</ a ></ li > </ ul > </ body > </ html > |
pvcreate /dev/vdb vgextend centos /dev/vdb lvextend -L +49G /dev/centos/root xfs_growfs /dev/centos/root
#!/bin/bash # 主机和端口信息 HOST="your-hostname-or-ip" PORT=your-port-number # 检查端口通连通性 check_port_connectivity() { echo "Testing connectivity to $HOST on port $PORT..." # 使用nc命令尝试连接到指定主机和端口 nc -z -v -w 5 $HOST $PORT # 检查返回状态码 if [ $? -eq 0 ]; then echo "Port $PORT on $HOST is accessible." else echo "Port $PORT on $HOST is not accessible." >> result.txt fi } # 主函数 main() { check_port_connectivity } main
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构