电商业务容器化遇瓶颈公有云Docker镜像P2P加速很安全

当前,电商平台会采用基于Docker的容器技术来承载618大促期间的一些关键业务版块,包括最简单的商品图片展示、订单详情页面等等。 通过容器化改造,电商平台的每个业务版块解耦,可以独立开发、部署和上线,从而让后台业务系统具备更高的稳定性、可扩展性和安全性,即便某个环节出现问题,也能保障平台高峰值期间的平稳运行。 镜像是Docker容器的基石,只有通过它才可以创建容器,而Registry是存放Docker镜像的仓库。但在实际应用中,由于需要频繁地从Registry下载镜像运行容器应用(比如发布新版本,打补钉等情形),其间的文件传输成为镜像分发的瓶颈, P2P加速镜像下载是有效的解决方案,但如何确保用户数据在公有云环境下的P2P传输安全性尤为关键,本文主要从链路层和业务层的安全加固,阐述了公有云Docker镜像P2P加速的安全性。 问题:在使用Docker运行容器化应用时,宿主机通常先要从Registry服务(如Docker Hub)下载相应的镜像(image)。这种镜像机制在开发环境中使用还是很有效的,团队成员之间可以很方便地共享同样的镜像。然而在实际的生产环境中,当大量主机需要同时从Registry下载镜像运行容器应用时(比如发布新版本,打补钉等情形),Registry 服务往往会成为镜像分发的瓶颈,应用镜像需要较长时间才能传送到所有主机上,使得应用发布的周期大大延长。 不少企业提出了P2P加速镜像下载的解决方案,但都是私有云及内部环境的使用场景,在公有云未得到使用。其中很大一部分原因是公有云使用P2P的安全性问题,如何确保用户数据在P2P传输中是安全的成为了其中的难点。我们就该问题设计实现了确保用户数据安全的P2P镜像分发系统。本文就其安全性展开阐述。 架构: 华为P2P容器镜像分发系统示例图 华为P2P容器镜像分发系统包含3个组件:客户端代理(Proxy)、BT客户端和BT Tracker。 客户端代理(Proxy) 客户端代理部署在集群的每个节点中,配置为Docker的Http Proxy,截获Docker Daemon的镜像下载请求,通知Client下载,并最终将镜像导入到Docker daemon中。 BT客户端 部署在集群节点的BT客户端和Tracker共同组成了一个完整的P2P文件传输系统。在整个镜像的分发过程中,它们利用BT协议完成镜像下载。 BT Tracker Tracker是BT系统的一部分,它存储了BT客户端下载过程中所需要的元数据信息和种子信息,并协助各个BT客户端完成整个通信过程。 安全:首先,我们限制了跨集群的P2P下载,最大限度防止租户间的数据泄露。 之后,在链路层面的安全性和业务层面的安全性做了增强。 链路安全一想到链路安全,我们首先会想到的是加密。 对称加密服务端和客户端采用相同的秘钥加密和解密,只要这个秘钥不公开,并且秘钥足够安全,那么链路就是安全的。但是在网络中都使用相同的对称加密秘钥,无异于公开传输,如果秘钥被劫持,那么就可以篡改链路的所有数据。 然后我们肯定会想到HTTPS,它是怎么实现安全的?我们先来了解下HTTPS的实现方式。 在具体的数据传输过程中,HTTPS采用的是对称加解密的方式,但是它在连接建立时增加了握手协商的过程。 什么是公钥:公钥是非对称加密中的概念。非对称加密算法方式基于一个秘钥对,数据通过一个秘钥加密,只有通过另外一个秘钥才能解密。服务端保存私钥,公钥发给客户端。 我们假设一个场景,我们生成秘钥对,客户端通过公钥加密数据,服务端通过私钥解密。那么即使用户劫持到公钥,他无法劫持篡改用户的数据。然而从服务端到客户端的链路还是不安全的。 HTTPS借助了非对称加密的这个特性,确保对称机密秘钥的传输是安全的,最后采用对称加密传输数据。 证书的意义:然而,这又产生了一个新的问题,公钥被劫持了怎么办? HTTPS当然不会这么简单就被劫持,为了解决上诉问题,它引入了数字证书和第三方机构。证书是由第三方认证机构通过公钥签发的,其中不仅包含公钥,还包含签名( 由签发节点的私钥加密产生)、有限期、签发机构、网址、失效日期等。 HTTPS返回的不在是私钥,而是证书。当客户端接收到证书,会对证书做一个校验。在各个机器中都会维护一个权威的第三方机构列表(包括它们的公钥),当客户端需要公钥时,可根据颁发机构信息本地查找到公钥。客户端通过颁发机构的公钥验证签名的有效性和证书的完整性,保证公钥未被篡改。 HTTPS通过私钥、证书、和CA(签发机构)确保了链路的安全性。在P2P场景下,BT Client之间是对等的,他们相互传输数据,更应该是服务端校验客户端,而不是HTTPS的客户端校验服务端。并且由于BT Client是部署在用户的节点,还需要考虑证书和私钥都被劫持的风险。 我们是怎么做的Client之间BT Client间传输数据肯定是需要加密的,防止链路的数据被劫持。但是只增加HTTPS,虽然链路被加密,但是客户端可能会被假冒,只要假冒者不校验服务端的证书,直接和服务端握手,就能从其他BT Client获取到他想要的数据。 我们借鉴HTTPS的实现,采用了双向验证的模式。 需要有证书,首先需要一个统一的CA(签发机构),因此我们在Tracker中保存证书和私钥做为签发机构,Proxy获取种子的同时返回CA,用户校验客户端的证书。 然后,只使用一个证书对并且放在Bt Client是危险的,很有可能性被入侵截获到证书,因此我们获取证书的方式改为从Tracker获取,获取种子的同时获取Tracker生成的临时证书私钥对,把它加入BT Client的下载队列。在BT Client开始相互连接时,首先相互确认对方的证书的有效性(签名、签发机构等信息),校验通过后才能请求并相互下载数据。 这种方式下,Client之间的链路是安全的。 (1)链路经过证书加密,直接截获链路是不可行的 (2)即使仿照BT Client的方式,由于Client每个连接都需要进行双向的证书校验,想通过这个方式截获数据就必须请求Tracker去获取,而访问Tracker首先是HTTPS的,然后我们还做了业务层的安全校验(下文业务层安全会提及),也是不可行的。 Docker Daemon 到 Proxy我们在Proxy中需要劫持Docker的请求,因为Docker在不配置时访问Registry采用的是HTTPS,因此Proxy劫持Docker请求就必须和Docker保持HTTPS连接。 我们让客户端代理只监听localhost端口,杜绝外部使用该代理的可能性。同时,客户端代理绑定一套临时生成的签发给registry域名的自签名证书和CA证书,用于劫持Docker Daemon的请求,并将CA证书添加到机器的信任证书当中。 代理绑定的证书只保存在内存中,即使通过特定方式获取到当前节点的CA证书和服务端证书,也无法截取其他节点数据。 从用户节点到Registry、Tracker首先,为了确保链路的安全,Regstry、Tracker都绑定从权威第三方机构购买的HTTPS证书私钥对。Proxy和BT Client在访问它们的时候都会去校验证书的有效性,只要在证书有效的情况下才发送请求,这从根源上杜绝了Regstry、Tracker被假冒的可能。 业务加密在确保链路安全后,我们还做了一层业务安全加固。首先我们先了解下JWT Token。 ...

June 18, 2020 · 1 min · jiezi

OpenYurt-开箱测评-一键让原生-K8s-集群具备边缘计算能力

作者| 郑超 阿里云高级开发工程师 随着物联网技术以及 5G 技术的高速发展,将云计算的能力延伸至边缘设备端,并通过中心进行统一交付、管控,已成为云计算的重要发展趋势。为服务更多开发者把握这一趋势,5 月 29 日,阿里巴巴正式对外开源了基于 ACK@Edge(边缘集群托管服务)的云原生边缘计算框架 —— OpenYurt。 自 OpenYurt 开源以来受到了开发者的关注,今天这篇文章将带大家快速上手 OpenYurt ,介绍如何使用 OpenYurt 提供的命令行管理工具 Yurtctl, 高效快速地部署 OpenYurt 集群。 OpenYurt 介绍OpenYurt 主打“云边一体化”概念,依托 Kubernetes 强大的容器应用编排能力,满足了云-边一体化的应用分发、交付、和管控的诉求。相较于其他基于 Kubernetes 的边缘计算框架,OpenYurt 秉持着“最小修改”原则,通过在边缘节点安装 Yurthub 组件,和在云端部署 Yurt-controller-manager,保证了在对 Kubernetes 零侵入的情况下,提供管理边缘计算应用所需的相关能力。OpenYurt 能帮用户解决在海量边、端资源上完成大规模应用交付、运维、管控的问题,并提供中心服务下沉通道,实现和边缘计算应用的无缝对接。在设计 OpenYurt 之初,我们就非常强调保持用户体验的一致性,不增加用户运维负担,让用户真正方便地 “Extending your native kubernetes to edge”。 Yurtctl:一键让原生 K8s 集群具备边缘计算能力为了让原生 K8s 集群具备边缘计算能力,OpenYurt 以 addon 为载体,非侵入式给原生 K8s 增强了如下能力: 边缘自治能力(YurtHub: 已开源),保证在弱网或者重启节点的情况下,部署在边缘节点上的应用也能正常运行;云边协同能力(待开源),通过云边运维通道解决边缘的运维需求,同时提供云边协同能力;单元化管理能力(待开源),为分散的边缘节点,边缘应用,应用间流量提供单元化闭环管理能力;其他一些能力。对于大家比较关心的问题:如何将增强的边缘计算能力和原生 K8s 无缝融合。基于过往 ACK@Edge 的线上运维经验,我们开源了 Yurtctl 命令行工具,帮助实现了原生 Kubernetes 和 OpenYurt 之间的无缝转换以及对 OpenYurt 相关组件的高效运维。 ...

June 9, 2020 · 3 min · jiezi

容器与虚拟化的结合浅谈安全容器技术发展趋势

【摘要】无论公有云还是私有云厂商,都认识到了将虚拟化的隔离性和容器的高效运维特性相结合,是云原生平台发展的必然趋势。容器是如何解决隔离问题的众所周知,容器技术的出现有两个关键原因: 1. 软件运行过程中的资源和环境的隔离。 2. 软件因为运行环境多样带来的打包和配置的复杂性。 而对于软件运行环境的隔离需求,从计算机出现之初就已经开始了,多任务分时操作系统和虚拟地址的引入,都是为了解决多个任务在同一主机上运行,并且让任务本身认为自己独占机器。当然这样的隔离是远远不够的,当今软件,根据不同的层级,可以将隔离技术分为以下三类: 1. 进程级别的隔离 2. 操作系统级别的隔离 3. 虚拟化级别的隔离 操作系统以进程作为程序运行过程的抽象,进程拥有独立的地址空间,进程的执行依靠操作系统的调度。但是进程共享了文件系统,函数库等资源,程序之间出现互相干扰的可能性很大。这个层级的隔离适合在相同主机上运行单个用户的不同程序,由用户自己保证程序之间的资源分配。 上世纪70年代出现了chroot,进行文件系统的隔离,21世纪初开始,随着计算硬件的性能提升,软件隔离的需求更加强烈,这时候开始出现如jail,cgroup,namespace等各种不同资源的隔离技术。我们将这些技术统一划分到操作系统的隔离技术,这类隔离技术可以实现软件在诸如硬件资源、文件系统、网络、进程号等方面的隔离,但是不同的应用依然是运行在相同的操作系统内核上,对于恶意的利用漏洞攻击的场景,这种隔离技术依然会捉襟见肘。但是这种级别的隔离带来的额外资源消耗较小,适合相同的组织内不同用户的应用在相同主机上运行。 虚拟化技术的出现,让相同的物理机上也能运行多个不同的操作系统。操作系统对硬件的接口,由虚拟机管理程序(VMM)负责模拟。运行在不同系统中的程序,内核也是隔离的。硬件资源则通过各种硬件辅助手段进行划分,虚拟机上的程序很难突破虚拟化层加上的资源限制。并且因为内核的隔离,资源的可见性也做到了很强的隔离性。即使是恶意的用户,也很难突破这层虚拟化的限制,已达到攻击物理机,或者相同主机上其他虚拟机的目的。 以上三种隔离是按照层级一步一步加强的,同时带来的理论损耗也是逐步递进的。虚拟化由于需要模拟各种设备,带来的资源损耗比其他两种隔离方式要大很多。 什么是“安全容器”容器概念出来的时候,最初大家做隔离的思路,几乎都是操作系统级的隔离,也就是基于内核提供的namespace、cgroup、seccomp等机制,实现容器内的资源、文件、系统调用等限制和隔离。这种隔离方式更加高效,损耗更小。但是随着容器的大规模使用,尤其是各种容器编排系统,如k8s的深入使用,人们逐渐发现这样的隔离级别往往不能满足要求。在公有云场景下,相同主机如果需要运行不同租户的应用,因为这种隔离级别依然采用了共内核的机制,存在这广泛的攻击面,容器的隔离级别完全不能满足要求。所以最初的公有云上的容器服务,都是配合虚拟机的使用来完成的,首先是用户需要创建一批虚拟机作为运行容器的节点,形成一个私有的集群,然后才能在其上创建容器应用。虚拟化级别的隔离已经被各种公有云的实践证明,是一种安全的隔离技术。 自从云计算的概念提出开始,虚拟机一直是云平台的基础,无论是平台本身服务还是用户的使用,都是从IaaS平台创建通用虚拟机开始的。一般都是创建相应的规格的虚拟机,使用一个完成操作系统镜像启动一个完整的操作系统,随后在其安装,配置,运行软件和服务。包括我们上节提到的公有云容器服务的提供形式也是如此。 虚拟化本身带来的隔离能力是受到普遍认可的,不过IaaS层希望提供的是一个和应用完全无关的基础设施层,它几乎完全不感知应用的任何信息。于是从基础设施到应用运维,中间巨大的鸿沟则是由PaaS和用户自己来填平,这中间依然需要耗费无数的人力和成本。通用的虚拟机服务诚然有它的好处,比如完整的操作系统很适合程序调试,或者作为工作办公环境等等。但是对于多数运行于云平台的软件,它需要的是它独有的运行环境,它的运行环境由它的镜像已经完全定义好了。如果在此之外,又启动一个完整的操作系统,既浪费资源,也增加了运维的成本。为什么不能直接将虚拟化级别的隔离引入到容器技术中呢?结合虚拟化的安全性和容器在软件生命周期管理方面的优势,是不是可以给软件开发运维带来巨大的便利呢? 也就是在这个时间,docker和coreos等一起成立了OCI组织,其目的是将容器的运行时和镜像管理等流程标准化。OCI标准定义了一套容器运行时的命令行接口和文件规范,docker将其RunC捐给OCI作为运行时标准的一个参考实现。2015年Hyper.sh开源了RunV,则是一种基于虚拟化的容器运行时接口的实现,它很好地结合了虚拟化的安全性和容器的便利性。后来RunV和ClearContainer合并成立了kata项目,kata提供了更加完整的基于虚拟化的容器实现。我们把这种基于虚拟化的容器实现称作安全容器。 除kata之外,还相继出现了多个安全容器的实现方式,比如google的gVisor、AWS的firecracker-containerd、IBM的Nabla、VMware的CRX等等,其原理不尽相同,但共同反应了一个趋势,就是将容器的便利和虚拟化的安全隔离结合起来,让虚拟化直接和应用运维结合,成为云原生技术的大势所趋。下面对这些“安全容器”的实现技术进行简要的介绍和对比。 Google gVisor相比于其他几种实现,gVisor的显著不同之处在于,它通过拦截容器中应用的系统调用,模拟了一个操作系统内核,因此gVisor实际上没有虚拟化,而是在用户态实现了一个操作系统。这种方式可以降低因为虚拟化带来的模拟设备内存损耗。gVisor提供的runsc符合OCI标准,可以直接对接docker、containerd等容器平台,同时它也完全兼容docker的镜像格式。但是由于不是一个标准linux内核,因为应用的兼容性有较大问题。另外拦截系统调用带来的巨大的性能损耗也是阻止其广泛使用的一个阻碍。 图片来自https://gvisor.dev/docs/ IBM nablanabla是继承于unikernel的隔离方式,应用采用rumprun打包成一个unikernel镜像,直接运行在一个专为运行unikernel定制虚拟机(ukvm)中。应用直接打包首先可以降低很多内核态和用户态转换的开销,另外通过ukvm暴露非常有限的主机上的syscall(只剩7个),可以大大缩小主机的攻击面。它是这些安全容器实现中,最安全的。不过由于它要求应用打包成unikernel镜像,因此和当前docker的镜像标准是不兼容的。另外,unikernel应用在诸如支持创建子进程等一些常规操作上都有很难解决的问题。 图片来自https://unit42.paloaltonetworks.com/making-containers-more-isolated-an-overview-of-sandboxed-container-technologies/ AWS Firecracker最初firecracker是为AWS的Lambda打造的高密度轻量级虚拟化组件。由于它是从头开始构建虚拟化,带着轻量化的目的,因此他抛掉了qemu这种通用虚拟化组件的大部分功能,只留下运行容器和Function必要的一些模拟设备。因此它的内存开销非常小(小于5M),启动速度非常快(小于125ms),一秒钟可以在一个节点上运行150个轻量级虚拟机。 为了让firecracker-microvm更好的运行容器,AWS启动了firecracker-containerd项目,firecracker-containerd是containerd-shim-v2的一个实现,不符合OCI标准,但是可以直接对接containerd启动容器,也就很容易通过containerd对接k8s的CRI接口。containerd-shim-v2是containerd定义的新的runtime接口,它是对最初shim-v1的一个简化,可以大大精简runtime的组件和内存使用。containerd是一个全插件化的代码框架,扩展性非常好。firecracker-containerd在该框架下,实现了一个snapshotter作为镜像插件,负责块设备镜像的生成;实现了一个shim-v2的runtime,负责容器的生命周期管理。另外还有个fc-control-plugin作为虚拟机的管理插件,提供grpc接口供runtime调用。在轻量级虚拟机内部,有一个agent负责监听runtime传进来的vsock,接收runtime的指令进行虚机内部真正的容器生命周期管理操作,它是直接调用runc来管理容器的。 图片来自https://github.com/firecracker-microvm/firecracker-containerd/blob/master/docs/architecture.md VMware CRXVMware发布的vSphere 7与kubernetes进行了融合,它利用k8s的CRD将其集群的虚拟机、容器、函数等运行实体管理的所有功能都集成到了k8s中。VMware是一个做虚拟化起家的公司,因此虚拟化作为它的老本行,这块的积累是很深厚的。它将虚拟化融合到它的容器runtime CRX中,因此和firecracker-containerd和kata类似,也是一个基于轻量级虚拟化的容器runtime的实现。通过对其虚拟化组件和guest内核的精简,CRX 容器同样做到了很低的内存损耗(20MB)、快速(100ms)的启动以及高密度部署(单个节点大于1000个pod)。 图片来自https://cormachogan.com/2019/11/22/project-pacific-vmworld-2019-deep-dive-updates/ vSphere对node上的kubelet组件改造比较大,节点上的Spherelet部分功能和kubelet重合,负责pod的生命周期管理(他们称之为Native Pod),运行在虚拟机中的SphereletAgent则集成了符合OCI接口规范的libcontainer,实现容器的生命周期管理,以及容器的监控日志采集、容器的shell登录(kubectl exec)。Spherelet和虚机中的SphereletAgent交互实现类似于kubelet使用CRI接口管理pod的效果。 kata containers相比于以上几种,kata containers 最大的特点是它专注于实现一个开放的符合OCI标准的安全容器runtime实现,对于对接什么样的虚拟化方案,它抽象了一套hypervisor接口,如今已经对接了多种虚拟化实现,比如qemu、nemu、firecracker、cloud-hypervisor等等。 图片来自https://katacontainers.io/ 通过containerd-shim-v2和vsock技术,kata精简了大量的组件,配合轻量级hypervisor和精简内核,kata可以做到将额外内存消耗降低到10MB以下。容器启动时间降低到100ms以下。后续还会通过rust语言重写等方式,提供更低内存额外消耗。 图片来自https://github.com/kata-containers/documentation/blob/master/design/architecture.md 现有安全容器技术对比 安全容器技术发展趋势随着Serverless等技术的兴起,应用部署和运维工作已经下沉到云平台上,人们需要一个更加高效的云原生技术平台。从这几年涌现的安全容器实现技术可以观察到,无论公有云还是私有云厂商,都认识到了将虚拟化的隔离性和容器的高效运维特性相结合,是云原生平台发展的必然趋势。结合当前安全容器实现中遇到的一些问题,我们可以预见到,未来这项技术发展的几个走向: 需要一个为安全容器而生的轻量级hypervisor,当前qemu+kvm是主流的虚拟化技术,但因为qemu是为通用的虚拟机而设计的,其体量过于庞大,而对于安全容器而言,一个模块化可定制的虚拟化实现尤为重要。如果结合gVisor和nabla的实现来看,内核的可定制性也是安全容器场景的必然要求。rust-vmm即是这样一种模块化的虚拟化组件库。linux内核本身的模块化特性可以部分满足容器场景下的内核定制需求,不过也许像gVisor那样实现一个专为容器而生的内核也许是未来的趋势。容器的启动时间是衡量一个云原生平台效率的重要指标,尤其是在Serverless场景下,程序运行时间本身可能很短,这时候启动时间可能占用了其绝大部分,那么这种低效就显得尤为明显。安全容器通过极致的轻量化,可以将容器启动时间降低到100ms以下,但是容器镜像拉取时间过长仍是当前容器部署过程中的一个短板。由于当前容器镜像格式和镜像挂载方式等方面的限制,需要在启动容器之前将容器镜像拉取到本地以后,才能启动容器。而容器启动本身需要的数据只占镜像的6%左右。因此我们亟需一个高效的镜像挂载方式,当前已经有一些免下载和懒加载(Lazy-Loading)的技术原型,后续需要尽快推出一个可商用的镜像下载加速方案。3. 当前公有云的网络普遍采用原IaaS的网络管理模式,在地址分配,网络配置效率等方面完全赶不上容器快速启停的需求,docker容器采用的veth方式在性能等方面也很难满足高效转发的要求。因此需要一个专为云原生设计的网络管理方案。 4. 我们看到云平台对应用的管理逐步深入,从只管理基础设施的IaaS层,发展到管理应用整体部署和运维的PaaS,再到如今服务网格(Service Mesh)技术将平台管理能力深入到应用内部的微服务级别。同时我们也看到,以K8s容器、Istio服务网格为代表的云原生技术已经和下层的计算/网络虚拟化等技术逐步整合到了一起,比如安全容器即是容器与计算虚拟化的结合,而Istio服务网格也会与虚拟化网络进行深度整合以提供更高的性能与更精细的QoS控制。 5. 当前硬件加速技术在AI和大数据等领域大行其道,安全容器需要与各种计算加速硬件技术进行结合,使得AI、大数据、科学计算等批量计算领域的用户可以利用云平台直接投递其海量的计算任务,可大大降低他们在底层技术上的心智负担。通过硬件加速也是提升云平台本身效率、降低云平台运行成本的有效手段。比如华为云擎天架构在硬件加速方面拥有的技术优势在“安全容器”领域已得到充分的证明,CCE Turbo裸金属容器已经实现了安全容器的部分硬件卸载能力。 总结未来必然是云原生技术大行其道的时代,我们已经看到很多传统行业也逐渐认识到云原生技术可以给传统企业的IT软件,工业自动化,线上运维和数据管理等带来明显的效率提升。我们将看到通过对底层硬件和上层服务的全栈整合,打造出一个高效智能的云计算技术平台,而这中间,容器将是串联整个技术栈的关键所在。 ...

June 8, 2020 · 1 min · jiezi