IBM云 Satellite:建立更快。安全。任何地方。 阅读更多

调试和记录Kubernetes应用程序

本教程适用于想要了解更多关于该教程的开发人员 Kubernetes.集群 以及如何从应用程序中调试和获取日志。

Kubernetes.是一个开源系统,用于在多个主机上管理容器化应用程序,为应用程序的部署,维护和扩展提供基本机制。开源项目由托管 云本机计算基础,在本教程中托管 IBM云 Kubernetes服务.

先决条件

在开始本教程之前,您需要:

  • 一个免费的IBM云 帐户:如果您没有IBM云帐户,则可以创建一个 这里 .
  • 创建一个 在IBM云上的Kubernetes集群.
  • 要部署示例应用程序并将kubectl连接到Kubernetes集群。你可以遵循 Lab 0Lab 1 for instructions.

预计的时间

完成本教程应需要大约20分钟。

脚步

容器日志

检查并调试您的豆荚

让’谈论应用程序部署。有时它可以顺利和你顺利’ll see the message deployment <your-app-name> created!

但是如果您的应用程序部署发生故障,会发生什么?很少有步骤可以采取:收集信息,计划如何修复和测试和执行。

让’S看这里在这里收集信息,因为有很多方法可以收集信息和技术。

  1. 要获得有关您的POD的基本信息,您可以使用此简单命令:

    $ kubectl get pods
    NAME                         READY     STATUS    RESTARTS   AGE
    guestbook-75786d799f-fg72k   1/1       Running   0          7m
    
  2. 但是如果您描述了特定的POD,则可以获得更多信息,如下所示:

    $ kubectl describe pod <your-pod-name>
    Name:           guestbook-75786d799f-fg72k
    Namespace:      default
    Node:           10.47.84.98/10.47.84.98
    Start Time:     Sun, 19 Aug 2018 12:56:23 +0300
    Labels:         pod-template-hash=3134283559
                       run=guestbook
    Annotations:    kubernetes.io/psp=ibm-privileged-psp
    Status:         Running
    ...
    

从上面,您可以看到有关容器和POD(标签,资源要求等)的配置信息以及有关容器和POD的状态信息(状态,准备,重新启动计数,事件, 等等)。

Sometimes using these basic command should be enough. For example, you can look at kubectl describe 和 see that you have an image pull error and you just forgot to put in some information (like a secret for an image pull). Or maybe you used the latest image version that wasn’工作良好,您希望切换回上一个版本。

但是如果我们不发生什么会发生什么’发现任何错误,我们需要深入深入潜入我们的日志吗?很多开发人员都不是多么的’t know is that the 事件 (kubectl get events) is actually a resource type in Kubernetes. 因此,当您执行此命令时,它将列出像它将列出任何其他资源的事件,并为您提供总结视图。 你必须知道事件资源是命名的,所以当你的时候’重新尝试获得特定事件,您应该提及要获取活动的命名空间,或者只是将其留空以获取所有事件。

  1. 要获取POD的事件列表,请使用命令:

         $kubectl get events [--namespace=default]
         LASTSEEN   FIRSTSEEN   COUNT     NAME                         KIND         SUBOBJECT                    TYPE      REASON                  SOURCE                  MESSAGE
         3m         3m          1         guestbook-75786d799f-r6mxl   Pod                                       Normal    Scheduled               default-scheduler       Successfully assigned guestbook-75786d799f-r6mxl to 10.77.155.84
         3m         3m          1         guestbook-75786d799f-r6mxl   Pod                                       Normal    SuccessfulMountVolume   kubelet, 10.77.155.84   MountVolume.SetUp succeeded for volume "默认-token-5rlxc"
         3m         3m          1         guestbook-75786d799f-r6mxl   Pod          spec.containers{guestbook}   Normal    Pulled                  kubelet, 10.77.155.84   Container image "ibmcom/guestbook:v1" already present on machine
         3m         3m          1         guestbook-75786d799f-r6mxl   Pod          spec.containers{guestbook}   Normal    Created                 kubelet, 10.77.155.84   Created container
         3m         3m          1         guestbook-75786d799f-r6mxl   Pod          spec.containers{guestbook}   Normal    Started                 kubelet, 10.77.155.84   Started container
         3m         3m          1         guestbook-75786d799f-xvpvv   Pod          spec.containers{guestbook}   Normal    Killing                 kubelet, 10.77.155.84   Killing container with id docker://guestbook:Need to kill Pod
         3m         3m          1         guestbook-75786d799f         ReplicaSet                                Normal    SuccessfulDelete        replicaset-controller   Deleted pod: guestbook-75786d799f-xvpvv
         3m         3m          1         guestbook-75786d799f         ReplicaSet                                Normal    SuccessfulCreate        replicaset-controller   Created pod: guestbook-75786d799f-r6mxl
         3m         3m          1         guestbook                    Deployment                                Normal    ScalingReplicaSet       deployment-controller   Scaled down replica set guestbook-75786d799f to 0
         3m         3m          1         guestbook                    Deployment                                Normal    ScalingReplicaSet       deployment-controller   Scaled up replica set guestbook-75786d799f to 1
    

您可以使用事件检测的一个常见场景是当您创建赢的POD时’t符合任何节点。它将在一个“Pending”国家,这可能发生在缺乏资源和你的情况下’请看看这个问题“Events” section. Let’s查看重要事件参数,您可以在其中看到事件记录包含以下内容:

  • KIND 指示事件的资源类型(Pod / replicaset /部署/等)。
  • TYPE,这是事件的状态。这可以标记为“Normal” or “Warning”可以将来添加新类型。
  • REASON 转换到对象的当前状态。
  • SOURCE 对于报告此事件的组件。
  • MESSAGE 表示它是事件的人类可读描述。

我们没有更多的参数’t see in the list above that might be useful for you like METADATA, which is a standard object meta data. EVENTTIME is when the event was first observed. And ACTION is the specific action that was taken/failed regarding the object.

获取应用程序日志

应用程序和系统日志可以帮助您更好地了解群集内部发生的内容。您可以获得特定POD的日志,如果POD具有多个容器,则可以指定所需的容器。

查看您的日志

要查看日志,可以运行此简单命令:

  $ kubectl logs <your-pod-name>
  [negroni] listening on :3000
  [negroni] 2018-08-19T11:55:39Z | 200 |   332.277µs | 173.193.106.55:32412 | GET /
  [negroni] 2018-08-19T11:55:39Z | 200 |   140.407µs | 173.193.106.55:32412 | GET /style.css
  [negroni] 2018-08-19T11:55:39Z | 200 |   123.595µs | 173.193.106.55:32412 | GET /script.js
  [negroni] 2018-08-19T11:55:39Z | 200 |   87.508µs | 173.193.106.55:32412 | GET /lrange/guestbook
  [negroni] 2018-08-19T11:55:39Z | 404 |   74.307µs | 173.193.106.55:32412 | GET /favicon.ico
  [negroni] 2018-08-19T11:57:30Z | 304 |   89.418µs | 173.193.106.55:32412 | GET /
  [negroni] 2018-08-19T11:57:30Z | 200 |   60.671µs | 173.193.106.55:32412 | GET /lrange/guestbook
  [negroni] 2018-08-19T12:06:23Z | 304 |   152.557µs | 173.193.106.55:32412 | GET /
  [negroni] 2018-08-19T12:06:23Z | 200 |   94.091µs | 173.193.106.55:32412 | GET /lrange/guestbook

笔记: To print to the logs, write to stdout/stderr from your application. Another thing to note is that there is no get in the logs command, which means that logs are not resources like events.

为了帮助您从日志中获得更好的结果,可以使用“kubetail”,这是一个开源项目,可以以不同颜色的方式绘制每种类型的日志。这里’s the link: //github.com/johanhaleby/kubetail.

以前的日志

You can always ask for previous logs with the --previous flag, but there are two more types of log levels you should know about: the Node level and Cluster level. They’彼此也有点不同。让’看看它们的不同:

  • 节点级别: A containerized application writes to stdoutstderr that are handled by a container engine. The container engine redirects those two streams to a logging driver, which is configured in Kubernetes to write to a file in json format. JSON日志记录驱动程序将每行作为单独的消息进行处理。使用日志记录驱动程序时,对多行消息没有直接支持。您需要在日志记录代理级别或更高版本处理多行消息。 默认情况下,如果容器重新启动,则Kubelet将一个终端容器带入其日志。如果从节点中驱逐POD,则也会驱逐所有相应的容器以及它们的日志。
  • 集群级别:虽然Kubernetes未提供群集级日志记录的本机解决方案,但您可以考虑几种常见的方法。以下是一些选项:
    • 使用在每个节点上运行的节点级日志记录代理。
    • 包括专用的Sidecar容器,用于登录应用程序POD。
    • 将日志直接按到应用程序中的后端。

有关这些方法的更多信息,您可以阅读此信息 指导 .

在运行容器中使用shell

Most of the time your container logs are your pod logs, especially if your pod only has one container in it. But if something has gone really wrong on your cluster and you cant get the logs from the pod with kubectl, you may have to somehow get into your container and get the logs (a debugging container) that will give you full control of what is going inside the container. You can use kubectl exec to access the shell running in the container and figure out where the process is in your troublesome container, which then gives you a more comfortable way to debug your container.

请记住,如果您在容器中有shell exec,则只能执行此操作。如果您使用的图像不起作用’t have it when you were building your container, you wont be able to use the exec command. shell exec可能会占用一些空间并使您的容器沉重,所以您可能会问“我为什么要把它放在我的容器里面? isn.’低重量使用容器的最大优势?” 在生产环境中,您可能希望最大化性能和那里’没有理由将shell放入图像中。然而,在测试环境中,你’D可能很高兴访问shell以在容器运行时运行测试。

  1. 为此,我们需要使用/ bin / bash创建新的pod:

    $ kubectl create -f //kubernetes.io/examples/application/shell-demo.yaml
    
  2. 让shell到容器:

    $ kubectl exec -it shell-demo -- /bin/bash
    
  3. 现在列出根目录:

    root@shell-demo:/# ls /
    bin   dev  home  lib64  mnt  proc  run   srv  tmp
    boot  etc  lib   media  opt  root  sbin  sys  usr
    

集群网络问题

网络问题是最常见的问题,因为aren’在你可以通过的任何子弹点,解决一切–你必须了解什么’您的群集网络内部错误。 为了帮助您找到这些问题,我列出了关键领域,以寻找您怀疑网络问题。 进一步阅读:对于Kubernetes网络的一些指导,退房 Kubernetes.网络:基本网络概念的实验室.

调试您的服务

常用于Kubernetes的新安装的问题是服务aren’t正常工作,因此您运行部署并创建服务,但仍然不’得到任何回复。在本节中,我们’请介绍一些可能帮助您弄清楚什么的命令’s not working.

有时我们忘记为我们的POD创建服务,因为有服务至关重要。否则,我们的Pod赢了’可以到达,我们会得到错误。

  1. 要查看所有服务,您可以使用像这样的简单命令,我们可以看到所有豆荚:

    $ kubectl get svc
    NAME        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
    guestbook   172.21.30.218   <nodes>       3000:32412/TCP   45m
    
  2. 如果您正在寻找服务’存在,您可以使用此命令创建它:

    $ kubectl expose deployment <your-deployment-name> --type="NodePort" --port=3000
    service "guestbook" exposed
    

如果您已拥有服务,则应查看其配置,看看问题是否存在。

  1. 让’s尝试获取有关此服务的更多信息:

    $ kubectl describe service <your-service-name>
    Name:                   guestbook
    Namespace:              default
    Labels:                 run=guestbook
    Annotations:            <none>
    Selector:               run=guestbook
    Type:                   NodePort
    IP:                     172.21.138.209
    Port:                   <unset> 3000/TCP
    NodePort:               <unset> 31235/TCP
    Endpoints:              172.30.87.71:3000
    Session Affinity:       None
    Events:                 <none>
    

检查您是否使用了右侧导陷以访问容器,并且您有端点。 If you see some false information (like no endpoints), try to re-create the service and double check your kubectl expose command for possible mistakes.

  1. 您还可以以JSON格式获取您的信息:

         $ kubectl get service <your-service-name> -o json
         {
             "apiVersion": "v1",
             "kind": "Service",
             "metadata": {
                 "creationTimestamp": "2018-08-19T11:55:12Z",
                 "labels": {
                     "run": "guestbook"
                 },
                 "name": "guestbook",
                 "namespace": "默认",
                 "resourceVersion": "1118",
                 "selfLink": "/api/v1/namespaces/default/services/guestbook",
                 "uid": "baa2e98d-a3a6-11e8-a994-f20601bb534c"
             },
             "spec": {
                 "clusterIP": "172.21.30.218",
                 "externalTrafficPolicy": "Cluster",
                 "ports": [
                     {
                         "nodePort": 32412,
                         "port": 3000,
                         "protocol": "TCP",
                         "targetPort": 3000
                     }
                 ],
                 "selector": {
                     "run": "guestbook"
                 },
                 "sessionAffinity": "None",
                 "type": "NodePort"
             },
             "status": {
                 "loadBalancer": {}
             }
         }
    

您应该始终仔细检查可能导致问题的某些配置,就像质疑.Ports是POD的右侧目标。使用相同协议的服务和吊舱吗?

  1. 有几种方法可以检查您的服务。你可以阅读更多 这里 .

检查DNS.

某些网络问题可能是由DNS配置或错误引起的。 So first you’LL需要检查DNS是否正常工作。

  1. Use the get pods command to get your pod name:

    $ kubectl get pods
    NAME                         READY     STATUS    RESTARTS   AGE
    guestbook-75786d799f-brrhf   1/1       Running   0          47m
    
  2. 使用以下命令检查POD DNS:

    $ kubectl exec -ti <your-pod-name> -- nslookup kubernetes.default
    Server:    172.21.0.10
    Address 1: 172.21.0.10 kube-dns.kube-system.svc.cluster.local
    
    Name:      kubernetes.default
    Address 1: 172.21.0.1 kubernetes.default.svc.cluster.local
    

请注意,如果你不’t use the “default”命名空间,您应该根据群集命名空间尝试其他名称。如果您的POD和服务处于不同的命名空间中,请尝试命名空间限定名称(默认值)– but you will need to adjust your app to use a cross-namespace name, or run your app and service in the same namespace. If it still fails, try a fully qualified name (e.g., 默认.svc.cluster.local). If the nslookup command fails, you should do some checks in configurations or find errors. Errors like nslookup: can't resolve 'kubernetes.default' might indicate that the problem is in the coredns/kube-dns add-on or associated services.

如果您能够完成完全限定的名称查找,但不是相对的名称,则需要检查/etc/resolv.conf文件是否正确。

  1. 转到rocolv.conf文件中以查看参数是否正常:

    $ kubectl exec <your-pod-name> cat /etc/resolv.conf
    nameserver 172.21.0.10
    search default.svc.cluster.local svc.cluster.local cluster.local
    options ndots:5
    

确保名称服务器线表示您的群集DNS服务;这与kubelet传递给了–Cluster-DNS标志。搜索行必须包含适当的后缀,供您查找服务名称。在这种情况下,它正在寻找本地命名空间(default.svc.cluster.local)的服务,所有命名空间(svc.cluster.local)和群集(cluster.local)中的服务。根据自己的安装,您可能有其他记录。将群集后缀与kubelet传递给–cluster-domain flag. The options line must set ndots high enough that your DNS client library considers search paths at all. Kubernetes sets this to 5 by default, which is high enough to cover all of the DNS names that it generates.

如果上述所有内容仍然失败,您可能需要检查您的 Kube-Proxy..

网络政策

NetworkPolicy定义了允许窗口彼此通信以及其他网络端点的方式。 NetworkPolicy使用标签来管理POD之间的流量。 如果您无法与POD通信,则可能需要检查您的网络策略以查看此POD是否允许获取任何请求。 默认情况下,POD不会被隔离,并且接受流量。但是一旦你有网络,你选择了一个特定的豆荚’LL拒绝与未经授权的连接进行任何通信。

让’S看一个网络,示例:

        kind: NetworkPolicy
        apiVersion: networking.k8s.io/v1
        metadata:
          name: access-nginx
        spec:
          podSelector:
            matchLabels:
              run: nginx
          policyTypes:
          - Ingress
          - Egress
          ingress:
          - from:
            - podSelector:
                matchLabels:
                  access: "true"
          egress:
          - to:
            - ipBlock:
                cidr: 10.0.0.0/24
            ports:
            - protocol: TCP
              port: 5978

与其他所有其他Kubernetes Config一样,NetworkPolicy具有常规信息的类,apierion和元数据参数。 在上面的示例中,您可以在上面的示例中看到规范内的PodSelector,它选择我们希望在此NetworkPolicy中包含的POD。在此示例中,将包括所有Nginx POD。 笔记: 如果您的PodSelector为空此NetworkPolicy将影响同一名称空间中的所有窗格!

您应该检查的另一个重要参数是进入和出口;它们影响允许哪些收入和结果网络与PodSelector中的吊舱通信。您应该仔细检查这些参数,并确保插入正确的标签,IP和端口,以便您可以允许POD通信且未被阻止。

使用织法范围

编织范围 是Docker和Kubernetes的开源可视化和监控工具。它为您的应用程序提供了自上而下的视图以及整个基础架构,并允许您实时诊断您的分布式容器化应用程序的任何问题,因为它部署到云提供商。 在Kubernetes集群上安装Weave Cope, 在这里找到方向. 如果没有编织范围,我非常鼓励您使用类似的监控工具来轻松显示您的容器正在做什么以及为什么。

使用Grafana.

格拉纳纳 是一个开源,通用仪表板和图形作曲家,它作为Web应用程序运行。 您可以使用Grafana获取群集和吊舱的CPU /内存/负载度量。 Every IBM Cloud 用户自动访问Grafana与帐户。开始使用Grafana, 阅读这里的教程. 要了解如何使用Grafana并为您的Kubernetes集群创建仪表板, 在这里阅读更多.

概括

现在您已经了解了Logging和Debugging的基础知识,您可以尝试使用和探索更多的工具: