You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
--client-ca-file= (for x509 client certificates specified in a file)
--token-auth-file= (for bearer tokens specified in a file)
--basic-auth-file= (for user/password pairs specified in a file)
服务帐户使用自动加载的身份验证插件,管理员可以提供两个可选的flag:
--service-account-key-file= (PEM encoded key for signing bearer tokens. If unspecified, the API server's TLS private key will be used.)
--service-account-lookup (If enabled, tokens that are deleted from the API will be revoked.)
各种身份验证插件将检查请求,并根据提供的凭据关联以下属性:用户名(用户友好名称),UID(唯一标识符,比用户名更一致)以及组(一组用户所属的组的名称)。
--authorization-mode=AlwaysDeny blocks all requests (used in tests).
--authorization-mode=AlwaysAllow allows all requests, use if you don't
need authorization.
--authorization-mode=ABAC allows for a simple local-file-based, user-configured authorization policy. ABAC stands for Attribute-Based Access Control.
--authorization-mode=RBAC is an experimental implementation that allows for authorization to be driven by the Kubernetes API. RBAC stands for Roles-Based Access Control.
--authorization-mode=Webhook allows for authorization to be driven by a remote service using REST.
> Kubectl create -f custom-namespace.yaml
namespace "custom-namespace" created
> kubectl get namesapces
NAME STATUS AGE
custom-namespace Active 39s
default Active 32d
kube-system Active 32d
> kubectl create -f some-pod.yaml --namespace=custom-namespace
pod "some-pod" created
> kubectl get pods --namespace=custom-namespace
NAME READY STATUS RESTARTS AGE
some-pod 1/1 Running 0 6m
# Listing pods without the namespace returns the pods in the default namespace
Understanding Kubernetes security challenges
Kubernetes是一个非常灵活的系统,以通用的方式管理非常底层的资源。Kubernetes本身可以部署在本地或云中的许多操作系统或虚拟机解决方案上。Kubernetes运行的工作负载是通过一个定义良好的运行时接口与运行时进行交互而实现的。Kubernetes操纵关键资源,例如网络,DNS和应用程序服务的资源分配。这意味着Kubernetes面临着应用程序管理员可以利用的提供良好安全机制和功能的难题,同时免于常见错误。
Node challenges
节点是运行时引擎的主机。如果攻击者访问节点,这是一个严重的威胁。它至少可以控制主机本身及其上运行的所有工作负载。但情况更糟。该节点有一个运行中的kubelet与API服务器通信。攻击者可以用修改后的版本替换kubelet,并通过与Kubernetes API服务器正常通信来有效逃避检测,同时运行自己的工作负载而不是预定的工作负载。该节点将有权访问共享资源和secret,从而可以使其更加深入。节点被突破是非常严重的,这既是由于可能的损害,也是因为事后发现它们狠困难。
节点也可能在物理层面受到入侵,这主要是在裸机上分配的Kubernetes集群。
另一个攻击媒介是资源枯竭。想象一下,你的节点成为僵尸网络的一部分,只是运行与你的Kubernetes集群无关的工作负载并耗尽CPU和内存。更危险的是Kubernetes和你的基础架构可能会自动扩展并分配更多资源。
另一个问题是在自动部署之外安装调试和故障排除工具或修改配置。这些通常是未经测试的,如果遗留下来并处于活跃状态,至少会导致性能下降,但也会导致更严重的问题。
Network challenges
一般任何Kubernetes集群至少跨越一个网络, 因此有很多与网络有关的挑战。你需要了解你的系统组件在非常低的层次上如何连接。哪些组件应该相互交谈?他们使用什么网络协议?什么端口?他们交换什么数据?
这里有一个暴露端口和功能或服务的复杂链:
使用overlay networks可以帮助进行纵深防御,即使攻击者获得对Docker容器的访问权限,他们也会被沙箱化,无法逃离底层网络基础架构。
组件发现也是一个很大的挑战。这里有几种选择,例如DNS,专用发现服务和负载均衡。每种产品都有优点和缺点,需要仔细的规划和洞察才能适应你的实际情况。
确保两个容器可以互相找到并交换信息不是那么简单的。你需要决定哪些资源和端点可以被公开访问。你需要想出一个合适的方式来验证用户和服务,并授权他们对资源进行操作。敏感数据必须在集群内外进行加密,有时也需要在存储时加密。这意味着密钥管理和安全密钥交换,这是安全问题中最难解决的问题之一。如果你的集群与其他Kubernetes集群或非Kubernetes进程共享网络基础架构,那么你必须勤于隔离和拆分。
其中的成分有网络策略,防火墙规则和软件定义网络(SDN)。方案通常是定制的,这对于内部和裸机集群尤其具有挑战性。让我们回顾一下:
在使容器,用户和服务容易在网络层面相互发现和交谈而不是锁定访问并阻止通过网络的攻击或对网络本身的攻击之间存在着持续的紧张的平衡关系。这些挑战中有许多不是Kubernetes特有的。但是,Kubernetes是一个管理关键基础设施和处理底层网络的通用平台,因此有必要考虑可将特定系统要求集成到Kubernetes中的动态且灵活的解决方案。
Image challenges
Kubernetes运行兼容其支持的运行时引擎的容器。它不知道这些容器在做什么。你可以通过配额对容器设置一定的限制。你还可以通过网络策略限制他们访问网络的其他部分。但最终,容器确实需要访问主机资源,网络中的其他主机,分布式存储和外部服务。镜像确定容器的行为。镜像有两类问题:
恶意镜像是包含代码或配置的镜像,这些代码或配置是由攻击者设计的,用来造成破坏或收集信息。恶意镜像可以注入到你的镜像准备管道中,包括你使用的任何镜像存储库。易受攻击的镜像是你设计的镜像,它只是包含一些漏洞,允许攻击者控制正在运行的容器或导致其他一些破坏,包括稍后注入他们自己的代码。
很难说哪个类别更糟糕。在极端情况下,它们是相同的,因为他们允许全面控制容器。其他防御措施已到位(纵深防御),对容器施加的限制将决定它可以造成多大的破坏。最大限度地减少不良镜像的危险是非常具有挑战性的。使用微服务的快速迭代的公司可能每天都会生成许多镜像。验证镜像也不是一件容易的事。例如,考虑Docker镜像是如何由多个层构成的。包含操作系统的基础镜像可能会在发现新的漏洞时变得易受攻击。而且,如果你依赖其他人准备的基础镜像(非常常见),那么恶意代码可能会进入那些你无法控制并且你隐式信任的基础镜像。总结镜像挑战:
Configuration and deployment challenges
Kubernetes集群是远程管理的。各种manifest和policy决定了每个时间点的集群状态。如果攻击者控制了对集群有管理权限的机器,他们可能会造成严重破坏,比如收集信息,注入不好的镜像,削弱安全性以及使用日志来雪藏攻击。错误和错误可能同样有害,因为忽视了重要的安全措施并使群集面临攻击。对集群进行管理的员工在家里或咖啡店远程工作,并将他们的笔记本电脑带在一起工作,这样你可以通过kubectl命令打开防洪门,这种情况非常普遍。让我们重申挑战:
Pod and container challenges
在Kubernetes中,pod是工作单元,包含一个或多个容器。该pod只是一个分组和部署结构,但实际上,在同一个pod中一起部署的容器通常直接交互。这些容器都共享同一个本地主机网络,并经常共享从主机挂载的卷。容器在同一个pod中的这种简单集成可能导致主机的部分暴露给所有容器。这可能会允许一个坏容器(无论是恶意的还是脆弱的)为攻击pod中其他容器开路,并随后接管节点本身。master插件通常与master组件搭配在一起,也有这种危险,因为其中大多数都是实验性的。对于在每个节点上运行pod的DaemonSet也是如此。多容器pod的挑战包括以下内容:
Organisational, cultural, and process challenges
安全性通常与生产力相悖。这是一个正常的权衡,无需担心。传统地,当开发者和操作是分开的时候,这个冲突是在组织层面进行管理的。开发人员推动提高生产力并将安全要求视为开展业务的成本。运营部门控制着生产环境,负责访问和安全程序。DevOps运动降低了开发者和运营之间的隔阂。现在,开发速度经常占据首位。诸如在没有人为干预的情况下每天部署多次的连续部署概念以前在大多数组织中闻所未闻。Kubernetes专为DevOps和云这个新世界而设计。但是,它是基于Google的经验开发的。谷歌有很多时间和熟练的专家来开发适当的流程和工具来平衡快速部署和安全性。对于小型组织来说,这种平衡行为可能非常具有挑战性,安全性可能会受到影响。采用Kubernetes的组织面临的挑战如下:
Hardening Kubernetes
请记住,Kubernetes集群是包含其他软件系统,人员和流程的更大系统的一部分。Kubernetes无法解决所有问题。你应始终记住一般安全原则,例如纵深防御,基于需要了解的以及最小权限原则。另外,在发生攻击时记录你认为可能有用的所有内容,并在系统偏离其状态时提醒你及早发现。这可能只是一个错误,或者它可能是一次攻击。无论哪种方式,你想知道它并做出回应。
Understanding service accounts in Kubernetes
Kubernetes在集群外管理常规用户,用于连接集群的人员(例如,通过kubectl命令),并且它有服务帐户。常规用户是全局用户,可以访问集群中的多个名称空间。服务帐户受限于一个名称空间。这个很重要。它确保了命名空间的隔离,因为无论API服务器何时收到来自pod的请求,其证书都将仅应用于其自己的命名空间。Kubernetes代表pod管理服务帐户。每当Kubernetes实例化一个pod时,它将为该pod分配一个服务帐户。pod进程在与API服务器交互时,服务帐户能识别所有的pod进程。每个服务帐户都有一组安装在secret卷中的证书。每个名称空间都有一个名为default的默认服务帐户。创建pod时,除非指定其他服务帐户,否则会自动为其分配默认服务帐户。
你可以创建其他服务帐户。使用以下内容创建一个名为custom-service-account.yaml的文件:
API服务器有一个专用组件,称为service account admission controller。它负责在Pod创建时检查它是否具有自定义服务帐户,如果存在,则检查自定义服务帐户是否存在。如果没有指定的服务帐户,则分配默认的服务帐户。它还确保该pod具有ImagePullSecrets,当需要从远程镜像注册表中提取镜像时,ImagePullSecrets是必需的。如果pod spec没有任何secret,它将使用服务帐户的ImagePullSecrets。最后,它为API访问添加一个带有API token的卷,并在/var/run/secrets/kubernetes.io/serviceaccount上添加了一个volumeSource。
每当创建服务帐户时,API token就会被另一个称为Token Controller的组件创建并添加到secret中。Token Controller还监视secret,并在从服务帐户中添加或删除secret的位置添加或删除token。service account controller确保每个名称空间都存在默认的服务帐户。
Accessing the API server
访问API需要一系列步骤,包括认证,授权和准入控制。在每个阶段,请求可能会被拒绝。每个阶段由多个链接在一起的插件组成。
Authenticating users
首次创建群集时,会为你创建客户端证书和密钥。Kubectl使用它们向API服务器进行身份验证,通过端口443上的TLS(加密的HTTPS连接)。你可以通过检查.kube/config文件找到你的客户端密钥和证书:
这只是建立了与Kubernetes API服务器本身的基本信任。你尚未被认证。各种认证模块可以查看请求并检查各种附加的客户端证书,密码,令牌和JWT令牌(用于服务帐户)。大多数请求都需要经过身份验证的用户(普通用户或服务帐户),尽管也存在一些匿名请求。如果一个请求没有通过所有认证者的认证,它将被拒绝并返回一个401 HTTP状态码(未经授权)。
集群管理员通过向API服务器提供各种命令行参数来确定要使用的认证策略:
服务帐户使用自动加载的身份验证插件,管理员可以提供两个可选的flag:
各种身份验证插件将检查请求,并根据提供的凭据关联以下属性:用户名(用户友好名称),UID(唯一标识符,比用户名更一致)以及组(一组用户所属的组的名称)。
Authorizing requests
一旦用户通过认证,授权开始。Kubernetes具有通用授权语义。一组授权插件接收请求,其中包括认证用户名和请求动词(列表,获取,观看,创建等)等信息。如果任何授权插件授权请求,它可能会继续。如果所有授权插件都拒绝了该请求,它将被403 HTTP状态码(禁止)拒绝。
集群管理员通过指定--authorization-mode命令行flag来确定要使用的授权插件,它是一个逗号分隔的插件名称列表。支持以下模式:
need authorization.
你可以通过实现以下Go interface添加自己的定制授权插件:
Using admission control plugins
这个请求必须经过一系列的admission control插件。与认证和授权不同,如果单个admission control拒绝请求,则拒绝该请求。admission control是一个优雅的概念。它的想法是,可以用全局的集群考虑组合来拒绝请求。没有admission control,所有授权都必须意识到这些问题并拒绝该请求。但对于admission control,这个逻辑可以只执行一次。另外,admission control可以修改请求。像往常一样,集群管理员通过提供名为admission-control的命令行参数来决定运行哪些插件。该值是一个逗号分隔且有序的插件列表:
如你所见,admission control插件具有非常多样的功能。它们支持命名空间范围的策略并主要从资源管理的角度强制验证请求的有效性。这可以让授权插件专注于有效的操作。ImagePolicyWebHook是验证镜像的门户,这是一个很大的挑战。
Securing pods
Using a private image repository
这种方法使你更有信心,你的集群只会提取你之前审核过的镜像,并且你可以更好地管理升级。你可以在每个节点上配置$HOME/.dockercfg或$HOME/.docker/config.json。但是,在许多云提供商环境中,你无法执行该操作,因为节点是自动配置的。
ImagePullSecrets
建议将此方法用于云提供商环境的群集。这个想法是,镜像注册表的证书将由pod提供,因此它将在哪个节点上运行并不重要。这规避了在节点级别的.dockercfg的问题。
首先,你需要为证书创建一个secret对象:
如果需要,你可以为多个注册表(或同一个注册表的多个用户)创建secret。kubelet将结合所有ImagePullSecrets。但是,由于pod只能在其自己的名称空间中访问secret,因此必须在该pod运行的每个命名空间上创建一个secret。一旦定义了secret,就可以将其添加到pod spec中并在集群上运行一些pod。该pod将使用来自secret的证书从目标镜像注册表中提取镜像:
Specifying a security context
安全上下文是一组操作系统级别的安全设置,如UID,gid,功能和SELinux角色。这些设置作为容器安全内容在容器级应用。你可以指定应用于pod中所有容器的pod安全上下文。pod安全上下文还可以将其安全设置(特别是fsGroup和seLinuxOptions)应用于卷。以下是一个示例pod安全上下文:
容器安全上下文应用于每个容器,并覆盖该容器的pod安全上下文。它嵌入在pod manifest的容器部分。容器上下文设置不能应用于在pod级别的卷。以下是容器安全内容示例:
Protecting your cluster with AppArmor
AppArmor是一个Linux内核安全模块。使用AppArmor,你可以将运行在容器中的进程限制为一组有限的资源,如网络访问,Linux功能和文件权限。你可以通过配置文件来配置AppArmor。
Pod security policies
Pod安全策略(PSP)必须启用,并且你还必须启用PSP admission control才能使用它们。PSP定义在集群级别并且定义了pod的安全上下文。使用PSP和直接在pod manifest中指定安全内容有一些区别:
PSP真正扩展了安全环境的概念。通常情况下,与pod数量相比,你的安全策略数量相对较少(或者更确切地说,pod模板)。这意味着许多pod模板和容器将具有相同的安全策略。没有PSP,你必须为每个pod manifest单独进行管理。这是一个示例PSP,它允许一切:
Managing network policies
节点,pod和容器安全性势在必行,但这还不够。网络分段对于设计允许多租户的安全Kubernetes集群来说至关重要,并且可以将安全漏洞的影响降至最低。纵深防御要求你划分不需要彼此交谈的系统部分,并仔细管理流量的方向,协议和端口。网络策略允许你对群集进行细粒度的控制和适当的网络分段。网络策略是一组防火墙规则,应用于由标签选择的一组命名空间和pod。这非常灵活,因为标签可以定义虚拟网段,并可以作为Kubernetes资源进行管理。
Defining a network policy
spec部分有两个重要部分,podSelector和ingress。podSelector管理此网络策略应用于哪个pod。ingress支配哪些命名空间和pod可以访问这些pod,以及可以使用哪些协议和端口。在示例网络策略中,pod选择器指定网络策略的目标为所有标记为role:db的pod。ingress部分有一个带有命名空间选择器和pod选择器的from子部分。集群中标记为project:cool-project的所有命名空间,以及这些命名空间中,所有标记为role:frontend的pod,都可以访问标记为role:db的目标pod。端口部分定义了一对(协议和端口)列表,它们进一步限制了允许的协议和端口。在这种情况下,协议是tcp,端口是6379(Redis标准端口)。
注意,网络策略以白名单方式运行。默认情况下,所有访问都被禁止,并且网络策略可以打开某些协议和端口到某些与标签匹配的Pod。这意味着,如果你的网络解决方案不支持网络策略,则所有访问都将被拒绝。白名单性质的另一个含义是,如果存在多个网络策略,则采用所有规则的联合。如果一个策略允许访问端口1234,另一个策略允许访问同一组Pod的端口5678,则一个Pod可以通过1234或5678访问。
Using secrets
安全系统中的secret是至关重要的。它们可以是证书,如用户名和密码,访问令牌,API密钥或加密密钥。secret通常很小。如果你想保护大量数据,则应对其进行加密并将加密/解密密钥保存为secret。
Storing secrets in Kubernetes
Kubernetes将secret作为明文存储在etcd中。 这意味着直接访问etcd应该受到限制。secret在命名空间级别进行管理。pod可以将secret通过secret volume挂载为文件或作为环境变量。 从安全的角度来看,这意味着当用户或服务可以在命名空间中创建一个pod,就可以访问该命名空间管理的任何secret。如果你想限制对secret的访问,请将其放入可供有限的一组用户或服务访问的命名空间中。
secret挂载到一个容器时,它永远不会写入磁盘。它存储在tmpfs中。当kubelet与API服务器通信时,它通常使用TLS,因此secret在传输过程中得到保护。
Creating secrets
在你尝试创建需要secrets的pod之前,必须先创建secrets。secrets必须存在,否则pod创建将失败。在这里我创建了一个名为hush-hash的generic密钥,其中包含两个密钥,即用户名和密码:
你可以使用--from-file而不是--from-literal来创建secret,如果你将secret值编码为base64,也可以手动创建secret。密钥内部的密钥名称必须遵循DNS sub-domains的规则(没有leading dot)。
Decoding secrets
Using secrets in a container
容器可以通过从pod中挂载volume来访问secrets。另一种方法是将secrets作为环境变量来访问。最后,容器可以直接访问Kubernetes API或使用kubectl获得secrets。要使用挂载volume的secrets,pod manifest应声明volume,并将其挂载到容器的spec中:
Running a multi-user cluster
The case for a multi-user cluster
为什么要为多个独立用户或部署运行单个集群?为每个用户设置一个专用集群并不简单吗?主要有两个原因:成本和操作复杂性。如果你有很多相对较小的部署并且想为每个集群创建一个专用集群,那么每一个专用集群将拥有一个单独的主节点,并可能分配一个三节点的etcd集群。这可以增加操作复杂性。管理数十或数百或数千个独立的集群不是野餐。每个升级和每个补丁都需要应用到每个集群。操作可能会失败,你将不得不管理一些集群,其中一些集群的状态与其他集群略有不同。所有集群的元操作可能会更加困难。你必须汇总并编写工具来执行操作并从所有集群收集数据。
Using namespaces for safe multi-tenancy
除了内置的kube-system和default之外,你还可以轻松创建命名空间。这是一个YAML文件,它将创建一个名为custom-namespace的新命名空间。它所拥有的只是一个名为name的元数据项。
Avoiding namespace pitfalls
命名空间非常好,但它们可能会增加一些冲突。当你使用默认命名空间的时候,你可以简单地省略命名空间。使用多个名称空间时,你必须使用命名空间限定所有内容。 这会增加一些负担,但会减少危险。但是,如果某些用户(例如集群管理员)可以访问多个命名空间,则可能会意外修改或查询错误的命名空间。避免这种情况的最好方法是为了密封命名空间并为每个命名空间要求不同用户和凭证。
此外,还有一些工具可以帮助你明确你正在操作的命名空间(例如,如果使用命令行进行shell提示或在Web界面中显着列出名称空间)。确保可以在专用命名空间上操作的用户无权访问默认命名空间,否则每次他们忘记指定一个命名空间时,他们将默认在默认命名空间上运行。
The text was updated successfully, but these errors were encountered: