一、K8S简介:
Kubernetes是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部署容器化的应用简单高效,Kubernetes提供了应用部署、规划、更新、维护的一种机制。 在Kubenetes中,所有的容器均在Pod中运行,一个Pod可以承载一个或者多个相关的容器。同一个Pod中的容器会部署在同一个物理机器上并且能够共享资源。一个Pod也可以包含0个或者多个磁盘卷组(volumes),这些卷组将会以目录的形式提供给一个容器,或者被所有Pod中的容器共享。
二、K8S组件:※※※※※
1、Kube-ApiServer:
kube-apiserver是整个K8S集群中,与Etcd直接交互,控制着集群中核心资源变化,提供了K8S各类资源对象(pod,RC,Service等)的增删改查及watch等HTTP Rest接口,是整个系统的数据总线和数据中心。
该端口默认值为6443(可修改),可以通过启动参数“--secure-port”的值来修改默认值。
默认IP地址非本地(Non-LocalHost)网络端口,通过启动参数“--bind-address”设置该值。
该端口用于接收客户端、dashboard等外部HTTPs请求,用于基于Token文件或客户端证书及HTTP Base的认证,用于基于策略的授权。
Kube-ApiServer的功能主要有以下几点:
①提供集群管理的REST API接口,包括认证授权、数据校验以及集群状态变更等,供客户端及其他组件调用;
②代理集群中的一些附加组件组件,如 Kubernetes UI(基于web的用户界面,它可以图表化显示当前集群状态)、metrics-server(离线监控数据组件)、npd(监视和报告节点的健康状况) 等;
③创建 kubernetes 服务,即提供 apiserver 的 Service,kubernetes Service;
④资源在不同版本之间的转换(Decoder通过internal version进行切换,例如:v1⇔v1alpha1,v1⇔v1beta1,v1beta1⇔v1alpha1);
internal version 作为一个通用的 version 会包含所有 version 的字段,它具有所有 version 的功能。 Decoder 会首先把 creater object 转换到 internal version,然后将其转换为 storage version,storage version 是在 etcd 中存储时的另一个 version。
⑤拥有完备的集群安全机制。
Kube-ApiServer的处理流程:
kube-apiserver 主要通过对外提供 API 的方式与其他组件进行交互,可以调用 kube-apiserver 的接口 $ curl -k https://<masterIP>:6443或者通过其提供的 swagger-ui 获取到,其主要有以下三种 API:
core group:主要在 /api/v1 下;
named groups:其 path 为 /apis/$NAME/$VERSION;
暴露系统状态的一些 API:如/metrics 、/healthz 等;
API 的 URL 大致以 /apis/group/version/namespaces/my-ns/myresource 组成,其中 API 的结构大致如下图所示:
K8S API测试(在早起版本可以本机访问):
curl --cacert /etc/kubernetes/ssl/ca.pem -H "Authorization: Bearer ${TOKEN]" https://172.16.0.4:6443
curl 127.0.0.1:6443/#返回所有的API列表
curl 127.0.0.1:6443/apis #分组API
curl 127.0.0.1:6443/api/v1#带具体版本号的API
curl 127.0.0.1:6443/version #API版本信息
curl 127.0.0.1:6443/healthz/etcd #与etcd的心跳监测
curl 127.0.0.1:6443/apis/autoscaling/v1 #API的详细信息
curl 127.0.0.1:6443/metrics #指标数据
2、Kube-scheduler:
调度器是一个控制面进程,负责将 Pods 指派到节点上。 调度器基于约束和可用资源为调度队列中每个 Pod 确定其可合法放置的节点。 调度器之后对所有合法的节点进行排序,将 Pod 绑定到一个合适的节点。
多个Pod依次执行,计算资源—>调度—>Pod1—>Node2—>再计算资源—>再调度—>Pod2—>Node1.......
scheduler通过 kubernetes 的监测(Watch)机制来发现集群中新创建且尚未被调度到 Node 上的 Pod。 scheduler会将发现的每一个未调度的 Pod 调度到一个合适的 Node 上来运行。node节点上的kubelet通过API Server监听到kubernetes Scheduler产生的Pod绑定信息,然后获取对应的Pod清单,下载lmage,并启动容器。
在同一个集群中可以使用多个不同的调度器。
scheduler工作原理:
调度主要分为以下几个部分:首先是预选过程,过滤掉不满足条件的节点,这个过程称为Predicates;然后是优选过程,对通过的节点按照优先级排序,称之为Priorities;最后从中选择优先级最高的节点,如果中间任何一步骤有错误,就直接返回错误,具体显示为pod状态会一直pending。
详细流程:
首先,客户端通过 API Server 的 REST API 或者 kubectl 工具创建 Pod 资源。
API Server 收到用户请求后,存储相关数据到 etcd 数据库中。
调度器监听 API Server 查看为调度(bind)的 Pod 列表,循环遍历地为每个 Pod 尝试分配节点,这个分配过程就是我们上面提到的两个阶段。
预选阶段(Predicates),过滤节点,调度器用一组规则过滤掉不符合要求的 Node 节点,比如 Pod 设置了资源的 request,那么可用资源比 Pod 需要的资源少的主机显然就会被过滤掉。
优选阶段(Priorities),为节点的优先级打分,将上一阶段过滤出来的 Node 列表进行打分,调度器会考虑一些整体的优化策略,比如把 Deployment 控制的多个 Pod 副本分布到不同的主机上,使用最低负载的主机等等策略。
经过上面的阶段过滤后选择打分最高的 Node 节点和 Pod 进行 binding 操作,然后将结果存储到 etcd 中
最后被选择出来的 Node 节点对应的 kubelet 去执行创建 Pod 的相关操作目前在插件化以后,scheduler更细化为多个阶段
sort最先执行的阶段,该节点主要是对pod的排序,通过对PodPriority的比较进行排序,将优先度高的pod排在前面,也就是优先级抢占策略 ,一般用在静态pod这类需要高优先级的pod上
Pre-filter 扩展用于对 Pod 的信息进行预处理,或者检查一些集群或 Pod 必须满足的前提条件,如果 pre-filter 返回了 error,则调度过程终止。
Filter 扩展用于排除那些不能运行该 Pod 的节点,对于每一个节点,调度器将按顺序执行 filter 扩展;如果任何一个 filter 将节点标记为不可选,则余下的 filter 扩展将不会被执行。调度器可以同时对多个节点执行 filter 扩展。
Post-filter 是一个通知类型的扩展点,调用该扩展的参数是 filter 阶段结束后被筛选为可选节点的节点列表,可以在扩展中使用这些信息更新内部状态,或者产生日志或 metrics 信息。
Scoring 扩展用于为所有可选节点进行打分,调度器将针对每一个节点调用 Soring 扩展,评分结果是一个范围内的整数。在 normalize scoring 阶段,调度器将会把每个 scoring 扩展对具体某个节点的评分结果和该扩展的权重合并起来,作为最终评分结果。
Normalize scoring 扩展在调度器对节点进行最终排序之前修改每个节点的评分结果,注册到该扩展点的扩展在被调用时,将获得同一个插件中的 scoring 扩展的评分结果作为参数,调度框架每执行一次调度,都将调用所有插件中的一个 normalize scoring 扩展一次。
Reserve 是一个通知性质的扩展点,有状态的插件可以使用该扩展点来获得节点上为 Pod 预留的资源,该事件发生在调度器将 Pod 绑定到节点之前,目的是避免调度器在等待 Pod 与节点绑定的过程中调度新的 Pod 到节点上时,发生实际使用资源超出可用资源的情况。(因为绑定 Pod 到节点上是异步发生的)。这是调度过程的最后一个步骤,Pod 进入 reserved 状态以后,要么在绑定失败时触发 Unreserve 扩展,要么在绑定成功时,由 Post-bind 扩展结束绑定过程。
Permit 扩展用于阻止或者延迟 Pod 与节点的绑定。Permit 扩展可以做下面三件事中的一项:
approve(批准):当所有的 permit 扩展都 approve 了 Pod 与节点的绑定,调度器将继续执行绑定过程
deny(拒绝):如果任何一个 permit 扩展 deny 了 Pod 与节点的绑定,Pod 将被放回到待调度队列,此时将触发 Unreserve 扩展
wait(等待):如果一个 permit 扩展返回了 wait,则 Pod 将保持在 permit 阶段,直到被其他扩展 approve,如果超时事件发生,wait 状态变成 deny,Pod 将被放回到待调度队列,此时将触发 Unreserve 扩展
Pre-bind 扩展用于在 Pod 绑定之前执行某些逻辑。例如,pre-bind 扩展可以将一个基于网络的数据卷挂载到节点上,以便 Pod 可以使用。如果任何一个 pre-bind 扩展返回错误,Pod 将被放回到待调度队列,此时将触发 Unreserve 扩展。
Bind 扩展用于将 Pod 绑定到节点上:只有所有的 pre-bind 扩展都成功执行了,bind 扩展才会执行 调度框架按照 bind 扩展注册的顺序逐个调用 bind 扩展 具体某个 bind 扩展可以选择处理或者不处理该 Pod 如果某个 bind 扩展处理了该 Pod 与节点的绑定,余下的 bind 扩展将被忽略
Post-bind 是一个通知性质的扩展:Post-bind 扩展在 Pod 成功绑定到节点上之后被动调用 Post-bind 扩展是绑定过程的最后一个步骤,可以用来执行资源清理的动作
Unreserve 是一个通知性质的扩展,如果为 Pod 预留了资源,Pod 又在被绑定过程中被拒绝绑定,则 unreserve 扩展将被调用。Unreserve 扩展应该释放已经为 Pod 预留的节点上的计算资源。在一个插件中,reserve 扩展和 unreserve 扩展应该成对出现。
scheduler默认调度算法:
scheduler中默认加载了许多调度算法具体如下:
LeastRequestedPriority:优先从备选节点列表中选择资源消耗最小的节点(CPU+内存)。
CalculateNodeLabelPriority:优先选择含有指定Label的节点。
BalancedResourceAllocation:优先从备选节点列表中选择各项资源使用率最均衡的节点。
PodFitsResources:节点上剩余的资源是否大于 Pod 请求的资源
PodFitsHost:如果 Pod 指定了 NodeName,检查节点名称是否和 NodeName 匹配
PodFitsHostPorts:节点上已经使用的 port 是否和 Pod 申请的 port 冲突
PodSelectorMatches:过滤掉和 Pod 指定的 label 不匹配的节点
NoDiskConflict:已经 mount 的 volume 和 Pod 指定的 volume 不冲突,除非它们都是只读的
CheckNodeDiskPressure:检查节点磁盘空间是否符合要求
CheckNodeMemoryPressure:检查节点内存是否够用
总结:1创2虑3筛4选。
3、kube-controller-manager:
Controller Manager作为集群内部的管理控制中心,负责集群内的Node、Pod副本、服务端点(Endpoint)、命名空间(Namespace)、服务账号(ServiceAccount)、资源定额(ResourceQuota)的管理,当某个Node意外宕机时,Controller Manager会及时发现并执行自动化修复流程,确保集群始终处于预期的工作状态。
每个Controller通过API Server提供的接口实时监控整个集群的每个资源对象的当前状态,当发生各种故障导致系统状态发生变化时,会尝试将系统状态修复到“期望状态”。
kube-controller-manager特征:
①controller-manager控制器每间隔5秒检查一次节点的状态。
②如果controller-manager控制器没有收到自节点的心跳,则将该node节点被标记为不可达。
③controller-manager将在标记为无法访问之前等待40秒。
④如果该node节点被标记为无法访问后5分钟还没有恢复,controller-manager会删除当前node节点的所有pod并在其它可用节点重建这些pod。
kube-controller-manager分类:
①replication controller——复制控制器:
(确保与RC关联的pod数量在任何时候都保持预设值)
Replication Controller会持续监控正在运行的pod列表,并保证相应“类型”的pod的数目与期望相符。如正在运行的pod太少,它会根据pod模板创建新的副本。如正在运行的pod太多,它将删除多余的副本。你可能会对有多余的副本感到奇怪。这可能有几个原因:
有人会手动创建相同类型的pod;有人更改现有的pod的“类型”;有人减少了所需的pod的数量,等等。
一个Replication Controller有三个主要部分:
label selector(标签选择器),用于确定ReplicationController作用域中有哪些pod
replica count(副本个数),指定应运行的pod数量
pod template(pod模板),用于创建新的pod副本
Replication Controller的副本个数、标签选择器,甚至是pod模板都可以随时修改,但只有副本数目的变更会影响现有的pod。
pod的重启策略是always的情况下,rc才会动态调整pod。
pod被创建后都不会消失,只有异常情况下,比如长时间处于failed状态(超时参数由系统设定),rc会回收这个pod,并在其他节点上创建pod副本。
rc创建完pod后,即使rc的yaml文件变更了,已创建出来的pod也不会更新,但是如果rc重新创建了pod副本,则新的pod是基于更改后的yaml创建的。
pod只需要修改标签就可以脱离rc的管控。
②node controller——节点控制器:
(通过api实时获取node状态,并尝试修改nodeStatusMap中节点状态信息)
kubelet进程在启动时通过API Server注册自身节点信息,并定时向API Server汇报状态信息,API Server在接收到这些信息后,将这些信息更新到etcd中。在etcd中存储的节点信息包括节点健康状况、节点资源、节点名称、节点地址信息、操作系统版本、Docker版本、kubelet版本等。
节点健康状况包括就绪(True)、未就绪(False)、未知(Unkown)三种。
Node Controller通过API Server实时获取Node的相关信息,实现管理和监控集群中的各个Node相关的控制功能。
③resourceQuota controller——资源配额管理器:
确保了指定的资源对象在任何时候都不会超量占用系统物理资源,避免了由于某些业务进程的设计或实现的缺陷导致整个系统运行紊乱,甚至意外宕机,对整个集群的平稳运行和稳定性有非常重要的作用。
1.容器级别,可以对CPU和Memory进行限制。
2.Pod级别,可以对一个Pod内所有容器的可用资源进行限制。
3.Namespace级别:
a.Pod数量
b.Replication Controller数量
c.Service 数量
d.ResourceQuota数量
e.Secret数量
f.PV 数量
④namespace controller——名称空间管理器:
用户通过API Server可以创建新的Namespace并将其保存在etcd中,Namespace Controller定时通过API Server读取这些Namespace的信息。如果Namespace被API标识为优雅删除(通过设置删除期限实现,即设置DeletionTimestamp属性),则将该NameSpace的状态设置成Terminating并保存到etcd中。同时Namespace Controller删除该Namespace下的ServiceAccount、RC、Pod、Secret、PersistentVolume、ListRange、ResourceQuota和Event等资源对象。
在Namespace的状态被设置成Terminating后,由Admission Controller的NamespaceLifecycle插件来阻止为该Namespace创建新的资源。同时,在Namespace Controller删除该Namespace中的所有资源对象后,Namespace Controller对该Namespace执行finalize操作,删除Namespace的spec.finalizers域中的信息。如果Namespace Controller观察到Namespace设置了删除期限,同时Namespace的spec.finalizers域值是空的,那么Namespace Controller将通过API Server删除该Namespace资源。
⑤ServiceAccount TokensController:
TokenController作为controller-manager的一部分运行。异步行为:
观察serviceAccount的创建,并创建一个相应的Secret 来允许API访问。
观察serviceAccount的删除,并删除所有相应的ServiceAccountToken Secret
观察secret 添加,并确保关联的ServiceAccount存在,并在需要时向secret 中添加一个Token。
观察secret 删除,并在需要时对应 ServiceAccount 的关联
⑥service controller——服务控制器:
Service Controller监听Service的变化,如果该Service是一个LoadBalancer类型的Service(externalLoadBalancers=true),则Service Controller确保在外部的云平台上该Service对应的LoadBalancer实例被相应地创建、删除及更新路由转发表(根据Endpoints的条目)。
⑦endpoint controller——端点控制器:
Endpoints表示一个Service对应的所有Pod副本的访问地址,Endpoints Controller就是负责生成和维护所有Endpoints对象的控制器。
Endpoints Controller负责监听Service和对应的Pod副本的变化,如果监测到Service被删除,则删除和该Service同名的Endpoints对象。如果监测到新的Service被创建或者修改,则根据该Service信息获得相关的Pod列表,然后创建或者更新Service对应的Endpoints对象。如果监测到Pod的事件,则更新它所对应的Service的Endpoints对象(增加、删除或者修改对应的Endpoint条目)。
⑧deployment controller——部署控制器:
⑨router controller——路由控制器:
等等。
4、kube-proxy:
Kubernetes网络代理运行在node 上,它反映了node 上 Kubernetes API中定义的服务,并可以通过一组后端进行简单的TCP、UDP和 SCTP流转发或者在一组后端进行循环TCP、UDP和 SCTP 转发,用户必须使用apiserver API创建一个服务来配置代理,其实就是kube-proxy通过在主机上维护网络规则并执行连接转发来实现Kubernetes服务访问。
kube-proxy运行在每个节点上,监听APl Server 中服务对象的变化,再通过管理IPtables或者IPVS规则来实现网络的转发。
ube-proxy维护节点上的网络规则,实现了Kubernetes Service 概念的一部分 。它的作用是使发往 Service 的流量(通过ClusterIP和端口)负载均衡到正确的后端Pod。
Kube-Proxy不同的版本可支持四种工作模式:
1、UserSpace: k8s v1.1之前使用,k8s 1.2及以后就已经淘汰
2、IPtables : k8s 1.1版本开始支持,1.2开始为默认
3、IPVS: k8s 1.9引人到1.11为正式版本,需要安装ipvsadm、ipset 工具包和加载ip_vs内核模块
4、Kernelspace:专用于windows,userspace 是早期版本的实现。
Kube-Proxy工作原理:
kube-proxy 监听 API server 中 资源对象的变化情况,包括以下三种:
service、endpoint/endpointslices、node
然后根据监听资源变化操作代理后端来为服务配置负载均衡。
如果你的 kubernetes 使用EndpointSlice,那么kube-proxy会监听EndpointSlice,否则会监听Endpoint。
如果你启用了服务拓扑,那么 kube-proxy 也会监听 node 信息 。服务拓扑(Service Topology)可以让一个服务基于集群的 Node 拓扑进行流量路由。 例如,一个服务可以指定流量是被优先路由到一个和客户端在同一个 Node 或者在同一可用区域的端点。
1、Iptables:
iptables是一种Linux内核功能,旨在成为一种高效的防火墙,具有足够的灵活性来处理各种常见的数据包操作和过滤需求。它允许将灵活的规则序列附加到内核的数据包处理管道中的各种钩子上。
在iptables模式下,kube-proxy将规则附加到“ NAT预路由”钩子上,以实现其NAT和负载均衡功能。这种方法很简单,使用成熟的内核功能,并且可以与通过iptables实现网络策略的组件“完美配合”。
默认的策略是,kube-proxy 在 iptables 模式下随机选择一个后端。
如果 kube-proxy 在 iptables 模式下运行,并且所选的第一个 Pod 没有响应, 则连接失败。 这与用户空间模式不同:在这种情况下,kube-proxy 将检测到与第一个 Pod 的连接已失败, 并会自动使用其他后端 Pod 重试。
但是,kube-proxy对iptables规则进行编程的方式是一种O(n)复杂度的算法,其中n与集群大小(或更确切地说,服务的数量和每个服务背后的后端Pod的数量)成比例地增长)。
2、IPVS:
IPVS是专门用于负载均衡的Linux内核功能。在IPVS模式下,kube-proxy可以对IPVS负载均衡器进行编程,而不是使用iptables。这非常有效,它还使用了成熟的内核功能,并且IPVS旨在均衡许多服务的负载。它具有优化的API和优化的查找例程,而不是一系列顺序规则。 结果是IPVS模式下kube-proxy的连接处理的计算复杂度为O(1)。换句话说,在大多数情况下,其连接处理性能将保持恒定,而与集群大小无关。
与 iptables 模式下的 kube-proxy 相比,IPVS 模式下的 kube-proxy 重定向通信的延迟要短,并且在同步代理规则时具有更好的性能。 与其他代理模式相比,IPVS 模式还支持更高的网络流量吞吐量。
IPVS提供了更多选项来平衡后端Pod的流量。 这些是:
rr: round-robin
lc: least connection (smallest number of open connections)
dh: destination hashing
sh: source hashing
sed: shortest expected delay
nq: never queue
IPVS的一个潜在缺点是,与正常情况下的数据包相比,由IPVS处理的数据包通过iptables筛选器钩子的路径不同。如果打算将IPVS与其他使用iptables的程序一起使用,则需要研究它们是否可以一起正常工作。 不过Ipvs代理模式已经推出很久了,很多组件已经适配的很好了,比如Calico。
性能对比:
从响应时间和CPU使用率两个角度对两种代理模式进行了对比。在专用节点上运行了一个“客户端”微服务Pod,它每秒向Kubernetes服务生成1000个请求,该请求由集群中其他节点上运行的10个“服务器”微服务Pod承载。然后,在iptables和IPVS模式下,使用各种数量的Kubernetes服务(每个服务有10个Pod支持),最多10,000个服务(带有100,000个服务后端)来测量客户端节点上的性能。
Round-Trip 响应时间:
在超过1,000个服务(10,000个后端Pod)之前,iptables和IPVS之间的平均往返响应时间之间的差异微不足道。
仅当不使用keepalive连接时,平均往返响应时间才有差异。
CPU消耗:
iptables和IPVS之间的CPU使用率差异不明显,直到超过1,000个服务(带有10,000个后端Pod)为止。
在10,000个服务(具有100,000个后端pod)的情况下,使用iptables的CPU的增加量约为内核的35%,而使用IPVS的CPU的增加量约为内核的8%。
总结:
对于iptables和IPVS模式,kube-proxy的响应时间开销与建立连接相关,而不是与在这些连接上发送的数据包或请求的数量有关。这是因为Linux使用的连接跟踪(conntrack)能够非常有效地将数据包与现有连接进行匹配。如果数据包在conntrack中匹配,则无需检查kube-proxy的iptables或IPVS规则即可确定该如何处理。
在集群中不超过1000个服务的时候,iptables 和 ipvs 并无太大的差异。而且由于iptables 与网络策略实现的良好兼容性,iptables 是个非常好的选择。
当你的集群服务超过1000个时,而且服务之间链接大多没有开启keepalive,IPVS模式可能是一个不错的选择。
IPVS相对IPtables效率会更高一些,使用IPVS模式需要在运行 Kube-Proxy的节点上安装ipvsadm、ipset工具包和加载 ip_vs内核模块,当Kube-Proxy 以 IPVS代理模式启动时,Kube-Proxy将验证节点上是否安装了IPVS模块,如果未安装,则Kube-Proxy将回退到lPtables代理模式。
使用IPVS模式, Kube-Proxy会监视Kubernetes Service对象和Endpoints,调用宿主机内核Netlink接口以相应地创建IPVS规则并定期与Kubernetes Service对象 Endpoints对象同步IPVS规则,以确保IPVS状态与期望一致,访问服务时,流量将被重定向到其中一个后端Pod,IPVS使用哈希表作为底层数据结构并在内核空间中工作,这意味着IPVS可以更快地重定向流量,并且在同步代理规则时具有更好的性能,此外,IPVS为负载均衡算法提供了更多选项,例如: rr(轮询调度)、lc(最小连接数)、dh(目标哈希)、sh(源哈希)、sed(最短期望延迟)、nq(不排队调度)等。
发展趋势:
kube-proxy 未来发展可能会朝着以下两个方向:
1、接口化,类似于cni。kube-proxy 只实现主体框架和接口规范,社区可以有iptables,ipvs,ebpf,nftables等具体实现。
2、无 kube-proxy。交给容器网络框架实现——cilium。
5、kubelet:
Kubelet 是 kubernetes 工作节点上的一个代理组件,运行在每个节点上,监视已经分配给节点的Pod,主要功能有:
1、向master汇报node节点的状态信息
2、接受指令并在Pod中创建docker容器
3、准备Pod所需的数据卷
4、返回pod的运行状态
5、在node节点执行容器健康检查
6、kubectl:
kubectl 是 Kubernetes 的命令行工具(CLI),是 Kubernetes 用户和管理员必备的管理工具。
7、dashboard:
Dashboard是基于网页的Kubernetes用户界面,可以使用Dashboard获取运行在集群中的应用的概览信息,也可以创建或者修改Kubernetes资源(如Deployment, Job,DaemonSet 等等),也可以对Deployment实现弹性伸缩、发起滚动升级、重启 Pod或者使用向导创建新的应用。
8、coredns:
service发现是k8s中的一个重要机制,其基本功能为:在集群内通过服务名对服务进行访问,即需要完成从服务名到ClusterIP的解析。
k8s主要有两种service发现机制:环境变量和DNS。没有DNS服务的时候,k8s会采用环境变量的形式,但一旦有多个service,环境变量会变复杂,为解决该问题,我们使用DNS服务。
DNS服务在kubernetes中经历了三个阶段(SkyDNS-》KubeDNS-》CoreDNS):
【第一阶段】在kubernetes 1.2版本时,dns服务使用的是由SkyDNS提供的,由4个容器组成:kube2sky、skydns、etcd和healthz。etcd存储dns记录;kube2sky监控service变化,生成dns记录;skydns读取服务,提供查询服务;healthz提供健康检查。
【第二阶段】在kubernetes 1.4版本开始使用KubeDNS,有3个容器组成:kubedns、dnsmasq和sidecar。kubedns监控service变化,并记录到内存(存到内存提高性能)中;dnsmasq获取dns记录,提供dns缓存,提供dns查询服务;sidecar提供健康检查。
【第三阶段】从kubernetes >=1.11版本开始,dns服务有CoreDNS提供,coredns支持自定义dns记录及配置upstream dns server,可以统一管理内部dns和物理dns。coredns只有一个coredns容器。
三、kubernetes pod调度流程:
1、用户通过kubectl命名发起请求。
2、apiserver通过对应的kubeconfig进行认证,认证通过后将yaml中的po信息存到etcd。
3、Controller-Manager通过apiserver的watch接口发现了pod信息的更新,执行该资源所依赖的拓扑结构整合,整合后将对应的信息交给apiserver,apiserver写到etcd,此时pod已经可以被调度了。
4、Scheduler同样通过apiserver的watch接口更新到pod可以被调度,通过算法给pod分配节点,并将pod和对应节点绑定的信息交给apiserver,apiserver写到etcd,然后将pod交给kubelet。
5、kubelet收到pod后,调用CNI接口给pod创建pod网络,调用CRI接口去启动容器,调用CSI进行存储卷的挂载。
6、网络,容器,存储创建完成后pod创建完成,等业务进程启动后,pod运行成功。