惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

IT之家
IT之家
T
Tailwind CSS Blog
V
V2EX
阮一峰的网络日志
阮一峰的网络日志
H
Help Net Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
腾讯CDC
GbyAI
GbyAI
酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Last Week in AI
Last Week in AI
A
About on SuperTechFans
L
LangChain Blog
Engineering at Meta
Engineering at Meta
F
Fortinet All Blogs
G
Google Developers Blog
The Cloudflare Blog
云风的 BLOG
云风的 BLOG
D
Docker
博客园 - 聂微东
博客园 - 司徒正美
Recent Announcements
Recent Announcements
MyScale Blog
MyScale Blog
U
Unit 42

陈少文的网站

巨变与机遇的未来十年 Kubernetes 平台管理软件压力测试方案 使用镜像部署 Hexo 静态页面 终于等到你 - GitHub 镜像仓库服务(ghcr.io) 一起来学 Go --(6)Interface 一起来学 Go --(5)Goroutine 和 Channel 什么是函数式编程 柯里化与偏函数 使用 PyGithub 自动创建 Label 软件产品是团队能力的输出 Helm 2 、Helm 3 比较 IoT 变现 Kubernetes 中的 DNS 服务 国内的 Helm 镜像源 Harbor 使用自签证书支持 Https 访问 DevOps 工具链之 Prow 如何使用 kfctl 安装 Kubeflow VS Code 无法下载 Go 插件的工具包 工程师更应具有服务精神 你不知道的 Docker 使用技巧 使用 Docker 运行 Tensorflow 论中国 什么是左移 如何清空 Git 仓库全部历史记录 一禅小和尚 有风吹过厨房 时间的玫瑰 如何在 CentOS 安装 GPU 驱动 开发 Tips(19) 使用 Velero 备份 Kubernetes 集群
如何在 Kubernetes 集群集成 Kata
微信公众号 · 2020-08-30 · via 陈少文的网站

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 直接与 runc 等 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 厂商一般没有开启相关的功能。我使用的是物理机,只能使用国内的网络。下面的脚本,可以用来提前下载相关镜像。

  • 查询镜像列表
1
2
3
4
5
6
7
8
9
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
  • 下载镜像
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
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-beijing.aliyuncs.com/google_containers/$imageName
    docker tag registry.cn-beijing.aliyuncs.com/google_containers/$imageName k8s.gcr.io/$imageName
    docker rmi registry.cn-beijing.aliyuncs.com/google_containers/$imageName
done
  • 查看安装的 Kubernetes 版本
1
2
3
4
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 操作系统为例:

1
2
3
4
5
6
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 之后,执行检测命令:

1
2
3
4
kata-runtime kata-check

System is capable of running Kata Containers
System can currently create Kata Containers

这里的输出表示,运行环境支持 Kata Containers 。

3.4 配置并测试 Docker

  • 配置 kata-runtime 参数
1
vim /etc/docker/daemon.json

新增如下内容,默认依然使用 runc,但是通过指定 runtime 参数可以使用 Kata 。

1
2
3
4
5
6
7
{
  "runtimes": {
    "kata-runtime": {
      "path": "/usr/bin/kata-runtime"
    }
  }
}
  • 重启 Docker 服务
1
2
systemctl daemon-reload
systemctl restart docker
  • 测试 Kata 是否安装成功
1
2
3
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
1
2
3
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

  • 新增配置文件
1
2
3
4
5
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
  • 重启生效
1
2
systemctl daemon-reload
systemctl restart kubelet

这里使用的是 containerd 。如果使用 CRI-O ,配置会不一样。

3.6 给 Kubernetes 提供 kata-runtime

通过直接创建 Container 可以使用 kata-runtime 。但在集群中,我们该如何告诉 Kubernetes 哪些负载需要使用 kata-runtime 呢?根据不同的版本,Kata 提供了不同的方式。

首先都需要生成 containerd 配置文件

1
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 配置文件中,增加如下内容:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
    [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 的方式

对于不符合上述版本要求的环境,可以使用之前的方式。

在配置文件中新增如下内容:

1
2
3
    [plugins.cri.containerd.untrusted_workload_runtime]
      runtime_type = "io.containerd.runtime.v1.linux"
      runtime_engine = "/usr/bin/kata-runtime"

最后,都需要重启 containerd。

1
2
containerd systemctl daemon-reload
systemctl restart containerd

4. 使用 kata-runtime

4.1 RuntimeClass 方式

  • 创建 RuntimeClass

kata-runtime.yaml

1
2
3
4
5
kind: RuntimeClass
apiVersion: node.k8s.io/v1beta1
metadata:
  name: kata-containers
handler: kata

也可以为 runc 创建 RuntimeClass

1
2
3
4
kubectl get runtimeclass

NAME              CREATED AT
kata-containers   2020-08-30
  • 创建负载 kata-pod.yaml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
apiVersion: v1
kind: Pod
metadata:
  name: kata-nginx
spec:
  runtimeClassName: kata-containers
  containers:
    - name: nginx
      image: nginx
      ports:
        - containerPort: 80
1
kubectl apply -f kata-pod.yaml
  • 查看负载

4.2 untrusted_workload_runtime 的方式

untrusted_workload_runtime 使用 annotations 告诉 Kubernetes 集群哪些负载需要使用 kata-runtime。

1
2
annotations:
  io.kubernetes.cri.untrusted-workload: "true"

下面是一个示例 kata-pod-untrusted.yaml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
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
1
kubectl apply -f kata-pod-untrusted.yaml

5. 参考