# Containerd 1.1.0 尝鲜记

[Containerd 1.1.0 的 Kubernetes 支持已经进入可用阶段](https://blog.fleeto.us/post/kubernetes-containerd-integration-goes-ga/)，Kubernetes 1.10 和未来的的 Docker 版本都会以此为基础，作为一个熟练软件安装工，自然是要先睹为快了。

这里使用 Kubeadm 进行测试。

## 环境准备

首先进行 Kubeadm 的环境准备：

1. 安装 libseccomp, conntrack
2. 关闭防火墙服务
3. 开启 sysctl：`ip_forward`、`net.bridge.bridge-nf-call-iptables`
4. 参考[官方指南](https://kubernetes.io/docs/tasks/tools/install-kubeadm/)，安装 kubeadm、kubelet 以及 kubectl，此处暂时不启动 kubelet 服务。

## 安装 contaierd

下载 [cri-containerd 1.1.0](https://storage.googleapis.com/cri-containerd-release/cri-containerd-1.1.0.linux-amd64.tar.gz)，并解压，其中包含 `/usr`、`/etc` 以及 `opt` 三个目录，这里我们只是用前两个目录的内容，目录结构如下，直接复制即可：

    ├── etc
    │   ├── crictl.yaml
    │   └── systemd
    │       └── system
    │           └── containerd.service
    └── usr
        └── local
            ├── bin
            │   ├── containerd
            │   ├── containerd-release
            │   ├── containerd-shim
            │   ├── containerd-stress
            │   ├── crictl
            │   ├── critest
            │   └── ctr
            └── sbin
                └── runc

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

这里可以发现，并没有包含 containerd 自己的配置文件，可以使用 `containerd config default > /etc/containerd/config.toml` 命令，来生成缺省配置文件，然后自行变更。例如可以[修改仓库镜像地址](https://github.com/containerd/cri/blob/v1.0.0/docs/registry.md)。

> 另外对国内用户比较重要的一点是，仍然是可以使用环境变量方式的配置来设置 `HTTP_PROXY` 以及 `NO_PROXY` 的内容。

配置完成后，使用 `systemctl` 启动服务。

## 载入镜像

- docker.io/coredns/coredns:1.0.6
- k8s.gcr.io/kube-proxy-amd64:v1.10.3
- k8s.gcr.io/etcd-amd64
- k8s.gcr.io/kube-apiserver-amd64:v1.10.3
- k8s.gcr.io/kube-controller-manager-amd64:v1.10.3
- k8s.gcr.io/kube-proxy-amd64:v1.10.3
- k8s.gcr.io/kube-scheduler-amd64:v1.10.3
- k8s.gcr.io/pause:3.1

**ctr 的镜像载入命令**：`ctr cri load image.tar`，似乎不支持 gz。

## 配置 Kubelet 使用 containerd

简单的在 Kubelet 的环境变量上加入如下内容，再启动 Kubelet 服务：

    [Service]
    Environment="KUBELET_EXTRA_ARGS=--runtime-cgroups=/system.slice/containerd.service --container-runtime=remote --runtime-request-timeout=15m --container-runtime-endpoint=unix:///run/containerd/containerd.sock"

## Kubeadm 集群安装

这里提供一个简单的初始化命令：

~~~sh
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 向服务器查询镜像列表。
~~~

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

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

> 接下来可以按照自己喜好安装网络插件了。

可以使用 `kubectl describe nodes [node name]` 来检查节点信息：

    ...
    Container Runtime Version:  containerd://1.1.0
    Kubelet Version:            v1.10.3
    Kube-Proxy Version:         v1.10.3
    PodCIDR:                     192.168.0.0/24
    ...

这里可以看到，运行时已经更新为 `containerd://1.1.0`

## 后记

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

## 下载链接以及参考链接

- **cri-containerd 1.1.0**：`https://storage.googleapis.com/cri-containerd-release/cri-containerd-1.1.0.linux-amd64.tar.gz`
- **kubeadm 安装指南**：`https://kubernetes.io/docs/tasks/tools/install-kubeadm/`
- **containerd 安装指南**：`https://github.com/containerd/containerd/releases`
- **Containerd 1.1.0 的 Kubernetes 支持已经进入可用阶段**： `https://blog.fleeto.us/post/kubernetes-containerd-integration-goes-ga/`
