<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>cri | 伪架构师</title>
    <link>/tags/cri/</link>
      <atom:link href="/tags/cri/index.xml" rel="self" type="application/rss+xml" />
    <description>cri</description>
    <generator>Source Themes Academic (https://sourcethemes.com/academic/)</generator><language>zh</language><lastBuildDate>Wed, 30 May 2018 00:41:44 +0800</lastBuildDate>
    <image>
      <url>/img/logo-wide.png</url>
      <title>cri</title>
      <link>/tags/cri/</link>
    </image>
    
    <item>
      <title>Containerd 1.1.0 尝鲜记</title>
      <link>/post/containerd-kubeadm/</link>
      <pubDate>Wed, 30 May 2018 00:41:44 +0800</pubDate>
      <guid>/post/containerd-kubeadm/</guid>
      <description>

&lt;p&gt;&lt;a href=&#34;https://blog.fleeto.us/post/kubernetes-containerd-integration-goes-ga/&#34; target=&#34;_blank&#34;&gt;Containerd 1.1.0 的 Kubernetes 支持已经进入可用阶段&lt;/a&gt;，Kubernetes 1.10 和未来的的 Docker 版本都会以此为基础，作为一个熟练软件安装工，自然是要先睹为快了。&lt;/p&gt;

&lt;p&gt;这里使用 Kubeadm 进行测试。&lt;/p&gt;

&lt;h2 id=&#34;环境准备&#34;&gt;环境准备&lt;/h2&gt;

&lt;p&gt;首先进行 Kubeadm 的环境准备：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;安装 libseccomp, conntrack&lt;/li&gt;
&lt;li&gt;关闭防火墙服务&lt;/li&gt;
&lt;li&gt;开启 sysctl：&lt;code&gt;ip_forward&lt;/code&gt;、&lt;code&gt;net.bridge.bridge-nf-call-iptables&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;参考&lt;a href=&#34;https://kubernetes.io/docs/tasks/tools/install-kubeadm/&#34; target=&#34;_blank&#34;&gt;官方指南&lt;/a&gt;，安装 kubeadm、kubelet 以及 kubectl，此处暂时不启动 kubelet 服务。&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&#34;安装-contaierd&#34;&gt;安装 contaierd&lt;/h2&gt;

&lt;p&gt;下载 &lt;a href=&#34;https://storage.googleapis.com/cri-containerd-release/cri-containerd-1.1.0.linux-amd64.tar.gz&#34; target=&#34;_blank&#34;&gt;cri-containerd 1.1.0&lt;/a&gt;，并解压，其中包含 &lt;code&gt;/usr&lt;/code&gt;、&lt;code&gt;/etc&lt;/code&gt; 以及 &lt;code&gt;opt&lt;/code&gt; 三个目录，这里我们只是用前两个目录的内容，目录结构如下，直接复制即可：&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;├── etc
│   ├── crictl.yaml
│   └── systemd
│       └── system
│           └── containerd.service
└── usr
    └── local
        ├── bin
        │   ├── containerd
        │   ├── containerd-release
        │   ├── containerd-shim
        │   ├── containerd-stress
        │   ├── crictl
        │   ├── critest
        │   └── ctr
        └── sbin
            └── runc
&lt;/code&gt;&lt;/pre&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;crictl.yaml&lt;/code&gt;：crictl 的配置文件，缺省包含一行 &lt;code&gt;runtime-endpoint: unix:///run/containerd/containerd.sock&lt;/code&gt;，指定运行时的连接方式。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;containerd.service&lt;/code&gt;：服务文件，设置自动启动即可。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ctr&lt;/code&gt;：containerd 客户端&lt;/li&gt;
&lt;li&gt;&lt;code&gt;crictl&lt;/code&gt;：cri 客户端&lt;/li&gt;
&lt;li&gt;&lt;code&gt;runc&lt;/code&gt;：运行时，contaienrd 依赖项&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;这里可以发现，并没有包含 containerd 自己的配置文件，可以使用 &lt;code&gt;containerd config default &amp;gt; /etc/containerd/config.toml&lt;/code&gt; 命令，来生成缺省配置文件，然后自行变更。例如可以&lt;a href=&#34;https://github.com/containerd/cri/blob/v1.0.0/docs/registry.md&#34; target=&#34;_blank&#34;&gt;修改仓库镜像地址&lt;/a&gt;。&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;另外对国内用户比较重要的一点是，仍然是可以使用环境变量方式的配置来设置 &lt;code&gt;HTTP_PROXY&lt;/code&gt; 以及 &lt;code&gt;NO_PROXY&lt;/code&gt; 的内容。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;配置完成后，使用 &lt;code&gt;systemctl&lt;/code&gt; 启动服务。&lt;/p&gt;

&lt;h2 id=&#34;载入镜像&#34;&gt;载入镜像&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;docker.io/coredns/coredns:1.0.6&lt;/li&gt;
&lt;li&gt;k8s.gcr.io/kube-proxy-amd64:v1.10.3&lt;/li&gt;
&lt;li&gt;k8s.gcr.io/etcd-amd64&lt;/li&gt;
&lt;li&gt;k8s.gcr.io/kube-apiserver-amd64:v1.10.3&lt;/li&gt;
&lt;li&gt;k8s.gcr.io/kube-controller-manager-amd64:v1.10.3&lt;/li&gt;
&lt;li&gt;k8s.gcr.io/kube-proxy-amd64:v1.10.3&lt;/li&gt;
&lt;li&gt;k8s.gcr.io/kube-scheduler-amd64:v1.10.3&lt;/li&gt;
&lt;li&gt;k8s.gcr.io/pause:3.1&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;ctr 的镜像载入命令&lt;/strong&gt;：&lt;code&gt;ctr cri load image.tar&lt;/code&gt;，似乎不支持 gz。&lt;/p&gt;

&lt;h2 id=&#34;配置-kubelet-使用-containerd&#34;&gt;配置 Kubelet 使用 containerd&lt;/h2&gt;

&lt;p&gt;简单的在 Kubelet 的环境变量上加入如下内容，再启动 Kubelet 服务：&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[Service]
Environment=&amp;quot;KUBELET_EXTRA_ARGS=--runtime-cgroups=/system.slice/containerd.service --container-runtime=remote --runtime-request-timeout=15m --container-runtime-endpoint=unix:///run/containerd/containerd.sock&amp;quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&#34;kubeadm-集群安装&#34;&gt;Kubeadm 集群安装&lt;/h2&gt;

&lt;p&gt;这里提供一个简单的初始化命令：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-sh&#34;&gt;kubeadm init \
--pod-network-cidr=192.168.0.0/16 \
--feature-gates CoreDNS=true \
--ignore-preflight-errors=Service-Docker \
--ignore-preflight-errors=SystemVerification \
--kubernetes-version=v1.10.3 # 防止 kubeadm 向服务器查询镜像列表。
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Kubeadm 缺省情况下依旧是需要检查 Docker 的运行情况的，因此这里我们使用 &lt;code&gt;--ignore-preflight-errors&lt;/code&gt; 开关关闭这项检查。&lt;/p&gt;

&lt;p&gt;Master 初始化结束之后，就可以跟随 kubeadm 指示，进入其他节点，运行 &lt;code&gt;kubeadm join&lt;/code&gt; 命令来加入集群了，加入命令同样需要设置 &lt;code&gt;--ignore-preflight-errors=all&lt;/code&gt; 来规避 Docker 检查。&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;接下来可以按照自己喜好安装网络插件了。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;可以使用 &lt;code&gt;kubectl describe nodes [node name]&lt;/code&gt; 来检查节点信息：&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;...
Container Runtime Version:  containerd://1.1.0
Kubelet Version:            v1.10.3
Kube-Proxy Version:         v1.10.3
PodCIDR:                     192.168.0.0/24
...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;这里可以看到，运行时已经更新为 &lt;code&gt;containerd://1.1.0&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&#34;后记&#34;&gt;后记&lt;/h2&gt;

&lt;p&gt;正如在前面文章提到的，containerd 并非 Docker 的替代品，只是一个子集，独立使用是很困难的，因此还是比较适合用于 Kubelet 控制之下的容器运行支持。&lt;/p&gt;

&lt;h2 id=&#34;下载链接以及参考链接&#34;&gt;下载链接以及参考链接&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;cri-containerd 1.1.0&lt;/strong&gt;：&lt;code&gt;https://storage.googleapis.com/cri-containerd-release/cri-containerd-1.1.0.linux-amd64.tar.gz&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;kubeadm 安装指南&lt;/strong&gt;：&lt;code&gt;https://kubernetes.io/docs/tasks/tools/install-kubeadm/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;containerd 安装指南&lt;/strong&gt;：&lt;code&gt;https://github.com/containerd/containerd/releases&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Containerd 1.1.0 的 Kubernetes 支持已经进入可用阶段&lt;/strong&gt;： &lt;code&gt;https://blog.fleeto.us/post/kubernetes-containerd-integration-goes-ga/&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Kubernetes 中的容器运行时接口</title>
      <link>/post/container-runtime-interface-cri-in-kubernetes/</link>
      <pubDate>Tue, 20 Dec 2016 22:13:18 +0800</pubDate>
      <guid>/post/container-runtime-interface-cri-in-kubernetes/</guid>
      <description>

&lt;p&gt;原文：&lt;a href=&#34;https://kubernetes.io/blog/2016/12/container-runtime-interface-cri-in-kubernetes&#34; target=&#34;_blank&#34;&gt;Introducing Container Runtime Interface (CRI) in Kubernetes&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;文中多次出现了个单词 &lt;code&gt;shim&lt;/code&gt;，胡翻成代理了，虽然垫片还是比鲁棒啥的好听。。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;归根结底，Kubernetes Node 的最底层就是启动和停止容器的组件了，这一部分我们称之为容器运行时（ Container Runtim ），这其中最知名的也就是 Docker 了，这一领域正在快速成长，他并不孤独。为了让 Kubernetes 更具扩展性，我们投入了不少精力，在 Kubernetes 中加入了容器运行时插件 API，我们称之为 “CRI”。&lt;/p&gt;

&lt;h2 id=&#34;cri-是什么-kubernetes-需要他么&#34;&gt;CRI 是什么？Kubernetes 需要他么？&lt;/h2&gt;

&lt;p&gt;每一种容器运行时都有其长处，因此不少用户希望 Kubernetes 能够支持更多的运行时。在 Kubernetes 1.5 中，我们引入了 &lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/242a97307b34076d5d8f5bbeb154fa4d97c9ef1d/docs/devel/container-runtime-interface.md&#34; target=&#34;_blank&#34;&gt;CRI&lt;/a&gt;，这一插件接口让 Kubernetes 无需重新编译就可以使用更多的容器运行时。CRI 包含 &lt;a href=&#34;https://developers.google.com/protocol-buffers/&#34; target=&#34;_blank&#34;&gt;Protocol Buffers&lt;/a&gt;、&lt;a href=&#34;http://www.grpc.io/&#34; target=&#34;_blank&#34;&gt;gRPC API&lt;/a&gt;、以及&lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/release-1.5/pkg/kubelet/server/streaming/server.go&#34; target=&#34;_blank&#34;&gt;运行库&lt;/a&gt;支持，还有尚在开发的标准规范和工具。 CRI 在 &lt;a href=&#34;http://blog.kubernetes.io/2016/12/kubernetes-1.5-supporting-production-workloads.html&#34; target=&#34;_blank&#34;&gt;Kubernetes 1.5&lt;/a&gt; 中发布了 Alpha 版本。&lt;/p&gt;

&lt;p&gt;可替代的容器运行时支持是 Kubernetes 中的新概念。在 1.3 时，我们发布了 &lt;a href=&#34;http://blog.kubernetes.io/2016/07/rktnetes-brings-rkt-container-engine-to-Kubernetes.html&#34; target=&#34;_blank&#34;&gt;rktnetes&lt;/a&gt; 项目，让 &lt;a href=&#34;https://github.com/coreos/rkt&#34; target=&#34;_blank&#34;&gt;rkt 容器引擎&lt;/a&gt; 成为 Docker 之外的又一选择。然而不管是 Docker 还是 rkt，都是用的 Kubelet 的内部接口，同 Kubelet 源码纠缠不清。这种程度的集成，需要对 Kubelet 内部机制有非常深入的了解，还会给社区带来管理压力。这样就给新生代容器运行时造成了难于跨越的集成壁垒。我们用清晰定义的抽象层清除了这一壁垒，让开发者能够专注于容器运行时本身。在通向插件式容器支持以及建设健康生态环境的路上，这是一小步，也是重要的一步。&lt;/p&gt;

&lt;h2 id=&#34;cri-概览&#34;&gt;CRI 概览&lt;/h2&gt;

&lt;p&gt;Kubelet 使用 gRPC 框架利用 Unix socket 同容器运行时（或者是 CRI 代理）进行通信，这一过程中 Kubelet 是客户端，CRI 代理是服务端。&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;images/overview.png&#34; alt=&#34;OVERVIEW&#34; /&gt;&lt;/p&gt;

&lt;p&gt;Protocol Buffers &lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/release-1.5/pkg/kubelet/api/v1alpha1/runtime/api.proto&#34; target=&#34;_blank&#34;&gt;API&lt;/a&gt; 包含两个 gRPC 服务，&lt;code&gt;ImageService&lt;/code&gt; 和 &lt;code&gt;RuntimeService&lt;/code&gt;。&lt;code&gt;ImageService&lt;/code&gt; 提供从仓库拉取镜像、查看和移除镜像的功能。&lt;code&gt;RuntimeService&lt;/code&gt; 包含了对 Pod 和容器的生命周期管理、和容器的交互（ exec/attach/port-forward ）。rtk 和 Docker 这样的容器运行时可以利用一个 Socket 同时提供两个服务。在 Kubelet 中可以用 &lt;code&gt;--container-runtime-endpoint&lt;/code&gt; 和 &lt;code&gt;--image-service-endpoint&lt;/code&gt; 参数设置这个 socket。&lt;/p&gt;

&lt;h2 id=&#34;pod-和容器的生命周期管理&#34;&gt;Pod 和容器的生命周期管理&lt;/h2&gt;

&lt;pre&gt;&lt;code class=&#34;language-go&#34;&gt;service RuntimeService {
    // Sandbox operations.
    rpc RunPodSandbox(RunPodSandboxRequest) returns (RunPodSandboxResponse) {}
    rpc StopPodSandbox(StopPodSandboxRequest) returns (StopPodSandboxResponse) {}
    rpc RemovePodSandbox(RemovePodSandboxRequest) returns (RemovePodSandboxResponse) {}
    rpc PodSandboxStatus(PodSandboxStatusRequest) returns (PodSandboxStatusResponse) {}
    rpc ListPodSandbox(ListPodSandboxRequest) returns (ListPodSandboxResponse) {}
    // Container operations.
    rpc CreateContainer(CreateContainerRequest) returns (CreateContainerResponse) {}
    rpc StartContainer(StartContainerRequest) returns (StartContainerResponse) {}
    rpc StopContainer(StopContainerRequest) returns (StopContainerResponse) {}
    rpc RemoveContainer(RemoveContainerRequest) returns (RemoveContainerResponse) {}
    rpc ListContainers(ListContainersRequest) returns (ListContainersResponse) {}
    rpc ContainerStatus(ContainerStatusRequest) returns (ContainerStatusResponse) {}
    ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Pod 由一组应用容器组成，其中包含了共有的环境和资源约束。在 CRI 里，这个环境被称为 &lt;code&gt;PodSandbox&lt;/code&gt;。我们有意的给容器运行时留下了一些发挥空间，他们可以根据自己的内部实现来解释 &lt;code&gt;PodSandbox&lt;/code&gt;。对于 Hypervisor 类的运行时，&lt;code&gt;PodSandbox&lt;/code&gt; 会具体化为一个虚拟机。其他的例如 Docker，会是一个 Linux 命名空间。在 v1alpha1 API 中，Kubelet 会创建 Pod 级别的 cgroup 传递给容器运行时，并以此运行所有进程来保障 PodSandbox 对 Pod 的资源保障。&lt;/p&gt;

&lt;p&gt;在启动 Pod 之前，Kubelet 调用 &lt;code&gt;RuntimeService.RunPodSandbox&lt;/code&gt; 来创建环境。这一过程包括为 Pod 设置网络（分配 IP）。&lt;code&gt;PodSandbox&lt;/code&gt; 激活之后，就可以独立的创建、启动、停止和删除不同的容器了。Kubelet 会在停止和删除 &lt;code&gt;PodSandbox&lt;/code&gt; 之前首先停止和删除其中的容器。&lt;/p&gt;

&lt;p&gt;Kubelet 的职责在于通过 RPC 管理容器的生命周期，实现容器生命周期的钩子，以及存活和健康监测，执行 Pod 的重启策略等。&lt;/p&gt;

&lt;h2 id=&#34;为什么-cri-是围绕容器进行的&#34;&gt;为什么 CRI 是围绕容器进行的？&lt;/h2&gt;

&lt;p&gt;Kubernetes 有一个 Pod 资源的接口。我们曾经可能采用的一个 CRI 的设计就是抽象复用 Pod 对象，容器运行时就可以自行实现自己的控制逻辑和状态转换，这样一来，就能极大地简化 API，让 CRI 能够更广泛的适用于多种容器运行时。但是经过深入讨论之后，我们放弃了这一想法。&lt;/p&gt;

&lt;p&gt;首先，Kubelet 有很多的 Pod 级功能和机制（例如循环崩溃的处理），交给容器运行时实现的话，会造成很重的负担；第二，更重要的是，Pod 标准还在高速前进。很多的新功能（例如容器初始化）是由 Kubelet 直接管理容器的，而无需容器运行时进行变更。&lt;/p&gt;

&lt;p&gt;CRI 选择了围绕容器进行实现，这样容器运行时能够共享这些通用特性，获得更好的开发进度。这并不意味着我们设计哲学的改变 —— Kubelet 要负责保证实际状态和声明状态的一致性。&lt;/p&gt;

&lt;h3 id=&#34;exec-attach-port-forward-请求&#34;&gt;Exec/attach/port-forward 请求&lt;/h3&gt;

&lt;pre&gt;&lt;code class=&#34;language-go&#34;&gt;service RuntimeService {
    ...
    // ExecSync runs a command in a container synchronously.
    rpc ExecSync(ExecSyncRequest) returns (ExecSyncResponse) {}
    // Exec prepares a streaming endpoint to execute a command in the container.
    rpc Exec(ExecRequest) returns (ExecResponse) {}
    // Attach prepares a streaming endpoint to attach to a running container.
    rpc Attach(AttachRequest) returns (AttachResponse) {}
    // PortForward prepares a streaming endpoint to forward ports from a PodSandbox.
    rpc PortForward(PortForwardRequest) returns (PortForwardResponse) {}
    ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Kubernetes 为用户提供了和 Pod 以及其中的容器进行交互的能力（&lt;code&gt;kubectl exec/attach/port-forward&lt;/code&gt;）。Kubelet 目前支持两种方式来支持这些功能：调用容器的本地方法，或者使用 Node 上的工具（例如 &lt;code&gt;nsenter&lt;/code&gt; 以及 &lt;code&gt;socat&lt;/code&gt;）。因为多数工具假设 Pod 利用 Linux namespace 做了隔离，因此使用 Node 上的工具并不是一个可移植的方案。在 CRI 中，我们显式的定义这些调用，让运行时可以做特定实现。&lt;/p&gt;

&lt;p&gt;当下还有一个潜在问题是，Kubelet 处理所有的请求连接，所以他有成为 Node 通信瓶颈的可能。在设计 CRI 的时候，我们采纳了一些反馈，让运行时能够排除中间人。容器运行时可以启动一个单独的流服务器处理请求（还能为 Pod 的资源使用进行记录），并把服务器地址返回给 Kubelet。这样 Kubelet 就能反馈信息给 API Server，使之可以直接连接到容器运行时的服务，并连接到客户端。&lt;/p&gt;

&lt;p&gt;CRI 还有很多本文没有提及的内容，可以参考&lt;a href=&#34;https://github.com/kubernetes/community/blob/master/contributors/devel/container-runtime-interface.md#design-docs-and-proposals&#34; target=&#34;_blank&#34;&gt;设计文档&lt;/a&gt;来获得更多内容。&lt;/p&gt;

&lt;h2 id=&#34;当前状态&#34;&gt;当前状态&lt;/h2&gt;

&lt;p&gt;虽然 CRI 还比较初级，但也已经有了很多项目在尝试把各种容器运行时纳入 CRI：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes-incubator/cri-o&#34; target=&#34;_blank&#34;&gt;cri-o&lt;/a&gt;：OCI 兼容运行时&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes-incubator/rktlet&#34; target=&#34;_blank&#34;&gt;rktlet&lt;/a&gt;：rkt 容器运行时。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/frakti&#34; target=&#34;_blank&#34;&gt;frakti&lt;/a&gt;：基于 hypervisor 的容器运行时。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/kubernetes/tree/release-1.5/pkg/kubelet/dockershim&#34; target=&#34;_blank&#34;&gt;Docker CRI 代理&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;如果对这些运行时感兴趣，可以浏览一下他们的仓库，获取最新的进展情况和相关资料。&lt;/p&gt;

&lt;p&gt;开发者如果有兴趣集成新的容器运行时，需要阅读&lt;a href=&#34;https://github.com/kubernetes/community/blob/master/contributors/devel/container-runtime-interface.md&#34; target=&#34;_blank&#34;&gt;开发者指南&lt;/a&gt;，会在这里得到 API 中已知的限制和问题。我们乐于从早期开发者这里获取反馈，加以改进来促进项目成长。开发者需要有对突发故障的心理准备，谁让我们还在 Alpha 呢。&lt;/p&gt;

&lt;h2 id=&#34;尝试新的-cri-docker&#34;&gt;尝试新的 CRI Docker&lt;/h2&gt;

&lt;p&gt;Kubelet 还没有把 CRI 作为缺省选项，我们正在积极促成这一转变。第一步就是用 CRI 的方式重新对 Docker 进行 Kubelet 的集成。在 1.5 中，我们让 Kubelet 开始支持 CRI，还给 Kubelet 加入了内嵌的 Docker CRI 代理。这样 Kubelet 就可以启动 Docker 的 gRPC 服务了。要尝试新的 Kubelet-CRI-Docker 集成，只需要简单的给 API-Server 参数加上 &lt;code&gt;--feature-gates=StreamingProxyRedirects=true&lt;/code&gt; 开关，就启用了新的请求重定向特性，然后用 &lt;code&gt;--experimental-cri=true&lt;/code&gt; 开关来启动 Kubelet。&lt;/p&gt;

&lt;p&gt;虽说现在的实现还有少量&lt;a href=&#34;https://github.com/kubernetes/community/blob/master/contributors/devel/container-runtime-interface.md#docker-cri-integration-known-issues&#34; target=&#34;_blank&#34;&gt;功能缺失&lt;/a&gt;，不过已经通过了主要的端到端测试，我们计划扩展测试覆盖范围，也再次邀请社区多多提供反馈来促进我们的工作。&lt;/p&gt;

&lt;h2 id=&#34;minikube-和-cri&#34;&gt;Minikube 和 CRI&lt;/h2&gt;

&lt;p&gt;如果想要测试新功能，却没时间部署新的测试集群。&lt;a href=&#34;https://github.com/kubernetes/minikube&#34; target=&#34;_blank&#34;&gt;Minikube&lt;/a&gt; 让你能够快速的启动一个本地集群。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;检查可用的 Kubernetes 版本，选择最新的 1.5.x，这里使用的是 v1.5.9-beta.1：&lt;code&gt;minikube get-k8s-versions&lt;/code&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;启动一个带有内置 Docker CRI 集成的 Minikube 集群：&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ minikube start --kubernetes-version=v1.5.0-beta.1  \
--extra-config=kubelet.EnableCRI=true \
--network-plugin=kubenet \
--extra-config=kubelet.PodCIDR=10.180.1.0/24 \
--iso-url=http://storage.googleapis.com/minikube/iso/buildroot/minikube-v0.0.6.iso
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;--extra-config=kubelet.EnableCRI=true&lt;/code&gt; 启用 Kubelet 的 CRI 实现，&lt;code&gt;--network-plugin=kubenet&lt;/code&gt; 和 &lt;code&gt;--extra-config=kubelet.PodCIDR=10.180.1.0/24&lt;/code&gt; 为网络插件提供了网络设置，分配 PodCIDR 给 Node。这里也可以使用 &lt;code&gt;cni&lt;/code&gt; 插件，就无需依赖 PodCIDR 了。&lt;code&gt;--iso-url&lt;/code&gt; 给 Minikube 指定一个例子中使用的 ISO 镜像。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;检查 Minikube 日志，确认 CRI 的启用&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ minikube logs | grep EnableCRI
I1209 01:48:51.150789    3226 localkube.go:116] Setting EnableCRI to true on kubelet.
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;创建一个 Pod 并检查状态，应该会看到 &amp;ldquo;SandboxReceived&amp;rdquo; 事件，这表明 Kubelet 正在使用 CRI&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ kubectl run foo --image=gcr.io/google_containers/pause-amd64:3.0
deployment &amp;quot;foo&amp;quot; created
$ kubectl describe pod foo
...
... From                Type   Reason          Message
... -----------------   -----  --------------- -----------------------------
...{default-scheduler } Normal Scheduled       Successfully assigned foo-141968229-v1op9 to minikube
...{kubelet minikube}   Normal SandboxReceived Pod sandbox received, it will be created.
...
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;注意 &lt;code&gt;kubectl attach/exec/port-forward&lt;/code&gt; 目前还不能对启用 CRI 模式的 Miniqube 生效，&lt;a href=&#34;https://github.com/kubernetes/minikube/issues/896&#34; target=&#34;_blank&#34;&gt;新版本&lt;/a&gt;将会加入支持。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&#34;相关引用&#34;&gt;相关引用&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CRI&lt;/strong&gt;：&lt;code&gt;https://github.com/kubernetes/kubernetes/blob/242a97307b34076d5d8f5bbeb154fa4d97c9ef1d/docs/devel/container-runtime-interface.md&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;cri-o&lt;/strong&gt;：&lt;code&gt;https://github.com/kubernetes-incubator/cri-o&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;rktlet&lt;/strong&gt;：&lt;code&gt;https://github.com/kubernetes-incubator/rktlet&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;frakti&lt;/strong&gt;：&lt;code&gt;https://github.com/kubernetes/frakti&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Docker CRI 代理&lt;/strong&gt;：&lt;code&gt;https://github.com/kubernetes/kubernetes/tree/release-1.5/pkg/kubelet/dockershim&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
  </channel>
</rss>
