<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>translation | 伪架构师</title>
    <link>/tags/translation/</link>
      <atom:link href="/tags/translation/index.xml" rel="self" type="application/rss+xml" />
    <description>translation</description>
    <generator>Source Themes Academic (https://sourcethemes.com/academic/)</generator><language>zh</language><lastBuildDate>Thu, 01 Jun 2017 19:25:48 +0800</lastBuildDate>
    <image>
      <url>/img/logo-wide.png</url>
      <title>translation</title>
      <link>/tags/translation/</link>
    </image>
    
    <item>
      <title>针对资源紧缺处理方式的配置</title>
      <link>/post/kubernetes-resource-evict/</link>
      <pubDate>Thu, 01 Jun 2017 19:25:48 +0800</pubDate>
      <guid>/post/kubernetes-resource-evict/</guid>
      <description>

&lt;p&gt;原文：&lt;a href=&#34;https://kubernetes.io/docs/tasks/administer-cluster/out-of-resource/&#34; target=&#34;_blank&#34;&gt;Configure Out Of Resource Handling&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;如何在资源紧缺的情况下，保证 Node 的稳定性，是 Kubelet 需要面对的一个重要的问题。尤其对于内存和磁盘这种不可压缩的资源，紧缺就相当于不稳定。&lt;/p&gt;

&lt;h2 id=&#34;驱逐策略&#34;&gt;驱逐策略&lt;/h2&gt;

&lt;p&gt;Kubelet 能够监控资源消耗，来防止计算资源被耗尽。一旦出现资源紧缺的迹象，Kubelet 就会主动终止一或多个 Pod 的运行，以回收紧俏资源。当一个 Pod 被终止时，其中的容器会全部停止，Pod 状态会被置为  &lt;code&gt;Failed&lt;/code&gt;。&lt;/p&gt;

&lt;h3 id=&#34;驱逐信号&#34;&gt;驱逐信号&lt;/h3&gt;

&lt;p&gt;下文中提到了一些信号，kubelet 能够利用这些信号作为决策依据来触发驱逐行为。描述列中的内容来自于 Kubelet summary API。&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;驱逐信号&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;

&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;memory.available&lt;/td&gt;
&lt;td&gt;memory.available := node.status.capacity[memory] - node.stats.memory.workingSet&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;nodefs.available&lt;/td&gt;
&lt;td&gt;nodefs.available := node.stats.fs.available&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;nodefs.inodesFree&lt;/td&gt;
&lt;td&gt;nodefs.inodesFree := node.stats.fs.inodesFree&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;imagefs.available&lt;/td&gt;
&lt;td&gt;imagefs.available := node.stats.runtime.imagefs.available&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;imagefs.inodesFree&lt;/td&gt;
&lt;td&gt;imagefs.inodesFree := node.stats.runtime.imagefs.inodesFree&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;上面的每个信号都支持整数值或者百分比。百分比的分母部分就是各个信号的总量。kubelet 支持两种文件系统分区。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;nodefs&lt;/code&gt;：保存 kubelet 的卷和守护进程日志等。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;imagefs&lt;/code&gt;：在容器运行时，用于保存镜像以及可写入层。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;imagefs 是可选的。Kubelet 能够利用 cAdvisor 自动发现这些文件系统。Kubelet 不关注其他的文件系统。所有其他类型的配置，例如保存在独立文件系统的卷和日志，都不被支持。&lt;/p&gt;

&lt;p&gt;因为磁盘压力已经被驱逐策略接管，因此未来将会停止对现有 &lt;a href=&#34;http://kubernetes.io/docs/admin/garbage-collection/&#34; target=&#34;_blank&#34;&gt;垃圾收集&lt;/a&gt; 方式的支持。&lt;/p&gt;

&lt;h3 id=&#34;驱逐阈-yù-音同-预-值&#34;&gt;驱逐阈（yù，音同“预”）值：&lt;/h3&gt;

&lt;p&gt;一旦超出阈值，就会触发 kubelet 进行资源回收的动作。阈值的定义方式如下：&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;eviction-signal&amp;gt;&amp;lt;operator&amp;gt;&amp;lt;quantity&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;上面的表格中列出了可用的 &lt;code&gt;eviction-signal&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;仅有一个 &lt;code&gt;operator&lt;/code&gt; 可用：&lt;strong&gt;&amp;lt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;quantity&lt;/code&gt; 需要符合 Kubernetes 中的描述方式。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;例如如果一个 Node 有 10Gi 内存，我们希望在可用内存不足 1Gi 时进行驱逐，就可以选取下面的一种方式来定义驱逐阈值：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;memory.available&amp;lt;10%&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;memory.available&amp;lt;1Gi&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&#34;驱逐软阈值&#34;&gt;驱逐软阈值&lt;/h4&gt;

&lt;p&gt;软阈值需要和一个宽限期参数协同工作。当系统资源消耗达到软阈值时，这一状况的持续时间超过了宽限期之前，Kubelet 不会触发任何动作。如果没有定义宽限期，Kubelet 会拒绝启动。&lt;/p&gt;

&lt;p&gt;另外还可以定义一个 Pod 结束的宽限期。如果定义了这一宽限期，那么 Kubelet 会使用 &lt;code&gt;pod.Spec.TerminationGracePeriodSeconds&lt;/code&gt; 和最大宽限期这两个值之间较小的那个（进行宽限），如果没有指定的话，kubelet 会不留宽限立即杀死 Pod。&lt;/p&gt;

&lt;p&gt;软阈值的定义包括以下几个参数：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;eviction-soft&lt;/code&gt;：描述一套驱逐阈值（例如 &lt;code&gt;memory.available&amp;lt;1.5Gi&lt;/code&gt; ），如果满足这一条件的持续时间超过宽限期，就会触发对 Pod 的驱逐动作。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;eviction-soft-grace-period&lt;/code&gt;：包含一套驱逐宽限期（例如 &lt;code&gt;memory.available=1m30s&lt;/code&gt;），用于定义达到软阈值之后，持续时间超过多久才进行驱逐。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;eviction-max-pod-grace-period&lt;/code&gt;：在因为达到软阈值之后，到驱逐一个 Pod 之前的最大宽限时间（单位是秒），&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&#34;驱逐硬阈值&#34;&gt;驱逐硬阈值&lt;/h4&gt;

&lt;p&gt;硬阈值没有宽限期，如果达到了硬阈值，kubelet 会立即杀掉 Pod 并进行资源回收。&lt;/p&gt;

&lt;p&gt;硬阈值的定义：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;eviction-hard&lt;/code&gt;：描述一系列的驱逐阈值（比如说 &lt;code&gt;memory.available&amp;lt;1Gi&lt;/code&gt;），一旦达到这一阈值，就会触发对 Pod 的驱逐，缺省的硬阈值定义是：&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&amp;ndash;eviction-hard=memory.available&amp;lt;100Mi&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&#34;驱逐监控频率&#34;&gt;驱逐监控频率&lt;/h3&gt;

&lt;p&gt;Housekeeping interval 参数定义一个时间间隔，Kubelet 每隔这一段就会对驱逐阈值进行评估。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;housekeeping-interval&lt;/code&gt;：容器检查的时间间隔。&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;节点状况&#34;&gt;节点状况&lt;/h2&gt;

&lt;p&gt;Kubelet 会把驱逐信号跟节点状况对应起来。&lt;/p&gt;

&lt;p&gt;如果触发了硬阈值，或者符合软阈值的时间持续了与其对应的宽限期，Kubelet 就会认为当前节点压力太大，下面的节点状态定义描述了这种对应关系。&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;节点状况&lt;/th&gt;
&lt;th&gt;驱逐信号&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;

&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;MemoryPressure&lt;/td&gt;
&lt;td&gt;memory.available&lt;/td&gt;
&lt;td&gt;节点的可用内存达到了驱逐阈值&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;DiskPressure&lt;/td&gt;
&lt;td&gt;nodefs.available, nodefs.inodesFree, imagefs.available, imagefs.inodesFree&lt;/td&gt;
&lt;td&gt;节点的 root 文件系统或者镜像文件系统的可用空间达到了驱逐阈值&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Kubelet 会持续报告节点状态的更新过程，这一频率由参数 &lt;strong&gt;&amp;ndash;node-status-update-frequency&lt;/strong&gt; 指定，缺省情况下取值为 &lt;strong&gt;10s&lt;/strong&gt;。&lt;/p&gt;

&lt;h3 id=&#34;节点状况的波动&#34;&gt;节点状况的波动&lt;/h3&gt;

&lt;p&gt;如果一个节点的状况在软阈值的上下波动，但是又不会超过他的宽限期，将会导致该节点的状态持续的在是否之间徘徊，最终会影响降低调度的决策过程。&lt;/p&gt;

&lt;p&gt;要防止这种状况，下面的标志可以用来通知 Kubelet，在脱离压力状态之前，必须等待。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;eviction-pressure-transition-period&lt;/code&gt; 定义了在跳出压力状态之前要等待的时间。&lt;/p&gt;

&lt;p&gt;Kubelet 在把压力状态设置为 False 之前，会确认在周期之内，该节点没有达到逐出阈值。&lt;/p&gt;

&lt;h2 id=&#34;回收节点级别的资源&#34;&gt;回收节点级别的资源&lt;/h2&gt;

&lt;p&gt;如果达到了驱逐阈值，并且超出了宽限期，那么 Kubelet 会开始回收超出限量的资源，直到驱逐信号量回到阈值以内。&lt;/p&gt;

&lt;p&gt;Kubelet 在驱逐用户 Pod 之前，会尝试回收节点级别的资源。如果服务器为容器定义了独立的 imagefs，他的回收过程会有所不同。&lt;/p&gt;

&lt;h3 id=&#34;有-imagefs&#34;&gt;有 Imagefs&lt;/h3&gt;

&lt;p&gt;如果 nodefs 文件系统到达了驱逐阈值，kubelet 会按照下面的顺序来清理空间。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;删除死掉的 Pod/容器&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;如果 imagefs 文件系统到达了驱逐阈值，kubelet 会按照下面的顺序来清理空间。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;删掉所有无用镜像&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&#34;没有-imagefs&#34;&gt;没有 Imagefs&lt;/h3&gt;

&lt;p&gt;如果 nodefs 文件系统到达了驱逐阈值，kubelet 会按照下面的顺序来清理空间。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;删除死掉的 Pod/容器&lt;/li&gt;
&lt;li&gt;删掉所有无用镜像&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&#34;驱逐用户-pod&#34;&gt;驱逐用户 Pod&lt;/h2&gt;

&lt;p&gt;如果 Kubelet 无法获取到足够的资源，就会开始驱逐 Pod。&lt;/p&gt;

&lt;p&gt;Kubelet 会按照下面的标准对 Pod 的驱逐行为进行评判：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;根据服务质量&lt;/li&gt;
&lt;li&gt;根据 Pod 调度请求的被耗尽资源的消耗量&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;接下来，Pod 按照下面的顺序进行驱逐：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;BestEffort&lt;/code&gt;：消耗最多紧缺资源的 Pod 最先失败。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Burstable&lt;/code&gt;：相对请求（request）最多紧缺资源的 Pod 最先被驱逐，如果没有 Pod 超出他们的请求，策略会瞄准紧缺资源消耗量最大的 Pod。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Guaranteed&lt;/code&gt;：相对请求（request）最多紧缺资源的 Pod 最先被驱逐，如果没有 Pod 超出他们的请求，策略会瞄准紧缺资源消耗量最大的 Pod。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;Guaranteed Pod&lt;/code&gt; 绝不会因为其他 Pod 的资源消费被驱逐。如果系统进程（例如 kubelet、docker、journald 等）消耗了超出 &lt;code&gt;system-reserved&lt;/code&gt; 或者 &lt;code&gt;kube-reserved&lt;/code&gt; 的资源，而且这一节点上只运行了 Guaranteed Pod，那么为了保证节点的稳定性并降低异常消费对其他 Guaranteed Pod 的影响，必须选择一个 Guaranteed Pod 进行驱逐。&lt;/p&gt;

&lt;p&gt;本地磁盘是一个 &lt;code&gt;BestEffort&lt;/code&gt; 资源。如有必要，kubelet 会在 &lt;code&gt;DiskPressure&lt;/code&gt; 的情况下，kubelet 会按照 QoS 进行评估。如果 Kubelet 判定缺乏 inode 资源，就会通过驱逐最低 QoS 的 Pod 的方式来回收 inodes。如果 kubelet 判定缺乏磁盘空间，就会通过在相同 QoS 的 Pods 中，选择消耗最多磁盘空间的 Pod 进行驱逐。&lt;/p&gt;

&lt;h3 id=&#34;有-imagefs-1&#34;&gt;有 Imagefs&lt;/h3&gt;

&lt;p&gt;如果 nodefs 触发了驱逐，Kubelet 会用 nodefs 的使用对 Pod 进行排序 - Pod 中所有容器的本地卷和日志。&lt;/p&gt;

&lt;p&gt;如果 imagefs 触发了驱逐，Kubelet 会根据 Pod 中所有容器的消耗的可写入层进行排序。&lt;/p&gt;

&lt;h3 id=&#34;没有-imagefs-1&#34;&gt;没有 Imagefs&lt;/h3&gt;

&lt;p&gt;如果 nodefs 触发了驱逐，Kubelet 会对各个 Pod 的所有容器的总体磁盘消耗进行排序 —— 本地卷 + 日志 + 写入层。&lt;/p&gt;

&lt;p&gt;在某些场景下，驱逐 Pod 可能只回收了很少的资源。这就导致了 kubelet 反复触发驱逐阈值。另外回收资源例如磁盘资源，是需要消耗时间的。&lt;/p&gt;

&lt;p&gt;要缓和这种状况，Kubelet 能够对每种资源定义 &lt;code&gt;minimum-reclaim&lt;/code&gt;。kubelet 一旦发现了资源压力，就会试着回收至少 &lt;code&gt;minimum-reclaim&lt;/code&gt; 的资源，使得资源消耗量回到期望范围。&lt;/p&gt;

&lt;p&gt;例如下面的配置：&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;--eviction-hard=memory.available&amp;lt;500Mi,nodefs.available&amp;lt;1Gi,imagefs.available&amp;lt;100Gi
--eviction-minimum-reclaim=&amp;quot;memory.available=0Mi,nodefs.available=500Mi,imagefs.available=2Gi&amp;quot;`
&lt;/code&gt;&lt;/pre&gt;

&lt;ul&gt;
&lt;li&gt;如果 &lt;code&gt;memory.available&lt;/code&gt; 被触发，Kubelet 会启动回收，让 &lt;code&gt;memory.available&lt;/code&gt; 至少有 &lt;strong&gt;500Mi&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;如果是 &lt;code&gt;nodefs.available&lt;/code&gt;，Kubelet 就要想法子让 &lt;code&gt;nodefs.available&lt;/code&gt; 回到至少 &lt;strong&gt;1.5Gi&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;而对于 &lt;code&gt;imagefs.available&lt;/code&gt;， kubelet 就要回收到最少 &lt;strong&gt;102Gi&lt;/strong&gt;。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;缺省情况下，所有资源的 &lt;code&gt;eviction-minimum-reclaim&lt;/code&gt; 为 &lt;strong&gt;0&lt;/strong&gt;。&lt;/p&gt;

&lt;h2 id=&#34;调度器&#34;&gt;调度器&lt;/h2&gt;

&lt;p&gt;在节点资源紧缺的情况下，节点会报告这一状况。调度器以此为信号，不再继续向此节点部署新的 Pod。&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;节点状况&lt;/th&gt;
&lt;th&gt;调度行为&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;

&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;MemoryPressure&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;不再分配新的 &lt;code&gt;BestEffort Pod&lt;/code&gt; 到这个节点&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;DiskPressure&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;不再向这一节点分配 Pod&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&#34;节点的-oom-行为&#34;&gt;节点的 OOM 行为&lt;/h2&gt;

&lt;p&gt;如果节点在 Kubelet 能够回收内存之前，遭遇到了系统的 OOM (内存不足)，节点就依赖 &lt;a href=&#34;https://lwn.net/Articles/391222/&#34; target=&#34;_blank&#34;&gt;&lt;code&gt;oom_killer&lt;/code&gt;&lt;/a&gt; 进行响应了。&lt;/p&gt;

&lt;p&gt;kubelet 根据 Pod 的 QoS 为每个容器设置了一个 &lt;code&gt;oom_score_adj&lt;/code&gt; 值。&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;QoS&lt;/th&gt;
&lt;th&gt;&lt;code&gt;oom_score_adj&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;

&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Guaranteed&lt;/td&gt;
&lt;td&gt;-998&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;BestEffort&lt;/td&gt;
&lt;td&gt;1000&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;Burstable&lt;/td&gt;
&lt;td&gt;&lt;code&gt;min(max(2, 1000 - (1000 * memoryRequestBytes) / machineMemoryCapacityBytes), 999)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;如果 kubelet 无法在系统 OOM 之前回收足够的内存，&lt;code&gt;oom_killer&lt;/code&gt; 就会根据根据内存使用比率来计算 &lt;code&gt;oom_score&lt;/code&gt;，得出结果和 &lt;code&gt;oom_score_adj&lt;/code&gt; 相加，最后得分最高的 Pod 会被首先驱逐。&lt;/p&gt;

&lt;p&gt;这一行为的思路是，QoS 最低，相对于调度的 Reqeust 来说又消耗最多内存的 Pod 会被首先清除，来保障内存的回收。&lt;/p&gt;

&lt;p&gt;跟 Pod 驱逐不同，如果一个 Pod 的容器被 OOM 杀掉，他是可能被 kubelet 根据 &lt;code&gt;RestartPolicy&lt;/code&gt; 重启的。&lt;/p&gt;

&lt;h2 id=&#34;最佳时间&#34;&gt;最佳时间&lt;/h2&gt;

&lt;h3 id=&#34;可调度的资源和驱逐策略&#34;&gt;可调度的资源和驱逐策略&lt;/h3&gt;

&lt;p&gt;我们想象如下的场景：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;节点内存容量：10Gi&lt;/li&gt;
&lt;li&gt;保留 10% 的内存容量给系统服务（内核，kubelet 等）。&lt;/li&gt;
&lt;li&gt;在 95% 内存使用率的时候驱逐 Pod，来降低系统 OOM 的发生率。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;所以我们用这样的参数启动 Kubelet：&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;--eviction-hard=memory.available&amp;lt;500Mi
--system-reserved=memory=1.5Gi
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;这个配置中隐含了一个设定就是，系统保留涵盖了驱逐标准。&lt;/p&gt;

&lt;p&gt;要达到这一容量，可能是有的 Pod 使用了超出其请求的数量，或者系统占用了超过 &lt;strong&gt;500Mi&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;这样的配置保证了调度器不会向即将发生内存压力的节点分配 Pod，避免触发驱逐。&lt;/p&gt;

&lt;h2 id=&#34;daemonset&#34;&gt;DaemonSet&lt;/h2&gt;

&lt;p&gt;因为 DaemonSet 中的 Pod 会立即重建到同一个节点，所以 Kubelet 不应驱逐 DaemonSet 中的 Pod。&lt;/p&gt;

&lt;p&gt;但是目前 Kubelet 无法分辨一个 Pod 是否由 DaemonSet 创建。如果/当 Kubelet 能够识别这一点，那么就可以先从驱逐候选列表中过滤掉 DaemonSet 的 Pod。&lt;/p&gt;

&lt;p&gt;一般来说，强烈建议 DaemonSet 不要创建 BestEffort Pod，而是使用 Guaranteed Pod，来避免进入驱逐候选列表。&lt;/p&gt;

&lt;h2 id=&#34;弃用的现存回收磁盘的选项&#34;&gt;弃用的现存回收磁盘的选项&lt;/h2&gt;

&lt;p&gt;为了保证节点的稳定性，Kubelet 已经尝试来释放磁盘空间了。&lt;/p&gt;

&lt;p&gt;因为基于磁盘的驱逐方式已经成熟，下列的 Kubelet 参数会被标记为弃用。&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;现有参数&lt;/th&gt;
&lt;th&gt;新参数&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;

&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&amp;ndash;image-gc-high-threshold&lt;/td&gt;
&lt;td&gt;&amp;ndash;eviction-hard or eviction-soft&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&amp;ndash;image-gc-low-threshold&lt;/td&gt;
&lt;td&gt;&amp;ndash;eviction-minimum-reclaim&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&amp;ndash;maximum-dead-containers&lt;/td&gt;
&lt;td&gt;弃用&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&amp;ndash;maximum-dead-containers-per-container&lt;/td&gt;
&lt;td&gt;弃用&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&amp;ndash;minimum-container-ttl-duration&lt;/td&gt;
&lt;td&gt;弃用&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&amp;ndash;low-diskspace-threshold-mb&lt;/td&gt;
&lt;td&gt;&amp;ndash;eviction-hard or eviction-soft&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&amp;ndash;outofdisk-transition-frequency&lt;/td&gt;
&lt;td&gt;&amp;ndash;eviction-pressure-transition-period&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&#34;已知问题&#34;&gt;已知问题&lt;/h2&gt;

&lt;h3 id=&#34;kubelet-无法及时观测到内存压力&#34;&gt;Kubelet 无法及时观测到内存压力&lt;/h3&gt;

&lt;p&gt;Kubelet 目前从 cAdvisor 定时获取内存使用状况统计。如果内存使用在这个时间段内发生了快速增长，Kubelet 就无法观察到 MemoryPressure，可能会触发 OOMKiller。我们正在尝试将这一过程集成到 memcg 通知 API 中，来降低这一延迟，而不是让内核首先发现这一情况。&lt;/p&gt;

&lt;p&gt;如果用户不是希望获得终极使用率，而是作为一个过量使用的衡量方式，对付这一个问题的较为可靠的方式就是设置驱逐阈值为 75% 容量。这样就提高了避开 OOM 的能力，提高了驱逐的标准，有助于集群状态的平衡。&lt;/p&gt;

&lt;h3 id=&#34;kubelet-可能驱逐超出需要的更多-pod&#34;&gt;Kubelet 可能驱逐超出需要的更多 Pod&lt;/h3&gt;

&lt;p&gt;这也是因为状态搜集的时间差导致的。未来会加入功能，让根容器的统计频率和其他容器分别开来（&lt;code&gt;https://github.com/google/cadvisor/issues/1247&lt;/code&gt;）。&lt;/p&gt;

&lt;h3 id=&#34;kubelet-如何在-inode-耗尽的时候评价-pod-的驱逐&#34;&gt;Kubelet 如何在 inode 耗尽的时候评价 Pod 的驱逐&lt;/h3&gt;

&lt;p&gt;目前不可能知道一个容器消耗了多少 inode。如果 Kubelet 觉察到了 inode 耗尽，他会利用 QoS 对 Pod 进行驱逐评估。在 &lt;a href=&#34;https://github.com/google/cadvisor/issues/1422&#34; target=&#34;_blank&#34;&gt;cadvisor 中有一个 issue&lt;/a&gt;，来跟踪容器的 inode 消耗，这样我们就能利用 inode 进行评估了。例如如果我们知道一个容器创建了大量的 0 字节文件，就会优先驱逐这一 Pod&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Minikube：轻松运行本地 Kuberntes 集群</title>
      <link>/post/minikube-easily-run-kubernetes-locally/</link>
      <pubDate>Thu, 14 Jul 2016 15:49:24 +0800</pubDate>
      <guid>/post/minikube-easily-run-kubernetes-locally/</guid>
      <description>

&lt;p&gt;原文：&lt;a href=&#34;https://kubernetes.io/blog/2016/07/minikube-easily-run-kubernetes-locally&#34; target=&#34;_blank&#34;&gt;Minikube: easily run Kubernetes locally&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Kubernetes 已经是目前最佳的应用容器化工具之一。在投入实际使用之后的一年来，Kubernetes（社区）需要一个本地开发平台。&lt;/p&gt;

&lt;p&gt;在过去的几个月中，Kubernetes 社区中的很多成员在为 Github 的 &lt;a href=&#34;http://github.com/kubernetes/minikube&#34; target=&#34;_blank&#34;&gt;Minikube 仓库&lt;/a&gt; 奋战。我们要建立一个可以一键运行的版本，这个版本要易用和准确兼顾，并且能够兼容 Mac、 Linux 以及 Windows 的工作站和笔记本电脑。&lt;/p&gt;

&lt;p&gt;感谢社区成员的贡献，我们自豪的宣告 Minikube 的诞生，并与 &lt;a href=&#34;http://blog.kubernetes.io/2016/07/kubernetes-1.3-bridging-cloud-native-and-enterprise-workloads.html&#34; target=&#34;_blank&#34;&gt;Kubernetes 1.3&lt;/a&gt; 一起发布，新的命令能够更好的跟本地集群通信，并且加入了试验性的对 xhyve（OS X）以及 KVM（Linux）的支持。&lt;/p&gt;

&lt;h2 id=&#34;使用-minikube&#34;&gt;使用 Minikube&lt;/h2&gt;

&lt;p&gt;Minitube 是一个独立的 Go 应用，所以只要下载运行就可以了：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Minikube 目前要求安装 &lt;a href=&#34;https://www.virtualbox.org/&#34; target=&#34;_blank&#34;&gt;VirtualBox&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;# 这是针对 Mac， 如果是 Linux 的话，用 minikube-linux-amd64 代替 minikube-darwin-amd64 即可

curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-darwin-amd64 &amp;amp;&amp;amp; chmod +x minikube &amp;amp;&amp;amp; sudo mv minikube /usr/local/bin/
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;要启动 Kubernetes 集群，要使用&lt;code&gt;minikube start&lt;/code&gt;命令：&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ minikube start
Starting local Kubernetes cluster...
Kubernetes is available at https://192.168.99.100:443
Kubectl is now configured to use the cluster
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;img src=&#34;images/cluster-starts.png&#34; alt=&#34;cluster starts&#34; /&gt;&lt;/p&gt;

&lt;p&gt;这样，就在你的电脑上启动了一个单节点的 Kubernetes 集群。Minikube 会给你配置 &lt;code&gt;kubectl&lt;/code&gt;，所以你现在就可以运行容器了。&lt;/p&gt;

&lt;p&gt;Minikube 创建了一个 Host-Only 的网络界面来和 Node 通信。要和其中的 Pod 或者 Service 通信，就需要跟这个地址进行交互。可以使用 &lt;code&gt;minikube ip&lt;/code&gt; 命令：&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;images/minikube-ip.png&#34; alt=&#34;minikube ip&#34; /&gt;&lt;/p&gt;

&lt;p&gt;Minikube 还自带了 Kubernetes Dashboard。要浏览这个界面，可以使用内置的 &lt;code&gt;minikube dashboard&lt;/code&gt;命令。&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;images/dashboard-cmd.png&#34; alt=&#34;dashboard command&#34; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;images/dashboard.png&#34; alt=&#34;dashboard screen shot&#34; /&gt;&lt;/p&gt;

&lt;p&gt;一般来说，Minikube 支持 Kubernetes 集群的所有内容。你可以使用 &lt;code&gt;kubectl exec&lt;/code&gt; 来在 pod 内获取一个 bash shell。还可以使用 &lt;code&gt;kubectl port-forward&lt;/code&gt; 以及 &lt;code&gt;kubectl proxy&lt;/code&gt; 命令来把通信从本地转发到一个 pod 或者 API server。&lt;/p&gt;

&lt;p&gt;Minikube 是运行在本地而不是云供应商，因此特定的 LoadBalancer 以及 PersistentVolume 也就无法使用了；当然，还是可以使用 NodePort 以及 HostPath 作为替代方案。&lt;/p&gt;

&lt;h2 id=&#34;架构&#34;&gt;架构&lt;/h2&gt;

&lt;p&gt;Minikube 构建于 Docker 的 &lt;a href=&#34;https://github.com/docker/machine/tree/master/libmachine&#34; target=&#34;_blank&#34;&gt;libmachine&lt;/a&gt;，利用他的驱动模型来创建、管理本地运行的虚拟机，并与其交互。&lt;/p&gt;

&lt;p&gt;慷慨的 &lt;a href=&#34;https://redspread.com/&#34; target=&#34;_blank&#34;&gt;RedSpread&lt;/a&gt;向 Minikube 贡献了他们的 &lt;a href=&#34;https://github.com/redspread/localkube&#34; target=&#34;_blank&#34;&gt;localkube&lt;/a&gt; 代码，得到这一帮助，我们有了在虚拟机中创建单进程 Kubernetes 集群的能力。Localkube 把 etcd、DNS、Kubelet 以及所有的 Kubernetes Master 组件都集成到了一个单独的 Go Lib 中并使用不同的 goroutine 执行。&lt;/p&gt;

&lt;h2 id=&#34;后续发展&#34;&gt;后续发展&lt;/h2&gt;

&lt;p&gt;Minikube 现在已经颇具可玩性了，为了改善 Kubernetes 开发体验，我们会持续对 Minikube 进行增强。如果你有任何设想，请移步 &lt;a href=&#34;https://github.com/kubernetes/minikube/issues&#34; target=&#34;_blank&#34;&gt;issue tracker&lt;/a&gt; 畅所欲言。&lt;/p&gt;

&lt;p&gt;我们希望尽快把下面列表中的内容加入 Minikube：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;为 OSX 以及 Windows 提供本地的 Native hypervisor 支持。

&lt;ul&gt;
&lt;li&gt;我们计划去掉对 Virtualbox 的依赖，转向 OSX 和 Windows 的本地 Hypervisor。&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;增强对 Kubernetes 特性的支持

&lt;ul&gt;
&lt;li&gt;希望能够进一步缩小功能差异，以便于引入 Ingress 之类的内容。&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;可配置的 Kubernetes 版本

&lt;ul&gt;
&lt;li&gt;目前 Minikube 只支持 Kubernetes 1.3。我们计划提供用户可控的 Kubernetes 版本支持，这样就能够让开发与生产环境更加贴近。&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;社区&#34;&gt;社区&lt;/h2&gt;

&lt;p&gt;我们乐于听取 Minikube 的反馈，可以用下面的方式参与社区：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;在 &lt;a href=&#34;https://github.com/kubernetes/minikube&#34; target=&#34;_blank&#34;&gt;GitHub&lt;/a&gt; 中提出 Issue 或者提出功能要求。&lt;/li&gt;
&lt;li&gt;加入 &lt;a href=&#34;https://kubernetes.slack.com/&#34; target=&#34;_blank&#34;&gt;Slack&lt;/a&gt; 的 &lt;code&gt;#minikube&lt;/code&gt; 频道&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;请给 Minikube 一个机会，并让我们能够获知 Minikube 的运行情况。&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>
