K8s-pod及service04

本文详细介绍了Kubernetes中Pod的标签管理、节点选择器、节点亲和性以及常见Pod状态和重启策略。此外,还讲解了Service的工作原理、集群中的IP地址类别以及Service的四种类型。内容涵盖Pod标签的添加、查看,节点选择器的使用,Pod亲和性和反亲和性的配置示例,以及Pod状态和重启策略的解释,包括存活性探测和就绪性探测的区别。Service部分则讨论了Service作为Pod逻辑集合的重要性,及其工作原理、集群中的IP类型和服务类型。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

pod知识点

一、标签

二、node节点选择器

三、Pod节点亲合度

例1:pod节点亲和性

例2:pod节点反亲和性

例3:换一个topologykey

四、常见的pod状态和重启策略

常见的pod状态

pod重启策略

存活性探测livenessProbe和就绪性探测readinessProbe

Pod探针相关的属性:

 两种探针区别:

Service知识点

一、Service概述

二、Service工作原理

三、 kubernetes集群中的三类IP地址

四、Service的四种类型


pod知识点

一、标签

标签概念

标签其实就一对 key/value ,被关联到对象上,比如Pod,标签的使用我们倾向于能够表示对象的特殊特点,就是一眼就看出了这个Pod是干什么的,标签可以用来划分特定的对象(比如版本,服务类型等),标签可以在创建一个对象的时候直接定义,也可以在后期随时修改,每一个对象可以拥有多个标签,但是,key值必须是唯一的。创建标签之后也可以方便我们对资源进行分组管理。如果对pod打标签,之后就可以使用标签来查看、删除指定的pod。

在k8s中,大部分资源都可以打标签。

给pod资源打标签

#对已经存在的pod打标签

[root@hd1.com~]# kubectl label pods pod-first  release=v1

查看标签是否打成功:

[root@hd1.com~]# kubectl get pods pod-first --show-labels

显示如下,显示如下,说明标签达成功了;

NAME         READY   STATUS    RESTARTS   AGE   LABELS

pod-first    1/1     Running   1          21h   release=v1, app=tomcat-pod-first

查看资源标签

#查看默认名称空间下所有pod资源的标签

[root@hd1.com~]# kubectl get pods --show-labels

#查看默认名称空间下指定pod具有的所有标签

[root@hd1.com~]# kubectl get pods pod-first --show-labels

#列出默认名称空间下标签key是release的pod,不显示标签

[root@hd1.com~]# kubectl get pods -l release

#列出默认名称空间下标签key是release、值是v1的pod,不显示标签

[root@hd1.com~]# kubectl get pods -l release=v1

#列出默认名称空间下标签key是release的所有pod,并打印对应的标签值

[root@hd1.com~]# kubectl get pods -L release

#查看所有名称空间下的所有pod的标签

[root@hd1.com ~]# kubectl get pods --all-namespaces --show-labels

二、node节点选择器

可以使用pod中的nodeName或者nodeSelector字段指定要调度到的node节点

nodeName:指定pod节点运行在哪个具体node上

 nodeSelector:指定pod调度到具有哪些标签的node节点上

通过这两种方式可以使pod到指定工作节点

#给node节点打标签

[root@hd1.com ~]# kubectl label nodes hd3.com disk=ceph

#查看节点的详细信息

[root@hd1 node]# kubectl describe nodes hd3.com

三、Pod节点亲合度

pod自身的亲和性调度有两种表示形式

podaffinity:pod和pod更倾向腻在一起,把相近的pod结合到相近的位置,如同一区域,同一机架,这样的话pod和pod之间更好通信,比方说有两个机房,这两个机房部署的集群有1000台主机,那么我们希望把nginx和tomcat都部署同一个地方的node节点上,可以提高通信效率;

podunaffinity:pod和pod更倾向不腻在一起,如果部署两套程序,那么这两套程序更倾向于反亲和性,这样相互之间不会有影响。

例1:pod节点亲和性

定义两个pod,第一个pod做为基准,第二个pod跟着它走

apiVersion: v1

kind: Pod

metadata:

  name: pod-first

  labels:

    app2: myapp2

    tier: frontend

spec:

  containers:

  - name: myapp

    image: ikubernetes/myapp:v1

    imagePullPolicy: IfNotPresent

---

apiVersion: v1

kind: Pod

metadata:

  name: pod-second

  labels:

    app: backend

    tier: db

spec:

  containers:

  - name: busybox

    image: busybox:1.28

    imagePullPolicy: IfNotPresent

    command: ["sh","-c","sleep 3600"]

  affinity:

    podAffinity:

      requiredDuringSchedulingIgnoredDuringExecution:

      - labelSelector:

          matchExpressions:

          - {key: app2, operator: In, values: ["myapp2"]}

        topologyKey: kubernetes.io/hostname

#上面表示创建的pod必须与拥有app=myapp2标签的pod在一个节点上

[root@hd1.com ~]# kubectl get pods -o wide

pod-first            running        hd2.com

pod-second           running        hd2.com

例2:pod节点反亲和性

定义两个pod,第一个pod做为基准,第二个pod跟它调度节点相反

    affinity:

      podAntiAffinity:

         requiredDuringSchedulingIgnoredDuringExecution:

         - labelSelector:

              matchExpressions:

              - {key: app1, operator: In, values: ["myapp1"]}

           topologyKey: kubernetes.io/hostname

[root@hd1.com ~]# kubectl get pods -o wide

pod-first            running        hd2.com

pod-second           running        hd3.com

#显示两个pod不在一个node节点上,这就是pod节点反亲和性

例3:换一个topologykey

[root@hd1.com ~]# kubectl label nodes  hd3.com  zone=foo

[root@hd1.com ~]# kubectl label nodes  hd2.com  zone=foo --overwrite

 affinity:

      podAntiAffinity:

         requiredDuringSchedulingIgnoredDuringExecution:

         - labelSelector:

              matchExpressions:

              - {key: app1, operator: In, values: ["myapp1"]}

           topologyKey: zone

[root@hd1.com ~]#kubectl get pods -o wide 显示如下:

pod-first              running         hd2.com

pod-second           pending         <none>

第二个节点现是pending,因为两个节点是同一个位置,现在没有不是同一个位置的了,而且我们要求反亲和性,所以就会处于pending状态,如果在反亲和性这个位置把required(硬亲合度)改成preferred(软亲合度),那么也会运行。

Pod常见的状态和重启策略

四、常见的pod状态和重启策略

常见的pod状态

Pod的status定义在PodStatus对象中,其中有一个phase字段。它简单描述了Pod在其生命周期的阶段。熟悉Pod的各种状态对我们理解如何设置Pod的调度策略、重启策略是很有必要的。下面是 phase 可能的值,也就是pod常见的状态:

挂起(Pending):我们在请求创建pod时,条件不满足,调度没有完成,没有任何一个节点能满足调度条件,已经创建了pod但是没有适合它运行的节点叫做挂起,调度没有完成,处于pending的状态会持续一段时间:包括调度Pod的时间和通过网络下载镜像的时间。

运行中(Running):Pod已经绑定到了一个节点上,Pod 中所有的容器都已被创建。至少有一个容器正在运行。

成功(Succeeded):Pod 中的所有容器都被成功终止,并且不会再重启。

失败(Failed):Pod 中的所有容器都已终止了,并且至少有一个容器是因为失败终止。也就是说,容器以非0状态退出或者被系统终止。

未知(Unknown):未知状态,所谓pod是什么状态是apiserver和运行在pod节点的kubelet进行通信获取状态信息的,如果节点之上的kubelet本身出故障,那么apiserver就连不上kubelet,得不到信息了,就会看Unknown

扩展:还有其他状态,如下:

Evicted状态:出现这种情况,多见于系统内存或硬盘资源不足,可df-h查看docker存储所在目录的资源使用情况,如果百分比大于85%,就要及时清理下资源,尤其是一些大文件、docker镜像。

CrashLoopBackOff:容器曾经启动了,但可能又异常退出了

Error 状态:Pod 启动过程中发生了错误

pod重启策略

Pod的重启策略(RestartPolicy)应用于Pod内的所有容器,并且仅在Pod所处的Node上由kubelet进行判断和重启操作。当某个容器异常退出或者健康检查失败时,kubelet将根据 RestartPolicy 的设置来进行相应的操作。

Pod的重启策略包括 Always、OnFailure和Never,默认值为Always。

Always:当容器失败时,由kubelet自动重启该容器。

OnFailure:当容器终止运行且退出码不为0时,由kubelet自动重启该容器。

Never:不论容器运行状态如何,kubelet都不会重启该容器。

存活性探测livenessProbe和就绪性探测readinessProbe

livenessProbe:存活性探测

        许多应用程序经过长时间运行,最终过渡到无法运行的状态,除了重启,无法恢复。通常情况下,K8S会发现应用程序已经终止,然后重启应用程序pod。有时应用程序可能因为某些原因(后端服务故障等)导致暂时无法对外提供服务,但应用软件没有终止,导致K8S无法隔离有故障的pod,调用者可能会访问到有故障的pod,导致业务不稳定。K8S提供livenessProbe来检测容器是否正常运行,并且对相应状况进行相应的补救措施。

readinessProbe:就绪性探测

        在没有配置readinessProbe的资源对象中,pod中的容器启动完成后,就认为pod中的应用程序可以对外提供服务,该pod就会加入相对应的service,对外提供服务。但有时一些应用程序启动后,需要较长时间的加载才能对外服务,如果这时对外提供服务,执行结果必然无法达到预期效果,影响用户体验。比如使用tomcat的应用程序来说,并不是简单地说tomcat启动成功就可以对外提供服务的,还需要等待spring容器初始化,数据库连接上等等。

目前LivenessProbe和ReadinessProbe两种探针都支持下面三种探测方法:

1、ExecAction:在容器中执行指定的命令,如果执行成功,退出码为 0 则探测成功。

2、TCPSocketAction:通过容器的 IP 地址和端口号执行 TCP 检 查,如果能够建立 TCP 连接,则表明容器健康。

3、HTTPGetAction:通过容器的IP地址、端口号及路径调用 HTTP Get方法,如果响应的状态码大于等于200且小于400,则认为容器健康

探针探测结果有以下值:

1、Success:表示通过检测。

2、Failure:表示未通过检测。

3、Unknown:表示检测没有正常进行。

Pod探针相关的属性:

探针(Probe)有许多可选字段,可以用来更加精确的控制Liveness和Readiness两种探针的行为

initialDelaySeconds: Pod启动后首次进行检查的等待时间,单位“秒”。

periodSeconds: 检查的间隔时间,默认为10s,单位“秒”。

timeoutSeconds: 探针执行检测请求后,等待响应的超时时间,默认为1s,单位“秒”。

successThreshold:连续探测几次成功,才认为探测成功,默认为 1,在 Liveness 探针中必须为1,最小值为1。

failureThreshold: 探测失败的重试次数,重试一定次数后将认为失败,在 readiness 探针中,Pod会被标记为未就绪,默认为 3,最小值为 1

 两种探针区别:

ReadinessProbe 和 livenessProbe 可以使用相同探测方式,只是对 Pod 的处置方式不同:

readinessProbe 当检测失败后,将 Pod 的 IP:Port 从对应的 EndPoint 列表中删除。

livenessProbe 当检测失败后,将杀死容器并根据 Pod 的重启策略来决定作出对应的措施。

Service知识点

为什么要有Service?

在kubernetes中,Pod是有生命周期的,如果Pod重启它的IP很有可能会发生变化。如果我们的服务都是将Pod的IP地址写死,Pod挂掉或者重启,和刚才重启的pod相关联的其他服务将会找不到它所关联的Pod,为了解决这个问题,在kubernetes中定义了service资源对象,Service 定义了一个服务访问的入口,客户端通过这个入口即可访问服务背后的应用集群实例,service是一组Pod的逻辑集合,这一组Pod能够被Service访问到,通常是通过Label Selector实现的。

可以看下面的图:

 

1、pod ip经常变化,service是pod的代理,我们客户端访问,只需要访问service,就会把请求代理到Pod

2、pod ip在k8s集群之外无法访问,所以需要创建service,这个service可以在k8s集群外访问的。

一、Service概述

        service是一个固定接入层,客户端可以通过访问service的ip和端口访问到service关联的后端pod,这个service工作依赖于在kubernetes集群之上部署的一个附件,就是kubernetes的dns服务(不同kubernetes版本的dns默认使用的也是不一样的,1.11之前的版本使用的是kubeDNs,较新的版本使用的是coredns),service的名称解析是依赖于dns附件的,因此在部署完k8s之后需要再部署dns附件,

kubernetes要想给客户端提供网络功能,需要依赖第三方的网络插件(flannel,calico等)。

        每个K8s节点上都有一个组件叫做kube-proxy,kube-proxy这个组件将始终监视着apiserver中有关service资源的变动信息,需要跟master之上的apiserver交互,随时连接到apiserver上获取任何一个与service资源相关的资源变动状态,这种是通过kubernetes中固有的一种请求方法watch(监视)来实现的,一旦有service资源的内容发生变动(如创建,删除),kube-proxy都会将它转化成当前节点之上的能够实现service资源调度,把我们请求调度到后端特定的pod资源之上的规则,这个规则可能是iptables,也可能是ipvs,取决于service的实现方式。

二、Service工作原理

        k8s在创建Service时,会根据标签选择器selector(lable selector)来查找Pod,据此创建与Service同名的endpoint对象,当Pod 地址发生变化时,endpoint也会随之发生变化,service接收前端client请求的时候,就会通过endpoint,找到转发到哪个Pod进行访问的地址。(至于转发到哪个节点的Pod,由负载均衡kube-proxy决定)

三、 kubernetes集群中的三类IP地址

1、Node Network(节点网络):物理节点或者虚拟节点的网络,如ens33接口上的网路地址

[root@hd1.com ~]# ip addr

2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP

    link/ether 00:0c:29:87:60:d5 brd ff:ff:ff:ff:ff:ff

inet 192.168.1.11/24 brd 192.168.1.255 scope global noprefixroute ens33

2、Pod network(pod 网络),创建的Pod具有的IP地址

[root@hd1.com ~]# kubectl get pods -o wide

NAME             READY   STATUS          IP               NODE      

frontend-h78gw   1/1       Running       10.244.187.76    hd3.com

Node Network和Pod network这两种网络地址是我们实实在在配置的,其中节点网络地址是配置在节点接口之上,而pod网络地址是配置在pod资源之上的,因此这些地址都是配置在某些设备之上的,这些设备可能是硬件,也可能是软件模拟的

3、Cluster Network(集群地址,也称为service network),这个地址是虚拟的地址(virtual ip),没有配置在某个接口上,只是出现在service的规则当中。

[root@hd1.com ~]# kubectl get svc

NAME               TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)       

kubernetes         ClusterIP   10.96.0.1           <none>        443/TCP  

四、Service的四种类型

1、ExternalName:

适用于k8s集群内部容器访问外部资源,它没有指定selector去选择pod,也没有定义任何的端口和Endpoint。

2、ClusterIP:

通过k8s集群内部IP暴露服务,选择该值,服务只能够在集群内部访问,这也是默认的ServiceType。

3、NodePort:

通过每个Node节点上的IP和静态端口暴露k8s集群内部的服务。通过请求<NodeIP>:<NodePort>可以把请求代理到内部的pod。Client----->NodeIP:NodePort----->Service Ip:ServicePort----->PodIP:ContainerPort。

4、LoadBalancer:

使用云提供商的负载均衡器,可以向外部暴露服务。外部的负载均衡器可以路由到NodePort服务和ClusterIP服务。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值