解释这个参数之前,先来回忆一下K8S滚动升级的步骤:
1K8S首先启动新的POD
2S等待新的POD进入Ready状态
3K8S创建Endpoint,将新的POD纳入负载均衡
4K8S移除与老POD相关的Endpoint,并且将老POD状态设置为Terminating,此时将不会有新的请求到达老POD
5同时 K8S 会给老POD发送SIGTERM信号,并且等待 terminationGracePeriodSeconds 这么长的时间。(默认为30秒)
6超过terminationGracePeriodSeconds等待时间后, K8S 会强制结束老POD
看到这里,我想大家应该明白了,terminationGracePeriodSeconds 就是K8S给你程序留的最后的缓冲时间,来处理关闭之前的 *** 作。
或许你会问,如果不配置或者不处理这个,有什么问题?
假象一下下面的场景:
既然知道可能带来的问题了,那么怎么解决呢?
明白这个参数的意义,那就很好解决了。
>昨天不知道说明原因,测试环境的物理机挂了,安装k8s的3台虚拟机正好全在这台物理机上面,现在要把他们全部启动起来,安装的时候好像没有相关的步骤,今天研究一下手动重启。
报错:The connection to the server 101001236:6443 was refused
很明显apiserver没有起来,但是apiserver安装的时候是以容器的方式安装的
显示一个容器也没起来,完全不知道咋整,搜索k8s重启,看了好几篇文章,有的文章居然是kubeadm init,这txx还有什么好说的呢。不过民间的高手也是很多的,如下:
静态pod可以直接被kubelet启动,那很有可能是kubelet没有正确启动,尝试如下:每台机器上都要 *** 作
然后用 docker ps 查看,可以看到master节点上的很多k8s容器已经启动起来了,但是worker node上的容器依然没有启动,用 kubectl get nodes ,看到node的状态还是notReady,那就很有可能是防火墙的问题了,直接关闭防火墙,看到worker node上的容器也起来了。
等待所有的calico pod启动完毕,node状态就变成ready了。
但是之前启动的 nignx pod 都不存在了,原因可能是:etcd的启动方式也是容器化的,重启后etcd内的数据被初始化了。
---本来怀疑是 systemctl daemon-reload 命令造成的,但是,今天这台服务器又重启了,我又试了一遍,不执行 systemctl daemon-reload 命令是无法重启k8s的。
---但是今天重启k8s,完成之后,昨天新建的2个pod仍然是存在的,那很有可能是我昨天不熟悉流程参杂了误 *** 作,但是现在也想不起来了,就暂时告一段落了,后面遇到问题再说吧。
适用版本: Kubernetes v122 [stable]
一个完整描述的目标并不是一个完整的对象,仅包括能体现用户意图的字段和值。 该目标(intent)可以用来创建一个新对象, 也可以通过服务器来实现与现有对象的合并。
系统支持多个应用者(appliers)在同一个对象上开展协作。
“字段管理(field management)”机制追踪对象字段的变化。 当一个字段值改变时,其所有权从当前管理器(manager)转移到施加变更的管理器。 当尝试将新配置应用到一个对象时,如果字段有不同的值,且由其他管理器管理, 将会引发冲突。 冲突引发警告信号:此 *** 作可能抹掉其他协作者的修改。 冲突可以被刻意忽略,这种情况下,值将会被改写,所有权也会发生转移。
当你从配置文件中删除一个字段,然后应用这个配置文件, 这将触发服务端应用检查此字段是否还被其他字段管理器拥有。 如果没有,那就从活动对象中删除该字段;如果有,那就重置为默认值。 该规则同样适用于 list 或 map 项目。
服务器端应用既是原有 kubectl apply 的替代品, 也是控制器发布自身变化的一个简化机制。
如果你启用了服务器端应用,控制平面就会跟踪被所有新创建对象管理的字段。
用户管理字段这件事,在服务器端应用的场景中,意味着用户依赖并期望字段的值不要改变。 最后一次对字段值做出断言的用户将被记录到当前字段管理器。 这可以通过发送 POST、 PUT、 或非应用(non-apply)方式的 PATCH 等命令来修改字段值的方式实现, 或通过把字段放在配置文件中,然后发送到服务器端应用的服务端点的方式实现。 当使用服务器端应用,尝试着去改变一个被其他人管理的字段, 会导致请求被拒绝(在没有设置强制执行时,参见冲突)。
如果两个或以上的应用者均把同一个字段设置为相同值,他们将共享此字段的所有权。 后续任何改变共享字段值的尝试,不管由那个应用者发起,都会导致冲突。 共享字段的所有者可以放弃字段的所有权,这只需从配置文件中删除该字段即可。
字段管理的信息存储在 managedFields 字段中,该字段是对象的 metadata 中的一部分。
服务器端应用创建对象的简单示例如下:
上述对象在 metadatamanagedFields 中包含了唯一的管理器。 管理器由管理实体自身的基本信息组成,比如 *** 作类型、API 版本、以及它管理的字段。
Note: 该字段由 API 服务器管理,用户不应该改动它。
不过,执行 Update *** 作修改 metadatamanagedFields 也是可实现的。 强烈不鼓励这么做,但当发生如下情况时, 比如 managedFields 进入不一致的状态(显然不应该发生这种情况), 这么做也是一个合理的尝试。
managedFields 的格式在 API 文档中描述。
管理器识别出正在修改对象的工作流程(在冲突时尤其有用), 管理器可以通过修改请求的参数 fieldManager 指定。 虽然 kubectl 默认发往 kubectl 服务端点,但它则请求到应用的服务端点(apply endpoint)。 对于其他的更新,它默认的是从用户代理计算得来。
此特性涉及两类 *** 作,分别是 Apply (内容类型为 application/apply-patch+yaml 的 PATCH 请求) 和 Update (所有修改对象的其他 *** 作)。 这两类 *** 作都会更新字段 managedFields,但行为表现有一点不同。
Note:
不管你提交的是 JSON 数据还是 YAML 数据, 都要使用 application/apply-patch+yaml 作为 Content-Type 的值。
所有的 JSON 文档 都是合法的 YAML。
例如,在冲突发生的时候,只有 apply *** 作失败,而 update 则不会。 此外,apply *** 作必须通过提供一个 fieldManager 查询参数来标识自身, 而此查询参数对于 update *** 作则是可选的。 最后,当使用 apply 命令时,你不能在应用中的对象中持有 managedFields。
一个包含多个管理器的对象,示例如下:
在这个例子中, 第二个 *** 作被管理器 kube-controller-manager 以 Update 的方式运行。 此 update 更改 data 字段的值, 并使得字段管理器被改为 kube-controller-manager。
如果把 update *** 作改为 Apply,那就会因为所有权冲突的原因,导致 *** 作失败。
由服务器端应用实现的合并策略,提供了一个总体更稳定的对象生命周期。 服务器端应用试图依据负责管理它们的主体来合并字段,而不是根据值来否决。 这么做是为了多个主体可以更新同一个对象,且不会引起意外的相互干扰。
当用户发送一个“完整描述的目标”对象到服务器端应用的服务端点, 服务器会将它和活动对象做一次合并,如果两者中有重复定义的值,那就以配置文件的为准。 如果配置文件中的项目集合不是此用户上一次 *** 作项目的超集, 所有缺少的、没有其他应用者管理的项目会被删除。 关于合并时用来做决策的对象规格的更多信息,参见 sigsk8sio/structured-merge-diff
Kubernetes 116 和 117 中添加了一些标记, 允许 API 开发人员描述由 list、map、和 structs 支持的合并策略。 这些标记可应用到相应类型的对象,在 Go 文件或在 CRD 的 OpenAPI 的模式中定义:
若未指定 listType,API 服务器将 patchMergeStrategy=merge 标记解释为 listType=map 并且视对应的 patchMergeKey 标记为 listMapKey 取值。
atomic 列表类型是递归的。
这些标记都是用源代码注释的方式给出的,不必作为字段标签(tag)再重复。
在极少的情况下,CRD 或者内置类型的作者可能希望更改其资源中的某个字段的 拓扑配置,同时又不提升版本号。 通过升级集群或者更新 CRD 来更改类型的拓扑信息与更新现有对象的结果不同。 变更的类型有两种:一种是将字段从 map/set/granular 更改为 atomic, 另一种是做逆向改变。
当 listType、mapType 或 structType 从 map/set/granular 改为 atomic 时,现有对象的整个列表、映射或结构的属主都会变为这些类型的 元素之一的属主。这意味着,对这些对象的进一步变更会引发冲突。
当一个列表、映射或结构从 atomic 改为 map/set/granular 之一 时,API 服务器无法推导这些字段的新的属主。因此,当对象的这些字段 再次被更新时不会引发冲突。出于这一原因,不建议将某类型从 atomic 改为 map/set/granular。
以下面的自定义资源为例:
在 specdata 从 atomic 改为 granular 之前,manager-one 是 specdata 字段及其所包含字段(key1 和 key2)的属主。 当对应的 CRD 被更改,使得 specdata 变为 granular 拓扑时, manager-one 继续拥有顶层字段 specdata(这意味着其他管理者想 删除名为 data 的映射而不引起冲突是不可能的),但不再拥有 key1 和 key2。因此,其他管理者可以在不引起冲突的情况下更改 或删除这些字段。
默认情况下,服务器端应用把自定义资源看做非结构化数据。 所有的键值(keys)就像 struct 的字段一样被处理, 所有的 list 被认为是原子性的。
如果自定义资源定义(Custom Resource Definition,CRD)定义了一个 模式, 它包含类似以前“合并策略”章节中定义过的注解, 这些注解将在合并此类型的对象时使用。
控制器的开发人员可以把服务器端应用作为简化控制器的更新逻辑的方式。 读-改-写 和/或 patch 的主要区别如下所示:
强烈推荐:设置控制器在冲突时强制执行,这是因为冲突发生时,它们没有其他解决方案或措施。
除了通过冲突解决方案提供的并发控制, 服务器端应用提供了一些协作方式来将字段所有权从用户转移到控制器。
最好通过例子来说明这一点。 让我们来看看,在使用 Horizo ntalPodAutoscaler 资源和与之配套的控制器, 且开启了 Deployment 的自动水平扩展功能之后, 怎么安全的将 replicas 字段的所有权从用户转移到控制器。
假设用户定义了 Deployment,且 replicas 字段已经设置为期望的值:
application/ssa/nginx-deploymentyaml
并且,用户使用服务器端应用,像这样创建 Deployment:
然后,为 Deployment 启用 HPA,例如:
现在,用户希望从他们的配置中删除 replicas,所以他们总是和 HPA 控制器冲突。 然而,这里存在一个竟态: 在 HPA 需要调整 replicas 之前会有一个时间窗口, 如果在 HPA 写入字段成为所有者之前,用户删除了replicas, 那 API 服务器就会把 replicas 的值设为 1, 也就是默认值。 这不是用户希望发生的事情,即使是暂时的。
这里有两个解决方案:
首先,用户新定义一个只包含 replicas 字段的配置文件:
application/ssa/nginx-deployment-replicas-onlyyaml
用户使用名为 handover-to-hpa 的字段管理器,应用此配置文件。
在此时间点,用户可以从配置文件中删除 replicas 。
application/ssa/nginx-deployment-no-replicasyaml
注意,只要 HPA 控制器为 replicas 设置了一个新值, 该临时字段管理器将不再拥有任何字段,会被自动删除。 这里不需要执行清理工作。
通过在配置文件中把一个字段设置为相同的值,用户可以在他们之间转移字段的所有权, 从而共享了字段的所有权。 当用户共享了字段的所有权,任何一个用户可以从他的配置文件中删除该字段, 并应用该变更,从而放弃所有权,并实现了所有权向其他用户的转移。
由服务器端应用实现的冲突检测和解决方案的一个结果就是, 应用者总是可以在本地状态中得到最新的字段值。 如果得不到最新值,下次执行应用 *** 作时就会发生冲突。 解决冲突三个选项的任意一个都会保证:此应用过的配置文件是服务器上对象字段的最新子集。
这和客户端应用(Client Side Apply) 不同,如果有其他用户覆盖了此值, 过期的值被留在了应用者本地的配置文件中。 除非用户更新了特定字段,此字段才会准确, 应用者没有途径去了解下一次应用 *** 作是否会覆盖其他用户的修改。
另一个区别是使用客户端应用的应用者不能改变他们正在使用的 API 版本,但服务器端应用支持这个场景。
客户端应用方式时,用户使用 kubectl apply 管理资源, 可以通过使用下面标记切换为使用服务器端应用。
默认情况下,对象的字段管理从客户端应用方式迁移到 kubectl 触发的服务器端应用时,不会发生冲突。
Caution:
保持注解 last-applied-configuration 是最新的。 从注解能推断出字段是由客户端应用管理的。 任何没有被客户端应用管理的字段将引发冲突。
举例说明,比如你在客户端应用之后, 使用 kubectl scale 去更新 replicas 字段, 可是该字段并没有被客户端应用所拥有, 在执行 kubectl apply --server-side 时就会产生冲突。
此 *** 作以 kubectl 作为字段管理器来应用到服务器端应用。 作为例外,可以指定一个不同的、非默认字段管理器停止的这种行为,如下面的例子所示。 对于 kubectl 触发的服务器端应用,默认的字段管理器是 kubectl。
如果你用 kubectl apply --server-side 管理一个资源, 可以直接用 kubectl apply 命令将其降级为客户端应用。
降级之所以可行,这是因为 kubectl server-side apply 会保存最新的 last-applied-configuration 注解。
此 *** 作以 kubectl 作为字段管理器应用到服务器端应用。 作为例外,可以指定一个不同的、非默认字段管理器停止这种行为,如下面的例子所示。 对于 kubectl 触发的服务器端应用,默认的字段管理器是 kubectl。
启用了服务器端应用特性之后, PATCH 服务端点接受额外的内容类型 application/apply-patch+yaml。 服务器端应用的用户就可以把 YAMl 格式的 部分定义对象(partially specified objects)发送到此端点。 当一个配置文件被应用时,它应该包含所有体现你意图的字段。
可以从对象中剥离所有 managedField, 实现方法是通过使用 MergePatch、 StrategicMergePatch、 JSONPatch、 Update、以及所有的非应用方式的 *** 作来覆盖它。 这可以通过用空条目覆盖 managedFields 字段的方式实现。以下是两个示例:
这一 *** 作将用只包含一个空条目的列表覆写 managedFields, 来实现从对象中整个的去除 managedFields。 注意,只把 managedFields 设置为空列表并不会重置字段。 这么做是有目的的,所以 managedFields 将永远不会被与该字段无关的客户删除。
在重置 *** 作结合 managedFields 以外其他字段更改的场景中, 将导致 managedFields 首先被重置,其他改变被押后处理。 其结果是,应用者取得了同一个请求中所有字段的所有权。
Caution: 对于不接受资源对象类型的子资源(sub-resources), 服务器端应用不能正确地跟踪其所有权。 如果你对这样的子资源使用服务器端应用,变更的字段将不会被跟踪。
参考链接:
>
Volume 提供了非常好的数据持久化方案,不过在可管理性上还有不足。
要使用 Volume,Pod 必须事先知道如下信息:
Pod 通常是由应用的开发人员维护,而 Volume 则通常是由存储系统的管理员维护。开发人员要获得上面的信息:
要么询问管理员。
要么自己就是管理员。
这样就带来一个管理上的问题:应用开发人员和系统管理员的职责耦合在一起了。如果系统规模较小或者对于开发环境这样的情况还可以接受。但当集群规模变大,特别是对于生成环境,考虑到效率和安全性,这就成了必须要解决的问题。
Kubernetes 给出的解决方案是什么 PersistentVolume (PV)和 PersistentVolumeClaim(PVC)。
PersistentVolume (PV) 是外部存储系统中的一块存储空间,由管理员创建和维护。与 Volume 一样,PV 具有持久性,生命周期独立于 Pod。
PersistentVolumeClaim (PVC) 是对 PV 的申请 (Claim)。PVC 通常由普通用户创建和维护。需要为 Pod 分配存储资源时,用户可以创建一个 PVC,指明存储资源的容量大小和访问模式(比如只读)等信息,Kubernetes 查找并提供满足条件的 PV。
有了 PersistentVolumeClaim,用户只需要告诉 Kubernetes 需要什么样的存储资源,而不必关心真正的空间从哪里分配,如何访问等底层细节信息。这些 Storage Provider 的底层信息交给管理员来处理,只有管理员才应该关心创建 PersistentVolume 的细节信息。
1、配置nfs
需要安装
k8s-master:nfs-server
k8s-node1:nfs-client
k8s-node2:nfs-client
所有节点安装nfs
在master节点创建共享目录
编辑exports文件
启动rpc和nfs(注意顺序)
作为准备工作,我们已经在 k8s-master 节点上搭建了一个 NFS 服务器,目录为 /nfsdata:
2、创建PV
下面创建一个 PV mypv,配置文件 nfs-pvyml 如下:
① capacity 指定 PV 的容量为 1G。
② accessModes 指定访问模式为 ReadWriteOnce,支持的访问模式有:
ReadWriteOnce:PV 能以 read-write 模式 mount 到单个节点。
ReadOnlyMany:PV 能以 read-only 模式 mount 到多个节点。
ReadWriteMany :PV 能以 read-write 模式 mount 到多个节点。
③ persistentVolumeReclaimPolicy 指定当 PV 的回收策略为 Recycle,支持的策略有:
Retain: 需要管理员手工回收。
Recycle:清除 PV 中的数据,效果相当于执行 rm -rf /thevolume/。
Delete: 删除 Storage Provider 上面的对应存储资源,例如 AWS EBS、GCE PD、Azure Disk、- OpenStack Cinder Volume 等。
④ storageClassName 指定 PV 的 class 为 nfs。相当于为 PV 设置了一个分类,PVC 可以指定 class 申请相应 class 的 PV。
⑤ 指定 PV 在 NFS 服务器上对应的目录。
创建 mypv:
STATUS 为 Available,表示 mypv 就绪,可以被 PVC 申请。
3、创建PVC
接下来创建 PVC mypvc,配置文件 nfs-pvcyml 如下:
部署pvc
4、创建pod
上面已经创建好了pv和pvc,pod中直接使用这个pvc即可
与使用普通 Volume 的格式类似,在 volumes 中通过 persistentVolumeClaim 指定使用 mypvc 申请的 Volume。
通过命令创建mypod:
在这里,可以尝试在任何一方删除文件,文件在两端都会消失;
当 PV 不再需要时,可通过删除 PVC 回收。未删除pvc之前 pv的状态是Bound
删除pod
删除pvc
再次查看pv的状态
删除pvc之后pv的状态变为Available,,此时解除绑定后则可以被新的 PVC 申请。
/nfsdata文件中的文件被删除了
因为 PV 的回收策略设置为 Recycle,所以数据会被清除,
但这可能不是我们想要的结果。如果我们希望保留数据,可以将策略设置为 Retain
虽然 mypv 中的数据得到了保留,但其 PV 状态会一直处于 Released,不能被其他 PVC 申请。为了重新使用存储资源,可以删除并重新创建 mypv。删除 *** 作只是删除了 PV 对象,存储空间中的数据并不会被删除。
PV 还支持 Delete 的回收策略,会删除 PV 在 Storage Provider 上对应存储空间。NFS 的 PV 不支持 Delete,支持 Delete 的 Provider 有 AWS EBS、GCE PD、Azure Disk、OpenStack Cinder Volume 等。
前面的例子中,我们提前创建了 PV,然后通过 PVC 申请 PV 并在 Pod 中使用,这种方式叫做静态供给(Static Provision)。
与之对应的是动态供给(Dynamical Provision),即如果没有满足 PVC 条件的 PV,会动态创建 PV。相比静态供给,动态供给有明显的优势:不需要提前创建 PV,减少了管理员的工作量,效率高。
基于NFS的PV动态供给(StorageClass)
静态:pod-->pvc-->pv
动态:pod -->pvc-->storageclass
去官网下载三个文件
这三个文件去网上下载 >
Kubernetes 是Google开源的分布式容器管理平台,是为了更方便的在服务器中管理我们的容器化应用。
Kubernetes 简称 K8S,为什么会有这个称号?因为K和S是 Kubernetes 首字母和尾字母,而K和S中间有八个字母,所以简称 K8S,加上 Kubernetes 比较绕口,所以一般使用简称 K8S。
Kubernetes 即是一款容器编排工具,也是一个全新的基于容器技术的分布式架构方案,在基于Docker的基础上,可以提供从 创建应用>应用部署>提供服务>动态伸缩>应用更新 一系列服务,提高了容器集群管理的便捷性。
大家可以先看一下,下面一张图,里面有我们的 mysql,redis,tomcat,nginx 等配置信息,如果我们想要安装里面的数据,我们需要一个一个手动安装,好像也可以,反正也就一个,虽然麻烦了一点,但也不耽误。
但是随着技术的发展和业务的需要,单台服务器已经不能满足我们日常的需要了,越来越多的公司,更多需要的是集群环境和多容器部署,那么如果还是一个一个去部署,运维恐怕要疯掉了,一天啥也不干就去部署机器了,有时候,可能因为某一个环节出错,要重新,那真的是吐血。。。。。,如下图所示:
如果我想要部署,以下几台机器:
如果要一个一个去部署,人都要傻掉了,这什么时候是个头,如果是某里巴的两万台机器,是不是要当场提交辞职信,所以 K8S 就是帮助我们来做这些事情的,方便我们对容器的管理和应用的自动化部署,减少重复劳动,并且能够自动化部署应用和故障自愈。
并且如果 K8S 对于微服务有很好的支持,并且一个微服务的副本可以跟着系统的负荷变化进行调整,K8S 内在的服务d性扩容机制也能够很好的应对突发流量。
Docker-Compose 是用来管理容器的,类似用户容器管家,我们有N多台容器或者应用需要启动的时候,如果手动去 *** 作,是非常耗费时间的,如果有了 Docker-Compose 只需要一个配置文件就可以帮我们搞定,但是 Docker-Compose 只能管理当前主机上的 Docker,不能去管理其他服务器上的服务。意思就是单机环境。
Docker Swarm 是由Docker 公司研发的一款用来管理集群上的Docker容器工具,弥补了 Docker-Compose 单节点的缺陷, Docker Swarm 可以帮助我们启动容器,监控容器的状态,如果容器服务挂掉会重新启动一个新的容器,保证正常的对外提供服务,也支持服务之间的负载均衡。而且这些东西 Docker-Compose 是不支持的,
Kubernetes 它本身的角色定位是和 Docker Swarm 是一样的,也就是说他们负责的工作在容器领域来说是相同的部分,当然也要一些不一样的特点, Kubernetes 是谷歌自己的产品,经过大量的实践和宿主机的实验,非常的成熟,所以 Kubernetes 正在成为容器编排领域的领导者,其 可配置性、可靠性和社区的广大支持,从而超越了 Docker Swarm ,作为谷歌的开源项目,它和整个谷歌的云平台协调工作。
在下图中,是K8S的一个集群,在这个集群中包含三台宿主机,这里的每一个方块都是我们的物理虚拟机,通过这三个物理机,我们形成了一个完整的集群,从角色划分,可以分为两种
打一个比较形象的比喻,我们可以把Pod理解成一个豆荚,容器就是里面的豆子,是一个共生体。
Pod里面到底装的是什么?
具体怎么部署Pod里面的容器,是按照我们项目的特性和资源的分配进行合理选择的。
pause容器:
Pause容器 全称infrastucture container(又叫infra)基础容器,作为init pod存在,其他pod都会从pause 容器中fork出来,这个容器对于Pod来说是必备的
一个Pod中的应用容器共享同一个资源:
在上图中如果没有 pause容器 ,我们的Nginx和Ghost,Pod内的容器想要彼此通信的话,都需要使用自己的IP地址和端口,才可以彼此进行访问,如果有 pause容器 ,对于整个Pod来说,我们可以看做一个整体,也就是我们的Nginx和Ghost直接使用localhost就可以进行访问了,他们唯一不同的就只是端口,这里面可能看着觉得比较简单,但其实是使用了很多网络底层的东西才实现的,感兴趣的小伙伴可以自行了解一下。
在 Kubernetes 中,每个Pod都会被分配一个单独的IP地址,但是Pod和Pod之间,是无法直接进行交互的,如果想要进行网络通信,必须要通过另外一个组件才能交流,也就是我们的 Service
Service 是服务的意思,在K8S中 Service 主要工作就是将多个不同主机上的Pod,通过 Service 进行连通,让Pod和Pod之间可以正常的通信
我们可以把 Service 看做一个域名,而相同服务的Pod集群就是不同的ip地址, Service 是通过 Label Selector 来进行定义的。
使用NodePort提供外部访问,只需要在每个Node上打开一个主机的真实端口,这样就可以通过Node的客户端访问到内部的Service。
Label 一般以 kv的方式附件在各种对象上,Label 是一个说明性的标签,它有着很重要的作用,我们在部署容器的时候,在哪些Pod进行 *** 作,都需要根据Label进行查找和筛选,我们可以理解Label是每一个Pod的别名,只有取了名称,作为K8S的Master主节点才能找到对应的Pod进行 *** 作。
用户通过 Kubectl 提交一个创建 Replication Controller 请求,这个请求通过 API Server 写入 etcd 中,这个时候 Controller Manager 通过 API Server 的监听到了创建的命名,经过它认真仔细的分析以后,发现当前集群里面居然还没有对应的Pod实例,赶紧根据 Replication Controller 模板定义造一个Pod对象,再通 过Api Server 写到我们 etcd 里面
到下面,如果被 Scheduler 发现了,好家伙不告诉我???,无业游民,这家伙一看就不是一个好人啊,它就会立即运行一个复杂的调度流程,为这个新的Pod选一个可以落户的Node,总算有个身份了,真是让人 *** 心,然后通过 API Server 将这个结果也写到etcd中,随后,我们的 Node 上运行的小管家 Kubelet 进程通过 API Server 检测到这个 新生的小宝宝——“Pod”,就会按照它,就会按照这个小宝宝的特性,启动这个Pod并任劳任怨的负责它的下半生,直到Pod的生命结束。
然后我们通过 Kubectl 提交一个新的映射到这个Pod的Service的创建请求, Controller Manager 会通过Label标签查询到相关联的Pod实例,生成Service的Endpoints的信息,并通过 API Server 写入到etcd中,接下来,所有 Node 上运行的Proxy进程通过 Api Server 查询并监听 Service对象 与其对应的 Endpoints 信息,建立一个软件方式的负载均衡器来实现 Service 访问到后端Pod的流量转发功能。
kube-proxy: 是一个代理,充当这多主机通信的代理人,前面我们讲过Service实现了跨主机、跨容器之间的网络通信,在技术上就是通过 kube-proxy 来实现的,service是在逻辑上对Pod进行了分组,底层是通过 kube-proxy 进行通信的
kubelet: 用于执行K8S的命令,也是K8S的核心命令,用于执行K8S的相关指令,负责当前Node节点上的Pod的创建、修改、监控、删除等生命周期管理,同时Kubelet定时“上报”本Node的状态信息到API Server里
etcd: 用于持久化存储集群中所有的资源对象,API Server提供了 *** 作 etcd的封装接口API,这些API基本上都是对资源对象的 *** 作和监听资源变化的接口
API Server : 提供资源对象的 *** 作入口,其他组件都需要通过它提供 *** 作的API来 *** 作资源数据,通过对相关的资源数据“全量查询”+ “变化监听”,可以实时的完成相关的业务功能。
Scheduler : 调度器,负责Pod在集群节点中的调度分配。
Controller Manager: 集群内部管理控制中心,主要是实现 Kubernetes 集群的故障检测和恢复的自动化工作。比如Pod的复制和移除,Endpoints对象的创建和更新,Node的发现、管理和状态监控等等都是由 Controller Manager 完成。
到这里K8S的基本情况我们就讲解完毕了,有喜欢的小伙伴记得 点赞关注 ,相比如Docker来说K8S有着更成熟的功能,经过谷歌大量实践的产物,是一个比较成熟和完善的系统。
关于K8S大家有什么想要了解或者疑问的地方欢迎大家留言告诉我。
我是牧小农,一个卑微的打工人,如果觉得文中的内容对你有帮助,记得一键三连,你们的三连是小农最大的动力。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)