如何在 Kubernetes 集群中集成 Kata
公众号关注 「奇妙的 Linux 世界」
设为「星标」,每天带你玩转 Linux !
1. Kata 解决什么问题
安全性和隔离性是 Kata Container 显著区别于 Docker Container 的地方。
Kata Container 来源于 Intel Clear Containers 和 Hyper runV 项目的合并。Intel Clear Containers 借助 Intel VT-x 技术使用轻量级虚拟机提供容器,解决安全性问题,同时性能优异。而 Hyper runV 对标的是 Docker 的 runc ,提供容器的运行时,遵循 OCI runtime 规范。
2. Kubernetes 中的 Kata
2.1 OCI 和 CRI-O
OCI 标准是为了避免容器标准被 Docker 独家挟持而出现的。
CRI 标准将 Kubelet 与运行时解耦,实现 CRI 标准的容器管理程序都可以用于 Pod 创建。
CRI-O 插件同时实现了 CRI 和 OCI 标准,可以用于替换 Containerd 直接与 runV 等 OCI runtime 对接。
如下图:
2.2 Kata 与 Containerd
为了兼容 OCI 标准,Docker 将管理运行时的功能从 Docker Daemon 中剥离出来,形成了 Containerd 。在运行容器时,可以不用 Docker 的 runc ,而替换为 kata-runtime 。
2.3 Kata 与 Kuberntes 的集成
如下图,Kata 主要替换的是 OCI runtime 层,其他部分与基于 Docker runc 的 Kubernetes 并无差异。同时,基于 kata-runtime 的 Pod 和基于 runc 的 Pod 可以共存于集群之中。
目前的主要问题是,Kata 不支持 host 网络。而 Kubernetes 中,etcd、nodelocaldns、kube-apiserver、kube-scheduler、metrics-server、node-exporter、kube-proxy、calico、kube-controller-manager 等,也就是 Static Pod 和 Daemonset 都会使用 host 网络。所以在安装部署时,依然使用 runc 作为默认的运行时,而将 kata-runtime 作为可选的运行时给特定的负载使用。
3. Kubernetes 集群集成 Kata
3.1 安装 Kubernetes 集群
使用 Kubeadm 安装集群非常方便,可以参考之前的文档 使用 Kubeadm 安装 Kubernetes 集群 。
也可以直接参考官方文档,https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/
。
由于,Kata 需要硬件虚拟化支持,IaaS 厂商一般没有开启相关的功能。我使用的是物理机,只能使用国内的网络。下面的脚本,可以用来提前下载相关镜像。
- 查询镜像列表
$ kubeadm config images list
k8s.gcr.io/kube-apiserver:v1.17.9
k8s.gcr.io/kube-controller-manager:v1.17.9
k8s.gcr.io/kube-scheduler:v1.17.9
k8s.gcr.io/kube-proxy:v1.17.9
k8s.gcr.io/pause:3.1
k8s.gcr.io/etcd:v3.3.12
k8s.gcr.io/coredns:1.6.9
- 下载镜像
images=(
kube-apiserver:v1.17.9
kube-controller-manager:v1.17.9
kube-scheduler:v1.17.9
kube-proxy:v1.17.9
pause:3.1
etcd:v3.3.12
coredns:1.6.9
)
for imageName in ${images[@]} ; do
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName k8s.gcr.io/$imageName
docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName
done
- 查看安装的 Kubernetes 版本
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.9", GitCommit:"4fb7ed12476d57b8437ada90b4f93b17ffaeed99", GitTreeState:"clean", BuildDate:"2020-07-15T16:18:16Z", GoVersion:"go1.13.9", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.9", GitCommit:"4fb7ed12476d57b8437ada90b4f93b17ffaeed99", GitTreeState:"clean", BuildDate:"2020-07-15T16:10:45Z", GoVersion:"go1.13.9", Compiler:"gc", Platform:"linux/amd64"}
3.2 安装 Kata 命令行工具
以 CentOS 操作系统为例:
$ source /etc/os-release
$ yum -y install yum-utils
$ ARCH=$(arch)
$ BRANCH="${BRANCH:-master}"
$ yum-config-manager --add-repo "http://download.opensuse.org/repositories/home:/katacontainers:/releases:/${ARCH}:/${BRANCH}/CentOS_${VERSION_ID}/home:katacontainers:releases:${ARCH}:${BRANCH}.repo"
$ yum -y install kata-runtime kata-proxy kata-shim
3.3 检测硬件是否支持 Kata
Kata 对硬件的要求需要满足以下任意条件:
- Intel VT-x technology.
- ARM Hyp mode (virtualization extension).
- IBM Power Systems.
- IBM Z mainframes.
安装完 kata-runtime 之后,执行检测命令:
$ kata-runtime kata-check
System is capable of running Kata Containers
System can currently create Kata Containers
这里的输出表示,运行环境支持 Kata Containers 。
3.4 配置并测试 Docker
- 配置 kata-runtime 参数
$ vim /etc/docker/daemon.json
新增如下内容,默认依然使用 runc,但是通过指定 runtime 参数可以使用 Kata 。
{
"runtimes": {
"kata-runtime": {
"path": "/usr/bin/kata-runtime"
}
}
}
重启 Docker 服务
$ systemctl daemon-reload
$ systemctl restart docker
测试 Kata 是否安装成功
$ docker run --runtime=kata-runtime busybox uname -a
Linux 249a23f53475 5.4.60-65.1.container #1 SMP Thu Jan 1 00:00:00 UTC 1970 x86_64 GNU/Linux
$ docker run busybox uname -a
Linux b4812ed8990c 3.10.0-1127.el7.x86_64 #1 SMP Tue Mar 31 23:36:51 UTC 2020 x86_64 GNU/Linux
kata-runtime 容器使用的内核版本与宿主机不同,这就说明 kata-runtime 配置成功了。
3.5 配置 Kubelet
- 新增配置文件
$ mkdir -p /etc/systemd/system/kubelet.service.d/
$ cat << EOF | sudo tee /etc/systemd/system/kubelet.service.d/0-containerd.conf
[Service]
Environment="KUBELET_EXTRA_ARGS=--container-runtime=remote --runtime-request-timeout=15m --container-runtime-endpoint=unix:///run/containerd/containerd.sock"
EOF
- 重启生效
$ systemctl daemon-reload
$ systemctl restart kubelet
这里使用的是 containerd 。如果使用 CRI-O ,配置会不一样。
3.6 给 Kubernetes 提供 kata-runtime
通过直接创建 Container 可以使用 kata-runtime 。但在集群中,我们该如何告诉 Kubernetes 哪些负载需要使用 kata-runtime 呢?根据不同的版本,Kata 提供了不同的方式。
首先都需要生成 containerd 配置文件
$ containerd config default > /etc/containerd/config.toml
- RuntimeClass 的方式
这种方式对相关组件版本有要求:
Kata Containers v1.5.0 or above (including 1.5.0-rc)
Containerd v1.2.0 or above
Kubernetes v1.12.0 or above
在 config.toml 配置文件中,增加如下内容:
[plugins.cri.containerd]
no_pivot = false
[plugins.cri.containerd.runtimes]
[plugins.cri.containerd.runtimes.runc]
runtime_type = "io.containerd.runc.v1"
[plugins.cri.containerd.runtimes.runc.options]
NoPivotRoot = false
NoNewKeyring = false
ShimCgroup = ""
IoUid = 0
IoGid = 0
BinaryName = "runc"
Root = ""
CriuPath = ""
SystemdCgroup = false
[plugins.cri.containerd.runtimes.kata]
runtime_type = "io.containerd.kata.v2"
[plugins.cri.containerd.runtimes.katacli]
runtime_type = "io.containerd.runc.v1"
[plugins.cri.containerd.runtimes.katacli.options]
NoPivotRoot = false
NoNewKeyring = false
ShimCgroup = ""
IoUid = 0
IoGid = 0
BinaryName = "/usr/bin/kata-runtime"
Root = ""
CriuPath = ""
SystemdCgroup = false
这里 [plugins.cri.containerd.runtimes.kata] 中的 kata 将被作为 RuntimeClass handler 关键字。
- 使用 untrusted_workload_runtime 的方式
对于不符合上述版本要求的环境,可以使用之前的方式。
在配置文件中新增如下内容:
[plugins.cri.containerd.untrusted_workload_runtime]
runtime_type = "io.containerd.runtime.v1.linux"
runtime_engine = "/usr/bin/kata-runtime"
最后,都需要重启 containerd。
$ containerd systemctl daemon-reload
$ systemctl restart containerd
4. 使用 kata-runtime
4.1 RuntimeClass 方式
- 创建 RuntimeClass
kata-runtime.yaml
kind: RuntimeClass
apiVersion: node.k8s.io/v1beta1
metadata:
name: kata-containers
handler: kata
也可以为 runc 创建 RuntimeClass
$ kubectl get runtimeclass
NAME CREATED AT
kata-containers 2020-08-30
创建负载 kata-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: kata-nginx
spec:
runtimeClassName: kata-containers
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
$ kubectl apply -f kata-pod.yaml
查看负载
$ kata-runtime list
4.2 untrusted_workload_runtime 的方式
untrusted_workload_runtime 使用 annotations 告诉 Kubernetes 集群哪些负载需要使用 kata-runtime。
annotations:
io.kubernetes.cri.untrusted-workload: "true"
下面是一个示例 kata-pod-untrusted.yaml
apiVersion: v1
kind: Pod
metadata:
name: kata-nginx-untrusted
annotations:
io.kubernetes.cri.untrusted-workload: "true"
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
$ kubectl apply -f kata-pod-untrusted.yaml
5. 参考
- https://github.com/kata-containers/documentation/blob/master/install/centos-installation-guide.md
- https://ustack.io/2019-11-21-container%E7%9B%B8%E5%85%B3%E6%A6%82%E5%BF%B5%E6%A2%B3%E7%90%86.html
- https://github.com/kata-containers/documentation/blob/master/how-to/how-to-use-k8s-with-cri-containerd-and-kata.md
- https://github.com/kubernetes/kubernetes/issues/73189
- https://blog.zufardhiyaulhaq.com/kubernetes-with-cri-containerd-and-kata-containers/
本文转载自:「陈少文的博客」,原文:https://tinyurl.com/y3b6b8zf,版权归原作者所有。欢迎投稿,投稿邮箱: editor@hi-linux.com。
- canvas实现拖动页面时显示窗口视频
- 鼠标滚轮事件介绍
- Understanding delete
- objC与js通信实现--WebViewJavascriptBridge
- 简单易学的机器学习算法——岭回归(Ridge Regression)
- QQ空间(日志、说说、个人信息)python爬虫源码(一天可抓取 400 万条数据)
- 文本分类实战: 机器学习vs深度学习算法对比(附代码)
- ReactJS分析之入口函数render
- 简单易学的机器学习算法——SVD奇异值分解
- AngularJS源码分析之依赖注入$injector
- 使用yield进行异步流程控制
- 【Java提高十七】Set接口集合详解
- 如何科学地蹭热点:用python爬虫获取热门微博评论并进行情感分析
- 使用ETag进行session的降级
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Spring Boot 入门
- Nginx 负载均衡
- Leetcode 289. 生命游戏(元胞自动机模拟)
- Nginx 简介
- 详解 Vue 目录及配置文件之 package.json
- Codeforces Round #382 (Div. 2) D. Taxes (数论 哥猜 大胆尝试)
- Vue Router
- Codeforces Round #318 [RussianCodeCup Thanks-Round] (Div. 1) B. Bear and Blocks (技巧dp 难想)
- Codeforces 727D-T-shirts Distribution (字符串 贪心)
- 详解 Vue 目录及配置文件之 build 目录
- Linux 常见文件管理命令及目录结构(1)
- Java parseInt( ) 方法
- 详解 Vue 目录及配置文件之 node_modules,src,static,test 目录
- 洛谷 P1077 摆花(记忆化搜索 or DP)
- Vue 使用 element-ui