gVisor使用探索


前言

容器虽然带来了高效快捷的虚拟化,但是由于共用内核,容器的安全性也是最受关注的。gVisor是google引入的一套全新的容器安全解决方案,重新实现容器进程的每一个系统调用,其性能相比runc等下降了不少。本文主要介绍gVisor的基本概念及使用。


提示:以下是本篇文章正文内容,下面案例可供参考

一、gVisor引入背景

容器主要使用Linux kernel提供的name space和cgroup机制进行了访问控制及资源隔离,相比裸金属方式的虚拟化,由于容器共用hostos kernel,其性能获得较大提升,但是共享kernel带来的最大问题就是安全性无法获得保障。google引入了gVisor,其在name space和cgroup隔离的基础上添加了一层防护,旨在提供进程级的轻量虚拟化。

二、gVisor简介

1.架构图

gVisor提供了两种方式对容器进程的系统调用进行了拦截实现,它包含以下几个进程:
gVisor架构图

2.gVisor组件简介

1. runsc: 遵循OCI(Open Container Initiative)标准的容器runtime,它可以在docker或者kubernetes中使用。
2. Sentry:gVisor中最大的组件,可以将它视为“用户态内核”,Sentry实现了应用程序所需的所有内核功能,包括:系统调用、信号传递、内存管理和页面错误逻辑、线程模型等等。
3. Gofer:Gofer是一个标准主机进程,由每个容器启动,并通过套接字或共享内存通道通过9P协议与Sentry进行通讯。Sentry进程在受限制的seccomp容器中启动,无法访问文件系统资源。Gofer协调所有对这些资源的访问,提供额外的隔离级别。
4. Application: OCI运行时bundle中的普通Linux二进制文件,gVisior旨在提供一个与Linux v4.4相同的运行环境,因此应用程序应该能够无修改运行,gVisor目前没有实现每个系统调用,/proc、/sys文件系统也没有实现。

三、使用

1.安装

官方安装脚本:

(
  set -e
  ARCH=$(uname -m)
  URL=https://storage.googleapis.com/gvisor/releases/release/latest/${ARCH}
  wget ${URL}/runsc ${URL}/runsc.sha512 \
    ${URL}/containerd-shim-runsc-v1 ${URL}/containerd-shim-runsc-v1.sha512
  sha512sum -c runsc.sha512 \
    -c containerd-shim-runsc-v1.sha512
  rm -f *.sha512
  chmod a+rx runsc containerd-shim-runsc-v1
  sudo mv runsc containerd-shim-runsc-v1 /usr/local/bin
)

安装gVisor作为docker的runtime,使用如下命令:

/usr/local/bin/runsc install
sudo systemctl reload docker
docker run --rm --runtime=runsc hello-world

2.配置

runsc使用kvm或者ptrace的方式对系统调用进行拦截,默认ptrace,如果想使用kvm,则需要进行如下配置:

  1. 架构选择
    如果运行的是基于Debian的系统,如Debian或Ubuntu,可以查看/dev/kvm确认模块已经加载。
	Inter CPU:sudo modprobe kvm-intel && sudo chmod a+rw /dev/kvm
	AMD CPU: sudo modprobe kvm-amd && sudo chmod a+rw /dev/kvm

配置docker,通过runsc --platform来选择,修改/etc/docker/daemon.json来设置此参数

{
    "runtimes": {
        "runsc": {
            "path": "/usr/local/bin/runsc",
            "runtimeArgs": [
                "--platform=kvm"
            ]
       }
    }
}   		
  1. 配置文件系统
    要将主机文件系统与sandbox隔离,可以在整个文件系统的顶部设置一个可写的tmpfs覆盖,所有修改都是对覆盖进行的,保持主机文件系统不变。修改/etc/docker/daemon.json然后重启docker daemon.
{
    "runtimes": {
        "runsc": {
            "path": "/usr/local/bin/runsc",
            "runtimeArgs": [
                "--overlay"
            ]
       }
    }
}
  1. 网络配置
    对于高性能网络应用程序,可以选择禁用用户空间网络堆栈,而使用主机网络堆栈,包括环回,此模式会降低与主机的隔离度。修改/etc/docker/daemon.json
{
   "runtimes": {
       "runsc": {
           "path": "/usr/local/bin/runsc",
           "runtimeArgs": [
               "--network=host"
           ]
      }
   }
}

要将主机和网络与sandbox完全隔离,可以禁用外部网络。sandbox仍将包含netstack提供的环回。
此时配置–network=none即可。

3.go get方式安装

笔者在使用pkgs.org中提供的rpm包直接安装后,使用runsc create容器时报错:

#runsc --platform=ptrace --debug --debug-log=/tmp/runsc-debug.log --strace --log-packets run hello
running container: creating container: waiting for sandbox to start: EOF
#runsc --platform=ptrace --debug --debug-log=/tmp/runsc-debug.log --strace --log-packets -TESTONLY-unsafe-nonroot run hello
#running container: starting container: starting root container: urpc method "containerManager.StartRoot" failed: EOF

随后卸载了rpm包的方式,使用go get重新安装,注意必须要"CGO_ENABLED=0 GO111MODULE=on",否则还是会报错。

#go env -w GO111MODULE=on;go env -w GOPROXY=https://goproxy.cn,direct
#echo "module runsc" > go.mod
GO111MODULE=on go get gvisor.dev/gvisor/runsc@go
CGO_ENABLED=0 GO111MODULE=on sudo -E go build -o /usr/local/bin/runsc gvisor.dev/gvisor/runsc

4.作为docker runtime使用

#sudo runsc install --runtime runsc-debug -- \
 --debug \
 --debug-log=/tmp/runsc-debug.log \
 --strace \
 --log-packets
#cat /etc/docker/daemon.json
"runtimes": {
       "runsc": {
           "path": "/usr/sbin/runsc"
       },
       "runsc-debug": {
           "path": "/usr/sbin/runsc",
           "runtimeArgs": [
               "--debug",
               "--debug-log=/tmp/runsc-debug.log",
               "--strace",
               "--log-packets"
           ]
       }
   }
#systemctl restart docker
#docker pull ubuntu
#docker run -it --runtime=runsc ubuntu bash
root@e2b2f32ea20a:/# ps
 PID TTY          TIME CMD
   1 ?        00:00:00 bash
   7 ?        00:00:00 ps
root@e2b2f32ea20a:/# 

使用另外一个终端查看容器信息:

[root@oe2109 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
e2b2f32ea20a        ubuntu              "bash"              14 minutes ago      Up 14 minutes                           zen_lovelace
[root@oe2109 ~]# docker inspect e2b2
...
"ShmSize": 67108864,
"Runtime": "runsc"
[root@oe2109 ~]# ps -aux | grep docker
root       11013  0.0  0.8 750412 30340 ?        Sl   14:11   0:00 runsc-gofer --root=/var/run/docker/runtime-runsc/moby --log=/run/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/e2b2f32ea20ac7a04dea3d89e47da51d6ce571edadeb50c432d71c5801f33100/log.json --log-format=json --log-fd=3 gofer --bundle /var/run/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/e2b2f32ea20ac7a04dea3d89e47da51d6ce571edadeb50c432d71c5801f33100 --spec-fd=4 --mounts-fd=5 --io-fds=6 --io-fds=7 --io-fds=8 --io-fds=9 --io-fds=10 --apply-caps=false --setup-root=false
nobody     11017  0.0  1.0 1812948 36204 pts/1   Ssl+ 14:11   0:00 runsc-sandbox --root=/var/run/docker/runtime-runsc/moby --log=/run/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/e2b2f32ea20ac7a04dea3d89e47da51d6ce571edadeb50c432d71c5801f33100/log.json --log-format=json --log-fd=3 boot --bundle=/var/run/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/e2b2f32ea20ac7a04dea3d89e47da51d6ce571edadeb50c432d71c5801f33100 --controller-fd=4 --mounts-fd=5 --spec-fd=6 --start-sync-fd=7 --io-fds=8 --io-fds=9 --io-fds=10 --io-fds=11 --io-fds=12 --stdio-fds=13 --stdio-fds=14 --stdio-fds=15 --cpu-num 4 --total-memory 3553030144 e2b2f32ea20ac7a04dea3d89e47da51d6ce571edadeb50c432d71c5801f33100

参考资料: https://gvisor.dev/docs/

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
在Kubernetes中实现互联网安全是一个重要的任务,以下是一些可以帮助您加强Kubernetes集群安全性的措施: 1. 访问控制:使用Kubernetes的RBAC(Role-Based Access Control)功能,限制和管理用户对集群资源的访问权限。为每个用户分配适当的角色和权限,确保只有授权的用户可以进行操作。 2. 网络策略:使用网络策略(Network Policies)来定义和限制Pod之间的网络通信。通过配置网络策略,您可以控制Pod之间的流量,只允许特定的网络请求。 3. 加密通信:为了保护集群中的通信安全,您可以启用TLS(Transport Layer Security)加密来保护API服务器和ETCD集群的通信。您还可以使用Ingress或Service Mesh来提供加密的入口和服务之间的通信。 4. 容器镜像安全:确保使用受信任和经过验证的容器镜像。您可以使用容器镜像扫描工具来检查容器镜像中的漏洞和安全问题,并定期更新和维护镜像。 5. 安全审计和日志记录:启用Kubernetes的审计功能,并将审计日志记录到安全的位置。这样可以跟踪和监控对集群的操作,并检测潜在的安全问题。 6. 容器运行时安全:确保您的容器运行时环境是安全的,并采取措施来减少容器之间的攻击面。例如,使用容器隔离技术如gVisor或Kata Containers来提供额外的安全层。 7. 安全更新和漏洞管理:保持集群中的组件和依赖项处于最新状态,及时修复已知的漏洞和安全问题。定期进行安全补丁更新,并监控相关的安全公告。 这些是一些常见的Kubernetes集群安全措施,但实际中还有更多的安全性实践可以采用。建议您参考Kubernetes官方文档中关于集群安全的详细指南,并根据您的具体需求和环境做出相应的安全配置。如有任何问题,请随时提问!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值