[TOC]
### **一、目标**
本文将安装kubernetes + containerd + kata/runc,发布容器时可以指定使用kata或runc来运行。
以前,我们把docker、containerd、runc等都叫做容器运行时。但是,更准确地来说,kata/runc叫容器运行时(low-level),docker/containerd叫做容器管理器(high-level)。kubelet通过cri调用containerd,containerd通过oci调用kata或runc。
本文以 [how-to-use-k8s-with-containerd-and-kata](https://github.com/kata-containers/kata-containers/blob/main/docs/how-to/how-to-use-k8s-with-containerd-and-kata.md) 文章为参考主线。
### **二、环境准备**
在windows上用vmware workstation 虚拟一台虚拟机,注意CPU要勾选开启 `虚拟化Intel VT-x/EPT 或 AMD-V/RVI(V)`。
操作系统内核为:centos-7.6 + kernel-5.4.228(4.19的内核发现起kata容器时有问题)
### **三、安装容器运行时**
#### **3.1 安装kata**
此 [链接](https://github.com/kata-containers/kata-containers/tree/main/docs/install) 给出了Kata相应的安装方式对比
![](https://img.kancloud.cn/a4/24/a424ce378a1121c241de39c67ac32ba2_2038x790.png)
我们使用的操作系统为CentOS-7.6,由于 [Using official distro packages](https://github.com/kata-containers/kata-containers/tree/main/docs/install#official-packages) 指引中,最低需要CentOS-8
![](https://img.kancloud.cn/9f/b2/9fb233d6bb945b8d85dcc45c7cbd2272_2187x239.png)
所以这里我们选择 [Manual](https://github.com/kata-containers/kata-containers/tree/main/docs/install#manual-installation) 的安装方式。
从kata的[release](https://github.com/kata-containers/kata-containers/releases)页面,下载对应版本的包,这里我们下载最新版本 [kata-static-2.5.2-x86_64.tar.xz](https://github.com/kata-containers/kata-containers/releases/download/2.5.2/kata-static-2.5.2-x86_64.tar.xz)。下载下来后,解压得到`/opt`目录下(tar.xz包解压后会有opt目录,所以直接解压到根目录下):
```
$ tar xvf kata-static-2.5.2-x86_64.tar.xz -C /
$ ls /opt/kata/bin/
cloud-hypervisor containerd-shim-kata-v2 firecracker jailer kata-collect-data.sh kata-monitor kata-runtime qemu-system-x86_64
```
然后需要把containerd-shim-kata-v2、kata-runtime、kata-collect-data.sh做一个软链接到PATH目录下:
```
$ ln -s /opt/kata/bin/containerd-shim-kata-v2 /usr/local/bin/containerd-shim-kata-v2
$ ln -s /opt/kata/bin/kata-collect-data.sh /usr/local/bin/kata-collect-data.sh
$ ln -s /opt/kata/bin/kata-runtime /usr/local/bin/kata-runtime
```
然后检查一下kata版本,以及检查一下系统是否能跑kata容器:
```
$ kata-runtime --version
kata-runtime : 2.5.2
commit : 4b39dc0a390584d2ee21072cca7707f4ee7f56c5
OCI specs: 1.0.2-dev
$ kata-runtime kata-check
WARN[0000] Not running network checks as super user arch=amd64 name=kata-runtime pid=10121 source=runtime
System is capable of running Kata Containers
System can currently create Kata Containers
```
#### **3.2 安装runc**
我们参考containerd的 [getting-started](https://github.com/containerd/containerd/blob/main/docs/getting-started.md#step-2-installing-runc) 一文,来安装runc。
我们从runc的[github release](https://github.com/opencontainers/runc/releases)页面,下载最新版本的runc二进制文件。这里我们下载 1.1.4版本的 [runc.amd64](https://github.com/opencontainers/runc/releases/download/v1.1.4/runc.amd64)。然后,把它安装到对应目录下:
```
$ install -m 755 runc.amd64 /usr/local/bin/runc
$ runc -v
runc version 1.1.4
commit: v1.1.4-0-g5fd4c4d1
spec: 1.0.2-dev
go: go1.17.10
libseccomp: 2.5.4
```
### **三、安装容器管理器containerd**
containerd的安装我们参考containerd的 [getting-started](https://github.com/containerd/containerd/blob/main/docs/getting-started.md#option-1-from-the-official-binaries) 文章,使用二进制进行安装。[kata文章中的containerd安装指引](https://github.com/kata-containers/kata-containers/blob/main/docs/install/container-manager/containerd/containerd-install.md#install-containerd) 其实类似,不过它是把kata作为默认运行时。
下载最新版本的 [containerd-1.6.15-linux-amd64.tar.gz](https://github.com/containerd/containerd/releases/download/v1.6.15/containerd-1.6.15-linux-amd64.tar.gz),解压到`/usr/local/`目录下:
```
$ tar xvf containerd-1.6.15-linux-amd64.tar.gz -C /usr/local/
bin/
bin/containerd-stress
bin/containerd-shim
bin/containerd-shim-runc-v1
bin/containerd-shim-runc-v2
bin/containerd
bin/ctr
$ containerd --version
containerd github.com/containerd/containerd v1.6.15 5b842e528e99d4d4c1686467debf2bd4b88ecd86
```
下载[containerd.service](https://raw.githubusercontent.com/containerd/containerd/main/containerd.service)文件,放到`/etc/systemd/system/`目录下。
接着,我们首先使用命令生成containerd的默认配置文件`/etc/containerd/config.toml`:
```
$ mkdir /etc/containerd
$ containerd config default > /etc/containerd/config.toml
```
默认的配置文件中,默认的容器运行时为runc。我们在该文件中的对应位置:(1)更改sanbox imgage为国内镜像,以免拉不下来(2)添加如下kata运行时的如下三行内容(内容可参考该样例配置[cri/config.md](https://github.com/containerd/containerd/blob/main/docs/cri/config.md)和[kata此文](https://github.com/kata-containers/kata-containers/blob/main/docs/install/container-manager/containerd/containerd-install.md#install-containerd))
```
...
[plugins]
...
[plugins."io.containerd.grpc.v1.cri"]
...
# 更改为国内的镜像,kubeadm init --image-repository 也不会影响此配置
sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.6"
...
[plugins."io.containerd.grpc.v1.cri".containerd]
default_runtime_name = "runc"
...
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
...
# 添加如下三行
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.kata]
runtime_type = "io.containerd.kata.v2"
privileged_without_host_devices = false
...
```
启动containerd
```
$ systemctl daemon-reload
$ systemctl start containerd
$ systemctl enable containerd
```
接着我们来运行一个runc容器和kata容器试试,参考[kata-container/containerd-install/test-installation](https://github.com/kata-containers/kata-containers/blob/main/docs/install/container-manager/containerd/containerd-install.md#test-the-installation)
```
$ ctr image pull docker.io/library/busybox:latest
# 运行一个容器,未指定runtime,默认为runc,内核为主机内核
$ ctr run --rm -t docker.io/library/busybox:latest test-kata uname -r
5.4.228-1.el7.elrepo.x86_64
# 运行一个容器,指定runtime为kata,内核与主机内核不一样
$ ctr run --runtime "io.containerd.kata.v2" --rm -t docker.io/library/busybox:latest test-kata uname -r
5.19.2
```
注意,由于containerd自身没有网络管理的能力,且我们没有在`/opt/cni/bin`与`/etc/cni/net.d`下配置网络,所以上面的容器里面只有一个lo网卡,相当于docker的none网络。
### **四、安装kubernetes**
创建`/etc/yum.repos.d/aliyun-kubernetes.repo`文件,内容如下:
```
[aliyun-kubernetes]
name=aliyun-kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
gpgcheck=0
enabled=1
```
然后执行命令安装指定版本的kubectl kubeadm kubelet
```
$ yum -y install kubelet-1.26.0 kubeadm-1.26.0 kubectl-1.26.0
```
接着,执行命令安装集群:
```
$ kubeadm init --cri-socket unix:///run/containerd/containerd.sock --kubernetes-version v1.26.0 --image-repository registry.aliyuncs.com/google_containers --pod-network-cidr 172.26.0.0/16
```
然后去掉污点(注意污点和以前的版本不一样了,以前是`node-role.kubernetes.io/master`):
```
$ kubectl taint nodes --all node-role.kubernetes.io/control-plane-
```
然后,下载 3.24版本的 [calico.yaml](
https://raw.githubusercontent.com/projectcalico/calico/v3.24.5/manifests/calico.yaml) 文件,无须做任何更改(已经不用再改PodCIDR了),安装:
```
$ kubectl apply -f calico.yaml
```
然后查看容器状态,这些容器都是用runc运行的:
```
$ kubectl get pod -n kube-system -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
calico-kube-controllers-7bdbfc669-lt995 1/1 Running 0 2m18s 172.26.167.131 kata01 <none> <none>
calico-node-qtllt 1/1 Running 0 2m18s 192.168.92.101 kata01 <none> <none>
coredns-5bbd96d687-824mc 1/1 Running 0 113m 172.26.167.129 kata01 <none> <none>
coredns-5bbd96d687-zb44d 1/1 Running 0 113m 172.26.167.130 kata01 <none> <none>
etcd-kata01 1/1 Running 0 113m 192.168.92.101 kata01 <none> <none>
kube-apiserver-kata01 1/1 Running 0 113m 192.168.92.101 kata01 <none> <none>
kube-controller-manager-kata01 1/1 Running 0 113m 192.168.92.101 kata01 <none> <none>
kube-proxy-5r994 1/1 Running 0 113m 192.168.92.101 kata01 <none> <none>
kube-scheduler-kata01 1/1 Running 0 113m 192.168.92.101 kata01 <none> <none>
```
### **五、发布kata容器**
创建runtime-kata.yaml文件,内容如下:
```
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: kata
handler: kata
```
然后创建这个资源对象:
```
$ kubectl apply -f runtime-kata.yaml
```
接着,我们创建文件busybox.yaml,内容如下:
```
apiVersion: v1
kind: Pod
metadata:
name: busybox
spec:
runtimeClassName: kata
containers:
- name: busybox
image: docker.io/library/busybox:latest
```
创建它,并查看Pod的状态:
```
$ kubectl apply -f busybox.yaml
$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
busybox 1/1 Running 0 2m3s 172.26.167.132 kata01 <none> <none>
```
查看该容器的内核:
```
$ kubectl exec busybox -- uname -r
5.19.2
```
### **六、FAQ**
**Q: kubeadm init时,报如下的错?**
```
[ERROR FileContent--proc-sys-net-bridge-bridge-nf-call-iptables]: /proc/sys/net/bridge/bridge-nf-call-iptables does not exist
```
A:要执行命令`modprobe br_netfilter`加载该内核模块。但重启主机后依然会失效,所以我们需要持久化。创建文件`/etc/modules-load.d/br_netfilter.conf`,内容为`br_netfilter`。
### **参考**
* https://github.com/kata-containers/kata-containers/blob/main/docs/how-to/how-to-use-k8s-with-containerd-and-kata.md
* https://github.com/kata-containers/kata-containers/blob/main/docs/how-to/containerd-kata.md
* https://github.com/kata-containers/kata-containers/tree/main/docs/install
* https://github.com/kata-containers/kata-containers/blob/main/docs/install/container-manager/containerd/containerd-install.md
* https://katacontainers.io/docs/
- 常用命令
- 安装
- 安装Kubeadm
- 安装单Master集群
- 安装高可用集群(手动分发证书)
- 安装高可用集群(自动分发证书)
- 启动参数解析
- certificate-key
- ETCD相关参数
- Kubernetes端口汇总
- 安装IPv4-IPv6双栈集群
- 下载二进制文件
- 使用Kata容器
- 快速安装shell脚本
- 存储
- 实践
- Ceph-RBD实践
- CephFS实践
- 对象存储
- 阿里云CSI
- CSI
- 安全
- 认证与授权
- 认证
- 认证-实践
- 授权
- ServiceAccount
- NodeAuthorizor
- TLS bootstrapping
- Kubelet的认证
- 准入控制
- 准入控制示例
- Pod安全上下文
- Selinux-Seccomp-Capabilities
- 给容器配置安全上下文
- PodSecurityPolicy
- K8S-1.8手动开启认证与授权
- Helm
- Helm命令
- Chart
- 快速入门
- 内置对象
- 模板函数与管道
- 模板函数列表
- 流程控制
- Chart依赖
- Repository
- 开源的Chart包
- CRD
- CRD入门
- 工作负载
- Pod
- Pod的重启策略
- Container
- 探针
- 工作负载的状态
- 有状态服务
- 网络插件
- Multus
- Calico+Flannel
- 容器网络限速
- 自研网络插件
- 设计文档
- Cilium
- 安装Cilium
- Calico
- Calico-FAQ
- IPAM
- Whereabouts
- 控制平面与Pod网络分开
- 重新编译
- 编译kubeadm
- 编译kubeadm-1.23
- 资源预留
- 资源预留简介
- imagefs与nodefs
- 资源预留 vs 驱逐 vs OOM
- 负载均衡
- 灰度与蓝绿
- Ingress的TLS
- 多个NginxIngressController实例
- Service的会话亲和
- CNI实践
- CNI规范
- 使用cnitool模拟调用
- CNI快速入门
- 性能测试
- 性能测试简介
- 制作kubemark镜像
- 使用clusterloader2进行性能测试
- 编译clusterloader2二进制文件
- 搭建性能测试环境
- 运行density测试
- 运行load测试
- 参数调优
- Measurement
- TestMetrics
- EtcdMetrics
- SLOMeasurement
- PrometheusMeasurement
- APIResponsivenessPrometheus
- PodStartupLatency
- FAQ
- 调度
- 亲和性与反亲和性
- GPU
- HPA
- 命名规范
- 可信云认证
- 磁盘限速
- Virtual-kubelet
- VK思路整理
- Kubebuilder
- FAQ
- 阿里云日志服务SLS