Kubernetes 调试 deployment 的思路

我是研究僧i 提交于 2020-02-24 10:18:24

Kubernetes 调试 deployment 的思路原文:https://learnk8s.io/troubleshooting-deployments

1、组件匹配规则

当你希望在Kubernetes中部署一个应用程序,你通常需要定义三个组件:

  • Deployment——这是创建名为Pods的应用程序副本的方法
  • Serivce——内部负载均衡器,将流量路由到Pods
  • Ingress——可以描述流量如何从集群外部流向Service

在Kubernetes中,你的应用程序通过两层负载均衡器暴露:内部和外部。内部负载均衡器称为Service,而外部负载均衡器则称为Ingress。

端口和标签需要匹配规则:

  1. Service selector应该匹配Pod的标签
  2. Service targerPort应该匹配在Pod内容器的containerPort
  3. Service 端口可以是任意数字。多个Service可以使用同个端口,因为它们已经分配了不同的IP地址
  4. Ingress的servicePort应该匹配在Service中的port
  5. Service的名称应该匹配在Ingress中的serviceName的字段

假设你想部署一个简单的Hello World应用程序,那么对于此类应用程序,其YAML文件与以下类似:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
  labels:
    track: canary
spec:
  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: v1
kind: Service
metadata:
  name: my-service
spec:
  ports:
  - port: 80
    targetPort: 8080
  selector:
    any-name: my-app
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: my-ingress
spec:
  rules:
  - http:
    paths:
    - backend:
        serviceName: my-service
        servicePort: 80
      path: /

2、排查 Pod 故障

在大多数情况下,问题出现在Pod本身。当Pod既没有Running也没有Ready。那么可以使用4个十分有用的命令可以帮助你排查Pod的故障:

这里有4个十分有用的命令可以帮助你排查Pod的故障:

  • kubectl logs 能够帮助检索Pod的容器日志
  • kubectl describe pod 能够有效地检索与Pod相关的事件列表
  • kubectl get pod 对于提取存储在Kubernetes中的Pod的YAML定义十分有用
  • kubectl exec -ti bash可以用于在Pod其中一个容器中运行一个交互式命令

如果由于你的容器重启过快而无法查看日志,你可以使用以下命令:

kubectl logs <pod-name> --previous

它将从之前的容器中打印错误信息。

3、排查 Service 故障

如果你的Pod正在运行并且准备就绪,但是你依旧无法接收来自应用程序的响应,你应该检查Service是否配置正确。

Service旨在根据pod的标签将流量路由到Pod。所以第一件事,你需要检查Service target多少个Pod。可以通过检查Service中的Endpoint来完成此步骤:

kubectl describe service <service-name> | grep Endpoints

一个endpoint是一对,并且当Service(至少)target一个pod时,至少有一对。

如果“Endpoint”部分是空的,那么有两种解释:

  1. 任何正在运行的Pod没有正确的label(提示:你需要检查以下你是否在正确的命名空间内)
  2. 在Service的selector标签中有错别字

如果你看到了endpoint列表,但依旧无法访问你的应用程序,那么你的Service中的targetPort可能是罪魁祸首。

你应该怎么测试Service?无论Service类型是什么,都可以使用kubectl port-forward连接到它:

kubectl port-forward service/<service-name> 3000:80

其中:

  • 是Service的名称
  • 3000是你想要在电脑上打开的端口
  • 80是由Service暴露的端口

4、排查 Ingress 故障

如果你走到了这个部分,这意味着:

  • Pod正在运行并且准备就绪
  • Service可以分发流量给Pod

但你依旧无法接收app的响应。那么这很有可能是Ingress配置出现错误。

Ingress使用serviceName和servicePort连接Service。你应该检查那些是否正确配置。你可以使用以下命令检查Ingress是否正确配置:

kubectl describe ingress <ingress-name>

如果Backend列是空的,那么配置中肯定存在错误。

如果你能在Backend列中看到endpoint,但依旧无法访问应用程序,那么可能是以下问题:

  • 你将Ingress暴露于公网的方式
  • 你将集群暴露于公网的方式

你可以通过直接连接到Ingress Pod将基础设施问题与Ingress隔离开来。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!