linux怎么查看本机内存大小
271
2022-09-10
k8s学习-问题诊断
诊断问题的第一步是对问题做个分类,该问题是Pod的问题、Deployment(StatefulSet/DaemonSet)控制器的问题,还是Service的问题
Debugging Pods
#任何时候,当你怀疑Pod碰到问题时,先看一下Pod的完整描述。执行如下语句可以查看到Pod最新的状态以及最近关联的事件:kubectl describe pods ${POD_NAME}##############输出结果#####################Name: nginx-deployment-5754944d6c-d8hs8Namespace: defaultPriority: 0Node: demo-worker002/172.17.216.82Start Time: Wed, 02 Oct 2019 22:36:19 +0800Labels: app=nginx pod-template-hash=5754944d6cAnnotations: cni.projectcalico.org/podIP: 192.168.15.129/32Status: RunningIP: 192.168.15.129Controlled By: ReplicaSet/nginx-deployment-5754944d6cContainers: nginx: Container ID: docker://70b70667e082d6b4cbc7ab7a5fba33c2fa93509e08794658fde9ad9ac04a0327 Image: nginx:1.7.9 Image ID: docker-pullable://nginx@sha256:e3456c851a152494c3e4ff5fcc26f240206abac0c9d794affb40e0714846c451 Port: 80/TCP Host Port: 0/TCP State: Running Started: Wed, 02 Oct 2019 22:36:22 +0800 Ready: True Restart Count: 0 Environment:
查看Pod中容器的状态:是否所有的容器都处于 Running 状态?是否近期有重启过?根据Pod/容器的状态
Pod一直是Pending
如果 Pod 一直停留在 Pending,意味着该 Pod 不能被调度到某一个节点上。通常,这是因为集群中缺乏足够的资源或者 “合适” 的资源。在上述 kubectl describe... 命令的输出中的 Events 字段,会有对应的事件描述为什么 Pod 不能调度到节点上。可能的原因有:
Type Reason Age From Message---- ------ ---- ---- -------Warning FailedScheduling
缺乏足够的资源:可能集群中的CPU或内存都已经耗尽,此时,您可以尝试:
删除某些 Pod调整Pod的资源请求向集群中添加新的节点
该Pod使用hostPort: 当Pod使用hostPort 时,该Pod可以调度的地方就比较有限了。大多数情况下,是不需要使用hostPort 的,可以尝试使用 Service 访问您的 Pod。如果您确实需要使用hostPort 时,Deployment/ReplicationController 中 replicas 副本数不能超过集群中的节点数,因为每台机器的 80 端口只有一个,任何其他端口也只有一个。如果该端口被其他程序占用了,也将导致Pod调度不成功
Pod一直是Wating
如果 Pod 停留在 Waiting 状态,此时该 Pod 已经被调度到某个节点上了,但是却不能运行。在上述 kubectl describe ... 命令的输出中,仍然注意 Events 字段的内容。最常见的 Pod 停留在 Waiting 状态的原因是抓取容器镜像失败。请检查:
容器镜像的名字是对的容器镜像已经推送到了镜像仓库中在对应的节点上手工执行docker pull
Pod已经Crash或者Unhealthy
此时通常是容器中应用程序的问题,您可以查看一下容器的日志,以诊断容器中应用程序出现了何种故障:
kubectl logs ${POD_NAME} ${CONTAINER_NAME}#如果容器之前 crash,通过上述命令查不到日志,可以尝试使用下面的命令查看上一次 crash 时的日志kubectl logs --previous ${POD_NAME} ${CONTAINER_NAME}#或者,执行容器中的命令kubectl exec ${POD_NAME} -c ${CONTAINER_NAME} -- ${CMD} ${ARG1} ${ARG2} ... ${ARGN}#示例,查看Cassandra的日志kubectl exec cassandra -- cat /var/log/cassandra/system.log
Pod处于Running状态,但是不工作
Pod已经处于Running状态了,但是不像您期望的那样工作,此时,很有可能是您的部署描述yaml文件(例如 Pod、Deployment、StatefulSet等)出现了问题,而创建时,kubectl 忽略了该错误。例如环境变量中某一个 Key 写错了,command 拼写成了 commnd 等。如果 command 拼写成了 commnd,您仍然能够使用该 yaml 文件创建工作负载,但是容器在运行时,却不会使用您原本期望的命令,而是执行了镜像中的 EntryPoint。
首先,在使用 kubectl apply -f 命令之前,可以尝试为其添加 --validate 选项,例如, kubectl apply --validate -f mypod.yaml。如果您将 command 拼写成 commnd,将看到如下错误信息
I0805 10:43:25.129850 46757 schema.go:126] unknown field: commndI0805 10:43:25.129973 46757 schema.go:129] this may be a false alarm, see Pod 和您预期的是一致的。执行命令 kubectl get pods/mypod -o yaml > mypod-on-apiserver.yaml。将输出结果与您创建 Pod 时所使用的文件做一个对比。通常通过此命令从服务器端获取到的信息比创建 Pod 时所使用的文件要多几行,这是正常的。然而,如果您创建的Pod时所示用的文件中,存在从服务器上获取的信息中没有的代码行,这可能就是问题所在了
Debugging Deployment
Deployment(或者 DaemonSet/StatefulSet/Job等),都会比较直接,他们要么可以创建 Pod,要么不可以,此时,请按照上面的方法检查 Pod 的问题。
您也可以通过 kubectl describe deployment ${DEPLOYMENT_NAME} (或者statefulset / job 等)命令查看与 Deployment 相关的事件,来发现到底出了什么问题。
Debugging Service
Service 可以为一组 Pod 提供负载均衡的功能。与Service相关,存在着几类常见问题。
#检查Service的Endpointskubectl get endpoints ${SERVICE_NAME}###############输出结果#####################NAME ENDPOINTS AGEweb-kuboard-press 192.168.144.158:80,192.168.199.135:80 70d
请确保 enpoints 的个数与您期望与该 Service 匹配的 Pod 的个数是相同的。例如,如果您使用 Deployment 部署了 web-kuboard-press,副本数为 2,此时,在输出结果的 ENDPOINTS 字段,应该有两个不同的 IP 地址。
Service中没有Endpoints
如果您的Service中没有Endpoints,请尝试使用 Service 的 label selector 查询一下是否存在 Pod
#service举例...metadata: name: myservice namespace: ns1spec: - selector: name: nginx type: frontend...#执行如下命令可以查看service所匹配的podkubectl get pods --selector=name=nginx,type=frontend -n ns1
请核对查出来的 Pod 列表是否是您期望使用的 Pod。
如果 Pod 列表是您期望的结果,但是 ENDPOINTS 还是空的,此时很可能是您没有为 Service 指定正确的端口。如果 Service 中指定的 containerPort 实际上并不存在于 Pod 中,该 Pod 不会被添加到 ENDPOINTS 列表里。请确保 Service 指定的 containerPort 在 Pod 中是可以访问的
网络转发问题
如果您的客户端可以连接上 Service,但是连接很快就被断开了,并且 endpoints 中有合适的内容,此时,有可能是 proxy 不能转发到您的 Pod 上。
请检查:
Pod是否正常工作?kubectl get pods 查看 Pod 的 restart count,并按照本文前面的步骤诊断一下 Pod 是否有问题是否可以直接连接到 Pod ?kubectl get pods -o wide 可以获得 Pod 的IP地址,从任意一个节点上执行ping
集群问题
查看集群
#查看集群中的节点来排查集群问题kubectl get nodes -o wide
检查是否所有的节点是否都在并且都处于 Ready 状态。对于您怀疑有问题的节点,可以查看节点上的详细信息,以及节点上的事件:
查看日志
可以按照如下方式查看集群各组件的日志:
容器化的集群组件
执行命令 kubectl get pods -n kube-system 查看所有 kube-system 名称空间下的容器
NAME READY STATUS RESTARTS AGEcalico-kube-controllers-65b8787765-4sbhj 1/1 Running 2 51dcalico-node-fz5t5 1/1 Running 0 7d22hcalico-node-lpd5d 1/1 Running 1 34dcalico-node-qjfqd 1/1 Running 1 10dcalico-node-zchvg 1/1 Running 6 51dcoredns-67c766df46-cbhf4 1/1 Running 1 8dcoredns-67c766df46-zthsk 1/1 Running 0 7d23heip-nfs-cluster-storage-6c9c7d46f4-lmxql 1/1 Running 0 7d23heip-nfs-nfs-on-centos-66c4fc8fbd-rd4zh 1/1 Running 0 7d5hetcd-demo-master-a-1 1/1 Running 0 8dkube-apiserver-demo-master-a-1 1/1 Running 0 8dkube-controller-manager-demo-master-a-1 1/1 Running 1 8dkube-proxy-4xz9h 1/1 Running 1 8dkube-proxy-5kljb 1/1 Running 1 8dkube-proxy-wmzlq 1/1 Running 0 7d22hkube-proxy-z55s9 1/1 Running 1 8dkube-scheduler-demo-master-a-1 1/1 Running 0 8dkuboard-7d6b54b946-xmv28 1/1 Running 0 3d3hkuboard-897b6487d-2bbmz 0/1 Terminating 6 13dmonitor-blackbox-exporter-7b97c74f8f-qcm4z 1/1 Running 0 7d4hmonitor-grafana-7d88f4b5d7-jxphs 1/1 Running 0 7d4hmonitor-kube-state-metrics-555b9cd949-hthlr 2/2 Running 0 7d4hmonitor-prometheus-6768d469b5-cmn9j 1/1 Running 0 7d4hmonitor-prometheus-node-exporter-dsfnl 1/1 Running 0 7d4hmonitor-prometheus-node-exporter-l5dbs 1/1 Running 0 7d4hmonitor-prometheus-node-exporter-t7d24 1/1 Running 0 7d4hmonitor-prometheus-node-exporter-z9ht5 1/1 Running 0 7d4h
其中,kube- 开头的 Pod 都是 Kubernetes 集群的系统级组件,calico- 开头是的 calico 网络插件,etcd- 开头的是 etcd,coredns- 开头的是 DNS 插件。
假设apiserver可能有故障,可以执行如下命令
kubectl logs -f kube-apiserver-demo-master-a-1 -n kube-system
kubelet的日志
执行命令 service kubelet status 可查看 kubelet 的运行状态,如下所示:
如果您的 kubelet 运行状态不是 active (running),那么您需要进一步查看 kubelet 的日志。
Redirecting to /bin/systemctl status kubelet.service● kubelet.service - kubelet: The Kubernetes Node Agent Loaded: loaded (/usr/lib/systemd/system/kubelet.service; enabled; vendor preset: disabled) Drop-In: /usr/lib/systemd/system/kubelet.service.d └─10-kubeadm.conf Active: active (running) since Wed 2019-10-02 22:06:37 CST; 1 weeks 1 days ago Docs: Main PID: 633 (kubelet) Tasks: 18 Memory: 213.2M CGroup: /system.slice/kubelet.service └─633 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --config=/var/lib/kubelet/config.yaml --cgroup-driver=systemd --network-plugin=cni --...#执行以下命令可以查看kubelet的日志journalctl -u kubelet
集群故障的常见原因
此处罗列了一部分 kubernetes 集群常见的故障原因以及应对办法:
可能的 Root causes:
虚拟机(或所在物理机)停机集群内部发生网络不通的情况,或者集群和用户之间网络不通Kubernetes 系统组件崩溃数据丢失,或持久化存储不可用运维人员的人为错误,例如,错误地配置了 Kubernetes 或者 Kubernetes 上部署的应用程序
具体的故障场景有:
Apiserver 所在虚拟机 shotdown 或者 apiserver 崩溃
导致的结果:
不能创建、停止、更新 Pod、Service、Deployment等已有的 Pod 和 Service 仍然能够正常工作,除非该 Pod 或 Service 需要调用 Kubernetes 的接口,例如 Kubernetes Dashboard 和 Kuboard
Apiserver 的后端数据丢失
导致的结果:
apiserver 将不能再启动已有的 Pod 和 Service 仍然能够正常工作,除非该 Pod 或 Service 需要调用 Kubernetes 的接口,例如 Kubernetes Dashboard 和 Kuboard需要手工恢复(或重建) apiserver 的数据才能启动 apiserver
其他 Master 组件崩溃
导致的结果和 apiserver 相同
个别节点(虚拟机或物理机)停机
导致的结果
该节点上的所有 Pod 不再运行
网络分片
导致的结果
区域A认为区域B中的节点已死机;区域B认为区域A中的 apiserver 已死机(假设apiserver在区域A)
kubelet 软件故障
导致的结果
已崩溃的 Kubelet 不能在该节点上再创建新的 Podkubelet 有可能错误地删除了 Pod节点被标记为unhealthyDeployment/ReplicationController 在其他节点创建新的 Pod
集群管理员的人为错误
导致的结果
丢失 Pod、Service 等丢失 apiserver 的数据用户不能访问接口等等...
应对办法
Action: 使用 IaaS 供应商提供的自动重启虚拟机的功能
应对问题:Apiserver 所在虚拟机停机或者 apiserver 崩溃应对问题:其他 Master 组件崩溃
Action: 为 apiserver + etcd 使用 IaaS 供应商提供的稳定可靠的持久化存储
应对问题: Apiserver 的后端数据丢失
Action: 使用高可用配置,
应对问题:Apiserver 所在虚拟机 shotdown 或者 apiserver 崩溃应对问题:其他 Master 组件崩溃应对问题:个别节点(虚拟机或物理机)停机
Action:周期性的为 apiserver 的 etcd 所使用的数据卷创建磁盘快照(Snapshot)
应对问题:Apiserver 的后端数据丢失应对问题:集群管理员的人为错误应对问题:kubelet 软件故障
Action:使用Deployment/StatefulSet/DaemonSet 等控制器,而不是直接创建 Pod
应对问题:个别节点(虚拟机或物理机)停机应对问题:kubelet 软件故障
Deployment故障排除
背景假设
当你希望在Kubernetes中部署应用程序时,你通常会定义三个组件:
一个Deployment - 这是一份用于创建你的应用程序的Pod副本的"食谱";一个Service - 一个内部负载均衡器,用于将流量路由到内部的Pod上;一个Ingress - 描述如何流量应该如何从集群外部流入到集群内部的你的服务上。
在Kubernetes中,你的应用程序通过两层负载均衡器暴露服务:内部的和外部的
内部的负载均衡器称为Service,而外部的负载均衡器称为Ingress
Pod不会直接部署。Deployment会负责创建Pod并管理它们
部署一个简单的"HelloWorld"应用,该应用的YAML文件的内容应该类似下面这样
apiVersion: apps/v1kind: Deploymentmetadata: name: my-deployment labels: track: canaryspec: selector: matchLabels: any-name: my-app template: metadata: labels: any-name: my-app spec: containers: - name: cont1 image: learnk8s/app:1.0.0 ports: - containerPort: 8080---apiVersion: v1kind: Servicemetadata: name: my-servicespec: ports: - port: 80 targetPort: 8080 selector: name: app---apiVersion: networking.k8s.io/v1beta1kind: Ingressmetadata: name: my-ingressspec: rules: - paths: - backend: serviceName: app servicePort: 80 path: /
连接Deployment和service
Service直接指向Pod,并完全跳过了Deployment。
Service selector应至少与Pod的一个标签匹配;Service的targetPort应与Pod中容器的containerPort匹配;Service的port可以是任何数字。多个Service可以使用同一端口号,因为它们被分配了不同的IP地址。
上面被一个服务暴露的Pod
创建Pod时,应为Pod中的每个容器定义containerPort端口
当创建一个Service时,你可以定义port和targetPort
targetPort和containerPort应该始终保持匹配
如果容器暴露3000端口(containerPort),那么targetPort应该匹配这一个端口号
连接Service和Ingress
配置ingress将应用暴露到集群外部
Ingress必须知道如何检索服务,然后检索Pod并将流量路由给它们。
Ingress按名字和暴露的端口检索正确的服务。
在Ingress和Service中应该匹配两件事:
Ingress的servicePort 应该匹配service的portIngress的serviceName 应该匹配服务的name
servive暴露一个port,Ingress有一个字段叫servicePort
service的port和Ingress的service应该始终保持匹配
检测ingress
#使用以下命令检索Ingress控制器的Pod名称$ kubectl get pods --all-namespacesNAMESPACE NAME READY STATUSkube-system coredns-5644d7b6d9-jn7cq 1/1 Runningkube-system etcd-minikube 1/1 Runningkube-system kube-apiserver-minikube 1/1 Runningkube-system kube-controller-manager-minikube 1/1 Runningkube-system kube-proxy-zvf2h 1/1 Runningkube-system kube-scheduler-minikube 1/1 Runningkube-system nginx-ingress-controller-6fc5bcc 1/1 Running#标识Ingress Pod(可能在其他命名空间中)并描述它以检索端口:$ kubectl describe pod nginx-ingress-controller-6fc5bcc \ --namespace kube-system \ | grep PortsPorts: 80/TCP, 443/TCP, 18080/TCP#连接到pod$ kubectl port-forward nginx-ingress-controller-6fc5bcc 3000:80 --namespace kube-system
访问计算机上的端口3000时,请求都会转发到Ingress控制器Pod上的端口80。
如果访问 selector应与Pod的标签匹配service的targetPort 应与Pod中容器的containerPort 匹配service的端口可以是任何数字。多个服务可以使用同一端口,因为它们分配了不同的IP地址。ingress的servicePort 应该匹配 service 的portserivce的名称应与 ingress 中的serviceName 字段匹配
k8s deployment故障排除的步骤
由于每个deployment中都有三个组件,因此你应该自下而上依次调试所有组件。
你应该先确保Pods正在运行然后,专注于让service将流量路由到到正确的Pod再检查是否正确配置了Ingress
首先,检查Pod是否已就绪并正在运行。
如果Pod已就绪,则应调查service是否可以将流量分配给Pod。
该检查service与ingress之间的连接。
Pod故障排除
确保Pod正在运行并准备就绪
$ kubectl get podsNAME READY STATUS RESTARTS AGEapp1 0/1 ImagePullBackOff 0 47happ2 0/1 Error 0 47happ3-76f9fcd46b-xbv4k 1/1 Running
在上述会话中,最后一个Pod处于就绪并正常运行的状态;但是,前两个Pod既不处于Running也不是Ready。
使用如下方式排查
kubectl logs
常见pod错误
Pod可能会出现启动和运行时错误。
启动错误包括:
ImagePullBackoffImageInspectErrorErrImagePullErrImageNeverPullRegistryUnavailableInvalidImageName
运行时错误包括:
CrashLoopBackOffRunContainerErrorKillContainerErrorVerifyNonRootErrorRunInitContainerErrorCreatePodSandboxErrorConfigPodSandboxErrorKillPodSandboxErrorSetupNetworkErrorTeardownNetworkError
ImagePullBackOff
当Kubernetes无法获取到Pod中某个容器的镜像时,将出现此错误。
共有三个可能的原因:
镜像名称无效-例如,你拼错了名称,或者image不存在你为image指定了不存在的标签你尝试检索的image属于一个私有registry,而Kubernetes没有凭据可以访问它
前两种情况可以通过更正image名称和标记来解决。
针对第三种情况,你应该将私有registry的访问凭证通过Secret添加到k8s中并在Pod中引用它。
CrashLoopBackOff
如果容器无法启动,则Kubernetes将显示错误状态为:CrashLoopBackOff。
通常,在以下情况下容器无法启动:
应用程序中存在错误,导致无法启动你未正确配置容器Liveness探针失败太多次
你应该尝试从该容器中检索日志以调查其失败的原因。
如果由于容器重新启动太快而看不到日志,则可以使用以下命令:
#打印前一个容器的错误消息$ kubectl logs
RunContainerError
当容器无法启动时,出现此错误。
甚至在容器内的应用程序启动之前。
该问题通常是由于配置错误,例如:
挂载不存在的卷,例如ConfigMap或Secrets将只读卷安装为可读写
使用 kubectl describe pod
处于Pending状态的Pod
假设你的调度程序组件运行良好,可能的原因如下:
集群没有足够的资源(例如CPU和内存)来运行Pod当前的命名空间具有ResourceQuota对象,创建Pod将使命名空间超过配额该Pod绑定到一个处于pending状态的 PersistentVolumeClaim
#检查pod$ kubectl describe pod
处于未就绪状态的Pod
如果Pod正在运行但未就绪(not ready),则表示readiness就绪探针失败。
当“就绪”探针失败时,Pod未连接到服务,并且没有流量转发到该实例。
就绪探针失败是应用程序的特定错误,因此你应检查 kubectl describe 中的 Events 部分以识别错误
服务的故障排查
Pod正在运行并处于就绪状态,但仍无法收到应用程序的响应,则应检查服务的配置是否正确
service旨在根据流量的标签将流量路由到Pod。
因此,你应该检查的第一件事是服务关联了多少个Pod。
你可以通过检查服务中的端点(endpoint)来做到这一点:
$ kubectl describe service
端点是一对,并且在服务(至少)以Pod为目标时,应该至少有一个端点。
如果“端点”部分为空,则有两种解释:
你没有运行带有正确标签的Pod(提示:你应检查自己是否在正确的命名空间中)service的selector 标签上有拼写错误
使用如下命令连接服务进行测试
$ kubectl port-forward service/
Ingress的故障排除
Pod正在运行并准备就绪服务会将流量分配到Pod
但是你仍然看不到应用程序的响应。
这意味着最有可能是Ingress配置错误。
由于正在使用的Ingress控制器是集群中的第三方组件,因此有不同的调试技术,具体取决于Ingress控制器的类型。
Ingress使用 serviceName 和 servicePort 连接到服务。
#检查ingress配置是否正确$ kubectl describe ingress
如果backend一列为空,则配置中必然有一个错误。
如果你可以在“backend”列中看到端点,但是仍然无法访问该应用程序,则可能是以下问题:
你如何将Ingress暴露于公共互联网你如何将集群暴露于公共互联网
你可以通过直接连接到Ingress Pod来将基础结构问题与Ingress隔离开。
#获取控制器pod$ kubectl get pods --all-namespaces########输出结果###################NAMESPACE NAME READY STATUSkube-system coredns-5644d7b6d9-jn7cq 1/1 Runningkube-system etcd-minikube 1/1 Runningkube-system kube-apiserver-minikube 1/1 Runningkube-system kube-controller-manager-minikube 1/1 Runningkube-system kube-proxy-zvf2h 1/1 Runningkube-system kube-scheduler-minikube 1/1 Runningkube-system nginx-ingress-controller-6fc5bcc 1/1 Running#执行 kubectl describe pod 以检索端口:$ kubectl describe pod nginx-ingress-controller-6fc5bcc --namespace kube-system \ | grep Ports#最后连接到pod$ kubectl port-forward nginx-ingress-controller-6fc5bcc 3000:80 --namespace kube-system
如果可行,则问题出在基础架构中。你应该调查流量如何路由到你的集群。如果不起作用,则问题出在Ingress控制器中。你应该调试Ingress。
如果仍然无法使Ingress控制器正常工作,则应开始对其进行调试。
目前有许多不同版本的Ingress控制器。
热门选项包括Nginx,HAProxy,Traefik等。
调试Ingress Nginx
Ingress Nginx 是使用比较多的的Ingress控制器之一.
Ingress-nginx 项目有一个 kubectl 的官方插件
可以用kubectl ingress-nginx来:
检查日志,后端,证书等连接到ingress检查当前配置
常用命令
kubectl ingress-nginx lint,它会检查nginx.confkubectl ingress-nginx backend,以检查后端(类似于kubectl describe ingress
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~