踩坑完毕,回到主线。
前面关于port的理解存在偏差,需要用实验来确认port配置的含义。
k8s官方文档对于对于这些配置项的解释还是没有很完善。下面是在其他博文中找到的解释。
已知:
从k8s集群内部的宿主机(物理机、虚拟机)可以直接访问pod的服务地址 ip:80
未知(需要测试):
1、同一局域网内,但没有加入k8s集群的其他服务器能否访问pod的服务地址 ip:80---无法访问
2、能否跳过pod直接访问容器的服务地址 ip:80---没查到ip
首先要知道容器的IP地址
可以看到上面的命令查出的结果是 - 无法看出ip,尝试进入容器查看
然后我就没辙了,不过根据linux系统的精神,所有内容都是文件,但是我google了好久也没找到ip地址到底存在哪一个文件中。然后我就怀疑是不是一定要容器开放端口,ip地址才可以用docker inspect查询,起了一个不开端口的容器,结果也是有ip的。后来问了一个底层开发的朋友,据说ip是不写文件的。
那只能先认为通过k8s启动的容器其实是没有容器ip的。
从侧面看,也很有可能k8s启动的容器确实没有ip
3、访问pod所在的主机的80端口能否返回相同的响应---无法访问
从以上的信息来看,这个port配置应该和docker中暴露端口的意思是一样的,例如下面的例子
来做一下实验:
在我们之前的pod配置文件上增加配置,如下
结果和我们之前的猜测保持一致,增加ports的配置之后,访问宿主机的ip:80也可以访问到pod的内容了。
我这里pod ip 是 101913067,宿主机是 101001237。curl 101913067 和 curl 101001237 得到的结果是一样的。正当我想再仔细看看的时候,服务器又挂了,wc,只能明天找网管重启了。
---第二天
昨天,我还想看看
1、关了这个pod之后是否就不能访问了
启动了2个pod如下,mynginx1没有配置ports,mynginx2配置了ports。
当我关了pod-mynginx2之后访问宿主机101002167应该就不能通了,结果居然是---能访问到!
大吃一惊!结果ip弄错了,宿主机不是101002167,而是101001237,犯了个低级错误。
结果如下:这回和预期的结果终于一样了。
2、宿主机上是不是本身就开启了nginx,所以恰巧就能访问
确认宿主机上没有开启nginx
3、宿主机上的端口开放情况
使用netstat查看宿主机的端口开放,居然没有发现80端口开着,好奇怪。
那如果在101001237宿主机上启动一个nginx端口开在80,结果会是什么样子呢。
我居然启动了,没有端口已被占用的报错。现在把宿主机上的nginx的index页面的内容改一下,看访问101001237:80时,到底访问的是哪一个nginx。
分别从集群内部3台服务器和集群外部1台服务器的机器取访问101001237:80,访问到的都是pod中的nginx。
会不会跟启动顺序有关,因为现在的情况是先启动了pod-nignx,后启动 宿主机-nginx,那现在将pod-nginx关闭,访问101001237:80,看是啥。
集群内部3台服务器和集群外部1台服务器访问101001237:80,结果一致,都是宿主机-nginx。
再启动pod-nginx,查看结果。
访问结果又变回pod-nginx了,4台服务器结果一致。
再去看一下宿主机-nginx的日志,有没有报错信息-----------没有错误日志
现在基本可以得出结论了:当pod和宿主机同时使用某一个端口时,不会因为冲突而报错,但是pod会优先占用端口,而与启动顺序无关。
至于为什么会这样,就不去深究了,毕竟精力有限,作为运维实施,了解到这样子的程度应该够用了。
本地存储Pod重启后能找到对应节点,这是因为本地存储是通过主机的本地文件系统提供持久化存储的。当Pod重启后,即使Pod所在的节点改变了,但是本地存储仍然可以通过本地文件系统找到之前存储的数据。这是因为本地存储的数据是直接存储在节点的本地文件系统中的,不需要通过网络访问其他节点的存储,因此不会受到节点变化的影响。但是需要注意的是,如果Pod所在的节点被删除或者重建,本地存储的数据也会丢失。
Deployment 不足以覆盖所有的应用编排问题,因为在它 看来 ,一个应用的 所有Pod,是完全一样的 ,所以它们之间就没有顺序,也无所谓运行在哪台宿主机上需要时,Deployment就通过Pod模板创建新的Pod,不需要时,就"杀掉"任意一个Pod
但是在实际场景中,并不是所有应用都满足这样的要求比如:主从关系,主备关系,还有就是数据存储类应用,多个实例通常会在本地磁盘上保存一份数据,而这些实例一旦被杀掉,即使重建出来,实例与数据之间的对应关系也已经丢失,从而导致应用失败
这种实例之间有不对等关系,或者 有依赖关系 的应用,被称为"有状态应用"(Stateful Application),为了能对"有状态应用"做出支持,Kubernetes在Deployment基础上,扩展出了:StatefulSet。
StatefulSet将真实世界里的应用状态,抽象为了两种情况:
1, 拓扑状态(顺序编号+固定的网络表示dns) 这种情况是说,应用的多个实例之间不是完全对等的关系这些应用实例,必须按照某些顺序启动,比如某个应用的主节点A要先于B启动,那么当我把A和B两个节点删除之后,重新创建出来时,也要是这个顺序才行并且,新创建出来的A和B,必须和原来的A和B网络标识一样,这样原先的访问者才能使用同样的方法,访问到这个新Pod
2, 存储状态 这种情况是说,应用的多个实例分别绑定了不同的存储数据对于这些应用实例来说,Pod A第一次读取到的数据,和隔了十分钟之后再次读取到的数据,应该是同一份,哪怕在此期间Pod A被重新创建过
所以,StatefulSet的核心功能,就是通过某种方式, 记录这些状态 ,然后在Pod被重新创建时,能够为新Pod恢复这些状态
在深入了解StatefulSet之前,咱们先来讲讲 Headless Service
我们知道,Service是Kubernetes项目中用来将一组Pod暴露给外界访问的一种机制,比如,一个Deployment有3个Pod,那么我就可以定义一个Service,然后用户只要能访问到这个Service,就能访问到某个具体的Pod
但是,这个Service是怎么被访问到的呢
第一种方式,以Service的VIP(Virtual IP,即: 虚拟IP )方式比如:当我访问19216801这个Service的IP地址时,它就是一个VIP在实际中,它会把请求转发到Service代理的具体Pod上
第二种方式,就是以Service的 DNS 方式在这里又分为两种处理方法:第一种是Normal Service这种情况下,当访问DNS记录时,解析到的是Service的VIP第二种是Headless Service这种情况下,访问DNS记录时,解析到的就是某一个Pod的IP地址
可以看到, Headless Service不需要分配一个VIP,而是可以直接以DNS记录的方式解析出被代理Pod的IP地址 这样设计有什么好处呢
service定义时,它的 clusterIP 字段的值是:None,即:这个 Service,没有一个 VIP 作为“头”。这也就是 Headless 的含义。所以,这个 Service 被创建后并不会被分配一个 VIP,而是会以 DNS 记录的方式暴露出它所代理的 Pod。当你按照这样的方式创建了一个 Headless Service 之后,它所代理的所有 Pod 的 IP 地址,都会被绑定一个这样格式的 DNS 记录,如下所示:
<pod-name><svc-name><namespace>svcclusterlocal
这个 DNS 记录,正是 Kubernetes 项目为 Pod 分配的唯一的“可解析身份”(Resolvable Identity)。而有了这个身份之后,只要知道了一个Pod的名字以及它对应的Service的名字,就可以非常确定地通过这条DNS记录访问到Pod的IP地址
介绍完Headless Service之后,咱们再回来讲讲,StatefulSet的核心功能,是如何在Pod被重新创建时,能够为新Pod恢复这些状态
为了详细讲解,现在编写一个StatefulSet的YAML文件,如下:
可以看到,在这个YAML文件中,多了一个 serviceName=nginx 字段这个字段的作用,就是告诉StatefulSet控制器,在执行控制循环时,要使用nginx这个Headless Service来保证Pod的"可解析身份"这样,在创建Pod过程中,StatefulSet给它所管理的所有Pod名字,进行编号,使得每个Pod实例不重复而更重要的是,这些Pod的创建,也是严格按照编号顺序来进行的
StatefulSet 就保证了 Pod 网络标识的稳定性 。
这样的意思就是说,当有主从关系时,有明确先后关系时,StatefulSet通过这种机制,使得先后创建顺序成为可能
通过这种方法, Kubernetes 就成功地将 Pod 的拓扑状态(比如:哪个节点先启动,哪个节点后启动),按照 Pod 的“名字 + 编号”的方式固定了下来 。此外,Kubernetes 还为每一个 Pod 提供了一个固定并且唯一的访问入口,即:这个 Pod 对应的 DNS 记录。
这些状态,在 StatefulSet 的整个生命周期里都会保持不变,绝不会因为对应 Pod 的删除或者重新创建而失效。
不过,相信你也已经注意到了,尽管 web-0nginx 这条记录本身不会变,但它解析到的 Pod 的 IP 地址,并不是固定的。这就意味着,对于“有状态应用”实例的访问,你必须使用 DNS 记录或者 hostname 的方式,而绝不应该直接访问这些 Pod 的 IP 地址。
Kubernetes 中 PVC 和 PV 的设计, 实际上类似于“接口”和“实现”的思想 。开发者只要知道并会使用“接口”,即:PVC;而运维人员则负责给“接口”绑定具体的实现,即:PV。而 PVC、PV 的设计,也使得 StatefulSet 对存储状态的管理成为了可能。 PVC 其实就是一种特殊的 Volume 。只不过一个 PVC 具体是什么类型的 Volume,要在跟某个 PV 绑定之后才知道。当然,PVC 与 PV 的绑定得以实现的前提是,运维人员已经在系统里创建好了符合条件的 PV(比如,我们在前面用到的 pv-volume);或者,你的 Kubernetes 集群运行在公有云上,这样 Kubernetes 就会通过 Dynamic Provisioning 的方式,自动为你创建与 PVC 匹配的 PV。 因为这种方式虽然开发可以直接使用PVC来做存储,但是却需要运维提前定义好PV,包括容量,个数等,这些往往是未知的,所以需要动态存储供应StorageClass 。
通过这种方式,Kubernetes 的 StatefulSet 就实现了对应用存储状态的管理。
看到这里,你是不是已经大致理解了 StatefulSet 的工作原理呢?现在,我再为你详细梳理一下吧。
首先,StatefulSet 的控制器直接管理的是 Pod 。这是因为,StatefulSet 里的不同 Pod 实例,不再像 ReplicaSet 中那样都是完全一样的,而是有了细微区别的。比如,每个 Pod 的 hostname、名字等都是不同的、携带了编号的。而 StatefulSet 区分这些实例的方式,就是通过在 Pod 的名字里加上事先约定好的编号。
其次,Kubernetes 通过 Headless Service,为这些有编号的 Pod,在 DNS 服务器中生成带有同样编号的 DNS 记录 。只要 StatefulSet 能够保证这些 Pod 名字里的编号不变,那么 Service 里类似于 web-0nginxdefaultsvcclusterlocal 这样的 DNS 记录也就不会变,而这条记录解析出来的 Pod 的 IP 地址,则会随着后端 Pod 的删除和再创建而自动更新。这当然是 Service 机制本身的能力,不需要 StatefulSet *** 心。
最后,StatefulSet 还为每一个 Pod 分配并创建一个同样编号的 PVC 。这样,Kubernetes 就可以通过 Persistent Volume 机制为这个 PVC 绑定上对应的 PV,从而保证了每一个 Pod 都拥有一个独立的 Volume。
在这种情况下,即使 Pod 被删除,它所对应的 PVC 和 PV 依然会保留下来。所以当这个 Pod 被重新创建出来之后,Kubernetes 会为它找到同样编号的 PVC,挂载这个 PVC 对应的 Volume,从而获取到以前保存在 Volume 里的数据。
其实StatefulSet就是一种特殊的Deployment,只不过它的每个Pod都被编号了 正是由于这种机制,使得具有主从关系的创建成为可能StatefulSet 其实可以认为是对 Deployment 的改良。与此同时,通过 Headless Service 的方式,StatefulSet 为每个 Pod 创建了一个固定并且稳定的 DNS 记录,来作为它的访问入口。实际上,在部署“有状态应用”的时候,应用的每个实例拥有唯一并且稳定的“网络标识”,是一个非常重要的假设。
如果容器直接启动失败(如业务进程异常退出),那么Kubelet会尝试 在本机重启容器,尝试间隔时间按照指数递增(10s,20s,40s),最长不超过5分钟 。
当业务容器启动成功后, Kubelet只能知道容器已经处于运行状态,但容器里面运行应用的真实状态就不得而知了。 为此,Kubelet引入了 探针 机制,Kubelet支持两种探针LivenessProbe和ReadinessProbe。
LivenessProbe( 存活探针):探测容器中的应用是否正在运行。如果探测失败,Kubelet会终止容器,并根据“重启策略”重建容器。如果设置存活探针,默认状态为Success,LivenessProbe的SuccessThreshold为1。
ReadinessProbe( 绪探探针):探测容器中,应用是否准备好服务请求。如果探测失败,端点控制器将从与Pod匹配的所有Service端点中删除该Pod的IP地址。初始延迟之前的就绪状态默认为Failure。如果容器不提供就绪探针,则默认状态为Success。
那么在什么条件下使用存活(liveness)或就绪(readiness)探针呢?
如果容器中的应用能够在遇到问题或不健康的情况下自行崩溃,则不一定需要存活探针,Kubelet根据Pod的restartPolicy自动执行正确的 *** 作。
如果应用在故障时仍然保持运行状态不退出,则需要借助 存活探针 ,探测服务真实状态,并指定restartPolicy为Always或OnFailure。
应用启动是需要时间的。为了避免容器刚启动(此时应用还未启动)时,kube-proxy就直接将流量导入容器引发的错误,需要引入 就绪探针 。探测成功后,才开始将业务流量导入Pod。(如果是多个副本,根据业务量进行d缩副本,引入就绪探针,外部访问时就可以避免访问到还没有启动完成的pod。如果是单个副本或者固定副本数,个人觉得并不需要就绪探针)
通常存活探针和就绪探针使用相同的探测方式来检测应用状态:
1)ExecAction:在容器内执行指定命令。如果命令退出时,返回码为0,则认为探测成功。
2)TCPSocketAction:对指定端口上的容器IP地址进行TCP检查。如果端口打开,则诊断为成功。这个可以理解为telnet端口,查看是否被监听。
3)>
可以创建一个Statefulset资源替代ReplicaSet来运行这类pod。它是专门定制的一类应用,这类应用中每一个实例都是不可替代的个体,都拥有稳定的名字和状态。
要很好地理解Statefulset的用途,最好先与ReplicaSet或ReplicationControllers对比一下。首先拿一个通用的类比来解释它们。
通过宠物与牛的类比来理解有状态
你可能已经听说过宠物与牛的类比。如果没有,先简单介绍一下。可以把我们的应用看作宠物或牛。
注意 Statefulset最初被称为PetSet,这个名字来源于宠物与牛的类比。
我们倾向于把应用看作宠物,给每个实例起一个名字,细心照顾每个实例。但是也许把它们看成牛更为合适,并不需要对单独的实例有太多关心。这样就可以非常方便地替换掉不健康的实例,就跟农场主替换掉一头生病的牛一样。
对于无状态的应用实例来说,行为非常像农场里的牛。一个实例挂掉后并没什么影响,可以创建一个新实例,而让用户完全无感知。
另一方面,有状态的应用的一个实例更像一个宠物。若一只宠物死掉,不能买到一只完全一样的,而不让用户感知到。若要替换掉这只宠物,需要找到一只行为举止与之完全一致的宠物。对应用来说,意味着新的实例需要拥有跟旧的案例完全一致的状态和标识。
Statefulset与ReplicaSet或ReplicationController的对比
RelicaSet或ReplicationController管理的pod副本比较像牛,这是因为它们都是无状态的,任何时候它们都可以被一个全新的pod替换。然而有状态的pod需要不同的方法,当一个有状态的pod挂掉后(或者它所在的节点故障),这个pod实例需要在别的节点上重建,但是新的实例必须与被替换的实例拥有相同的名称、网络标识和状态。这就是StatefulSet如何管理pod的。
Statefulset保证了pod在重新调度后保留它们的标识和状态。它让你方便地扩容、缩容。与ReplicaSet类似,Statefulset也会指定期望的副本个数,它决定了在同一时间内运行的宠物的数量。与ReplicaSet类似,pod也是依据Statefulset的pod模板创建的(想象一下曲奇饼干模板)。与ReplicaSet不同的是,Statefulset创建的pod副本并不是完全一样的。每个pod都可以拥有一组独立的数据卷(持久化状态)而有所区别。另外“宠物”pod的名字都是规律的(固定的),而不是每个新pod都随机获取一个名字。
一个Statefulset创建的每个pod都有一个从零开始的顺序索引,这个会体现在pod的名称和主机名上,同样还会体现在pod对应的固定存储上。这些pod的名称则是可预知的,因为它是由Statefulset的名称加该实例的顺序索引值组成的。不同于pod随机生成一个名称,这样有规则的pod名称是很方便管理的,如图105所示。
[上传失败(image-bf81d6-1627605883814)]
图105 与ReplicaSet不同,由Statefulset创建的pod拥有规则的名称(和主机名)
控制服务介绍
让pod拥有可预知的名称和主机名并不是全部,与普通的pod不一样的是,有状态的pod有时候需要通过其主机名来定位,而无状态的pod则不需要,因为每个无状态的pod都是一样的,在需要的时候随便选择一个即可。但对于有状态的pod来说,因为它们都是彼此不同的(比如拥有不同的状态),通常希望 *** 作的是其中特定的一个。
基于以上原因,一个Statefulset通常要求你创建一个用来记录每个pod网络标记的headless Service。通过这个Service,每个pod将拥有独立的DNS记录,这样集群里它的伙伴或者客户端可以通过主机名方便地找到它。比如说,一个属于default命名空间,名为foo的控制服务,它的一个pod名称为A-0,那么可以通过下面的完整域名来访问它:a-0foodefaultsvcclusterlocal。而在ReplicaSet中这样是行不通的。
另外,也可以通过DNS服务,查找域名foodefaultsvcclusterlocal对应的所有SRV记录,获取一个Statefulset中所有pod的名称。我们将在104节中介绍SRV记录,解释如何通过它来发现一个Statefulset中的所有成员。
替换消失的宠物
当一个Statefulset管理的一个pod实例消失后(pod所在节点发生故障,或有人手动删除pod),Statefulset会保证重启一个新的pod实例替换它,这与ReplicaSet类似。但与ReplicaSet不同的是,新的pod会拥有与之前pod完全一致的名称和主机名(ReplicaSet和Statefulset的差异如图106所示)。
image
图106 Statefulset使用标识完全一致的新的pod替换,ReplicaSet则是使用一个不相干的新的pod替换
如你之前了解的那样,pod运行在哪个节点上并不重要,新的pod并不一定会调度到相同的节点上。对于有状态的pod来说也是这样,即使新的pod被调度到一个不同的节点,也同样可以通过主机名来访问。
扩缩容Statefulset
扩容一个Statefulset会使用下一个还没用到的顺序索引值创建一个新的pod实例。比如,要把一个Statefulset从两个实例扩容到三个实例,那么新实例的索引值就会是2(现有实例使用的索引值为0和1)。
当缩容一个Statefulset时,比较好的是很明确哪个pod将要被删除。作为对比,ReplicaSet的缩容 *** 作则不同,不知道哪个实例会被删除,也不能指定先删除哪个实例(也许这个功能会在将来实现)。缩容一个Statefulset将会最先删除最高索引值的实例(如图107所示),所以缩容的结果是可预知的。
[上传失败(image-d8c3f0-1627605883814)]image
图107 缩容一个Statefulset将会最先删除最高索引值的实例
因为Statefulset缩容任何时候只会 *** 作一个pod实例,所以有状态应用的缩容不会很迅速。举例来说,一个分布式存储应用若同时下线多个节点,则可能导致其数据丢失。比如说一个数据项副本数设置为2的数据存储应用,若同时有两个节点下线,一份数据记录就会丢失,如果它正好保存在这两个节点上。若缩容是线性的,则分布式存储应用就有时间把丢失的副本复制到其他节点,保证数据不会丢失。
基于以上原因,Statefulset在有实例不健康的情况下是不允许做缩容 *** 作的。若一个实例是不健康的,而这时再缩容一个实例的话,也就意味着你实际上同时失去了两个集群成员。
你已经知道了Statefulset如何保证一个有状态的pod拥有稳定的标识,那存储呢?一个有状态的pod需要拥有自己的存储,即使该有状态的pod被重新调度(新的pod与之前pod的标识完全一致),新的实例也必须挂载着相同的存储。那Statefulset是如何做到这一点的呢?
很明显,有状态的pod的存储必须是持久的,并且与pod解耦。在第6章中学习了持久卷和持久卷声明,通过在pod中关联一个持久卷声明的名称,就可以为pod提供持久化存储。因为持久卷声明与持久卷是一对一的关系,所以每个Statefulset的pod都需要关联到不同的持久卷声明,与独自的持久卷相对应。因为所有的pod实例都是依据一个相同的pod模板创建的,那它们是如何关联到不同的持久卷是的呢?并且由谁来创建这些持久卷是呢?当然你肯定不想手在动创建Statefulset之前,依据pod的个数创建相同数量的持久卷量。当然不用这么做!
在pod模板中添加卷声明模板
像Statefulset创建pod一样,Statefulset也需要创建持久卷声明。所以一个Statefulset可以拥有一个或多个卷声明模板,这些持久卷声明会在创建pod前创建出来,绑定到一个pod实例上(如图108所示)。
image
图108 一个Statefulset创建pod和持久卷声明
声明的持久卷既可以通过administrator用户预先创建出来,也可以如第6章所述,由持久卷的动态供应机制实时创建出来。
持久卷的创建和删除
扩容StatefulSet增加一个副本数时,会创建两个或更多的API对象(一个pod和与之关联的一个或多个持久卷声明)。但是对缩容来说,则只会删除一个pod,而遗留下之前创建的声明。当你知道一个声明被删除会发生什么的话,你就明白为什么这么做了。当一个声明被删除后,与之绑定的持久卷就会被回收或删除,则其上面的数据就会丢失。
因为有状态的pod是用来运行有状态应用的,所以其在数据卷上存储的数据非常重要,在Statefulset缩容时删除这个声明将是灾难性的,特别是对于Statefulset来说,缩容就像减少其replicas数值一样简单。基于这个原因,当你需要释放特定的持久卷时,需要手动删除对应的持久卷声明。
重新挂载持久卷声明到相同pod的新实例上
因为缩容Statefulset时会保留持久卷声明,所以在随后的扩容 *** 作中,新的pod实例会使用绑定在持久卷上的相同声明和其上的数据(如图109所示)。当你因为误 *** 作而缩容一个Statefulset后,可以做一次扩容来弥补自己的过失,新的pod实例会运行到与之前完全一致的状态(名字也是一样的)。
image
图109 Statefulset缩容时不删除持久卷声明,扩容时会重新挂载上
如之前描述的,Statefulset的行为与ReplicaSet是不一样的。Statefulset不仅拥有稳定的标记和独立的存储,它的pod还有其他的一些保障。
稳定标识和独立存储的影响
通常来说,无状态的pod是可以替代的,而有状态的pod则不行。我们之前已经描述了一个有状态的pod总是会被一个完全一致的pod替换(两者有相同的名称、主机名和存储等)。这个替换发生在Kubernetes发现旧的pod不存在时(例如手动删除这个pod)。
那么当Kubernetes不能确定一个pod的状态时呢?如果它创建一个完全一致的pod,那系统中就会有两个完全一致的pod在同时运行。这两个pod会绑定到相同的存储,所以这两个相同标记的进程会同时写相同的文件。对于ReplicaSet的pod来说,这不是问题,因为应用本来就是设计为在相同的文件上工作的。并且我们知道ReplicaSet会以一个随机的标识来创建pod,所以不可能存在两个相同标识的进程同时运行。
介绍Statefulset的at-most-one的语义
Kubernetes必须保证两个拥有相同标记和绑定相同持久卷声明的有状态的pod实例不会同时运行。一个Statefulset必须保证有状态的pod实例的at-most-one语义。
也就是说一个Statefulset必须在准确确认一个pod不再运行后,才会去创建它的替换pod。这对如何处理节点故障有很大的影响,我们会在本章后面详细介绍。在我们做这些之前,需要先创建一个Statefulset,看看它是如何工作的。在这个过程中,你会学到更多的知识。
tag: k8s coredns
有个同学不小心将CoreDNS干掉了,直接使用helm安装,但是DNS SVC的IP会重新分配一个。部署的POD的dns服务器地址不会变成新的(老的也不会改变)。
kubelet 通过 --cluster-dns=<dns-service-ip> 传递dns的地址。当创建POD时,如果使用ClusterDNS,则 /etc/resolvconf 文件里的地址就使用这个。参考 官网
查看kubelet的PID,及启动配置。
--config=/etc/kubelet/node-configyaml 节点配置,里面配置了dns的地址。
默认dns地址为: 172165610
以kubeadm部署集群为例,kubeadm默认获取svc网段下的第10个IP作为DNS的地址。
cmd/kubeadm/app/constants/constantsgo:GetDNSIP
用户对pod的配置,会在内部进行转换,转为以下3种。
pkg/kubelet/network/dns/dnsgo:getPodDNSType
>
以上就是关于k8s-pod-初探2全部的内容,包括:k8s-pod-初探2、本地存储pod重启后能找到对应节点、StatefulSet等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)