Deployment是kubernetes在12版本中引入的新概念,用于更好的解决Pod的编排问题,为此,Deployment在内部使用了ReplicaSet来实现目的,我们可以把Deployment理解为ReplicaSet的一次升级,两者的相似度超过90%
Deployment的使用场景有以下几个:
1)创建一个Deployment对象来生成对应的ReplicaSet并完成Pod副本的创建
2)检查Deployment的状态来看部署动作是否完成(Pod副本数量是否达到了预期的值)
3)更新Deployment以创建新的Pod(比如镜像升级)
4)如果当前Deployment不稳定,可以回滚到一个早先的Deployment版本
5)暂停Deployment以便于一次性修改多个PodTemplateSpec的配置项,之后在恢复Deployment,进行新的发布
6)扩展Deployment以应对高负载
7)查看Deployment的状态,以此作为发布是否成功的标志
8)清理不在需要的旧版本ReplicaSet
可以通过kubectl命令行方式获取更加详细信息
除了API生命与Kind类型有区别,Deployment的定义与Replica Set的定义很类似。
controller/deploymentdemoyml
微服务部署:蓝绿部署、滚动部署、灰度发布、金丝雀发布。
Deployment控制器支持自定义控制更新过程中的滚动节奏,如“暂停(pause)”或“继续(resume)”更新 *** 作。比如等待第一批新的Pod资源创建完成后立即暂停更新过程,此时,仅存在一部分新版本的应用,主体部分还是旧的版本。然后,再筛选一小部分的用户请求路由到新版本的Pod应用,继续观察能否稳定地按期望的方式运行。确定没问题之后再继续完成余下的Pod资源滚动更新,否则立即回滚更新 *** 作。这就是所谓的金丝雀发布(Canary Release)
默认情况下,kubernetes 会在系统中保存前两次的 Deployment 的 rollout 历史记录,以便可以随时回退(您可以修改 revision history limit 来更改保存的revision数)。
注意: 只要 Deployment 的 rollout 被触发就会创建一个 revision。也就是说当且仅当
Deployment 的 Pod template(如 spectemplate )被更改,例如更新template 中的 label 和容器镜像时,就会创建出一个新的 revision。
其他的更新,比如扩容 Deployment 不会创建 revision——因此我们可以很方便的手动或者自动扩容。这意味着当您回退到历史 revision 时,只有 Deployment 中的 Pod template 部分才会回退。
kubectl rollout history deployment deploymentdemo1
kubectl rollout status deployment deploymentdemo1
Deployment 可以保证在升级时只有一定数量的 Pod 是 down 的。默认的,它会确保至少有比期望的Pod数量少
一个是up状态(最多一个不可用)
Deployment 同时也可以确保只创建出超过期望数量的一定数量的 Pod。默认的,它会确保最多比期望的Pod数
量多一个的 Pod 是 up 的(最多1个 surge )
Kuberentes 版本v1175中,从1-1变成25%-25%
Deployment为Pod和Replica Set(下一代Replication Controller)提供声明式更新。
只需要在 Deployment 中描述想要的目标状态是什么,Deployment controller 就会帮您将 Pod 和ReplicaSet 的实际状态改变到您的目标状态。也可以定义一个全新的 Deployment 来创建 ReplicaSet或者删除已有的 Deployment 并创建一个新的来替换。
Replicas(副本数量):
specreplicas 是可以选字段,指定期望的pod数量,默认是1。
Selector(选择器):
specselector是可选字段,用来指定 label selector ,圈定Deployment管理的pod范围。如果被指定, specselector 必须匹配 spectemplatemetadatalabels,否则它将被API拒绝。如果specselector 没有被指定, specselectormatchLabels 默认是spectemplatemetadatalabels。
在Pod的template跟spectemplate不同或者数量超过了specreplicas规定的数量的情况下,Deployment会杀掉label跟selector不同的Pod。
Pod Template(Pod模板):
spectemplate 是 spec中唯一要求的字段。
spectemplate 是 pod template 它跟 Pod有一模一样的schema,除了它是嵌套的并且不需要apiVersion 和 kind字段。
另外为了划分Pod的范围,Deployment中的pod template必须指定适当的label(不要跟其他controller重复了,参考selector)和适当的重启策略。
spectemplatespecrestartPolicy 可以设置为 Always , 如果不指定的话这就是默认配置。
strategy(更新策略):
specstrategy 指定新的Pod替换旧的Pod的策略。 specstrategytype 可以是"Recreate"或者是"RollingUpdate"。"RollingUpdate"是默认值。
Recreate:
重建式更新,就是删一个建一个。类似于ReplicaSet的更新方式,即首先删除现有的Pod对象,然后由控制器基于新模板重新创建新版本资源对象。
rollingUpdate:
滚动更新,简单定义 更新期间pod最多有几个等。可以指定 maxUnavailable 和 maxSurge 来控制 rolling update 进程。
maxSurge:
specstrategyrollingUpdatemaxSurge 是可选配置项,用来指定可以超过期望的Pod数量的最大个数。该值可以是一个绝对值(例如5)或者是期望的Pod数量的百分比(例如10%)。当 MaxUnavailable 为0时该值不可以为0。通过百分比计算的绝对值向上取整。默认值是1。
例如,该值设置成30%,启动rolling update后新的ReplicatSet将会立即扩容,新老Pod的总数不能超过期望的Pod数量的130%。旧的Pod被杀掉后,新的ReplicaSet将继续扩容,旧的ReplicaSet会进一步缩容,确保在升级的所有时刻所有的Pod数量和不会超过期望Pod数量的130%。
maxUnavailable:
specstrategyrollingUpdatemaxUnavailable 是可选配置项,用来指定在升级过程中不可用Pod的最大数量。该值可以是一个绝对值(例如5),也可以是期望Pod数量的百分比(例如10%)。通过计算百分比的绝对值向下取整。 如 果 specstrategyrollingUpdatemaxSurge 为0时,这个值不可以为0。默认值是1。
例如,该值设置成30%,启动rolling update后旧的ReplicatSet将会立即缩容到期望的Pod数量的70%。新的Pod ready后,随着新的ReplicaSet的扩容,旧的ReplicaSet会进一步缩容确保在升级的所有时刻可以用的Pod数量至少是期望Pod数量的70%。
rollbackTo:
specrollbackTo 是一个可以选配置项,用来配置Deployment回退的配置。设置该参数将触发回退 *** 作,每次回退完成后,该值就会被清除。
revision:
specrollbackTorevision 是一个可选配置项,用来指定回退到的revision。默认是0,意味着回退到上一个revision。
progressDeadlineSeconds:
specprogressDeadlineSeconds 是可选配置项,用来指定在系统报告Deployment的failed progressing一一表现为resource的状态中 type=Progressing 、 Status=False 、 Reason=ProgressDeadlineExceeded 前可以等待的Deployment进行的秒数。Deployment controller会继续重试该Deployment。未来,在实现了自动回滚后, deployment controller在观察到这种状态时就会自动回滚。
如果设置该参数,该值必须大于 specminReadySeconds 。
paused:
specpaused 是可以可选配置项,boolean值。用来指定暂停和恢复Deployment。Paused和没有paused的Deployment之间的唯一区别就是,所有对paused deployment中的PodTemplateSpec的修改都不会触发新的rollout。Deployment被创建之后默认是非paused。
k8s是什么
Kubernetes 是一个可移植的,可扩展的开源容器编排平台,用于管理容器化的工作负载和服务,方便了声明式配置和自动化。它拥有一个庞大且快速增长的生态系统。Kubernetes 的服务,支持和工具广泛可用。
为什么现在流行使用容器
早期: 在物理服务器上面部署应用程序存在资源分配问题,因为其不能在物理服务器中的应用程序定义资源边界,导致应用程序资源利用不足而无法扩展
后来: 为了解决该问题,引入了虚拟化技术, 虚拟化技术是指允许你在单个物理服务器的 CPU 上运行多个虚拟机,可以让多个应用程序在虚拟机之间进行隔离,具有一定的安全性, 每一个虚拟机就是一台完整的计算机, 在虚拟化硬件之上运行所有组件
现在: 多数在物理服务器上面部署应用程序都是采kubectl用容器的方式,容器类似于虚拟机,它们都具有自己的文件系统、CPU、内存、进程空间等, 且由于它们与基础架构分离,因此可以跨云和 OS 发行版本进行移植。基于此特点被企业大范围使用
为什么需要使用k8s容器
若出现这样一个环境: 在生产环境中如果一个容器发生故障,则我们需要手动去启动另外一个容器,这样的 *** 作是对我们的管理员来说是不太方便的, 若一个容器出现故障,另一个容器可以自动启动容器接管故障的容器,这样是最好的
k8s就可以实现该效果,Kubernetes 提供了一个可d性运行分布式系统的框架。 Kubernetes 会满足你的扩展要求、故障转移、部署模式等。
k8s功能: 服务发现和负载均衡, 存储编排, 自动部署和回滚, 自动完成装箱计算, 自我修复, 密钥与配置管理
名词解释
secret
Secret有三种类型:
Service Account:用来访问Kubernetes API,由Kubernetes自动创建,并且会自动挂载到Pod的目录中;/run/secrets/kubernetesio/serviceaccountOpaque:base64编码格式的Secret,用来存储密码、密钥等;kubernetesio/dockerconfigjson:用来存储私有docker registry的认证信息。k8s的组成
k8s是由组件,API,对象等组成
包含所有相互关联组件的 Kubernetes 集群图如下:
组件
控制平面组件kube-apiserver: 为k8s的api服务器,公开了所有Kubernetes API, 其他所有组件都必须通过它提供的API来 *** 作资源数据保证集群状态访问的安全隔离集群状态访问的方式和后端存储实现的方式:API Server是状态访问的方式,不会因为后端存储技术etcd的改变而改变。etcd: 为k8s的键值数据库,保存了k8s所有集群数据的后台数据库。kube-scheduler: 收集和分析当前Kubernetes集群中所有Node节点的资源(内存、CPU)负载情况,然后依此分发新建的Pod到Kubernetes集群中可用的节点。 kube-controller-manager: 在主节点上运行 控制器 的组件。cloud-controller-manager: 云控制器管理器是指嵌入特定云的控制逻辑的 控制平面组件Node 组件kubelet: 一个在集群中每个节点(node)上运行的代理。 它保证容器(containers)都 运行在 Pod 中。kube-proxy: kube-proxy是集群中每个节点上运行的网络代理,维护节点上的网络规则。这些网络规则允许从集群内部或外部的网络会话与 Pod 进行网络通信。容器运行时: 负责运行容器的软件。插件(Addons)DNS: 集群 DNS 是一个 DNS 服务器,和环境中的其他 DNS 服务器一起工作,它为 Kubernetes 服务提供 DNS 记录。Web 界面(仪表盘): Dashboard 是Kubernetes 集群的通用的、基于 Web 的用户界面。容器资源监控: 容器资源监控 将关于容器的一些常见的时间序列度量值保存到一个集中的数据库中,并提供用于浏览这些数据的界面。集群层面日志: 集群层面日志 机制负责将容器的日志数据 保存到一个集中的日志存储中,该存储能够提供搜索和浏览接口。API
Kubernetes 控制面 的核心是 API 服务器。 API 服务器负责提供 >
对象
Kubernetes对象是Kubernetes系统中的持久实体。Kubernetes使用这些实体来表示集群的状态
具体来说,他们可以描述:
容器化应用正在运行(以及在哪些节点上)这些应用可用的资源关于这些应用如何运行的策略,如重新策略,升级和容错Kubernetes 架构
Kubernetes 架构由节点,控制面到节点通信, 控制器, 云控制器管理器组成
master 流程图
Kubecfg将特定的请求,比如创建Pod,发送给Kubernetes Client。Kubernetes Client将请求发送给API server。API Server根据请求的类型,比如创建Pod时storage类型是pods,然后依此选择何种REST Storage API对请求作出处理。REST Storage API对的请求作相应的处理。将处理的结果存入高可用键值存储系统Etcd中。在API Server响应Kubecfg的请求后,Scheduler会根据Kubernetes Client获取集群中运行Pod及Minion/Node信息。依据从Kubernetes Client获取的信息,Scheduler将未分发的Pod分发到可用的Minion/Node节点上。节点
节点可以是一个虚拟机或者物理机器,取决于所在的集群配置。 每个节点包含运行 Pods 所需的服务, 这些 Pods 由 控制面 负责管理
节点上的组件包括 kubelet、 容器运行时以及 kube-proxy。
节点状态
可以使用 kubectl 来查看节点状态和其他细节信息:
kubectl describe node <�节点名称>
一个节点包含以下信息:
地址HostName:由节点的内核设置。可以通过 kubelet 的 —hostname-override 参数覆盖。ExternalIP:通常是节点的可外部路由(从集群外可访问)的 IP 地址。InternalIP:通常是节点的仅可在集群内部路由的 IP 地址。状况(conditions 字段描述了所有 Running 节点的状态)Ready 如节点是健康的并已经准备好接收 Pod 则为 True;False 表示节点不健康而且不能接收 Pod;Unknown 表示节点控制器在最近 node-monitor-grace-period 期间(默认 40 秒)没有收到节点的消息DiskPressure为True则表示节点的空闲空间不足以用于添加新 Pod, 否则为 FalseMemoryPressure为True则表示节点存在内存压力,即节点内存可用量低,否则为 FalsePIDPressure为True则表示节点存在进程压力,即节点上进程过多;否则为 FalseNetworkUnavailable为True则表示节点网络配置不正确;否则为 False容量与可分配描述节点上的可用资源:CPU、内存和可以调度到节点上的 Pod 的个数上限。信息关于节点的一般性信息,例如内核版本、Kubernetes 版本(kubelet 和 kube-proxy 版本)、 Docker 版本(如果使用了)和 *** 作系统名称。这些信息由 kubelet 从节点上搜集而来。控制面到节点通信
节点到控制面apiserver在安全的 )上监听远程连接请求以客户端证书的形式将客户端凭据提供给 kubelet控制面到节点API 服务器到 kubelet连接用于获取 Pod 日志挂接(通过 kubectl)到运行中的 Pod提供 kubelet 的端口转发功能。(注: 在连接状态下, 默认apiserver 不检查 kubelet 的服务证书。容易受到中间人攻击,不安全)apiserver 到节点、Pod 和服务SSH 隧道(目前已经废弃)产生原因: 若无服务证书, 又要求避免在非受信网络或公共网络上进行连接,则可以在apiserver 和 kubelet 之间使用ssh隧道Kubernetes 支持使用 SSH 隧道来保护从控制面到节点的通信路径。Konnectivity 服务为ssh隧道的替代品, Konnectivity 服务提供 TCP 层的代理,以便支持从控制面到集群的通信。控制器
在 Kubernetes 中,控制器通过监控集群 的公共状态,并致力于将当前状态转变为期望的状态。
举个例子: 当前室内温度为20度, 我们通过调节遥控器,使其温度上升至24度, 这20度到24度的变化即为让其从当前状态接近期望状态。
控制器模式分为直接控制和通过API服务器来控制
云控制器管理器
云控制器管理器是指嵌入特定云的控制逻辑的 控制平面组件。 云控制器管理器允许您链接聚合到云提供商的应用编程接口中, 并分离出相互作用的组件与您的集群交互的组件。
云控制器管理器中的控制器包括:
节点控制器节点控制器负责在云基础设施中创建了新服务器时为之 创建 节点(Node)对象。 节点控制器从云提供商获取当前租户中主机的信息。执行功能:针对控制器通过云平台驱动的 API 所发现的每个服务器初始化一个 Node 对象利用特定云平台的信息为 Node 对象添加注解和标签获取节点的网络地址和主机名检查节点的健康状况。路由控制器Route 控制器负责适当地配置云平台中的路由,以便 Kubernetes 集群中不同节点上的 容器之间可以相互通信。服务控制器服务(Service)与受控的负载均衡器、 IP 地址、网络包过滤、目标健康检查等云基础设施组件集成。 服务控制器与云驱动的 API 交互,以配置负载均衡器和其他基础设施组件。Kubernetes 安全性
云原生安全
云原生安全4个C: 云(Cloud)、集群(Cluster)、容器(Container)和代码(Code)
云原生安全模型的每一层都是基于下一个最外层,代码层受益于强大的基础安全层(云、集群、容器)。我们无法通过在代码层解决安全问题来为基础层中糟糕的安全标准提供保护。
基础设施安全
Kubetnetes 基础架构关注领域
建议
通过网络访问 API 服务(控制平面)
所有对 Kubernetes 控制平面的访问不允许在 Internet 上公开,同时应由网络访问控制列表控制,该列表包含管理集群所需的 IP 地址集。
通过网络访问 Node(节点)
节点应配置为 仅能 从控制平面上通过指定端口来接受(通过网络访问控制列表)连接,以及接受 NodePort 和 LoadBalancer 类型的 Kubernetes 服务连接。如果可能的话,这些节点不应完全暴露在公共互联网上。
Kubernetes 云访问提供商的 API
每个云提供商都需要向 Kubernetes 控制平面和节点授予不同的权限集。为集群提供云提供商访问权限时,最好遵循对需要管理的资源的最小特权原则。Kops 文档提供有关 IAM 策略和角色的信息。
访问 etcd
对 etcd(Kubernetes 的数据存储)的访问应仅限于控制平面。根据配置情况,你应该尝试通过 TLS 来使用 etcd。更多信息可以在 etcd 文档中找到。
etcd 加密
在所有可能的情况下,最好对所有驱动器进行静态数据加密,但是由于 etcd 拥有整个集群的状态(包括机密信息),因此其磁盘更应该进行静态数据加密。
集群组件安全
运行的应用程序的安全性关注领域访问控制授权(访问 Kubernetes API)认证方式应用程序 Secret 管理 (并在 etcd 中对其进行静态数据加密)Pod 安全策略服务质量(和集群资源管理)网络策略Kubernetes Ingress 的 TLS 支持容器安全
容器安全性关注领域容器搭建配置(配置不当,危险挂载, 特权用户)容器服务自身缺陷Linux内核漏洞镜像签名和执行代码安全
代码安全关注领域仅通过 TLS 访问(流量加密)限制通信端口范围第三方依赖性安全静态代码分析动态探测攻击(黑盒)Kubernetes架构常见问题
Kubernetes ATTACK 矩阵
信息泄露
云账号AK泄露
API凭证(即阿里云AccessKey)是用户访问内部资源最重要的身份凭证。用户调用API时的通信加密和身份认证会使用API凭证
API凭证是云上用户调用云服务API、访问云上资源的唯一身份凭证。
API凭证相当于登录密码,用于程序方式调用云服务API
k8s configfile泄露
kubeconfig文件所在的位置:
$HOME/kube/config
Kubeconfig文件包含有关Kubernetes集群的详细信息,包括它们的位置和凭据。
云厂商会给用户提供该文件,以便于用户可以通过kubectl对集群进行管理 如果攻击者能够访问到此文件(如办公网员工机器入侵、泄露到Github的代码等),就可以直接通过API Server接管K8s集群,带来风险隐患。
Master节点SSH登录泄露
常见的容器集群管理方式是通过登录Master节点或运维跳板机,然后再通过kubectl命令工具来控制k8s。
云服务器提供了通过ssh登陆的形式进行登陆master节点
若Master节点SSH连接地址泄露,攻击者可对ssh登陆进行爆破,从而登陆上ssh,控制集群
容器组件未鉴权服务
Kubernetes架构下常见的开放服务指纹如下:
kube-apiserver: 6443, 8080kubectl proxy: 8080, 8081kubelet: 10250, 10255, 4149dashboard: 30000docker api: 2375etcd: 2379, 2380kube-controller-manager: 10252kube-proxy: 10256, 31442kube-scheduler: 10251weave: 6781, 6782, 6783kubeflow-dashboard: 8080注:前六个重点关注: 一旦被控制可以直接获取相应容器、相应节点、集群权限的服务
了解各个组件被攻击时所造成的影响
组件分工图:
假如用户想在集群里面新建一个容器集合单元, 流程如下:
用户与 kubectl进行交互,提出需求(例: kubectl create -f podyaml)kubectl 会读取 ~/kube/config 配置,并与 apiserver 进行交互,协议:apiserver 会协同 ETCD, kube-controller-manager, scheduler 等组件准备下发新建容器的配置给到节点,协议:apiserver 与 kubelet 进行交互,告知其容器创建的需求,协议:;kubelet 与Docker等容器引擎进行交互,创建容器,协议:容器已然在集群节点上创建成功攻击apiserver
apiserver介绍:
在Kubernetes中,对于未鉴权对apiserver, 能访问到 apiserver 一般情况下就能获取了集群的权限
在攻击者眼中Kubernetes APIServer
容器编排K8S总控组件pods, services, secrets, serviceaccounts, bindings, componentstatuses, configmaps,endpoints, events, limitranges, namespaces, nodes, persistentvolumeclaims,persistentvolumes, podtemplates, replicationcontrollers, resourcequotas …可控以上所有k8s资源可获取几乎所有容器的交互式shell利用一定技巧可获取所有容器母机的交互式shell默认情况下apiserver都有鉴权:
未鉴权配置如下:
对于这类的未鉴权的设置来说,访问到 apiserver 一般情况下就获取了集群的权限:
如何通过apiserver来进行渗透,可参考:>
攻击kubelet
每一个Node节点都有一个kubelet(每个节点上运行的代理)服务,kubelet监听了10250,10248,10255等端口。
10250端口,是kubelet与apiserver进行通信对主要端口, 通过该端口,kubelet可以知道当前应该处理的任务该端口在最新版Kubernetes是有鉴权的, 但在开启了接受匿名请求的情况下,不带鉴权信息的请求也可以使用10250提供的能力, 在Kubernetes早期,很多挖矿木马基于该端口进行传播
在配置文件中,若进行如下配置,则可能存在未授权访问漏洞
/var/bin/kubulet/config/yaml
若10250端口存在未授权访问漏洞,我们可以直接访问/pods进行查看
根据在pods中获取的信息,我们可以在容器中执行命令
curl -Gks >
上述命令得到websocket地址,连接websocket得到命令结果:
使用wscat工具连接websocket
wscat -c “>
即可得到我们执行命令的结果
获取token
/var/run/secrets/kubernetesio/serviceaccount
然后即可访问kube-api server,获取集群权限
curl -ks -H "Authorization: Bearer \ ttps://master:6443/api/v1/namespaces/{namespace}/secrets
"
攻击kubelet总体步骤如下:
访问pods获取信息获取namespace、podsname、containername执行exec获取token/var/run/secrets/kubernetesio/serviceaccount利用Token访问API Server进行对pods *** 作。攻击dashboard
dashboard登陆链接如下:
>
dashboard界面如下:
dashboard是Kubernetes官方推出的控制Kubernetes的图形化界面在Kubernetes配置不当导致dashboard未授权访问漏洞的情况下,通过dashboard我们可以控制整个集群。
默认情况下, dashboard是需要进行鉴权 *** 作的,当用户开启了enable-skip-login时可以在登录界面点击Skip跳过登录进入dashboard
通过skip登陆的dashboard默认是没有 *** 作集群的权限,因为Kubernetes使用RBAC(Role-based access control)机制进行身份认证和权限管理,不同的serviceaccount拥有不同的集群权限。
但有些开发者为了方便或者在测试环境中会为Kubernetes-dashboard绑定cluster-admin这个ClusterRole(cluster-admin拥有管理集群的最高权限)
为Kubernetes-dashboard绑定cluster-admin 设置如下:
新建dashboard-adminyaml内容apiVersion: rbacauthorizationk8sio/v1kind: ClusterRoleBindingmetadata: name: kubernetes-dashboardroleRef: apiGroup: rbacauthorizationk8sio kind: ClusterRole name: cluster-adminsubjects : kind: ServiceAccount name: kubernetes-dashboard namespace: kubernetes-dashboardkubectl create -f dashboard-adminyaml后通过skip登陆dashboard便有了管理集群的权限
创建Pod控制node节点,该pod主要是将宿主机根目录挂载到容器tmp目录下。
新建一个Pod如下:
通过该容器的tmp目录管理node节点的文件
攻击etcd
Kubernetes默认使用了etcd v3来存储数据, 若能na
etcd对内暴露2379端口,本地127001可免认证访问 其他地址要带—endpoint参数和cert进行认证。
未授权访问流程:
检查是否正常链接etcdctl endpoint health读取service account tokenetcdctl get / --prefix --keys-only | grep /secrets/kube-system/clusterrole通过token认访问API-Server端口6443,接管集群:kubectl --insecure-skip-tls-verify -s攻击docker remote api(Docker daemon公网暴露)
2375是docker远程 *** 控的默认端口,通过这个端口可以直接对远程的docker 守护进程进行 *** 作。Docker 守护进程默认监听2375端口且未鉴权
当机器以方式启动daemon时,可以在外部机器对该机器的docker daemon进行直接 *** 作:
docker daemon -H=0000:2375
之后依次执行systemctl daemon-reload、systemctl restart docker
外部主机使用 即可 *** 作暴露2375端口的主机
-H
因此当你有访问到目标Docker API 的网络能力或主机能力的时候,你就拥有了控制当前服务器的能力。我们可以利用Docker API在远程主机上创建一个特权容器,并且挂载主机根目录到容器
检测目标是否存在docker api未授权访问漏洞的方式也很简单,访问>
攻击kubectl proxy
二次开发所产生的问题
管理Kubernetes无论是使用 kubectl 或 Kubernetes dashboard 的UI功能,其实都是间接在和 APIServer 做交互
如果有需求对k8s进行二次开发的话,大部分的开发功能请求了 APIServer 的 Rest API 从而使功能实现的。
例如:
给用户销毁自己POD的能力DELETE类似于这样去调用apiserver, 攻击者若修改namespace、pod和容器名, 那么即可造成越权
推荐工具
Kube-Hunter扫描漏洞
kube-hunter是一款用于寻找Kubernetes集群中的安全漏洞扫描器
下载地址: >
CDK(强推)
CDK是一款为容器环境定制的渗透测试工具,在已攻陷的容器内部提供零依赖的常用命令及PoC/EXP。集成Docker/K8s场景特有的 逃逸、横向移动、持久化利用方式,插件化管理。
下载地址: >
参考链接
>
Knative Serving 是 Knative 系统的核心,而理解 Knative Serving 系统内的组件能更容易了理解 Knative Serving 系统的实现:
了解其中的控制流和数据流的走向,了解其在扩缩容过程中的作用。因篇幅有限,这里只对组件进行简要描述,后续会针对每个组件进行详细的单独讲解。
queue-proxy 是 一个伴随着用户容器运行的 Sidecar 容器,跟用户容器运行在同一个 Pod 中。每个请求到达业务容器之前都会经过 queue-proxy 容器,
这也是它问什么叫 proxy 的原因。
queue-proxy 的主要作用是统计和限制到达业务容器的请求并发量,当对一个 Revision 设置了并发量之后(比如设置了5), queue-proxy 会确保不会同时有超过5个请求打到业务容器。当有超过5个请求到来时, queue-proxy 会先把请求暂存在自己的队列 queue 里,(这也是为什么名字里有个 queue的缘故)。 queue-proxy 同时会统计进来的请求量,同时会通过指定端口提供平均并发量和 rps(每秒请求量)的查询。
Autoscaler 是 Knative Serving 系统中一个重要的 pod,它由三部分组成:
PodAutoscaler reconciler 会监测 PodAutoscaler (KPA)的变更,然后交由 Collector 和 Decider 处理
Collector 主要负责从应用的 queue-proxy 那里收集指标, Collector 会收集每个实例的指标,然后汇总得到整个系统的指标。为了实现扩缩容,会搜集所有应用实例的样本,并将收集到的样本反映到整个集群。
Decider 得到指标之后,来决定多少个Pod 被扩容出来。简单的计算公式如下:
另外,扩缩容的量也会受到 Revision 中最大最小实例数的限制。同时 Autoscaler 还会计算当前系统中剩余多少突发请求容量(可扩缩容多少实例)进来决定 请求是否走 Activator 转发。
Activator 是整个系统中所用应用共享的一个组件,是可以扩缩容的,主要目的是缓存请求并给 Autoscaler 主动上报请求指标
Activator 主要作用在从零启动和缩容到零的过程,能根据请求量来对请求进行负载均衡。当 revision 缩容到零之后,请求先经过 Activator 而不是直接到 revision 。 当请求到达时, Activator 会缓存这这些请求,同时携带请求指标(请求并发数)去触发 Autoscaler 扩容实例,当实例 ready后, Activator 才会将请求从缓存中取出来转发出去。同时为了避免后端的实例过载, Activator 还会充当一个负载均衡器的作用,根据请求量决定转发到哪个实例(通过将请求分发到后端所有的Pod上,而不是他们超过设置的负载并发量)。 Knative Serving 会根据不同的情况来决定是否让请求经过 Activator ,当一个应用系统中有足够多的pod实例时, Activator 将不再担任代理转发角色,请求会直接打到 revision 来降低网络性能开销。
跟 queue-proxy 不同, Activator 是通过 websocket 主动上报指标给 Autoscaler ,这种设计当然是为了应用实例尽可能快的冷启动。 queue-proxy 是被动的拉取: Autoscaler 去 queue-proxy 指定端口拉取指标。
API: podautoscalersautoscalinginternalknativedev
PodAutoscaler 是对扩缩容的一个抽象,简写是 KPA 或 PA ,每个 revision
会对应生成一个 PodAutoscaler 。
可通过下面的指令查看
API: serverlessservicesnetworkinginternalknativedev
ServerlessServices 是 KPA 产生的,一个 KPA 生成一个 SKS , SKS 是对 k8s service 之上的一个抽象,
主要是用来控制数据流是直接流向服务 revision (实例数不为零) 还是经过 Activator (实例数为0)。
对于每个 revision ,会对应生成两个k8s service ,一个 public service ,一个 private service
private service 是标准的 k8s service,通过label selector 来筛选对应的deploy 产生的pod,即 svc 对应的 endpoints 由 k8s 自动管控。
public service 是不受 k8s 管控的,它没有 label selector,不会像 private service 一样 自动生成 endpoints。 public service 对应的 endpoints
由 Knative SKS reconciler 来控制。
SKS 有两种模式: proxy 和 serve
下面看几种情况下的数据流向,加深对Knative 扩缩容系统机制的理解。
稳定状态下的工作流程如下:
缩容到零过程的工作流程如下:
冷启动过程的工作流程如下:
当 revision 缩容到零之后,此时如果有请求进来,则系统需要扩容。因为 SKS 在 proxy 模式,流量会直接请求到 Activator 。 Activator 会统计请求量并将 指标主动上报到 Autoscaler , 同时 Activator 会缓存请求,并 watch SKS 的 private service , 直到 private service 对应的endpoints产生。
Autoscaler 收到 Activator 发送的指标后,会立即启动扩容的逻辑。这个过程的得出的结论是至少一个Pod要被创造出来, AutoScaler 会修改 revision 对应 Deployment 的副本数为为N(N>0), AutoScaler 同时会将 SKS 的状态置为 serve 模式,流量会直接到导到 revision 对应的 pod上。
Activator 最终会监测到 private service 对应的endpoints的产生,并对 endpoints 进行健康检查。健康检查通过后, Activator 会将之前缓存的请求转发到
健康的实例上。
最终 revison 完成了冷启动(从零扩容)。
Kubernetes使用Horizontal Pod Autoscaler(HPA)的控制器实现基于CPU使用率进行自动Pod扩缩容的功能。HPA控制器周期性地监测目标Pod的资源性能指标,并与HPA资源对象中的扩缩容条件进行对比,在满足条件时对Pod副本数量进行调整。Kubernetes中的某个Metrics Server(Heapster或自定义Metrics Server)持续采集所有Pod副本的指标数据。HPA控制器通过Metrics Server的API(Heapster的API或聚合API)获取这些数据,基于用户定义的扩缩容规则进行计算,得到目标Pod副本数量。
当目标Pod副本数量与当前副本数量不同时,HPA控制器就向Pod的副本控制器(Deployment、RC或ReplicaSet)发起scale *** 作,调整Pod的副本数量,完成扩缩容 *** 作。我推荐你去看看时速云,他们是一家全栈云原生技术服务提供商,提供云原生应用及数据平台产品,其中涵盖容器云PaaS、DevOps、微服务治理、服务网格、API网关等。大家可以去体验一下。 如果我的回答能够对您有帮助的话,求给大大的赞。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)