<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Janakiram MSV | 伪架构师</title>
    <link>/authors/janakiram-msv/</link>
      <atom:link href="/authors/janakiram-msv/index.xml" rel="self" type="application/rss+xml" />
    <description>Janakiram MSV</description>
    <generator>Source Themes Academic (https://sourcethemes.com/academic/)</generator><language>zh</language><lastBuildDate>Sat, 20 Oct 2018 00:46:47 +0800</lastBuildDate>
    <image>
      <url>/img/logo-wide.png</url>
      <title>Janakiram MSV</title>
      <link>/authors/janakiram-msv/</link>
    </image>
    
    <item>
      <title>在 Kubernetes 和 Istio 环境下进行蓝绿部署</title>
      <link>/post/tutorial-blue-green-deployments-with-kubernetes-and-istio/</link>
      <pubDate>Sat, 20 Oct 2018 00:46:47 +0800</pubDate>
      <guid>/post/tutorial-blue-green-deployments-with-kubernetes-and-istio/</guid>
      <description>

&lt;p&gt;原文：&lt;a href=&#34;https://thenewstack.io/tutorial-blue-green-deployments-with-kubernetes-and-istio/&#34; target=&#34;_blank&#34;&gt;Tutorial: Blue/Green Deployments with Kubernetes and Istio&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;作者：&lt;a href=&#34;https://thenewstack.io/author/janakiram/&#34; target=&#34;_blank&#34;&gt;Janakiram MSV&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;作为一个服务网格系统，Istio 为服务间通信提供稳定性、透明性和安全性方面的保障。不论集群内外的服务，只要其访问目标是网格内的服务，就都会被 Istio 所拦截并进行处理。&lt;/p&gt;

&lt;p&gt;Istio 有很多功能，例如服务间通信的加密、自动的指标记录、访问控制策略、频率限制以及配额等，这里我们仅着眼于最常用的流量管理能力。&lt;/p&gt;

&lt;p&gt;Istio 让 DevOps 团队有能力为内部服务创建智能的路由规则。断路器、超时和重试之类的服务级属性非常容易配置，配置包含蓝绿部署及金丝雀发布的过程也很轻松。&lt;/p&gt;

&lt;p&gt;本文教程用于帮助读者理解配置 Kubernetes + Istio 环境下的蓝绿部署过程。无需很多知识背景，只要理解一些在 Kubernetes 中部署 Pod 和服务的基础概念就好。我们会在 Minikube 和 Istio 中完成示例。&lt;/p&gt;

&lt;p&gt;教程包含四个步骤：安装 Minikube、安装 Istio 并进行验证、安装一个应用的两个版本，最后配置服务的蓝绿部署。我们会使用两个简单的构建好了的镜像，分别作为蓝（v1）、绿（v2）两个版本。&lt;/p&gt;

&lt;h2 id=&#34;步骤-1-安装-minikube&#34;&gt;步骤 1：安装 Minikube&lt;/h2&gt;

&lt;p&gt;为了降低依赖，我们会使用 Minikube 作为测试平台。因为需要自定义配置，所以要删除已经存在的配置，并使用额外参数重新启动集群：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;minikube start --memory=8192 --cpus=4 --kubernetes-version=v1.10.0 \
--extra-config=controller-manager.cluster-signing-cert-file=&amp;quot;/var/lib/localkube/certs/ca.crt&amp;quot; \
--extra-config=controller-manager.cluster-signing-key-file=&amp;quot;/var/lib/localkube/certs/ca.key&amp;quot; \
--vm-driver=virtualbox
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;要在 Minikube 上运行 Istio，需要至少 8G 内存和 4 个 CPU 核心。等集群启动：&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;images/b1cfb731-istio-0-1024x431.png&#34; alt=&#34;minikube startup&#34; /&gt;&lt;/p&gt;

&lt;h2 id=&#34;步骤-2-安装-istio&#34;&gt;步骤 2：安装 Istio&lt;/h2&gt;

&lt;p&gt;Kubernetes 集群成功启动之后，就可以安装 Istio 了。用下面的步骤完成：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;curl -L https://git.io/getLatestIstio | sh -
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;在运行上述命令的目录中会发现一个 &lt;code&gt;istio-1.0.2&lt;/code&gt; 目录，可以把 &lt;code&gt;istio-1.0.2/bin&lt;/code&gt; 目录加入 &lt;code&gt;PATH&lt;/code&gt; 变量，方便后面的命令执行过程。&lt;/p&gt;

&lt;p&gt;由于我们在 Minikube 环境下运行的 Istio，所以我们要在下一步进行之前，要把 Ingress Gateway 服务从 &lt;code&gt;LoadBalancer&lt;/code&gt; 改为 &lt;code&gt;NodePort&lt;/code&gt;。&lt;/p&gt;

&lt;p&gt;打开文件 &lt;code&gt;istio-1.0.2/install/kubernetes/istio-demo.yaml&lt;/code&gt;，查找并替换：&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;images/2a64731e-istio-1.png&#34; alt=&#34;Changing Service Type&#34; /&gt;&lt;/p&gt;

&lt;p&gt;Istio 中包含了很多 CRD，可以帮用户来进行虚拟服务、规则、网关以及其他对象的管理。在部署服务网格之前首先要部署一下这些 CRD：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl apply -f install/kubernetes/helm/istio/templates/crds.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;最后，在 Kubernetes 中安装 Istio：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl apply -f install/kubernetes/istio-demo.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;上面的步骤会创建新的命名空间（&lt;code&gt;istio-system&lt;/code&gt;）：&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;images/38e93379-istio-3.png&#34; alt=&#34;kubectl get ns&#34; /&gt;&lt;/p&gt;

&lt;p&gt;会看到这里还有很多服务：&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;images/38e93379-istio-3-1024x524.png&#34; alt=&#34;kubectl get svc&#34; /&gt;&lt;/p&gt;

&lt;p&gt;稍候片刻，会看到很多 Pod：&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;images/846a8174-istio-4-1024x498.png&#34; alt=&#34;kubectl get po&#34; /&gt;&lt;/p&gt;

&lt;p&gt;Istio 如果成功部署，所有这些 Pod 只能是 &lt;code&gt;Running&lt;/code&gt; 或者 &lt;code&gt;Completed&lt;/code&gt; 状态。&lt;/p&gt;

&lt;p&gt;下一步就要准备用于蓝绿部署的应用了。&lt;/p&gt;

&lt;h2 id=&#34;步骤-3-安装同一应用的两个版本&#34;&gt;步骤 3：安装同一应用的两个版本&lt;/h2&gt;

&lt;p&gt;为了展示应用的不同版本，我构建了基于 Nginx 的简单镜像 - &lt;code&gt;janakiramm/myapp:v1&lt;/code&gt; 和 &lt;code&gt;janakiramm/myapp:v2&lt;/code&gt;。部署之后，会展示蓝色或者绿色的背景。&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-yaml&#34;&gt;apiVersion: v1
kind: Service
metadata:
  name: myapp
  labels:
    app: myapp
spec:
  type: ClusterIP
  ports:
  - port: 80
    name: http
  selector:
    app: myapp
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: myapp-v1
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: myapp
        version: v1
    spec:
      containers:
      - name: myapp
        image: janakiramm/myapp:v1
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: myapp-v2
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: myapp
        version: v2
    spec:
      containers:
      - name: myapp
        image: janakiramm/myapp:v2
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;也可以在 &lt;a href=&#34;https://gist.github.com/janakiramm/123dc67b78ef187a109e7f928d6a6878&#34; target=&#34;_blank&#34;&gt;Github&lt;/a&gt; 上看到这些代码。&lt;/p&gt;

&lt;p&gt;接着就要创建 YAML 文件来定义 v1 和 v2 服务了。注意 Pod 标签的差异代表了不同的版本 —— &lt;code&gt;app&lt;/code&gt; 保持一致，但 &lt;code&gt;version&lt;/code&gt; 是不同的。这样一来，Istio 就会认为这是同一应用的不同版本。&lt;/p&gt;

&lt;p&gt;而服务中的选择器定义只针对 &lt;code&gt;app&lt;/code&gt; 标签进行设置，也就是说不同版本的 Pod 都会参与这一服务。&lt;/p&gt;

&lt;p&gt;用 &lt;code&gt;kubectl&lt;/code&gt; 创建 &lt;code&gt;Service&lt;/code&gt; 和 &lt;code&gt;Deployment&lt;/code&gt;。注意这个简单的应用对 Istio 一无所知。Istio 和应用的唯一可见的连接就是标签：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl apply -f myapp.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;img src=&#34;images/7ddbc930-istio-5.png&#34; alt=&#34;apply -f yaml&#34; /&gt;&lt;/p&gt;

&lt;p&gt;配置 Istio 路由之前，首先检查一下应用的版本。可以使用端口转发的方式来访问 Pod。&lt;/p&gt;

&lt;p&gt;要访问应用的 &lt;code&gt;v1&lt;/code&gt; 版本，可以运行下面的命令，然后访问 &lt;code&gt;localhost:8080&lt;/code&gt;，验证完成之后，按 &lt;code&gt;CTRL+C&lt;/code&gt; 结束端口映射命令。&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl port-forward deployment/myapp-v1 8080:80
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;img src=&#34;images/b5088c7c-istio-6-300x183.png&#34; alt=&#34;app image blue&#34; /&gt;&lt;/p&gt;

&lt;p&gt;要访问应用的 &lt;code&gt;v2&lt;/code&gt; 版本，可以运行下面的命令，然后访问 &lt;code&gt;localhost:8081&lt;/code&gt;，验证完成之后，按 &lt;code&gt;CTRL+C&lt;/code&gt; 结束端口映射命令。&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl port-forward deployment/myapp-v2 8081:80
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;img src=&#34;images/a187169b-istio-7-300x183.png&#34; alt=&#34;app image green&#34; /&gt;&lt;/p&gt;

&lt;h2 id=&#34;步骤-4-配置蓝绿部署&#34;&gt;步骤 4：配置蓝绿部署&lt;/h2&gt;

&lt;p&gt;我们的目标是在不停机的情况下，让流量选择性的进入某一版本。为了完成这一目的，就需要告知 Istio 根据权重进行路由。完成这一任务需要三个对象：&lt;/p&gt;

&lt;h3 id=&#34;gateway&#34;&gt;Gateway&lt;/h3&gt;

&lt;p&gt;Istio Gateway 描述了网格边缘的负载均衡组件，用于 HTTP/TCP 连接的接收和发出。定义中包含一组要开放的端口、使用的协议、负载均衡的 SNI 等。下面的定义中我们将 Gateway 指向 Istio 部署过程中建立的缺省的 Ingress Gategeway。&lt;/p&gt;

&lt;p&gt;用 Kubernetes 的方式创建 Gateway 对象：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-yaml&#34;&gt;apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: app-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - &amp;quot;*&amp;quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;目标规则&#34;&gt;目标规则&lt;/h3&gt;

&lt;p&gt;Istio &lt;code&gt;DestinationRule&lt;/code&gt; 定义了在一个服务成为路由目标之后的行为。注意一下这一规则中是如何通过标签来对 Kubernetes 的原生 Deployment 进行区分的：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-yaml&#34;&gt;apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: myapp
spec:
  host: myapp
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;虚拟服务&#34;&gt;虚拟服务&lt;/h3&gt;

&lt;p&gt;虚拟服务中定义了一组流量路由规则，在其中的 &lt;code&gt;host&lt;/code&gt; 被访问时就会触发。每个路由规则中都定义了对某一协议进行匹配的标准。如果流量匹配这一标准，那么就发送给对应的区分了版本的目标服务。&lt;/p&gt;

&lt;p&gt;下面的定义中我们定义两个版本的服务权重都是 50，也就是说流量会在版本间进行平均分配：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-yaml&#34;&gt;apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: myapp
spec:
  hosts:
  - &amp;quot;*&amp;quot;
  gateways:
  - app-gateway
  http:
    - route:
      - destination:
          host: myapp
          subset: v1
        weight: 50
      - destination:
          host: myapp
          subset: v2
        weight: 50
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;所有这些都可以定义在同一个 YAML 文件中，然后用 &lt;code&gt;kubectl&lt;/code&gt; 提交给集群，同样可以在 &lt;a href=&#34;https://gist.github.com/janakiramm/35078d95730745caa62f81d917d6d553&#34; target=&#34;_blank&#34;&gt;Gtihub&lt;/a&gt; 中获取这一文件。&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl apply -f app-gateway.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;img src=&#34;images/b64331f6-istio-8-300x75.png&#34; alt=&#34;app gateway&#34; /&gt;&lt;/p&gt;

&lt;p&gt;接下来就可以尝试访问这一服务了。因为我们使用的是 NodePort 模式的服务，所以就需要首先判断一下 Ingress Gateway 所在的端口。&lt;/p&gt;

&lt;p&gt;运行下面的命令来访问 MiniKube 的 Ingress 端口。&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;$ export INGRESS_HOST=$(minikube ip)

$ export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath=&#39;{.spec.ports[?(@.name==&amp;quot;http2&amp;quot;)].nodePort}&#39;)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;从浏览器访问这个 URL，会看到流量被均等的在蓝色和绿色版本之间进行分配。&lt;/p&gt;

&lt;p&gt;也可以在终端里面查看命令结果。运行下面的命令会看到 V1 和 V2 的响应：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;while : ;do export GREP_COLOR=&#39;1;33&#39;;curl -s  192.168.99.100:31380 \
 |  grep --color=always &amp;quot;V1&amp;quot; ; export GREP_COLOR=&#39;1;36&#39;;\
 curl -s  192.168.99.100:31380 \
 | grep --color=always &amp;quot;vNext&amp;quot; ; sleep 1; done
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;img src=&#34;images/840d897c-istio-9-1024x674.png&#34; alt=&#34;curl&#34; /&gt;&lt;/p&gt;

&lt;p&gt;上面的命令会循环运行，我们可以返回编辑 &lt;code&gt;gateway.yaml&lt;/code&gt;，修改其中的权重分配。把 V1 的权重设置为 0，V2 的权重设置为 100.&lt;/p&gt;

&lt;p&gt;把新的定义提交到 Istio。&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;$ istioctl replace -f app-gateway.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;img src=&#34;images/0b6f6f9e-istio-10-300x59.png&#34; alt=&#34;replace&#34; /&gt;&lt;/p&gt;

&lt;p&gt;更新权重之后，V2 的响应比例会提升到 100%。这一结果会体现在输出之中：&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;images/82d4e75d-istio-11.png&#34; alt=&#34;v2-100%&#34; /&gt;&lt;/p&gt;

&lt;p&gt;可以继续对权重进行修改，查看路由的动态变化过程。&lt;/p&gt;

&lt;p&gt;流量管理只是 Istio 的一个功能，后续文章中尝试更多其他特性。&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Kubernetes 如何走向统一调度之路</title>
      <link>/post/how-k8s-transforming-into-scheduler/</link>
      <pubDate>Tue, 18 Sep 2018 22:04:06 +0800</pubDate>
      <guid>/post/how-k8s-transforming-into-scheduler/</guid>
      <description>

&lt;p&gt;原文：&lt;a href=&#34;https://thenewstack.io/how-kubernetes-is-transforming-into-a-universal-scheduler/&#34; target=&#34;_blank&#34;&gt;How Kubernetes Is Transforming into a Universal Scheduler&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;作者：&lt;a href=&#34;https://thenewstack.io/author/janakiram/&#34; target=&#34;_blank&#34;&gt;Janakiram MSV&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;计算机科学里，调度指的是一种能够为作业分配满足其执行所需资源的方法。IBM 在 60 年代的 S/360 中首次提出这一概念，可以说是年代久远了。&lt;/p&gt;

&lt;p&gt;对所有存在资源需求的作业来说，调度都是至关重要的。在操作系统的上下文中，作业可能是个简单的程序，资源可能是 CPU 核心。类似的，操作系统中的调度器可能就只是一些用于操作线程或信号的代码。&lt;/p&gt;

&lt;p&gt;分布式计算将调度器的疆土从内部的进程和线程扩展到了物理机集群之中。90 年代中，Corba、DCOM 以及 J2EE 等分布式平台应运而生，在应用服务器集群内发展了各自的调度组件。&lt;/p&gt;

&lt;p&gt;再后来，出现了 Amazon EC2、Azure Fabric 以及 OpenStack Nova 这样的 IaaS 平台，这些平台的控制平面完成了对运行于物理机基础之上的虚拟机的调度工作。根据资源需求将虚拟机实例安置在合适的物理机上。&lt;/p&gt;

&lt;p&gt;基于 Apache Hadoop 和 MapReduce 算法的大数据工作负载对调度算法非常依赖。Hadoop 的文件系统 HDFS 就用于保障集群上的节点能够访问到数据集。这一架构聚焦于资源的的稳定性和可用性保障。&lt;/p&gt;

&lt;p&gt;Cloud Foundry 和 Heroku 这样的 PaaS 实现中包含了设计精密的调度逻辑，用来为服务提供隔离的环境。每个服务都被打包，部署在虚拟或物理服务器的执行环境之中。&lt;/p&gt;

&lt;p&gt;横空出世的容器，强迫业界重新审视资源调度器的设计。新一代调度器的设计理念更加重视简单性和伸缩性。传统应用服务器面对的是少量服务器，而容器管理平台要管理的容器工作节点数量可能从几台到几千台。&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;images/15fb358d-k8s-sched-0.jpg&#34; alt=&#34;几种不同的调度器&#34; /&gt;&lt;/p&gt;

&lt;p&gt;Kubernetes 和 Mesosphere 是当代资源调度器的代表。它们的设计对底层基础设施进行了抽象，用透明的方式为用户提供调度服务。&lt;/p&gt;

&lt;h2 id=&#34;kubernetes-中的调度&#34;&gt;Kubernetes 中的调度&lt;/h2&gt;

&lt;p&gt;Kubernetes 平台中，调度器是一个关键组件。它在主节点上运行，和 API Server 以及 Controller 紧密合作。调度器的核心任务就是对 Pod 和 Node 进行撮合。可以在 &lt;a href=&#34;https://thenewstack.io/kubernetes-an-overview/&#34; target=&#34;_blank&#34;&gt;Kubernetes architecture&lt;/a&gt; 一文中透彻的了解其架构。&lt;/p&gt;

&lt;p&gt;调度器会在多个方面对可用资源进行评估，从而为 Pod 分配合适的节点。另外还可以通过对节点亲和性的设置，为 Pod &lt;a href=&#34;https://kubernetes.io/blog/2017/03/advanced-scheduling-in-kubernetes/&#34; target=&#34;_blank&#34;&gt;分配指定特性的节点&lt;/a&gt;。例如一个一个高 IO 的数据库 Pod 可能需要调度到配有 SSD 存储的节点上。还有可能为了降低延迟，将一系列的 Pod 调度到同一节点上，这一操作称为 Pod 亲和性。Kubernetes 还支持自定义调度器，完全由第三方实现分配逻辑。&lt;/p&gt;

&lt;p&gt;Kubernetes 调度器的最大亮点就是其简单性。前面描述的多数策略都能很轻松的实现。只要通过一点注解和标签，就能完成 Pod 和节点之间的亲和或排斥的定义。通过对 Pod 和节点的键值对设置就能够实现成熟的调度逻辑。&lt;/p&gt;

&lt;h2 id=&#34;超越-pod-和节点的-kubernetes-调度器&#34;&gt;超越 Pod 和节点的 Kubernetes 调度器&lt;/h2&gt;

&lt;p&gt;Kubernetes 可能是目前最好的资源调度器之一。兼顾简单和扩展能力的调度器让用户能够解决很多传统分布式系统中的调度问题。&lt;/p&gt;

&lt;p&gt;在高度分布的环境中，Kubernetes 正在成为首选的作业调度和管理工具。这些作业包括在物理服务器上部署虚拟机、在边缘设备上运行容器，甚至还具有将控制平面扩展到 Serverless 环境这样的其他调度器上的能力。&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;http://kubevirt.io/&#34; target=&#34;_blank&#34;&gt;KuberVirt&lt;/a&gt; 就是一个 Kubernetes 上的虚拟机管理插件，它让用户能够像 Pod 一样在 Kubernetes 或 OpenShift 集群上运行虚拟机。这一系统用 &lt;a href=&#34;https://kubernetes.io/docs/concepts/api-extension/custom-resources/#customresourcedefinitions&#34; target=&#34;_blank&#34;&gt;CRD&lt;/a&gt; 的形式来进行虚拟机的设置，完成了对 Kubernetes 的扩展。KubeVirt 虚拟机运行在普通的 Kubernetes Pod 之内，从而具有了访问标准 Pod 网络和存储的能力，并且可以使用标准的 &lt;code&gt;kubectl&lt;/code&gt; 或者类似的 Kubernetes 工具来进行管理。&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;images/d4c17aba-k8s-scheduler-1.png&#34; alt=&#34;KubeVirt&#34; /&gt;&lt;/p&gt;

&lt;p&gt;来自 Mirantis 的 &lt;a href=&#34;https://github.com/Mirantis/virtlet&#34; target=&#34;_blank&#34;&gt;Virtlet&lt;/a&gt; 项目让虚拟机可以在 Kubernetes 集群中像普通 Pod 一样运行。运维人员可以用 &lt;code&gt;kubectl&lt;/code&gt; 命令管理虚拟机，并且将虚拟机以一等公民的身份纳入集群网络。有了 Virtlet 就可以构建高级的 Kubernetes 对象，例如 Deployment、Statefulset 或者 DaemonSet。&lt;/p&gt;

&lt;p&gt;微软的 &lt;a href=&#34;https://github.com/virtual-kubelet/virtual-kubelet&#34; target=&#34;_blank&#34;&gt;Virtual Kubelet&lt;/a&gt; 是最有趣的一个调度器。Virtual Kubelet 是一个 Agent，运行在注册为 Kubernetes 集群节点的外部环境之中。这个 Agent 会通过 Kubernetes API 创建节点资源。通过对&lt;a href=&#34;https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/&#34; target=&#34;_blank&#34;&gt;污染和隔离&lt;/a&gt;功能的使用，会通过本地 API 来进行外部环境中的 Pod 调度。&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;images/1cd893e9-k8s-scheduler-2.jpg&#34; alt=&#34;Virtual Kubelet&#34; /&gt;&lt;/p&gt;

&lt;p&gt;Virtual Kubelet 可以在 &lt;a href=&#34;https://azure.microsoft.com/en-us/services/container-instances/&#34; target=&#34;_blank&#34;&gt;Azure Container Instance&lt;/a&gt;、&lt;a href=&#34;https://azure.microsoft.com/en-us/services/iot-edge/&#34; target=&#34;_blank&#34;&gt;Azure IoT Edge&lt;/a&gt; 以及 &lt;a href=&#34;https://aws.amazon.com/fargate/&#34; target=&#34;_blank&#34;&gt;AWS Fargate&lt;/a&gt; 上运行。&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;images/25822176-k8s-scheduler-3.png&#34; alt=&#34;Virtual Kubelet on Azure Container &#34; /&gt;&lt;/p&gt;

&lt;p&gt;另外，我还写过其他文章，介绍了 Virtual Kubelet 的&lt;a href=&#34;https://thenewstack.io/lightning-fast-container-provisioning-with-microsofts-azure-container-instances/&#34; target=&#34;_blank&#34;&gt;架构&lt;/a&gt;和&lt;a href=&#34;https://thenewstack.io/explore-multicloud-deployments-aci-connector-kubernetes/&#34; target=&#34;_blank&#34;&gt;部署指南&lt;/a&gt;，可供读者参考。&lt;/p&gt;

&lt;h2 id=&#34;更进一步-自定义调度器和-crd&#34;&gt;更进一步——自定义调度器和 CRD&lt;/h2&gt;

&lt;p&gt;上面讨论的例子只是冰山一角。Kubernetes 正在成为当代基础设施的基础，正在迈入传统业务应用领域——例如 ERP 和 CRM。&lt;/p&gt;

&lt;p&gt;应用提供商们将会越来越重的依赖 Kubernetes 的两个功能：自定义调度器和 CRD。&lt;/p&gt;

&lt;p&gt;正如前文所说，Kubernetes 的自定义调度器让开发者可以实现自己的调度逻辑。Pod 的声明中就可以通知控制面跳过缺省调度器，转而采用自定义调度。这一机制能够保障集群内的 Pod 得到正确安置。&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;https://portworx.com/&#34; target=&#34;_blank&#34;&gt;Portworx&lt;/a&gt; 是一个云原生生存储公司，它使用自定义调度器来创建 &lt;a href=&#34;https://portworx.com/stork-storage-orchestration-kubernetes/&#34; target=&#34;_blank&#34;&gt;STORK&lt;/a&gt;（Kubernetes 存储编排运行时：STorage Orchestrator Runtime for Kubernetes）。从而保障它的 Stateful Pod 只会在安装了 Portworx 驱动和存储的节点上运行。这一功能对于运行其上的数据库负载的可用性保障很有帮助。&lt;/p&gt;

&lt;p&gt;Kubernetes 中的 CRD 为自定义对象提供了简单且强大的生命周期支持。自定义资源是一种对象，对 Kubernetes API 进行了扩展，开发人员可以利用这一机制将自己的 API 引入 Kubernetes。CRD 文件声明了自定义对象的定义，让 API Server 能够处理整个生命周期。在 Kubernetes 中部署 CRD，就是让 Kubernetes API Server 开始支持某种自定义资源。&lt;/p&gt;

&lt;p&gt;CRD 创建之后，运维人员可以使用 &lt;code&gt;kubectl&lt;/code&gt; 或者第三方工具来进行管理，这一过程和 Pod 等内置对象并无二致。ISV 可以利用 CRD 的方式将自己的软件进行打包和部署。&lt;/p&gt;

&lt;p&gt;Kubernetes 的扩展性，使其具备了成为统一调度管理工具的潜质。&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>
