大家好,今天来介绍k8s资源类型详解(kubernetes存储方案)的问题,以下是渲大师小编对此问题的归纳和整理,感兴趣的来一起看看吧!
什么是K8S
k8s是什么?
Kubernetes 是一个可移植的,可扩展的开源容器编排平台,用于管理容器化的工作负载和服务,方便了声明式配置和自动化。它拥有一个庞大且快速增长的生态系统。Kubernetes 的服务,支持和工具广泛可用。
为什么现在流行使用容器?
早期: 在物理服务器上面部署应用程序存在资源分配问题,因为其不能在物理服务器中的应用程序定义资源边界,导致应用程序资源利用不足而无法扩展.
后来: 为了解决该问题,引入了虚拟化技术, 虚拟化技术是指允许你在单个物理服务器的 CPU 上运行多个虚拟机,可以让多个应用程序在虚拟机之间进行隔离,具有一定的安全性, 每一个虚拟机就是一台完整的计算机, 在虚拟化硬件之上运行所有组件.
现在: 多数在物理服务器上面部署应用程序都是采kubectl用容器的方式,容器类似于虚拟机,它们都具宽大如有自己的文件系统、CPU、内存、进程空间等, 且由于它们与基础架构分离,因此可以跨云和 OS 发行版本进行移植。基于此特点被企业大范围使用.
为什么需要使用k8s容器?
若出现这样一个环境: 在生产环境中如果一个容器发生故障,则我们需要手动去启动另外一个容器,这样的操作是对我们的管理员来说是不太方便的, 若一个容器出现故障,另一个容器可以自动启动容器接管故障的容器,这样是最好的.
k8s就可以实现该效果,Kubernetes 提供了一个可弹性运行分布式系统的框架。 Kubernetes 会满足你的扩展要求、故障转移、部署模式等。
k8s功能: 服务发现和负载均衡, 存储编排, 自动部署和回滚, 自动完成装箱计算, 自我修复, 密钥与配置管理
名词解释
secret
Secret有三种类型:
- Service Account:用来访问Kubernetes API,由Kubernetes自动创建,并且会自动挂载到Pod的目录中;
- /run/secrets/kubernetes.io/serviceaccount
- Opaque:base64编码格式的Secret,用来存储密码、密钥等;
- kubernetes.io/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: 云控制器管理器是指嵌入特定云的控制逻辑的 控制平面组件
- kube-apiserver: 为k8s的api服务器,公开了所有Kubernetes API, 其他所有组件都必须通过它提供的API来操作资源数据.
- 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 服务器负责提供 HTTP 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, 否则为 False
- MemoryPressure为True则表示节点存在内存压力,即节点内存可用量低,否则为 False
- PIDPressure为True则表示节点存在进程压力,即节点上进程过多;否则为 False
- NetworkUnavailable为True则表示节点网络配置不正确;否则为 False
- 容量与可分配
- 描述节点上的可用资源:CPU、内存和可以调度到节点上的 Pod 的个数上限。
- 信息
- 关于节点的一般性信息,例如内核版本、Kubernetes 版本(kubelet 和 kube-proxy 版本)、 Docker 版本(如果使用了)和操作系统名称。这些信息由 kubelet 从节点上搜集而来。
控制面到节点通信
- 节点到控制面
- apiserver在安全的 HTTPS 端口(443)上监听远程连接请求
- 以客户端证书的形式将客户端凭据提供给 kubelet
- 控制面到节点
- API 服务器到 kubelet连接用于
- 获取 Pod 日志
- 挂接(通过 kubectl)到运行中的 Pod
- 提供 kubelet 的端口转发功能。
- (注: 在连接状态下, 默认apiserver 不检查 kubelet 的服务证书。容易受到中间人攻击,不安全.)
- apiserver 到节点、Pod 和服务
- SSH 隧道(目前已经废弃)
- 产生原因: 若无服务证书, 又要求避免在非受信网络或公共网络上进行连接,则可以在apiserver 和 kubelet 之间使用ssh隧道.
- Kubernetes 支持使用 SSH 隧道来保护从控制面到节点的通信路径。
- Konnectivity 服务
- 为ssh隧道的替代品, Konnectivity 服务提供 TCP 层的代理,以便支持从控制面到集群的通信。
- SSH 隧道(目前已经废弃)
- API 服务器到 kubelet连接用于
控制器
在 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, 8080
- kubectl proxy: 8080, 8081
- kubelet: 10250, 10255, 4149
- dashboard: 30000
- docker api: 2375
- etcd: 2379, 2380
- kube-controller-manager: 10252
- kube-proxy: 10256, 31442
- kube-scheduler: 10251
- weave: 6781, 6782, 6783
- kubeflow-dashboard: 8080
注:前六个重点关注: 一旦被控制可以直接获取相应容器、相应节点、集群权限的服务
了解各个组件被攻击时所造成的影响
组件分工图:
假如用户想在集群里面新建一个容器集合单元, 流程如下:
- 用户与 kubectl进行交互,提出需求(例: kubectl create -f pod.yaml)
- kubectl 会读取 ~/.kube/config 配置,并与 apiserver 进行交互,协议:http/https
- apiserver 会协同 ETCD, kube-controller-manager, scheduler 等组件准备下发新建容器的配置给到节点,协议:http/https
- apiserver 与 kubelet 进行交互,告知其容器创建的需求,协议:http/https;
- kubelet 与Docker等容器引擎进行交互,创建容器,协议:http/unix socket.
- 容器已然在集群节点上创建成功
攻击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来进行渗透,可参考:https://Kubernetes.io/docs/reference/generated/kubectl/kubectl-commands
攻击kubelet
每一个Node节点都有一个kubelet(每个节点上运行的代理)服务,kubelet监听了10250,10248,10255等端口。
10250端口,是kubelet与apiserver进行通信对主要端口, 通过该端口,kubelet可以知道当前应该处理的任务.该端口在最新版Kubernetes是有鉴权的, 但在开启了接受匿名请求的情况下,不带鉴权信息的请求也可以使用10250提供的能力, 在Kubernetes早期,很多挖矿木马基于该端口进行传播.
在配置文件中,若进行如下配置,则可能存在未授权访问漏洞.
/var/bin/kubulet/config/yaml
若10250端口存在未授权访问漏洞,我们可以直接访问/pods进行查看
根据在pods中获取的信息,我们可以在容器中执行命令
curl -Gks https://host:10250/exec/{namespace}/{podname}/{containername} \-d 'input=1' -d 'output=1' -d 'tty=1' \-d 'command=whoami'
上述命令得到websocket地址,连接websocket得到命令结果:
使用wscat工具连接websocket
wscat -c “https://X.X.X.X:10250/{websocket}” --no-check
即可得到我们执行命令的结果.
获取token
/var/run/secrets/kubernetes.io/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/kubernetes.io/serviceaccount
- 利用Token访问API Server进行对pods操作。
攻击dashboard
dashboard登陆链接如下:
http://xxx.xxx.xxx.xxx:xxxx/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/#/login
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-admin.yaml内容
- apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata: name: kubernetes-dashboardroleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-adminsubjects : kind: ServiceAccount name: kubernetes-dashboard namespace: kubernetes-dashboard
- kubectl create -f dashboard-admin.yaml
后通过skip登陆dashboard便有了管理集群的权限.
创建Pod控制node节点,该pod主要是将宿主机根目录挂载到容器tmp目录下。
新建一个Pod如下:
通过该容器的tmp目录管理node节点的文件
攻击etcd
Kubernetes默认使用了etcd v3来存储数据, 若能na
etcd对内暴露2379端口,本地127.0.0.1可免认证访问. 其他地址要带—endpoint参数和cert进行认证。
未授权访问流程:
- 检查是否正常链接
- etcdctl endpoint health
- 读取service account token
- etcdctl get / --prefix --keys-only grep /secrets/kube-system/clusterrole
- 通过token认访问API-Server端口6443,接管集群:
- kubectl --insecure-skip-tls-verify -s https://127.0.0.1:6443/ --token="[ey...]" -n kube-system get pods
攻击docker remote api(Docker daemon公网暴露)
2375是docker远程操控的默认端口,通过这个端口可以直接对远程的docker 守护进程进行操作。Docker 守护进程默认监听2375端口且未鉴权.
当机器以方式启动daemon时,可以在外部机器对该机器的docker daemon进行直接操作:
docker daemon -H=0.0.0.0:2375
之后依次执行systemctl daemon-reload、systemctl restart docker
外部主机使用 即可操作暴露2375端口的主机.
-H
因此当你有访问到目标Docker API 的网络能力或主机能力的时候,你就拥有了控制当前服务器的能力。我们可以利用Docker API在远程主机上创建一个特权容器,并且挂载主机根目录到容器.
检测目标是否存在docker api未授权访问漏洞的方式也很简单,访问http://[host]:[port]/info路径是否含有ContainersRunning、DockerRootDir等关键字。
攻击kubectl proxy
二次开发所产生的问题
管理Kubernetes无论是使用 kubectl 或 Kubernetes dashboard 的UI功能,其实都是间接在和 APIServer 做交互.
如果有需求对k8s进行二次开发的话,大部分的开发功能请求了 APIServer 的 Rest API 从而使功能实现的。
例如:
- 给用户销毁自己POD的能力
- DELETE https://apiserver:8443/api/v1/namespaces/default/pods/sleep-75c6fd99c-g5kss
类似于这样去调用apiserver, 攻击者若修改namespace、pod和容器名, 那么即可造成越权.
推荐工具
Kube-Hunter扫描漏洞
kube-hunter是一款用于寻找Kubernetes集群中的安全漏洞扫描器
下载地址: https://github.com/aquasecurity/kube-hunter
CDK(强推)
CDK是一款为容器环境定制的渗透测试工具,在已攻陷的容器内部提供零依赖的常用命令及PoC/EXP。集成Docker/K8s场景特有的 逃逸、横向移动、持久化利用方式,插件化管理。
下载地址: https://github.com/cdk-team/CDK/wiki/CDK-Home-CN
参考链接
https://developer.aliyun.com/article/765449?groupCode=aliyunsecurity
https://xz.aliyun.com/t/4276#toc-2
https://www.secrss.com/articles/29544
https://kubernetes.io/zh/docs/concepts/workloads/pods/#what-is-a-pod
https://www.huweihuang.com/kubernetes-notes/concepts/architecture/kubernetes-architecture.html
https://www.kubernetes.org.cn/service-account
https://www.aquasec.com/cloud-native-academy/cloud-native-applications/cloud-native-infrastructure/
https://www.cdxy.me/?p=827
Kubernetes 存储资源 PV、PVC 和StorageClass详解
Kubernetes 官方文档地址:
在 Kubernetes 中,存储资源和计算资源(CPU、Memory)同样重要,Kubernetes 为了能让缺誉管理员方便管理集群中的存储资源,同时也为了让使用者使用存储更加方便,所以屏蔽了底层存储的实现细节,将存储抽象出两个 API 资源 PersistentVolume 和 PersistentVolumeClaim 对象来对存储进行管理。
PersistentVolume 类型实现为插件,目前 Kubernetes 支持以下插件:
PV 生命周期总共四个阶段:
Kubernetes 支持多种存储,这里使用最广泛的 NFS 存储为例来介绍,下面是一个 PV 的例子:
PV 可以通过配置 capacity 中的 storage 参数,对 PV 挂多大存储空间进行设置
PV 可以通过配置 volumeMode 参数,对存储卷类型进行设置,可选项包括:
volumeMode: Filesystem
PV 可以通过配置 accessModes 参数,设置访问模式来限制应用对资源的访问权限,有以下机制访问模式:
`accessModes:
不过不同的存储所支持的访问模式也不相同,具体如下:
PV 可以根据不同的存储卷类型,设置不同的挂载参数,每种类型的存储卷可配置参数都不相同。如 NFS 存储,可以设置 NFS 挂载配置,如下:
PV 可以通过配置 storageClassName 参数指定一个存储类 StorageClass 资源,具有特定 StorageClass 的 PV 只能与指定相同 StorageClass 的 PVC 进行绑定,没有设置 StorageClass 的 PV 也是同样只能与没有指定 StorageClass 的 PVC 绑定。
storageClassName: slow
PV 可以通过配置 persistentVolumeReclaimPolicy 参数设置回收策略,可选项如下:
persistentVolumeReclaimPolicy: Recycle
PVC 可以通过在 Selecter 中设置 Laberl 标签,筛选出带有指定 Label 的 PV 进行绑定。 Selecter 中可以指定 matchLabels 或 matchExpressions ,如果两个字段都设定了就需要同时满足才能匹配。
PVC 设置目前只有 requests.storage 一个参数,用于指定申请存储空间的大小。
PVC 要想绑定带有特定 StorageClass 的 PV 时,也必须设定 storageClassName 参数,且名称也必须要和 PV 中的 storageClassName 保持一致。如果要绑定的 PV 没有设置 storageClassName 则 PVC 中也不需要设置。
当 PVC 中如果未指定 storageClassName 参数或者指定为空值,则还需要考虑 Kubernetes 中是否设置了默认的 StorageClass :
storageClassName: slow
PVC 中可设置的访问模式与 PV 种一样,用于限制应用对资源的访问权限。
PVC 中可设置的存储卷模式与 PV 种一样,分为 Filesystem 和 Block 两种。
这里使用 NFS 存储,创建 StorageClass 示例:
在创建 StorageClass 之前需要 Kubernetes 集群中存在 Provisioner (存储分配提供者)应用,如 NFS 存储需要有 NFS-Provisioner (NFS 存储分配提供者)应用,如果集群中没有该应用,那么创建的 StorageClass 只能作为标记,而不能提供创建 PV 的作用。
provisioner: nfs-client
后端存储提供的参野陵数,不同的 Provisioner 可与配置的参数也是不颂扮戚相同。例如 NFS Provisioner 可与提供如下参数:
在 StorageClass 中,可以根据不同的存储来指定不同的挂载参数,此参数会与 StorageClass 绑定的 Provisioner 创建 PV 时,将此挂载参数与创建的 PV 关联。
可与在 Kubernetes 集群中设置一个默认的 StorageClass,这样当创建 PVC 时如果未指定 StorageClass 则会使用默认的 StorageClass。
PV 是 Kubernetes 集群的存储资源,而 PVC 则是对存储资源的需求,创建 PVC 需要对 PV 发起使用申请,即和 PV 进行绑定。 PV 和 PVC 是一一对应的关系,它们二者的交互遵循如下生命周期:
存储供给(Provisioning)是指为 PVC 准备可用的 PV 的一种机制。Kubernetes 支持 PV 供给方式有 静态供给 和 动态供给 两种:
在静态模式下,在用户定义好 PVC 后,Kubernetes 将根据 PVC 提出的“申请空间的大小”、“访问模式”从集群中寻找已经存在且满足条件的 PV 进行绑定,如果集群中没有匹配的 PV 则 PVC 将处于 Pending 等待状态,知道系统创建了符合条件的 PV 再与其绑定。PV 与 PVC 绑定后就不能和别的 PVC 进行绑定。
在动态模式下,当创建 PVC 并且指定 StorageClass 后,与 StorageClass 关联的存储插件会自动创建对应的 PV 与该 PVC 进行绑定。
完成存储卷的使用目标之后删除 PVC 对象,以便进行资源回收。不过,至于如何操作则取决于 PV 的回收策略 ,目前有三种策略:
一般 Deployment 中使用 PVC,大部分都是静态供给方式创建,即先创建 PV,再创建 PVC 与 PV 绑定,在设置应用于 PVC 关联。
下面是一个 NFS 存储创建 PV 的例子,如下:
创建 PVC 与 PV 进行关联绑定:
创建应用于 PVC 进行关联:
在有状态的应用中,我们经常使用动态供给方式创建 PV 和 PVC,不过提前需要集群拥有:
只有拥有上面两种资源同时存在时才能使用动态存储,本人这里使用的是 NFS 存储,关于如何创建 NFS Provisioner 可以查看 NFS Provisioner 一文 ,假如 Kubernetes 集群中使用 NFS 存储,且存在 Provisioner 的名称为 nfs-client 那就可以下面创建 StorageClass 示例:
然后 StatefulSet 可以按下方式,在 volumeClaimTemplates 参数中指定使用的 StorageClass ,然后与 StorageClass 关联的 NFS Provisioner 会执行创建 PVC 和 PV,然后两者进行绑定,下面是 StatefulSet 方式使用 volumeClaimTemplates 挂载存储的示例:
K8s 精选Kubernetes CRD 简介
CRD 本身是一种 Kubernetes 内置的资源类型,即 自定义资源的定义 ,用于描述用户定义的资源是什么样子。CRD 的相关概念:① 从 Kubernetes 的用户角度来看,所有东西都叫资源 Resource ,就是 Yaml 里的字段 Kind 的内容,例如 Service、Deployment 等。② 除了常见内置资源之外,Kubernetes 允许用户自定义资源 Custom Resource,而 CRD 表示自定义资源的定义 。
参考 Future of CRDs: Structural Schemas ,Schema 可以确保 Yaml 描述的资源是规范的、合法的。 CRD 本质是一个 Open Api 的 Schema,向 Kubernetes 集群注册一种新资源,并告诉 ApiServer,这种资源怎么被合法的定义 。
拓展:什么是控制器模式?
以 Deployment 为实例,Deployment 没有直接创建 Pod,而是管理 RS,而 RS 管理 Pod,这就是控制器模式。控制器模式允许基于已有的资源定义更高阶的控制器,用来实现更复杂的能力,详情可参考 Kubernetes 控制器的工作原理解读
用户可以自定义控制器的逻辑,实者含消现 Kubernetes 集群原生不支持的功能。下面利用 Kubebuilder 创建 CRD 实现 Kubernetes 集群内置微服务管理 。
App 负责管理整个应用的生命周期, MicroService 负责管理微服务的生命周期 。① 部署方面 : App 可以直接管理多个 MicroService ,同时 MicroService 利用控制器模式,可以为每个版本创建一个 Deployment , 实现多个版本同时部署。
② 发布方面 :微服务管理具备 蓝绿发布 、 灰度发布 的功能。 MicroService 为自己创建 1 个首知的 LoadBalance ,也为每个版本创建了 Service 。如下图所示, MicroService 下的每个版本(对应每个 Deployment )都有 Service ,而本身也有 LoadBalance ,即总共拥有 n+1 个 Service 。 LoadBalance 和 CurrentVersion 实现了蓝绿发老液布 。 MicroService 利用 nginx ingress controller 的能力,通过修改 LoadBalance 的 canary 配置,实现按照 header/cookie/比例 的灰度发布
CRD 配置详解可以参考 Kuberneters(K8s)CRD资源详解
利用 Kubebuilder 实现 Kubernetes 集群内置微服务管理 , App 和 MicroService 的 Controller 的主要逻辑如下:
① 从 功能 角度分析, CRD 是积木 。用户可以把 Kubernetes 已有的资源和能力自由堆砌起来,从而拓展了 Kubernetes 原生不具备的能力。
② 从 产品 角度分析, CRD 允许用户基于自己产品的概念,让 Kubernetes 已有的资源为用户服务 ,而不是思考如何将场景应用到 Kubernetes。基于 Kubernetes 开发产品,无法避免如何将产品概念想 Kubernetes 靠拢,例如一个服务就是一个 Deployment ,一个实例就是一个 Pod 等。
k8s的功能
k8s是一个docker集群的管理工具
治愈
弹性伸缩
服务的自动发现和负载均衡
滚动升级和一键回滚
k8s最适合跑微服务项目!
k8s最小的资源单位是pod,所有的资源都可以用yaml创建
k8s yaml的主要组成
pod资源:至少由两个容器组成,pod基础容器和业务容器组成
rc:保证指定数量的pod始终存活,rc通过标签选择器来关联pod
k8s资源的常见操作:
创建一个rc
service帮助pod暴露端口
修改nodePort范围
vim /etc/kubernetes/apiserver
KUBE_API_ARGS="--service-node-port-range=3000-50000"
service默认使用iptables来实现负载均衡, k8s 1.8新版本中推荐旅困使用lvs(四层负载均衡)
有rc在滚动升级之后,会造成服务访问中断,于是k8s引入了deployment资源
创建deployment
deployment,先启动一个rs资源,rs控制pod的数量
rs90%的功能和rc一样
deployment升级斗纤和回滚
命令行创建deployment
K8s易混点辨析空镇仿:nodePort、port、targetPort、containerPort
https://blog.csdn.net/yjk13703623757/article/details/79819415
在k8s中容器之间相互访问,通过VIP地址!
K8S——Label详解
1 Label含义
1.1 Label其实就一对 key/value ,被关联到对象上,比如Pod,标签的使用我们倾向于能够标示对象的特殊特点,Labels的值对系统本身并没有什么含义,只是对用户才有意义。同一个资源对象的labels属性的key必须唯一,label可以附加到各种资源历胡对象上,如Node,Pod,Service,RC等。一个资源拥有多个标签,可以实现不同维度的管理。标签(Label)的组成: key=value。Label可以在创建对象时就附加到对象上,也可以在对象创建后通过API进行额外添加或修改。
1.2 Label命名规肢型拦范
label 必须以字母或数字开头,可以使用字母、数字、连字符、点和下划线,最长63个字符。
2 使用Label原因
2.1 当相同类型的资源越来越多,对资源划分管理是很有必要,此时就可以使用Label为资源对象 命名,以便于配置,部署等管理工作,提升资源的管理效率。label 作用类似Java包能对不同文件分开管理,让整体更加有条理,有利于维护。
2.2 通过Label来对对象进行引用。
3Label创建脚本
3.1 命令创建
label [--overwrite] (-f FILENAME TYPE NAME) KEY_1=VAL_1 ... KEY_N=VAL_N [--resource-version=version]
3.1.1 kubectl get pods 命令默认不会列出任何标签,使用 --show-labels 选项来查看 :
kubectl get po --show-labels
3.1.2 指定标签查看
kubectl get po -L creation_method,env
查看匹配标签条件的node
kubectl get nodes -l 标签key=标签values
kubectl get nodes -l app=tomcat
查看匹配 标签key的pod
kubectl get po -L app
3.1.3 给名为tomcat 的Pod添加label app=tomcat。
kubectl label pods tomcat app=tomcat
3.1.4 把名为tomcat 的Pod修改label 为 app=tomcat1,且覆盖现有的value
kubectl label --overwrite pods tomcat app=tomcat1
3.1.5 把 namespace 中的所有 pod 添加 label
kubectl label pods --all test=test
3.1.6 删除名为“app”的label 。(使租昌用“ - ”减号相连)
kubectl label pods tomcat app-
3.2 yaml脚本创建
vim label-pod-test.yaml
apiVersion: v1
kind: Pod
metadata:
name: tomcat
labels:
app: tomcat
release: stable
spec:
containers:
- name: tomcat
image: tomcat
ports:
- containerPort: 80
为tomcat的Pod添加了两个Label,分别为app: tomcat和release: tomcat
4Label使用场景
常用的,多维度标签分类:
版本标签(release): stable(稳定版),canary(金丝雀版本),beta(测试版)
环境类(environment): dev(开发),qa(测试),production(生产),op(运维)
应用类(applaction): ui(设计),as(应用软件),pc(电脑端),sc(网络方面)
架构层(tier): frontend(前端),backend(后端),cache(缓存)
分区标签(partition): customerA(客户),customerB
品控级别(track): daily(每天),weekly(每周)
vim label-pod-test.yaml
apiVersion: v1
kind: Pod
metadata:
name: label-pod-test
labels: #使用labels字段来定义标签,可以一次定义多个标签,这里定义3个标签
release: stable #版本:稳定版
env: qa #环境:测试
tier: frontend #架构类:前端
spec:
containers:
- name: testTomcatLabel
image: tomcat #部署的是tomcat服务
最后祝各位小伙伴新年快乐,万事如意!!有好的建议和意见,欢迎下方留言。力求每次分享能为大家带来更多的收获。
本文地址:https://gpu.xuandashi.com/73508.html,转载请说明来源于:渲大师
声明:本站部分内容来自网络,如无特殊说明或标注,均为本站原创发布。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。分享目的仅供大家学习与参考,不代表本站立场!