k8s简介
目录
[toc]
原文链接
https://onedayxyy.cn/docs/k8s-introd
推荐文章
我的开源项目:
https://onedayxyy.cn/docs/MyOpenSourceProject
k8s简介
Kubernetes(简称 K8S) 的出现是容器化技术发展的必然结果,容器化是应用程序级别的虚拟化,运行单个内核上有多个独立的用户空间实例,这些实例就是容器。容器提供了将应用程序的代码、运行时、系统工具、系统库和配置打包到一个实例中的标准方法,而且容器是共享一个内核的。由于容器技术的兴起,导致大量的容器应用出现,所以就出现了一些用来支持应用程序容器化部署和组织的容器编排技术,一些流行的开源容器编排工具有 Docker Swarm、Kubernetes 等,但是在发展过程中 Kubernetes 现在已经成为了容器编排领域事实上的一个标准了。
Kubernetes 是 Google 团队发起的一个开源项目,它的目标是管理跨多个主机的容器,用于自动部署、扩展和管理容器化的应用程序,主要实现语言为 Go 语言,他的理论基础来源与 Google 内部的 Borg 项目,所以 Kubernetes 项目的理论基础就比其他开源项目要“先进”很多,因为 Borg 系统一直依赖就被称为 Google 公司内部最强大的“私密武器”。
为什么使用k8s
使用 Kubernetes 的理由很多,最重要的理由是,IT 行业从来都是由新技术驱动的。Docker 容器化技术已经被很多公司采用,从单机走向集群已成为必然。云计算的蓬勃发展正在加速这一进程,Kubernetes 作为当前被业界广泛认可和看好的基于 Docker 的大规模容器化分布式系统解决方案,得到了以谷歌为首的 IT 巨头们的大力宣传和维持推进。
2015 年,谷歌联合 20 多家公司一起建立了 CNCF(Cloud Native Computing Foundation,云原生计算基金会)开源组织来推广 Kubernetes,并由此开创了云原生应用(Cloud Native Application)的新时代。作为 CNCF “钦定”的官方云原生平台,Kubernetes 正在颠覆应用程序的开发方式。我们可以从以下几个方面来看看为什么需要使用K8s!
一个平台搞定所有
使用 Kubernetes 部署任何应用都是小菜一碟。只要应用可以打包成镜像,能够容器部署,Kubernetes 就一定能启动它。
不管什么语言、什么框架写的应用(如 Java, Python, Node.js),Kubernetes 都可以在任何环境中安全的启动它,如物理服务器、虚拟机、云环境。
云环境无缝迁移
如果你有更换云环境的需求,例如从 GCP 到 AWS,使用 Kubernetes 的话,你就不用有任何担心。
Kubernetes 完全兼容各种云服务提供商,例如 Google Cloud、Amazon、Microsoft Azure、阿里云等,还可以工作在 CloudStack, OpenStack, VSphere 上等。
高效的利用资源
看下图,左边是 4 个虚拟机,黄色和蓝色部分是运行的应用,白色部分是未使用的内存和处理器资源。右边,同样的应用打包运行在容器中。
Kubernetes 如果发现有节点工作不饱和,便会重新分配 Pod,帮助我们节省开销,高效的利用内存、处理器等资源。
如果一个节点宕机了,Kubernetes 会自动重新创建之前运行在此节点上的 Pod,在其他节点上运行。
开箱即用的自动缩放能力
网络、负载均衡、副本等特性,对于 Kubernetes 都是开箱即用的。Pod 是无状态运行的,任何时候有 Pod 宕了,立马会有其他 Pod 接替它的工作,用户完全感觉不到。如果用户量突然暴增,现有的 Pod 规模不足了,那么会自动创建出一批新的 Pod,以适应当前的需求。反之亦然,当负载降下来的时候,Kubernetes 也会自动缩减 Pod 的数量。
使 DevOps 更更简单
你不必精通 Chef 或 Ansible 这类工具,只需要对 CI 服务写个简单的脚本然后运行它,就会使用你的代码创建一个新的 Pod,并部署到 Kubernetes 集群里面。应用打包在容器中使其可以安全的运行在任何地方,例如你的 PC、一个云服务器,使得测试极其简单。
可靠性
Kubernetes 如此流行的一个重要原因是:应用会一直顺利运行,不会被 Pod 或节点的故障所中断。如果出现故障,Kubernetes 会创建必要数量的应用镜像,并分配到健康的 Pod 或节点中,直到系统恢复。
一个容器化的基础设施是有自愈能力的,可以提供应用程序的不间断操作,即使一部分基础设施出现故障。
总结
Kubernetes 使得应用的启动、迁移、部署变得简单又安全。
不必担心应用迁移后工作出现问题,也不用担心一台服务器无法应付突发的用户量。
需要注意的是,你的应用最好使用微服务架构进行开发,因为微服务应用比单体应用更适合做容器化。不要为了单纯的使用 Kubernetes 而引入,要看你的系统规模是否值得去用,否则可能适得其反,毕竟 Kubernetes 的学习是需要一定成本。
接下来我们就来了解下 Kubernetes 的架构和具体的相关概念吧。
k8s架构
Kubernetes 项目依托着 Borg 项目的理论优势,确定了一个如下图所示的全局架构图:
从上面我们可以看出 Kubernetes 由 Master 和 Node 两种节点组成,这两种角色分别对应着控制节点和工作节点(可以理解为老板和员工)。
其中 Master 节点由三个独立的组件组成,它们分别是负责整个集群通信的 API 服务的 kube-apiserver
、负责容器调度的 kube-scheduler
以及负责维护集群状态的 kube-controller-manager
组件。整个集群的数据都是通过 kube-apiserver 保存到 etcd 数据库中的,而其他所有组件的通信也都是通过 kube-apiserver 和 etcd 数据库进行通信的,都不会直接和 etcd 进行通信。
工作节点上最核心的组件就是 kubelet
,当然还有底层的容器运行时,比如 Docker。
其中 kubelet 就是主要来实现和底层的容器运行时进行通信的,这个通信的过程也被 Kubernetes 抽象成了一个 CRI
(Container Runtime Interface)的远程调用接口,这个接口里面定义了容器运行时的所有标准操作,比如创建容器、删除容器等等。所以对于 Kubernetes 来说他根本不关心你部署的到底是什么容器运行时,只要你这个容器运行时可以实现 CRI 接口就可以被 Kubernetes 来管理。
kubelet 的另外一个重要功能就是调用网络插件(CNI)和存储插件(CSI)为容器配置网络和存储功能。同样的 kubelet 也是把这两个重要功能通过接口暴露给外部了,所以如果我们想要实现自己的网络插件,只需要使用 CNI 就可以很方便的对接到 Kubernetes 集群当中去。
可能下面的架构图看上去更清晰一些:
k8s组件
上面我介绍了 Kubernetes 集群的整体架构,下面我们再来更加详细的了解下这些组件的功能。
kube-apiserver
API Server 提供了资源对象的唯一操作入口,其它所有组件都必须通过它提供的 API 来操作资源数据。
只有 API Server 会与 etcd 进行通信,其它模块都必须通过 API Server 访问集群状态。
API Server 作为 Kubernetes 系统的入口,封装了核心对象的增删改查操作。
API Server 以 RESTFul 接口方式提供给外部客户端和内部组件调用,API Server 再对相关的资源数据(全量查询 + 变化监听
)进行操作,以达到实时完成相关的业务功能。
以 API Server 为 Kubernetes 入口的设计主要有以下好处:
- 保证了集群状态访问的安全
- API Server 隔离了集群状态访问和后端存储实现,这样 API Server 状态访问的方式不会因为后端存储技术 Etcd 的改变而改变,让后端存储方式选择更加灵活,方便了整个架构的扩展。
kube-Controller Manager
Controller Manager 用于实现 Kubernetes 集群故障检测和恢复的自动化工作。主要负责执行各种控制器:
- Replication Controller:主要是定期关联 Replication Controller (RC) 和 Pod,以保证集群中一个 RC (一种资源对象) 所关联的 Pod 副本数始终保持为与预设值一致。
- Node Controller:Kubelet 在启动时会通过 API Server 注册自身的节点信息,并定时向 API Server 汇报状态信息。API Server 在接收到信息后将信息更新到 Etcd 中。Node Controller 通过 API Server 实时获取 Node 的相关信息,实现管理和监控集群中的各个 Node 节点的相关控制功能。
- ResourceQuota Controller:资源配额管理控制器用于确保指定的资源对象在任何时候都不会超量占用系统上物理资源。
- Namespace Controller:用户通过 API Server 可以创建新的 Namespace 并保存在 Etcd 中,Namespace Controller 定时通过 API Server 读取这些 Namespace 信息来操作 Namespace。比如:Namespace 被 API 标记为优雅删除,则将该 Namespace 状态设置为 Terminating 并保存到 Etcd 中。同时 Namespace Controller 删除该 Namespace 下的 ServiceAccount、Deployment、Pod 等资源对象。
- Service Account Controller:服务账号控制器主要在命名空间内管理 ServiceAccount,以保证名为 default 的 ServiceAccount 在每个命名空间中存在。
- Token Controller:令牌控制器作为 Controller Manager 的一部分,主要用作:监听 serviceAccount 的创建和删除动作以及监听 secret 的添加、删除动作。
- Service Controller:服务控制器主要用作监听 Service 的变化。比如:创建的是一个 LoadBalancer 类型的 Service,Service Controller 则要确保外部的云平台上对该 Service 对应的 LoadBalancer 实例被创建、删除以及相应的路由转发表被更新。
- Endpoint Controller:Endpoints 表示了一个 Service 对应的所有 Pod 副本的访问地址,而 Endpoints Controller 是负责生成和维护所有 Endpoints 对象的控制器。Endpoint Controller 负责监听 Service 和对应的 Pod 副本的变化。定期关联 Service 和 Pod (关联信息由 Endpoint 对象维护),以保证 Service 到 Pod 的映射总是最新的。
kube-scheduler
Scheduler 是负责整个集群的资源调度的,主要的职责如下所示:
- 主要用于收集和分析当前 Kubernetes 集群中所有 Node 节点的资源 (包括内存、CPU 等) 负载情况,然后依据资源占用情况分发新建的 Pod 到 Kubernetes 集群中可用的节点
- 实时监测 Kubernetes 集群中未分发和已分发的所有运行的 Pod
- 实时监测 Node 节点信息,由于会频繁查找 Node 节点,所以 Scheduler 同时会缓存一份最新的信息在本地
- 在分发 Pod 到指定的 Node 节点后,会把 Pod 相关的 Binding 信息写回 API Server,以方便其它组件使用
kubelet
kubelet 是负责容器真正运行的核心组件,主要的职责如下所示:
负责 Node 节点上 Pod 的创建、修改、监控、删除等全生命周期的管理
定时上报本地 Node 的状态信息给 API Server
kubelet 是 Master 和 Node 之间的桥梁,接收 API Server 分配给它的任务并执行
kubelet 通过 API Server 间接与 Etcd 集群交互来读取集群配置信息
kubelet 在 Node 上做的主要工作具体如下:
- 设置容器的环境变量、给容器绑定 Volume、给容器绑定 Port、根据指定的 Pod 运行一个单一容器、给指定的 Pod 创建 Network 容器
- 同步 Pod 的状态
- 在容器中运行命令、杀死容器、删除 Pod 的所有容器
kube-proxy
特别注意这个组件。
==kube-proxy 是为了解决外部网络能够访问集群中容器提供的应用服务而设计的。==
Proxy 运行在每个Node 上。
每创建一个 Service,kube-proxy 就会从 API Server 获取 Services 和 Endpoints 的配置信息,然后根据其配置信息在 Node 上启动一个 Proxy 的进程并监听相应的服务端口。
当接收到外部请求时,kube-proxy 会根据 Load Balancer 将请求分发到后端正确的容器处理。
kube-proxy 不但解决了同一宿主机相同服务端口冲突的问题,还提供了 Service 转发服务端口对外提供服务的能力。
kube-proxy 后端使用随机、轮循
等负载均衡算法进行调度。
kubectl
Kubectl 是 Kubernetes 的集群管理命令行客户端工具集。通过 Kubectl 命令对 API Server 进行操作,API Server 响应并返回对应的命令结果,从而达到对 Kubernetes 集群的管理。
核心资源对象
上面我们都是在架构层面了解 Kubernetes,但是似乎没有发现关于容器的说明,Kubernetes 作为容器编排引擎,那么他是怎么去对容器进行编排的呢?在 Kubernetes 集群中抽象了很多集群内部的资源对象,我们可以通过这些资源对象去操作容器的编排工作。
Pod
Pod 是一组紧密关联的容器集合
,它们共享 PID、IPC、Network 和 UTS namespace,是Kubernetes 调度的基本单位
。Pod 的设计理念是支持多个容器在一个 Pod 中共享网络和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务。我们知道容器本质上就是进程,那么 Pod 实际上就是进程组了,只是这一组进程是作为一个整体来进行调度的。
🚩
在 Kubernetes 中,所有资源对象都使用资源清单(yaml或json)来定义,比如我们可以定义一个简单的 nginx 服务,它包含一个镜像为 nginx 的容器:(nginx-pod.yaml)
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
spec: #注意,这里的spec就相当于是一个清单,规范,细则。
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
定义了这样一个资源清单文件后,我们就可以利用上面我们提到的 Kubectl 工具将这个 Pod 创建到 Kubernetes 集群中:
kubectl apply -f nginx-pod.yaml
Pod 在 Kubernetes 集群中被创建的基本流程如下所示:
- 用户通过 REST API 创建一个 Pod
- apiserver 将其写入 etcd
- scheduluer 检测到未绑定 Node 的 Pod,开始调度并更新 Pod 的 Node 绑定
- kubelet 检测到有新的 Pod 调度过来,通过 container runtime 运行该 Pod
- kubelet 通过 container runtime 取到 Pod 状态,并更新到 apiserver 中
🚩 sandbox容器
我们的定义了一个pod,比如说是nginx的pod,那么这个pod里面只有一个image,这个image就是nginx的image,但事实上,kubernetes 在起这个pod的时候,它并不是只起一个容器的,它是起2个容器的,其中一个容器叫sandbox。
比如说CRI的接口,事实上都是2部分,一部分是对sandox的操作,一部分是对user container的操作。那这个容器相当于kubernetes出厂自带了一个叫做pase
的这样一个image,它起sandbox container的时候就是去先起那个image的pause,这个pause里面就1条命令叫sleep infality,就是说这个镜像一旦运行起来,它不做任何事情,就直接sleep掉了。那sleep掉了,就意味着这个镜像非常小,而且它不需要cpu资源,而且极度稳定,它不会crash,不会oom,也不会有空指针。
所以这样的话,它的目的是什么呢?就需要一个非常稳定而精简的,小而精的这样一个不消耗资源的基础镜像,那么这个基础镜像是干什么的呢?
任何的容器在运行的时候,必须要有一个独立的网络namesapce,所以它会先起sandbox container,这个sandbox container,你可以把它理解为一个永远不会退出的进程。然后接下来它会creat network namespace,然后把这个sandbox进程和这个namespace进程相关,然后所有的网络配置都是配置在sandbox container的namespace的,那么当所有的网路setup完成的时候,它才会去起主container。
那起主container的时候,为什么需要这样呢?因为你想:
第一点:你的主container启动的时候就需要网络,你可能要去拉一些包,那么就意味着你的主container启动之前网络一定是要先配好的,所以一定要有个网路的预加载;
第二点:网络的这个namesapce是要和跟进程绑定的,那么假设说你主container 绑了网络namseapce,那么你主container有可能panic,你写代码有可能空指针啊,有可能内存泄露啊,那么一重启,整个网络的setup都丢了,那么这个pod就不通了,有可能你要重新setup网络。
所以基于这个考虑,kubernrtes在起pod的时候,它会先起一个sandbox,沙箱。
Label
Label 标签在 Kubernetes 资源对象中使用很多,也是非常重要的一个属性,Label 是识别 Kubernetes 对象的标签,以 key/value
的方式附加到对象上(key最长不能超过63字节,value 可以为空,也可以是不超过253字节的字符串)。
上面我们定义的 Nginx 的 Pod 就添加了一个 app=nginx
的 Label 标签。Label 不提供唯一性,并且实际上经常是很多对象(如Pods)都使用相同的 Label 来标志具体的应用。Label 定义好后其他对象可以使用 Label Selector
来选择一组相同 Label 的对象(比如 Service 用 Label 来选择一组 Pod)。Label Selector 支持以下几种方式:
- 等式,如
app=nginx
和env!=production
- 集合,如
env in (production, qa)
- 多个 Label(它们之间是
AND
关系),如app=nginx,env=test
Namespace
Namespace 是对一组资源和对象的抽象集合,比如可以用来将系统内部的对象划分为不同的项目组或用户组。 常见的 Pods、Services、Deployments 等都是属于某一个 Namespace 的(默认是 default),比如上面我们的 Nginx Pod 没有指定 namespace,则默认就在 default 命名空间下面,而 Node, PersistentVolumes 等资源则不属于任何 Namespace,是全局的。
注意:它并不是 Linux Namespace,二者没有任何关系,它只是 Kubernetes 划分不同工作空间的一个逻辑单位。
Deployment
我们说了 Pod 是 Kubernetes 集群中的最基本的调度单元,但是如果想要创建同一个容器的多份拷贝,需要一个一个分别创建出来么,那么能否将 Pods 划到一个逻辑组里面呢?Deployment 就是来管理 Pod 的资源对象。
Deployment 确保任意时间都有指定数量的 Pod“副本”在运行。如果为某个 Pod 创建了 Deployment 并且指定3个副本,它会创建3个 Pod,并且持续监控它们。如果某个 Pod 不响应,那么 Deployment 会替换它,始终保持总数为3。
如果之前不响应的 Pod 恢复了,现在就有4个 Pod 了,那么 Deployment 会将其中一个终止保持总数为3。如果在运行中将副本总数改为5,Deployment 会立刻启动2个新 Pod,保证总数为5。
当创建 Deployment 时,需要指定两个东西:
- Pod 模板:用来创建 Pod 副本的模板
- Label 标签:Deployment 需要监控的 Pod 的标签。
现在已经创建了 Pod 的一些副本,那么这些副本上如何进行负载呢?如何把这些 Pod 暴露出去呢?这个时候我们就需要用到 Service 这种资源对象了。
注意:
- Deployment表示用户对 Kubernetes 集群的一次更新操作。
- Deployment是一个比 RS 应用模式更广的 API 对象,可以是创建一个新的应用,更新一个已存在的应用,也可以是滚动升级一个应用。
- 滚动升级一个服务,实际是创建一个新的 RS,然后逐渐将新 RS 中副本数增加到理想状态,将旧 RS 中的副本数减小到 0 的复合操作。这样一个复合操作用一个 RS 是不太好描述的,所以用一个更通用的 Deployment 来描述。以 Kubernetes 的发展方向,未来对所有长期伺服型的的业务的管理,都会通过 Deployment 来管理。
对于无状态应用,我们最常用的对象就是deployment对象了。
它确保了:
第一:我定义好了滚动升级的策略,那么你在做版本升级的时候,我可以做一个对用户没有影响,不会让service宕机的这样一个滚动升级。
第二:**它会建一个副本集(replicaset)**,然后确保说我一个应用一定要有多少个实例。那么当某些实例被删掉的时候,我会补一个新的出来,那么这是deployment的一个作用。
🚩
deployment对象属性
你可以看到,kubernetes给我们添加了很多很多附加的属性。那么这些属性都是默认值。就是有些东西你不填的话,那么kubernetes就会帮你填上默认值。所以我们来理解下,deployment做了些什么。
它加了一个最重要的部分叫做strategy,那么这个strategy叫做type: RollingUpdate
的strategy。其实这个strategy就是kubernetes为deployment定义的默认升级策略,升级策略的类型是:滚动升级(RollingUpdate)
如何滚动升级呢?maxSurge: 25%
一次升级25%,maxUnavailable: 25%
最多不可用25%。(也就是说如果他发现有25%的实例已经not ready了,不能用了,那么它的这个升级就要停在那里)。这个目的是什么呢?就是说有时候我们升级版本的时候,新版本可能有bug,你可能跑起来以后,出问题了,跑着跑着它变的不能接收流量了,已经不能提供服务了。那么你不能继续升级了,继续升级整个业务就故障了。那通过这种方式就如果有25%的实例都不能提供服务了,那么它就会暂停升级。
好,这是第一个部分。
第二个部分,pod template也加了很多属性。
刚才是spec部分,我们可以看到一个简单的spec被添加了很多另外的属性。
之前讲过,任何对象都是有status,status是controller干完活,然后controller填上去的,这是这个对象的真实状态。
所以我们接下来看一下status这部分,可以看到,status里面有个conditions。conditions相当于是这个对象的状态的一些细节。
Service
Service 是应用服务的抽象,通过 labels 为应用提供负载均衡和服务发现。匹配 labels的 Pod IP和端口列表组成 endpoints,由 Kube-proxy 负责将服务 IP 负载均衡到这些 endpoints 上。
每个默认类型 Service 都会自动分配一个 cluster IP(仅在集群内部可访问的虚拟地址)和 DNS名,其他容器可以通过该地址或 DNS 来访问服务,而不需要了解后端容器的运行。
RC、RS 和 Deployment 只是保证了支撑服务的微服务 Pod 的数量,但是没有解决如何访问这些服务的问题。一个 Pod 只是一个运行服务的实例,随时可能在一个节点上停止,在另一个节点以一个新的 IP 启动一个新的Pod,因此不能以确定的 IP 和端口号提供服务。
要稳定地提供服务需要服务发现和负载均衡能力。
服务发现完成的工作,是针对客户端访问的服务,找到对应的的后端服务实例。在 Kubernetes 集群中,客户端需要访问的服务就是 Service 对象。每个 Service 会对应一个集群内部有效的虚拟 IP,集群内部通过虚拟 IP 访问一个服务。
在Kubernetes 集群中微服务的负载均衡是由 Kube-proxy 实现的。Kube-proxy 是 Kubernetes 集群内部的负载均衡器。它是一个分布式代理服务器,在 Kubernetes 的每个节点上都有一个,这一设计体现了它的伸缩性优势,需要访问服务的节点越多,提供负载均衡能力的 Kube-proxy 就越多,高可用节点也随之增多。与之相比,我们平时在服务器端使用反向代理作负载均衡,还要进一步解决反向代理的高可用问题。
🚩 QA
==Q :对运维来讲,部署了2个服务以后,他们之间可以直接通信吗?==
A:可以直接通信。service本身从模型上来讲,它就是描述一个负载均衡的,就相当于我刚才给大家展示过一点点,你通过service selector来决定说我select哪一堆pod,我可以定义说我在哪个端口上expose哪个service。那最终的实现是通过比如说对labels本身来讲,它是配了ipvs,iptable,或者通过ebpf去配了这个负载均衡的规则,那么2个服务之间直接通信,A服务要调用B服务的时候,就走了这些转发规则,然后请求就过去了。
==Q:service的 ip是某个机器的ip吗?外部可访问吗?会不会和其中一个xx重复?==
A:pod的ip和service的ip是不同的range。
1、那pod的ip是通过你的CNI的pliugin去配置的,CNI的plugin在setup的时候会去配说我的xxxx是什么。
2、那么service ip或者叫cluster ip,就是这里说的虚ip,它是怎么分配的呢?是apiserver在启动的时候,它会配一个cluster ip range,那所有service ip都是从那个range里面去配的。
那么它是某个机器的ip吗?这个 其实要去看你是什么样的plugin。
那么如果是iptables的plugin,那么这个ip是不配置在任何device上的。它其实就是配linux kernel里的一些转发规则,所以这一块又涉及到Linux kernel这一块的讲解了,就是要去将linux内核协议栈处理。
那么如果是ipvs的话,它是要绑定到本机的一个xxx device上面的,叫ipvs里面的一个xx device。
但是这些ip对外都是不可路由的,也就是数说你从外部是不可访问的。
那么外部想如何访问集群内的一个服务呢?有两种方法:
一种方式:比方说你有一个成熟的cloud,比如说很多企业都有自己的负载均衡器,那么这些复杂均衡器要跟kubernetes做集成,那么怎么集成呢?如果你是一个标准的cloud,那么cloud provide就提供了一个这样的集成。有可能你不是一个标准的cloud,那么你可能自己要写service controller。
另一种方式:就是通过NodePort,就是节点端口,service有多种类型。这个我们会在服务发现的时候讲。那么,NodePort就相当于在起一个service的时候,它会在一个机器上开一个端口,那么你在访问这个端口的时候,它就会把这个请求转到backend pod里面去。
其它资源对象
Node
- Node 是 Pod 真正运行的主机,可以是物理机,也可以是虚拟机。
- Node 对象用来描述节点的计算资源:
- Capacity:计算能力,代表当前节点的所有资源;
- Allocatable:可分配资源,代表当前节点的可分配资源,通常是所有资源-预留资源-已分配资源;那么这个信息是给谁消费的呢?是scheduler消费的。scheduler会读取这个信息,然后知道每个节点的资源使用情况,那它做调度的时候就可以做正确决策。
- Kubelet 会按固定频率检查节点健康状态并上报给 APIServer,该状态会记录在 Node 对象的status 中。
ReplicaSet
- Pod 描述的是具体的应用实例,当 Pod 被删除后,就彻底消失了;
- 为保证应用的高可用,引入副本集来确保应用的总副本数永远与期望一致;
- 若某个 Pod 隶属于某个副本集,若该 Pod 被删除,则 ReplicaSet Controller 会发现当前运行的副本数量与用户的期望不一致,则会创建新的 Pod。
那你想,如果我是一个服务的提供商,万一我的pod被建出来后,被别人给误删了,那我的服务就宕了。所以,这个时候,我的应用要确保高可用的,那确保高可用,要怎么保证呢?我要去定义另外一个对象。为了应对不同的业务场景,我们应该组合不同的对象来完成这一目标,那我就通过副本集。
所谓的副本集,其实它本质上就是在pod的spec上面包了一层,它把pod的spec做为template的spec,作为一个pod的模板,在上面就定义了一下我要几个replicaset。那么kubernetes会去确保说,总会有那么多副本,能够满足你的需求。
k get rs -oyaml|less
关于我
我的博客主旨:
- 排版美观,语言精炼;
- 文档即手册,步骤明细,拒绝埋坑,提供源码;
- 本人实战文档都是亲测成功的,各位小伙伴在实际操作过程中如有什么疑问,可随时联系本人帮您解决问题,让我们一起进步!
🍀 微信二维码
x2675263825 (舍得), qq:2675263825。
🍀 微信公众号
《云原生架构师实战》
🍀 个人博客站点
http://47.97.48.237/ (即将上线域名:onedayxyy.cn)
🍀 语雀
https://www.yuque.com/xyy-onlyone
🍀 csdn
https://blog.csdn.net/weixin_39246554?spm=1010.2135.3001.5421
🍀 知乎
https://www.zhihu.com/people/foryouone
最后
好了,关于本次就到这里了,感谢大家阅读,最后祝大家生活快乐,每天都过的有意义哦,我们下期见!