OpenShift+VMware:新的容器架构

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenShift+VMware:新的容器架构相关的知识,希望对你有一定的参考价值。

参考技术A

这是一个由VMware的Robbie Jerrom撰写的访客帖子。Robbie与VMware在欧洲的一些最大客户一起工作,因为他们专注于将现代和云本机应用程序和平台带到他们的VMware软件定义的数据中心。在加入VMware之前,Robbie花了十年时间作为软件工程师构建企业软件,如Java虚拟机、CICS和WebSphere。Robbie也是VMware首席技术官大使社区的成员,确保了VMware的工程组织和现实世界客户之间的紧密协作。

在这篇博客中,我们更深入地探讨了根据最近的发布,VMware和Red Hat是如何协作以更好地集成OpenShift容器平台和VMware的软件定义数据中心(SDDC)基础架构堆栈的。我们有许多共同客户希望充分利用他们的技术投资组合。而且,由于VMware和Red Hat都将Kubernetes作为支持其现代应用程序的核心平台,因此,我们共同致力于为在VMware SDDC上部署OpenShift的客户实现成功,这是合乎逻辑的。

下面,第一步是沟通和分享我们已经拥有的共同点。

VMware vSphere和Red HatEnterprise Linux已经可以很好地协同工作;但是IT团队和OpenShift管理员往往忽略了为交付更好的存储和SDN而进行的体系结构调整。为了解决这一问题,本文概述了Red Hat OpenShift Container Platform 3.11核心文档的最新更新,其中包括了SDN和存储集成的最新指导文档以及支持SDN(NSX-T/NCP)和Kubernetes存储的专用VMware文档。

让我们一起深入研究这两个领域。

一、存储

为了支持容器的持久存储需求,VMware开发了vSphere云服务程序及其相应的卷管理插件。这些可以提供给Red Hat OpenShift,用以支撑VMWare的vSAN或者支持vSphere的任意数据库。虽然每个存储后端的各不相同,但这种集成方案依旧可以满足。

这些公布的存储产品为VMFS、NFS或vSAN数据存储。企业级功能(如基于存储策略的管理(SPBM))提供了自动化的资源调配和管理,使客户能够确保其业务关键应用程序请求的QoS,并在SDDC平台上确保SLA达成。

SPBM在广泛的数据服务和存储解决方案中提供单一的统一控制平面。SPBM还使vSphere管理员能够克服预先的存储资源调配挑战,例如:容量规划、差异化的服务级别和管理容量净空。

Kubernets StorageClass允许按需创建持久卷,而不需要创建存储并将其挂载在OpenShift的节点之上。StorageClass指定一个提供者和相关参数,用于定义持久卷预期策略,该策略将动态地提供。

组合使用SPBM和vSphere数据存储的组合作为抽象,我们隐藏了复杂的存储细节,并为从OpenShift存储持久数据(PV)环境提供了统一的接口。

根据使用的后端存储,数据存储可以是vSAN、VMFS或NFS:

●VSAN支持可提供强大性能和可靠性的超聚合基础架构解决方案。VSAN的优点是简化了存储管理功能特性,具有诸如在vSphere IaaS层上驱动的存储策略等功能。

●VMFS(虚拟机文件系统)是一个群集文件系统,允许虚拟化扩展到多个VMware vSphere服务器的单个节点之外。VMFS通过提供对存储池的共享访问来提高资源利用率。

●NFS(网络文件系统)是一种分布式文件协议,可以像本地存储一样通过网络访问存储。

1)静态和动态资源调拨

vSphere Cloud Provider提供两种向Red Hat OpenShift容器平台提供存储的方法:静态资源调配和动态资源调配。首选的方法是使用动态资源调配——让IaaS平台处理复杂性。与静态资源调配不同,动态资源调配会自动触发创建PV及其后端VMDK文件。这是一种更安全的方式,对于在vSphere上提供可靠的Red Hat OpenShift容器平台至关重要。

2)动态调拨

●为OpenShift集群定义默认的StorageClass

●在Kubernetes中创建Persistent Volume Claim

3)静态调拨

●在vSphere存储上创建虚拟磁盘并挂载到Red Hat OpenShift容器平台节点

●在OpenShift中为该磁盘创建持久卷(PV)

●创建一个持久卷,申请一个PVC

●允许POD认领PVC

与SPBM一起使用vSphere Cloud Provider,可以让vSphere和OpenShift管理员了解存储,并让他们能够在不增加OpenShift层复杂性的情况下利用后端存储功能。

二、网络(SDN)

NSX-T数据中心通过NSX容器插件(NCP)帮助OpenShift客户简化了网络和基于网络的安全性。NCP在IaaS级别提供OpenShift和VMware NSX Manager之间的接口。

NCP在每个OpenShift节点上运行,并将容器的网络接口连接到NSX覆盖网络。它监视容器生命周期事件,并通过调用NSX API管理容器的网络资源,如负载平衡器、逻辑端口、交换机、路由器和安全组。这包括客户vSwitch的编程,以便在容器接口和虚拟网络接口卡(VNIC)之间标记和转发容器流量。

NCP提供如下功能:

●自动为OpenShift集群创建NSX-T逻辑拓扑,并为每个OpenShift命名空间创建单独的逻辑网络

●将OpenShift pods连接到逻辑网络,并分配IP和MAC地址

●支持网络地址转换(NAT),并为每个OpenShift命名空间分配一个单独的SNAT IP

●使用NSX-T分布式防火墙实施OpenShift网络策略

●支持进出网络策略

●在网络策略中支持IPBlock选择器

●当为网络策略指定标签选择器时,支持matchLabels和MatchExpression

●使用NSX-T的7层负载均衡器实现OpenShift路由器

●通过TLS edge termination支持HTTP路由和HTTPS路由

●支持具有备用后端和通配符子域的路由

●为NSX-T逻辑交换机端口命名空间、pod名称创建标签,标记pod,并允许管理员基于标记定义NSX-T安全组和策略。

1)微分段

NSX-T(通过NCP)可以使用预定义的基于标签的规则和每个命名空间的Kubernetes网络策略,将微分段应用到OpenShift pod。预定义的标记规则使您能够在部署之前根据业务逻辑定义防火墙策略,而不是使用诸如静态IP地址等效率较低的方法来制定安全策略。使用此方法,NSX-T中定义的安全组具有入口和出口策略,并进行了微分段,以保护敏感应用程序和数据,可以达到POD和容器底层级别。

最后,NSX-T为OpenShift集群提供了完整的网络可跟踪性和可视性。NSX-T为Kubernetes提供了内置的操作工具,包括:

●端口连接

●流量追踪

●端口镜像

●IpFIX

以上方法为DevOps和专用网络团队提供对OpenShift容器网络的更好可见性,使网络管理员和OpenShift管理员在诊断和排除问题时能够有共同语言。

三、总结

VMware SDDC提供了弹性、可扩展的基础架构,与VMware的Kubernetes解决方案以及Red Hat等关键合作伙伴的解决方案紧密集成。

展望未来,VMware和Red Hat都致力于支持我们的共同客户和Kubernetes社区,共同目标是通过可参考体系结构提供更好的产品集成,该体系结构使改进的工具能够在VMware的SDDC和Red Hat OpenShift容器平台上交付和管理云本机应用程序。

原文链接:

ArthurGuo 职场老司机。21世纪初开始拥抱开源,后转型项目管理。现在某云计算公司担任技术总监。掌握多门计算机语言,但更擅长人类语言。爱玩文字,不喜毒舌。

RedHat OpenShift QuickStart 2.4 容器主机

原文:https://learn.openshift.com/subsystems/container-internals-lab-2-0-part-4

 

一、容器引擎&Linux内核

如果在搜索引擎上搜索docker架构,会出现大量描述错误的架构设计或者只讲对了一部分。

为什么人们总是理解错误,有两个主要原因:

首先,大多数架构图都将docker守护进程画为容器主机上的蓝色框,显示容器运行在docker守护进程之上,那是错误的,容器不在docker上运行,docker引擎只是通用容器引擎的一个例子,人们将命令传达给docker引擎,docker引擎在将其传给Linux内核-事实上容器是由Linux内核创建、运行的。即使画对了容器引擎和内核的架构关系,他们也从未显示和容器引擎并排运行的容器。

技术图片

其次,当设计图显示容器是Linux进程时,它们从不并排显示容器引擎。这导致人们从不把这两件事放在一起考虑,因此用户会对一部分内容感到困惑:

技术图片

做一个简单的实验,使用top命令运行三个容器

docker run -td registry.access.redhat.com/ubi7/ubi top
docker run -td registry.access.redhat.com/ubi7/ubi top
podman run -td registry.access.redhat.com/ubi7/ubi top

现在来检查容器主机的进程表:

ps -efZ | grep -v grep | grep " top"

ps -efZ # 查看主体(进程)的安全上下文

grep -v grep # 排除掉带grep命令的进程

grep " top " # 查看带有top的进程

 

现在在每个容器中都使用了 top 命令,两个使用docker启动的,一个使用podman启动的。通过ps 命令我们发现他们就是常规的进程,因为容器化进程只是花哨的Linux进程,和普通进程之间存在额外的隔离。docker 守护进程和容器化进程是并排运行的,就像下图这样:

技术图片

在内核中,没有单一的数据结构表示容器是什么。目前Linux社区的思想是提供许多从试验性的到非常成熟的技术,使用户能够以创造性的方式来将其混合在一起。这正是容器引擎所做的(docker,podman,CRI-O等),它利用内核去创建我们称之为容器等东西。容器的概念是人们创造出来的,而不是内核。这是Linux常见的模式:区分底层(kernel)技术和上层(userspace)技术,这允许内核开发者专注于新增技术,而用户可以尝试使用这些技术去更好的工作。

技术图片 

Linux内核只有一个主要的数据结构来追踪进程--进程id表。ps命令转储此数据结构的内容。但是这不是容器的全部定义:容器引擎追踪使用了哪些内核隔离技术,甚至是挂载了哪些数据卷,这些可以看作是容器的元数据。目前为止,我们应该明白容器化进程就是常规的Linux进程,使用namespace、selinux和cgroups内核技术将其隔离。有时将其描述为虚拟化的沙盒、隔离或者幻觉。

最后,容器化进程只是常规的Linux进程。所有的进程并排运行,无论是常规的Linux进程、长期运行的守护进程、批处理进程、你手动运行的交互式命令或者是虚拟化进程。所有这些进程都会向Linux内核请求受保护的资源像存储,RAM,TCP套接字等。

 

二、一步一步来创建一个容器

这一节看一下容器等基本构造,几乎所有符合OCI的容器引擎的容器基本构造都相同。

  1. 拉取/扩展/挂载镜像
  2. 创建符合OCI规范的文件
  3. 使用spec文件调用runc

1. 拉取/扩展/挂载镜像

Podman可让您轻松分解容器构造的每个步骤以进行学习。首先拉取镜像,拓展它,给容器创建一个新的覆盖文件系统作为容器的读/写根文件系统。为了做到这一点,使用一个特殊构造的容器镜像,来分解步骤,而不是一次全都开始。

podman create -dt --name on-off-container -v /mnt:/mnt:Z quay.io/fatherlinux/on-off-container

使用上面命令使用本地镜像创建一个容器,使用 podman ps -a 命令来查看状态,容器是created状态,而不是running。

 使用mount命令来查看存储:mount | grep -v docker | grep merged 。发现没有任何结果,这是因为它被挂载在所谓的mount namespace中,你只能在容器内看到挂载。podman提供了叫做podman-mount的功能,你可以用这个功能在容器外查看挂载的路径:

podman mount on-off-container

返回的目录是容器使用的覆盖文件系统中的系统级挂载点。 您现在可以立即更改容器文件系统中的任何内容。 可以通过下面命令创建/test文件夹:

touch $(podman mount on-off-container)/test
ls $(podman mount on-off-container)

技术图片

 

现在可以看见test文件,下面在容器里运行shell的时候你同样可以看到这个test文件。

 

2. 创建spec文件

容器已经存在本地并挂载了数据卷,但是目前还没有runc的spec文件。手动创建spec文件非常繁琐,因为他们是由许多不同选项的复杂JSON组成的(由OCI 运行时规范控制),幸运的是,容器引擎会帮我们创建这个spec文件,任何OCI兼容的运行时都可以使用此完全相同的规范文件(runc,crun,katacontainer,gvisor等)。首先来检查一下它在哪里:

cat /var/lib/containers/storage/overlay-containers/$(podman ps -l -q --no-trunc)/userdata/config.json|jq .

#jq . 规范json文件

这命令现在会报错因为容器引擎还没有创建它,现在使用podman和一个特点的容器镜像来创建这个文件:

podman start on-off-container

现在config.json文件已经被创建,继续使用上面的cat 命令检查这个文件,其中有一些选项与podman选项十分相似,这spec文件真正突出了API。

podman此时并未启动容器,使用podman ps -a查看 发现STATUS是Exited。使用inspect命令检查细节,发现:

技术图片

 

# -f filename 如果 filename为常规文件,则为真 。shell 命令

 

即如果/mnt下面由on文件,容器才会运行top命令。

 

3. 调用运行时

现在我们有了存储和一个config.json,通过config.json创建一个虚拟化进程。我们已经构建了一个容器镜像,它只有在/mnt/on文件存在的情况下才会创建一个进程,现在来创建这个on文件:touch /mnt/on,并启动容器podman start on-off-container,继续使用podman ps -a命令查看容器状态,发现此时的状态是up。使用exec命令在容器中创建交互式终端:

podman exec -it on-off-container bash

使用ls -alh命令查看,发现结果和预期的一样,test文件就存在那。我们通过三个基本步骤才真正创建了一个容器

 

三、ELinux和sVirt:动态生成上下文来保护您的容器

运行下面命令,得到如下结果:

$ podman run -dt registry.access.redhat.com/ubi7/ubi sleep 10
244b6bda438e899db9d055335dbd015b93a50e5de7277f8ac0919c65f9b32470
$ podman run -dt registry.access.redhat.com/ubi7/ubi sleep 10
a2652ee6f9e4b4b849fedcbad4872c36e1cef398fa6b00e90988811237bfbbf8
$ sleep 3
$ ps -efZ | grep container_t | grep sleep
system_u:system_r:container_t:s0:c666,c809 root 25067 25023  7 14:03 pts/0 00:00:00 sleep 10
system_u:system_r:container_t:s0:c471,c835 root 25189 25174  7 14:03 pts/0 00:00:00 sleep 10
$

请注意,每个容器都标有动态生成的多级安全性(Multi Level Security (MLS))标签。例如上面结果第一个MLS标签是c66,c809,第二个MLS标签是c471,c835。因此每个容器启动都会生成一个不同的MLS标签,它们被阻止访问彼此的存储和文件等。

SELinux不只是标记进程,它还必须标记进程访问的文件,下面为数据创建一个目录,并检查目录上的SELinux标签。注意,类型设置为“user_tmp_t”,但没有设置MLS标签:

$ ls -alhZ /tmp/selinux-test/
drwxr-xr-x. root root unconfined_u:object_r:user_tmp_t:s0 .
drwxrwxrwt. root root system_u:object_r:tmp_t:s0       ..
$

多启动几次同一个镜像,发现每次多MLS都不一样,这是sVirt在工作:

$ podman run -t -v /tmp/selinux-test:/tmp/selinux-test:Z registry.access.redhat.com/ubi7/ubi ls -alhZ /tmp/selinux-test
drwxr-xr-x. root root system_u:object_r:container_file_t:s0:c729,c736 .
drwxrwxrwt. root root system_u:object_r:container_file_t:s0:c729,c736 ..
$ podman run -t -v /tmp/selinux-test:/tmp/selinux-test:Z registry.access.redhat.com/ubi7/ubi ls -alhZ /tmp/selinux-test
drwxr-xr-x. root root system_u:object_r:container_file_t:s0:c363,c698 .
drwxrwxrwt. root root system_u:object_r:container_file_t:s0:c363,c698 ..
$ podman run -t -v /tmp/selinux-test:/tmp/selinux-test:Z registry.access.redhat.com/ubi7/ubi ls -alhZ /tmp/selinux-test
drwxr-xr-x. root root system_u:object_r:container_file_t:s0:c479,c515 .
drwxrwxrwt. root root system_u:object_r:container_file_t:s0:c479,c515 ..
$

最终,查看/tmp/selinux-test目录多MLS,发现始终和最后一次运行的容器的MLS相同。:Z选项会自动标记和绑定挂载,以便容器可以访问和更改挂载点上的文件。 这样可以防止任何其他进程访问此数据,并且对最终用户是透明的。

 

四、Cgroups:使用容器实例动态创建

本节的目的是为了了解容器如何防止使用彼此的保留资源.Linux内核有一个称为cgroups (control groups的缩写)的特性,它限制、说明和隔离进程的资源使用(CPU、内存、磁盘I/O、网络等)。通常,这些控制组是由系统管理员(使用cgexec)设置的,或者使用systemd (system -run--slice)配置的,但是使用容器引擎时,会自动处理这种配置。

podman run -dt registry.access.redhat.com/ubi7/ubi sleep 10
podman run -dt registry.access.redhat.com/ubi7/ubi sleep 10
sleep 3
for i in $(podman ps | grep sleep | awk {print $1} | grep [0-9]); do find /sys/fs/cgroup/ | grep $i; done

容器引擎自动将容器化进程放进自己的cgroup中,这是十分方便的,类似sVirt。

 

五、SECCOMP:限制容器化进程与内核交互的方式

可以将SECCOMP看过是防火墙,它可以阻止某些系统调用。虽然这是可选的,并且默认情况下是关闭的。但它是一个可以用来阻挡不正常容器的十分强大的工具。

$ cat ~/labs/lab3-step5/chmod.json
{
  "defaultAction": "SCMP_ACT_ALLOW",
  "syscalls": [
    {
      "name": "fchmodat",
      "action": "SCMP_ACT_ERRNO"
    }
  ]
}
$ podman run -it --security-opt seccomp=./labs/lab3-step5/chmod.json registry.access.redhat.com/ubi7/ubi chmod 777 /etc/hosts
chmod: changing permissions of /etc/hosts: Operation not permitted
$

# fchmodat - change permissions of a file relative to a directory file descriptor

更改/etc/hosts权限的行为被阻止

以上是关于OpenShift+VMware:新的容器架构的主要内容,如果未能解决你的问题,请参考以下文章

RedHat OpenShift QuickStart 2.4 容器主机

两大容器管理平台,Kubernetes与OpenShift有啥区别?

OpenShift 容器平台社区版 OKD 4.10.0部署

Kubernetes社区发行版:开源容器云OpenShift Origin(OKD)认知

新书《OpenShift云原生架构:原理与实践》第一章第三节:企业级PaaS平台OpenShift

新书《OpenShift云原生架构:原理与实践》第一章第三节:企业级PaaS平台OpenShift