<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>debug | 伪架构师</title>
    <link>/tags/debug/</link>
      <atom:link href="/tags/debug/index.xml" rel="self" type="application/rss+xml" />
    <description>debug</description>
    <generator>Source Themes Academic (https://sourcethemes.com/academic/)</generator><language>zh</language><lastBuildDate>Tue, 05 Sep 2017 06:03:04 +0800</lastBuildDate>
    <image>
      <url>/img/logo-wide.png</url>
      <title>debug</title>
      <link>/tags/debug/</link>
    </image>
    
    <item>
      <title>Kubernetes 应用故障的一些定位方法</title>
      <link>/post/debug-in-kubernetes/</link>
      <pubDate>Tue, 05 Sep 2017 06:03:04 +0800</pubDate>
      <guid>/post/debug-in-kubernetes/</guid>
      <description>

&lt;h2 id=&#34;常备工作&#34;&gt;常备工作&lt;/h2&gt;

&lt;h3 id=&#34;准备一个工具镜像&#34;&gt;准备一个工具镜像&lt;/h3&gt;

&lt;p&gt;其中包含 nslookup, ping, curl, 甚至是 ab、siege 等常用工具以及一个顺手的 Shell。一言不合就可以用静态 Pod 的方式将其运行到 Kubernetes 之中进行内部诊断。&lt;/p&gt;

&lt;h3 id=&#34;sysctl-a-grep-forwarding&#34;&gt;sysctl -a | grep forwarding&lt;/h3&gt;

&lt;p&gt;你猜这是干啥的？&lt;/p&gt;

&lt;h3 id=&#34;服务状态查询&#34;&gt;服务状态查询&lt;/h3&gt;

&lt;p&gt;各个 Kubernetes 组件的状态检查。可以使用 Ansible 之类的工具进行快速查询。&lt;/p&gt;

&lt;h2 id=&#34;service-不通&#34;&gt;Service 不通&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;这里我们首先假设 Pod 工作正常&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;目前我们的应用均采用的是 NodePort 模式对外提供服务：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;逻辑&lt;/strong&gt;：Service 将 &lt;strong&gt;符合其选择器的 Pod 暴露的端口&lt;/strong&gt; 从 &lt;strong&gt;各个 Node&lt;/strong&gt; 的同一端口暴露出来对外进行监听。&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;技术&lt;/strong&gt;：&lt;strong&gt;Kube-proxy&lt;/strong&gt; 通过网络插件，一般利用 Iptables vxLan 等乌七八糟的蜜汁技术，完成对外服务负载均衡，并分发给各个 Pod 的内部 IP 的相应端口。&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;前面我们假设 Pod 是正常工作的，因此，这里只考虑 Service 的情况。&lt;/p&gt;

&lt;p&gt;通过上面的陈述我们能看到大致的一些要素，下面从内向外进行列表：&lt;/p&gt;

&lt;h3 id=&#34;pod-能够正常工作&#34;&gt;Pod 能够正常工作&lt;/h3&gt;

&lt;p&gt;见后文&lt;/p&gt;

&lt;h3 id=&#34;service-的选择器能够正确的找到-pod&#34;&gt;Service 的选择器能够正确的找到 Pod&lt;/h3&gt;

&lt;p&gt;这里我们可以使用&lt;code&gt;kubectl describe svc panic-service&lt;/code&gt;命令，查看输出内容的&lt;code&gt;endpoint&lt;/code&gt;一节内容，如果其中有 Pod 地址，也就说明选择器和 Pod 的标签是匹配的。如果为空，则需要对服务或者 Pod Controller 的定义进行排查。&lt;/p&gt;

&lt;h3 id=&#34;proxy-的工作状态&#34;&gt;Proxy 的工作状态&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;首先可以使用&lt;code&gt;systemctl -l Kube-proxy&lt;/code&gt;来查看服务状况。&lt;/li&gt;
&lt;li&gt;还可以使用其他 Node 的同一端口测试访问，看是否单一节点的故障。&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&#34;dns-工作状态&#34;&gt;DNS 工作状态&lt;/h3&gt;

&lt;p&gt;Kubectl 查看 DNS 各个 Pod 的存活状态。&lt;/p&gt;

&lt;p&gt;利用上面提到的工具 Pod 尝试解析服务。失败了其实也没啥办法，删 DNS Pod 重启吧。&lt;/p&gt;

&lt;h3 id=&#34;端口是否定义正确&#34;&gt;端口是否定义正确&lt;/h3&gt;

&lt;p&gt;看 Pod 的端口是否能够正确侦听，是否符合服务定义。例如 Service 定义了到 Pod 8080 端口的访问，而 Pod 开放的却是 80，这样的情况跟标签无法匹配一样，是很常见的问题。&lt;/p&gt;

&lt;h2 id=&#34;说完了服务-我们来说说-pod&#34;&gt;说完了服务，我们来说说 Pod&lt;/h2&gt;

&lt;h3 id=&#34;两个顺手的命令&#34;&gt;两个顺手的命令：&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;kubectl get po -o wide | grep -v Running&lt;/code&gt;
 &lt;code&gt;kubectl describe po unhealthy&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;一般来说，一个行为端正的 Pod，应该是以 Running 状态持续运行的。在进入 Running 之前，大致有调度、创建、初始化等几个环节，如果正常运行之后出了故障，会发生重启。如果在启动容器内进程时出现问题，则会进入 CrashLoopBackOff 的状态。&lt;/p&gt;

&lt;h3 id=&#34;除了-running-complet-以及-crashloopbackoff&#34;&gt;除了 Running/Complet 以及 CrashLoopBackOff：&lt;/h3&gt;

&lt;p&gt;这几种情况其实不同，不过随性写到这，就不深究了，首先是 describe 一下。&lt;/p&gt;

&lt;p&gt;Pod 启动有几个条件：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;有符合要求的节点供其运行

&lt;ul&gt;
&lt;li&gt;Taint 隔离的节点，要求 Pod 有显式声明对该种 Taint 的容错能力，才可以在其上运行。&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;节点和 Pod 的亲和性定义&lt;/li&gt;
&lt;li&gt;Node Selector 的定义&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;符合其需求的资源

&lt;ul&gt;
&lt;li&gt;CPU 和 内存的 request limit 定义&lt;/li&gt;
&lt;li&gt;可能存在的第三方资源需求定义&lt;/li&gt;
&lt;li&gt;加载卷（nfs gluster ceph 等）/Secret/Configmap 的定义&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;镜像必须存在，可 Pull&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;调度部分一般来说查看 Pod 定义，和节点的 Describe 进行匹配即可，Describe 内容中也会明确说出无合适 Pod。&lt;/p&gt;

&lt;p&gt;资源部分 CPU 和内存的 Describe 结果也会很明显。&lt;/p&gt;

&lt;p&gt;存储部分，往往就需要更复杂的排查：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;首先看看是不是每个 Node 都如此。&lt;/li&gt;
&lt;li&gt;是否安装了对应的客户端驱动。&lt;/li&gt;
&lt;li&gt;对分布式存储的访问网络是否可用。&lt;/li&gt;
&lt;li&gt;存储服务容量是否足够分配。&lt;/li&gt;
&lt;li&gt;是否能够成功的手工 Mount。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;至于对 ConfigMap 和 Secret 的依赖，很简单，Kubectl 查询即可。&lt;/p&gt;

&lt;h3 id=&#34;crashloopbackoff-以及-restart-大于-1&#34;&gt;CrashLoopBackOff 以及 Restart 大于 1&lt;/h3&gt;

&lt;p&gt;这种情况一般来说属于业务内部的问题，可以通过 &lt;code&gt;kubectl logs -f ...&lt;/code&gt;
命令进行查看，目前经验比较多的非业务情况是：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;对于 Kubernetes API 进行访问的应用，经常会是因为 RBAC 权限不足导致无法启动&lt;/li&gt;
&lt;li&gt;依赖的 Service 无法访问。&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
  </channel>
</rss>
