最近有个项目需要考虑安全容器,因此先调研下 kata contaienr,尝尝鲜
Kata container 简介
Kata Container 是两个现有的开源项目合并:Intel Clear Containers和Hyper runV。
Intel Clear Container项目的目标是通过英特尔®虚拟化技术(VT)解决容器内部的安全问题,并且能够将容器作为轻量级虚拟机(VM)启动,提供了一个可选的运行时间,专注于性能(<100ms启动时间),可与Kubernetes 和Docker 等常用容器环境互操作。英特尔®Clear Container表明,安全性和性能不必是一个折衷,将硬件隔离的安全性与容器的性能可以兼得。
hyper runV优先于技术无关支持许多不同的CPU架构和管理程序。
容器安全
使用Docker轻量级的容器时,最大的问题就是会碰到安全性的问题,其中几个不同的容器可以互相的进行攻击,如果把这个内核给攻掉了,其他所有容器都会崩溃。如果使用KVM等虚拟化技术,会完美解决安全性的问题,但响应的性能会受到一定的影响。
单单就Docker来说,安全性可以概括为两点:
- 不会对主机造成影响
- 不会对其他容器造成影响
所以安全性问题90%以上可以归结为隔离性问题。而Docker的安全问题本质上就是容器技术的安全性问题,这包括共用内核问题以及Namespace还不够完善的限制:
- /proc、/sys等未完全隔离
- Top, free, iostat等命令展示的信息未隔离
- Root用户未隔离
- /dev设备未隔离
- 内核模块未隔离
- SELinux、time、syslog等所有现有Namespace之外的信息都未隔离
当然,镜像本身不安全也会导致安全性问题。
kata 隔离技术
我们都知道 Docker 等一类的容器使用 Cgroup 进行资源限制,使用 linux 的 namespace 机制对容器进行隔离,但在实际运行中,仍是由宿主机向容器直接提供网络、存储、计算等资源,虽然性能损失很小,但存在一定的安全问题。
Kata Containers是一个开放源代码社区,致力于通过轻量级虚拟机来构建安全的容器运行时,这些虚拟机的感觉和性能类似于容器,但是使用硬件虚拟化技术作为第二防御层,可以提供更强的工作负载隔离。
kata 底层实现了Intel Clear Containers的最佳部分与Hyper.sh RunV合并,并进行了扩展,以包括对主要架构的支持,包括x86_64之外的AMD64,ARM,IBM p系列和IBM z系列。
Kata Containers还支持多个虚拟机管理程序,包括QEMU,NEMU和Firecracker,并与其他容器化项目集成。
QEMU 一种虚拟机,与KVM相似,但KVM 是硬件辅助的虚拟化技术,主要负责 比较繁琐的 CPU 和内存虚拟化,而 Qemu 则负责 I/O 虚拟化
架构原理
kata 实际上是通过创建轻量级虚拟机实现容器之间的资源隔离,再在虚拟机中运行容器运行时,这样就使容器在专用内核中运行,提供网络,I / O和内存的隔离,并可以通过虚拟化VT扩展利用硬件强制隔离。提供安全性的同时,其仍然由很高的性能。
kata 包含的主要组件有两部分:
- container runtime: 负责为每个 container 或 pod 创建QEMU/KVM虚拟机,支持 OCI 运行时规范,可以以插件形式嵌入到 Docker 中作为底层的容器运行时;也支持 K8s 的 CRI 接口*,可以与 CRI-O 和 containerd 集成
- agent :在宿主机中用于管理容器和在这些容器中运行的进程。
kata 与 kata-shim
在 Docker 引擎中,Docker 调用 containerd,containerd 通过 shim 调用 runc创建底层的容器,(之前在 深入理解container 篇中详细描述过此过程),若将kata 集成到 Docker 中时,containerd 则调用 kata 提供的 kata-shim
去创建 kata 容器运行时。
值得提的一点是,kata 现在正在努力推行 shimv2 接口,shimv2 主要影响了 K8s 调用 CRI 创建 pod 和容器。
借助shimv2,Kubernetes可以使用每个Pod一个shimv2 而不是2N + 1 个shim(每个容器和Pod沙箱本身的容器shim和kata shim)
agent
容器进程由 agent 生成,agent 在虚拟机内部作为守护进程运行。
kata-agent使用 VIRTIO 串行或 VSOCK 接口在宿主机中运行gRPC服务器,QEMU在宿主机中通过暴露 socket 文件向外部提供链接。kata-runtime 使用 gRPC 协议与 agent 进行通信。该协议允许运行时将容器管理命令发送到 agent。该协议还用于在容器和管理引擎(例如Docker Engine)之间传输I/O流(stdout,stderr,stdin)。也就是说在容器中,包括 init 进程在内,所有与容器交互的命令以及 IO 均会通过 VIRTIO 或 VSOCK。
K8s 集成 kata-container
准备过程
- 硬件支持
首先节点需要支持以下四种任意一种cpu虚拟化技术- Intel VT-x technology
- ARM Hyp mode
- IBM Power Systems
- IBM Z manframes
> 如果部署在VMware虚拟机中,需要在宿主机开启**嵌套虚拟化**的功能,开启步骤见链接 https://blog.51cto.com/11434894/2389180?source=dra
- 软件依赖
- 正常运行的 K8s 环境
- containerd
安装 kata-container
执行以下脚本安装
source /etc/os-release
sudo yum -y install yum-utils
ARCH=$(arch)
BRANCH="${BRANCH:-master}"
sudo -E yum-config-manager --add-repo "http://download.opensuse.org/repositories/home:/katacontainers:/releases:/${ARCH}:/${BRANCH}/CentOS_${VERSION_ID}/home:katacontainers:releases:${ARCH}:${BRANCH}.repo"
sudo -E yum -y install kata-runtime kata-proxy kata-shim
注意:我在安装时,kata 刚刚发布了 1.11 alpha0 版本,此版本中依赖的 qume-vanilla 版本为
4.1.1+git.99c5874a9b
,但是 repo 源中只有4.1.0+git.9e06029aea-6.1.x86_64
,因此在执行脚本之前,需要设置 BRANCH 环境变量:export BRANCH='stable-1.10'
安装完成之后,执行命令 kata-runtime kata-check
检查系统是否支持运行 kata runtime
WARN[0000] modprobe insert module failed: modprobe: FATAL: Module vhost_vsock not found.
arch=amd64 error="exit status 1" module=vhost_vsock name=kata-runtime pid=21060 source=runtime
ERRO[0000] kernel property not found arch=amd64 description="Host Support for Linux VM Sockets" name=vhost_vsock pid=21060 source=runtime type=module
System is capable of running Kata Containers
System can currently create Kata Containers
这里的error 有可能是我使用了VMware 嵌套虚拟化导致的,暂且放置。
K8s 对接运行时更改为 containerd
- 首先启用 containerd
systemctl enable containerd
修改 containerd 的配置文件,/etc/containerd/config.toml
,官网默认配置见链接:https://github. com/containerd/cri/blob/master/docs/config.md
需要注意的是:
- [plugins.cri] 条目下,可以配置 K8s sandbox 使用的镜像, 默认为`k8s.io/pause-amd64:3.2`
- containerd 1.3.2 版本以前,不支持非安全的 registry,也就是说拉镜像时使用的必须是 https 协议,自 己搭私有仓库的同学,可以升级到 1.3.3,并且增加条目
```toml
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."your registry".tls]
insecure_skip_verify = true
```
2. 修改 kubelet 启动参数
```bash
$ sudo 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
```
3. 重启 containerd 和 kubelet
```bash
systemctl daemon-reload
systemctl start containerd
systemctl restart kubelet
```
K8s 配置使用Kata
K8s 使用 Kata 有两种方式:
- 使用 K8s untrustedworkloadruntime
- 使用 K8s 的 RuntimeClass,这个在 1.12 版本作为alpha特性使用
使用 untrustedworkloadruntime
首先在 containerd 的配置文件中,增加条目
# "plugins.cri.containerd.untrusted_workload_runtime" is a runtime to run untrusted workloads on it.
[plugins.cri.containerd.untrusted_workload_runtime]
# runtime_type is the runtime type to use in containerd e.g. io.containerd.runtime.v1.linux
runtime_type = "io.containerd.kata.v2"
若使用的 kata 版本较低,不支持 shimV2,则使用条目
[plugins.cri.containerd.untrusted_workload_runtime]
# runtime_type is the runtime type to use in containerd e.g. io.containerd.runtime.v1.linux
runtime_type = "io.containerd.runtime.v1.linux"
# runtime_engine is the name of the runtime engine used by containerd.
runtime_engine = "/usr/bin/kata-runtime"
然后重启 containerd systemctl daemon-reload & systemctl restart containerd
K8s 资源需要增加 annotation
annotations:
io.kubernetes.cri.untrusted-workload: "true"
例如:
apiVersion: v1
kind: Pod
metadata:
name: nginx-untrusted
annotations:
io.kubernetes.cri.untrusted-workload: "true"
spec:
nodeName: k8s3
containers:
- name: nginx
image: nginx
使用 RuntimeClass
这种模式下,相关软件版本需求如下:
- Kata Container >= 1.5.0
- containerd >= 1.2.0
- K8s >= 1.12.0
在 Containerd 配置文件中配置相关条目
[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
在 K8s 中创建 RuntimeClass
apiVersion: node.k8s.io/v1beta1 # RuntimeClass is defined in the node.k8s.io API group
kind: RuntimeClass
metadata:
name: kata
handler: kata # 这里与containerd配置文件中的 [plugins.cri.containerd.runtimes.{handler}] 匹配
创建pod
apiVersion: v1
kind: Pod
metadata:
name: kata-nginx
spec:
runtimeClassName: kata
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
通过kata-runtime list
可以查看创建出来的 container
ID PID STATUS BUNDLE CREATED OWNER
5a512bfa19cd166c6cc6411dd7e1d20cc41490d0f2df064adab7871c9656a058 -1 running /run/containerd/io.containerd.runtime.v2.task/k8s.io/5a512bfa19cd166c6cc6411dd7e1d20cc41490d0f2df064adab7871c9656a058 2020-02-26T09:49:43.743162591Z #0
432628537c5d5606707e225869846542c68cb7406992dcf55a4b48a494f333b8 -1 running /run/containerd/io.containerd.runtime.v2.task/k8s.io/432628537c5d5606707e225869846542c68cb7406992dcf55a4b48a494f333b8 2020-02-26T09:49:47.928499707Z #0
如果喜欢,请关注我的公众号,或者查看我的博客 http://packyzbq.coding.me. 我会不定时的发送我自己的学习记录,大家互相学习交流哈~
今天的文章K8s-katacontainer 实践分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/19250.html