<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>K8S on 日日是好日-我的生活记录</title>
    <link>http://www.ririshihaori.com:80/categories/k8s/</link>
    <description>Recent content in K8S on 日日是好日-我的生活记录</description>
    <generator>Hugo</generator>
    <language>zh-cn</language>
    <lastBuildDate>Wed, 21 Apr 2021 10:43:56 +0800</lastBuildDate>
    <atom:link href="http://www.ririshihaori.com:80/categories/k8s/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>K8S In Action读书笔记</title>
      <link>http://www.ririshihaori.com:80/posts/2021/4/k8s_in_action/</link>
      <pubDate>Wed, 21 Apr 2021 10:43:56 +0800</pubDate>
      <guid>http://www.ririshihaori.com:80/posts/2021/4/k8s_in_action/</guid>
      <description>&lt;!-- raw HTML omitted --&gt;</description>
    </item>
    <item>
      <title>K8s_informer</title>
      <link>http://www.ririshihaori.com:80/posts/2021/4/k8s_informer/</link>
      <pubDate>Thu, 01 Apr 2021 10:43:56 +0800</pubDate>
      <guid>http://www.ririshihaori.com:80/posts/2021/4/k8s_informer/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://cloudnative.to/blog/client-go-informer-source-code/&#34;&gt;https://cloudnative.to/blog/client-go-informer-source-code/&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Kube-Batch学习笔记</title>
      <link>http://www.ririshihaori.com:80/posts/2020/1/kube-batch/</link>
      <pubDate>Thu, 09 Jan 2020 17:40:49 +0800</pubDate>
      <guid>http://www.ririshihaori.com:80/posts/2020/1/kube-batch/</guid>
      <description>&lt;h1 id=&#34;1概述&#34;&gt;1.概述&lt;/h1&gt;&#xA;&lt;p&gt;　　kube-batch是k8s下面向高性能计算领域的批调度器。&lt;/p&gt;&#xA;&lt;p&gt;　　k8s原生的调度器会将需要启动的容器，放到一个优先队列（Priority Queue）里面，每次从队列里面取出一个容器，将其调度到一个节点上。&lt;/p&gt;&#xA;&lt;p&gt;　　AI分布式训练需要所有worker都启动后，训练才能够开始进行。但是原生的调度器的调度是以pod为粒度的，对AI任务很不利，使用原生调度器，可能会出现以下问题：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;一个任务包含了10个worker，但是集群的资源只满足9个worker。原生调度器会将任务的9个worker调度并启动，而最后一个worker一直无法启动。这样训练一直无法开始，9个已经启动的worker的资源被浪费了。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;两个任务，各包含10个worker，集群的资源只能启动10个worker。两个任务分别有5个worker被启动了，但两个任务都无法开始训练。10个worker的资源被浪费了。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;　　由此可见，原生调度器对于分布式训练的调度存在问题，影响了资源的利用率。而Kubernetes社区提供了一个批调度器kube-batch， 它能够将一个训练任务的多个worker当做一个整体进行调度，只有当任务所有worker的资源都满足，才会将容器在节点上启动。（要不全部，要不全部不，all or none）     &lt;br&gt;&#xA;　　如图所示，kube-batch定义了job和pod group的概念，一个job对应一个pod group，一个pod group里有一个或者多个pod，分别对应一个或多个task。&lt;/p&gt;&#xA;&lt;!-- raw HTML omitted --&gt;&#xA;&lt;h1 id=&#34;2整体框架&#34;&gt;2.整体框架&lt;/h1&gt;&#xA;&lt;!-- raw HTML omitted --&gt;&#xA;&lt;p&gt;　　如图所示，kube-batch中有四个模块，分别是Cache、Session、Plugin和Action。         &lt;br&gt;&#xA;　　其中，Cache负责调用API Server的相关接口，维护整个系统内当前资源的分配状态，供调度器查询和计算。Session是调度器对pod/pod group/queue等进行调度时构建的一个对象，一次会话就是一次调度，调度时会从待调度的pod/queue中选择优先级最高的一个进行调度。          &lt;br&gt;&#xA;　　个人理解：调度时所依据的相关算法/规则/策略就是Plugin，调度产生的结果就是各种Action。&lt;/p&gt;&#xA;&lt;h3 id=&#34;21-cache&#34;&gt;2.1 Cache&lt;/h3&gt;&#xA;&lt;p&gt;　　Cache模块封装了对API Server的节点、容器等对象的数据同步逻辑。Kubernetes的数据保存在分布式存储etcd中，所有对数据的查询和操作都通过调用API Server的接口，而非直接操作etcd。在调度时，需要集群中的节点和容器的使用资源和状态等信息。Cache模块通过调用Kubernetes的SDK，通过watch机制监听集群中的节点、容器的状态变化，将信息同步到自己的数据结构中。        &lt;br&gt;&#xA;　　Cache模块还封装了对API server的接口的调用。比如Cache.Bind这个接口，会去调用API Server的Bind接口，将容器绑定到指定的节点上。在kube-batch中只有cache模块需要和API Server交互，其他模块只需要调用Cache模块的接口。&lt;/p&gt;&#xA;&lt;h3 id=&#34;22-session&#34;&gt;2.2 Session&lt;/h3&gt;&#xA;&lt;p&gt;　　Session模块是将其他三个模块串联起来的一个模块。Kube-batch在每个调度周期开始时，都会新建一个Session对象，这个Session的初始化时，会做以下操作：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;调用Cache.Snapshot接口，将Cache中节点、任务和队列的信息拷贝一份副本，之后在这个调度周期中使用这份副本进行调度。因为Cache的数据会不断变化，为了保持同个调度周期中的数据一致性，在一开始就拷贝了一份副本。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;将配置中的各个Plugin初始化，然后调用plugin的OnSessionOpen接口。Plugin在OnSessionOpen中，会初始化自己需要的数据，并将一些回调函数注册到session中。Plugin可以向Session中注册的函数是：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;jobOrderFns： 决定哪个训练任务优先被处理（调度、回收、抢占）&lt;/li&gt;&#xA;&lt;li&gt;queueOrderFns：决定哪个训练队列优先被处理&lt;/li&gt;&#xA;&lt;li&gt;taskOrderFns：决定任务中哪个容器优先被处理&lt;/li&gt;&#xA;&lt;li&gt;predicateFns： 判断某个节点是否满足容器的基本调度要求。比如容器中指定的节点的标签&lt;/li&gt;&#xA;&lt;li&gt;nodeOrderFns： 当多个节点满足容器的调度要求时，优先选择哪个节点&lt;/li&gt;&#xA;&lt;li&gt;preemptableFns： 决定某个容器是否可以被抢占&lt;/li&gt;&#xA;&lt;li&gt;reclaimableFns ：决定某个容器是否可以被回收&lt;/li&gt;&#xA;&lt;li&gt;overusedFns： 决定某个队列使用的资源是否超过限额，是的话不再调度对队列中的任务&lt;/li&gt;&#xA;&lt;li&gt;jobReadyFns：判断某个任务是否已经准备好，可以调用API Server的接口将任务的容器调度到节点&lt;/li&gt;&#xA;&lt;li&gt;jobPipelinedFns ： 判断某个任务是否处于Pipelined状态&lt;/li&gt;&#xA;&lt;li&gt;jobValidFns： 判断某个任务是否有效&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;　　Plugin不需要注册上面所有的函数，而是可以根据自己的需要，注册某几个函数。比如Predict plugin就只注册了predicateFns这个函数到Session中。      &lt;br&gt;&#xA;　　而某些plugin的使用与否（包括某些action使用与否）都由配置文件决定:(&lt;code&gt;kube-batch/pkg/scheduler/util.go&lt;/code&gt;)&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;var defaultSchedulerConf = `&#xA;actions: &amp;#34;allocate, backfill&amp;#34;&#xA;tiers:&#xA;- plugins:&#xA;  - name: priority&#xA;  - name: gang&#xA;- plugins:&#xA;  - name: drf&#xA;  - name: predicates&#xA;  - name: proportion&#xA;  - name: nodeorder&#xA;```　　&#xA;可知默认配置使用2种action(allocate和backfill)和6种plugin。（tiers是什么意思暂时不明）        &#xA;代码可以参考：&#xA;(`kube-batch/pkg/scheduler/framework/framework.go`)和&#xA;(`kube-batch/pkg/scheduler/framework/session.go`)&#xA;&#xA;### 2.3 Plugin&#xA;&#xA;　　Plugin模块顾名思义，提供了一种可插拔的方式，向调度提供不同的策略的实现。&#xA;&#xA;　　如整体框架中所示，目前有7个Plugin，它们分别是：   &#xA;&#xA;+ for Jobs&#xA;    + drf：实现了Dominant Resouce Fairenss算法，这个算法能够有效对多种“主要资源”（CPU、Memory、GPU）进行调度。&#xA;    + gang：实现了gang scheduling的逻辑，即保证任务所需worker同时被启动。&#xA;    + predict：判断某个节点是否满足容器的基本要求。&#xA;    + priority： 根据容器和队列设置的PriorityClass决定容器和队列的优先级。&#xA;    + node order：决定满足调度要求的节点中，哪个节点优先被选择。&#xA;    + conformance：&#xA;&#xA;+ for Queues:&#xA;    + proportion： 根据队列设置的权重决定每个队列分配到的资源。&#xA;&#xA;　　下面对部分plugin进行说明。&#xA;&#xA;#### 2.3.1 drf&#xA;&#xA;&#xA;&amp;lt;div align=center&amp;gt;&amp;lt;img src = &amp;#39;/2020/1/kube-batch/3.png&amp;#39; style=&amp;#34;zoom:70%&amp;#34; title=&amp;#34;drf&amp;#34;/&amp;gt;&amp;lt;/div&amp;gt;&#xA;&#xA;　　目的是尽量避免集群内某一类资源使用比例偏高，而其他类型资源使用比例却很低的不良状态。在调度时，让具有最低资源占用比例的任务具有高优先级。&#xA;代码位于`kube-batch/pkg/scheduler/plugins/drf/drf.go`，主要关注`onSessionOpen`函数：        &#xA;&#xA;1. 统计集群中所有node可分配资源总量&#xA;2. 统计Job资源申请，计算资源占比（资源申请/资源总量）&#xA;3. 注册Job排序函数，根据资源占比进行排序，主要资源占比越低job优先级越高&#xA;4. 注册事件处理函数，包括分配函数以及驱逐函数，函数实现比较简单，就是当task发生变化时，增加（分配）/减少（驱逐）Job资源申请总量，并且更新资源占比。&#xA;&#xA;　　drf注册2个function，分别是:&#xA;&#xA;+ `jobOrderFn` 是job的排序函数，会让share值越小的job排在最前面，即拥有最高的优先级，这个是实现drf的关键。           &#xA;+  `preemptableFn`返回可抢占的job列表，job的筛选规则是：如果待选job的share值大于将被调度的job的share值，则选中该待选job。      &#xA;&#xA;#### 2.3.2 gang&#xA;&#xA;　　gang需要实现的策略是只有当job中的全部pod，或者用户指定的某几个pod都分配到资源后，才真正将pod调度到node上。（即先从逻辑上分配资源给pod，等满足条件后才真正进行调度。）                &#xA;　　gang注册3个function，分别是：         &#xA;&#xA;+ `preemptableFn` 为避免gang的策略被preempt和reclaiｍ干扰，定义了preemptableFn,排除那些还未准备就绪的job，避免其被抢占。（虽然实际上这些job未真正调度到node上去，但是确实从逻辑上把资源分配给它了）&#xA;+ `jobOrderFn` 为让已经就绪的job尽快被调度到节点，定义了jobOrderFn ,让已经就绪的job拥有更高的优先级&#xA;+ `jobReadyFn` 用来判断一个job是否已经就绪。`jobReady`会调用所有注册了的 plugin的Ready判定函数，只有都判定为ready ,才返回true&#xA;　&#xA;&#xA;#### 2.3.3 predicates&#xA;&#xA;　　predicates注册预测函数,用来判断某个节点是否满足容器的基本要求，如         &#xA;&#xA;+ CheckNodeCondition Predicate&#xA;+ CheckNodeUnschedulable Predicate&#xA;+ NodeSelector Predicate&#xA;+ HostPorts Predicate&#xA;+ Toleration/Taint Predicate        &#xA;+ ...&#xA;&#xA;#### 2.3.4 priority&#xA;&#xA;　　priority注册         &#xA;&#xA;+ task排序函数，根据pod优先级排序&#xA;+ job排序函数，根据job优先级排序&#xA;&#xA;#### 2.3.5 proportion&#xA;&#xA;　　针对队列。&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;type queueAttr struct {&#xA;queueID api.QueueID       // 队列的id&#xA;name    string            // 队列的名字&#xA;weight  int32             // 队列的权重,决定分配到的资源的多少&#xA;share   float64           // 参考drf处的share&#xA;　&#xA;deserved  *api.Resource　 // 声明的资源总量&#xA;allocated *api.Resource   // 实际分配到的资源总量&#xA;request   *api.Resource   // 该队列中所有job声明的要分配的资源总量&#xA;}&lt;/p&gt;</description>
    </item>
    <item>
      <title>Kubernetes学习笔记</title>
      <link>http://www.ririshihaori.com:80/posts/2020/1/k8s/</link>
      <pubDate>Thu, 09 Jan 2020 13:32:38 +0800</pubDate>
      <guid>http://www.ririshihaori.com:80/posts/2020/1/k8s/</guid>
      <description>&lt;h1 id=&#34;背景&#34;&gt;背景&lt;/h1&gt;&#xA;&lt;p&gt;应用程序发展趋势：  &lt;br&gt;&#xA;　　单体应用 -&amp;gt; 微服务&lt;/p&gt;&#xA;&lt;p&gt;产生需求：  　&lt;br&gt;&#xA;　　微服务扩容、部署、软件环境需求差异、自动监控（运维）&lt;/p&gt;&#xA;&lt;h1 id=&#34;linux容器技术&#34;&gt;Linux容器技术&lt;/h1&gt;&#xA;&lt;p&gt;两种隔离机制：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Linux命名空间       &lt;br&gt;&#xA;使每个进程只能看到自己的系统视图（文件、进程、网络接口、主机名等）&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Linux控制组(cgroups)        &lt;br&gt;&#xA;限制了进程能使用的资源量（CPU、内存、网络带宽等）&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h1 id=&#34;虚拟机与容器比较&#34;&gt;虚拟机与容器比较：&lt;/h1&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;前者需要在每个隔离单元中运行系统服务，而后者不需要&lt;/li&gt;&#xA;&lt;li&gt;前者在宿主操作系统上有多个虚拟机操作系统内核，后者只需要一个宿主机系统内核&lt;/li&gt;&#xA;&lt;li&gt;前者的好处是提供完全隔离的环境，可用于隔离少量进程；后者的好处是低消耗，可用于在同一台机器上运行大量被隔离的进程&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h1 id=&#34;docker&#34;&gt;Docker&lt;/h1&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;镜像（image）     &lt;br&gt;&#xA;　　镜像“层”的概念：使镜像分发更高效，减少存储空间（公用层只读，各自新的改动保存在新的层上）&lt;/li&gt;&#xA;&lt;li&gt;镜像仓库&lt;/li&gt;&#xA;&lt;li&gt;容器（container）&lt;/li&gt;&#xA;&lt;li&gt;Docker安装、build&amp;amp;run、Dockerfile、ps -a、rm、tag、push&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h1 id=&#34;rkt&#34;&gt;rkt&lt;/h1&gt;&#xA;&lt;p&gt;强调安全性、可构建性并遵从开放标准，使用OCI容器镜像，甚至可运行常规Docker镜像&lt;/p&gt;&#xA;&lt;h1 id=&#34;kubernetes介绍&#34;&gt;Kubernetes介绍&lt;/h1&gt;&#xA;&lt;p&gt;　　用于部署和管理容器化应用的软件系统，可以提高开发者和运维的效率&lt;/p&gt;&#xA;&lt;h3 id=&#34;kubernetes集群架构&#34;&gt;Kubernetes集群架构&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;主节点（控制面板）&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Kubernetes API服务器&lt;/li&gt;&#xA;&lt;li&gt;Scheduler（调度器）&lt;/li&gt;&#xA;&lt;li&gt;Controller manager（执行集群级别的功能，如复制组件、持续跟踪工作节点、处理节点失败）&lt;/li&gt;&#xA;&lt;li&gt;etcd（可靠的分布式存储，持久化存储集群配置）&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;工作节点（运行用户实际部署的应用）&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Docker、rkt或其他的容器类型&lt;/li&gt;&#xA;&lt;li&gt;Kubelet（与API服务器通信，并管理它所在节点的容器）&lt;/li&gt;&#xA;&lt;li&gt;Kubernetes Service Proxy（kube-proxy）(负责组件之间的负载均衡网络流量)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;使用k8s的好处&#34;&gt;使用k8s的好处&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;简化应用程序部署（开发+运维）&lt;/li&gt;&#xA;&lt;li&gt;更好地利用硬件&lt;/li&gt;&#xA;&lt;li&gt;健康检查和自修复&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;kube-batch&#34;&gt;Kube-Batch&lt;/h3&gt;&#xA;&lt;p&gt;　　Kube-Batch是运行在k8s上面向机器学习/大数据/HPC的批调度器（batch scheduler）。            &lt;br&gt;&#xA;　　开源仓库：https://github.com/kubernetes-sigs/kube-batch&lt;/p&gt;&#xA;&lt;h1 id=&#34;使用minikube构建单节点集群&#34;&gt;使用Minikube构建单节点集群&lt;/h1&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;下载kubectl        &lt;br&gt;&#xA;&lt;code&gt;# curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.16.0/bin/linux/amd64/kubectl&lt;/code&gt;     &lt;br&gt;&#xA;&lt;code&gt;# mv kubectl /usr/local/bin/ &amp;amp;&amp;amp; chmod +x /usr/local/bin/kubectl&lt;/code&gt;         &lt;br&gt;&#xA;&lt;code&gt;# kubectl version&lt;/code&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;kubectl zsh下自动补全，~/.zshrc中增加：         &lt;br&gt;&#xA;&lt;code&gt;plugins=(kubectl)&lt;/code&gt;       &lt;br&gt;&#xA;&lt;code&gt;source &amp;lt;(kubectl completion zsh)&lt;/code&gt;           &lt;br&gt;&#xA;然后终端中source &lt;code&gt;~/.zshrc&lt;/code&gt;&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
