Torres-tao  

Pod状态和生命周期管理

Pod概览

理解Pod

Pod是Kubernetes中可以创建和部署的最小单位。Pod代表着集群中运行的进程。

Pod中封装着应用的容器,存储、独立的网络IP,管理容器如何运行的策略选项。Pod代表着部署的一个单位:Kubernetes中应用的一个实例,可能由一个或多个容器组合在一起共享资源。

在Kubernetes集群中Pod有如下两种使用方式:

  • 一个Pod中运行一个容器:这种模式是最常见的用法,在这种使用方式中,可将Pod想象成单个容器的封装,Kubernetes管理的是Pod而不是直接管理容器。
  • 在一个Pod中同时运行多个容器:一个Pod中也可以同时封装几个需要紧密耦合、互相协作的容器,它们之间共享资源。这些在同一个Pod中的容器可以互相协作成为一个service单位——一个容器共享文件,另一个来更新这些文件。Pod将这些容器的存储资源作为一个实体来管理。

Pod中如何管理多个容器

Pod中可以同时运行多个进程(作为容器运行)协同工作。同一个Pod中的容器会自动的分配到同一个node上。同一个Pod中的容器共享资源、网络环境和依赖,它们总是被同时调度。

注意:在一个Pod中同时运行多个容器时一种比较高级的用法。只有当你的容器需要紧密配合协作的时候才考虑这种模式。

Pod中可以共享两种资源:网络和存储

网络

每个Pod都会被分配一个唯一的IP地址。Pod中的所有容器共享网络空间,包括IP地址和端口。Pod内部的容器可以使用localhost互相通信。Pod中的容器与外界通信时,必须分配共享网络资源(例如使用宿主机的端口映射)

存储

可以为一个Pod指定多个共享的Volume。Pod中的所有容器都可以访问共享的volume。Volume也可以用来持久化Pod中的存储资源,以防容器重启后文件丢失。

使用Pod

当Pod被创建后,都会被Kubernetes调度到集群的Node上。直到Pod的进程终止、被删掉、因为缺少资源而被驱逐、或Node故障之前,这个Pod都会一直保持在那个Node上。

注意:重启Pod这种的容器和重启Pod是两码事。Pod只提供容器的运行环境并保持容器的运行状态,重启容器不会造成Pod重启。

Pod不会自愈。如果Pod运行的Node故障,或者是调度器本身故障,这个Pod就会被删除。同样的,如果Pod所在Node缺少资源或Pod处于维护状态,Pod也会被驱逐。Kubernetes使用更高级的Controller来管理Pod实例。虽然可以直接使用Pod(自主式),但是在Kubernetes中通常是使用Controller来管理Pod的。

自主式Pod

自主式pod,即pod自己管理自己。

测试:

apiVersion: v1
kind: Pod
metadata:
  name: tomcat-pod
  namespace: default
  labels:
    tomcat: tomcat-pod
spec:
  containers:
    - name: tomcat-pod-java
      ports:
        - containersPort: 8080
      image: tomcat:latest
      imagePullPolicy: IfNotPresent
#创建pod
[root@k8s-master pod]# kubectl apply -f pod.yaml 
pod/tomcat-pod created
#查看pod
[root@k8s-master pod]# kubectl get pods | grep tomcat
tomcat-pod                  1/1     Running   0          2m24s
#效果验证
[root@k8s-master pod]# kubectl get pods -o wide
NAME                        READY   STATUS    RESTARTS   AGE   IP               NODE        NOMINATED NODE   READINESS GATES
my-nginx-5b56ccd65f-dqpcn   1/1     Running   0          44m   10.244.169.133   k8s-node2   <none>           <none>
my-nginx-5b56ccd65f-kzc5x   1/1     Running   0          48m   10.244.169.132   k8s-node2   <none>           <none>
tomcat-pod                  1/1     Running   0          54s   10.244.36.73     k8s-node1   <none>           <none>
[root@k8s-master pod]# curl 10.244.36.73:8080
<!doctype html><html lang="en"><head><title>HTTP Status 404 – Not Found</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 404 – Not Found</h1><hr class="line" /><p><b>Type</b> Status Report</p><p><b>Description</b> The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.</p><hr class="line" /><h3>Apache Tomcat/10.0.14</h3></body></html>

#删除pod,看看效果
[root@k8s-master pod]# kubectl delete pods tomcat-pod
pod "tomcat-pod" deleted
[root@k8s-master pod]# kubectl get pods
NAME                        READY   STATUS    RESTARTS   AGE
my-nginx-5b56ccd65f-dqpcn   1/1     Running   0          53m
my-nginx-5b56ccd65f-kzc5x   1/1     Running   0          57m

可以看到,当删除pod之后,pod不会再创建一个新的pod,而是彻底从机器上删除了,这种自主式pod适合测试环境或者非核心业务场景。

问题:tomcat为何报404?

tomcat官方镜像是精简的镜像,需要将镜像中webapps.dist目录下的ROOT目录复制到webapps目录下

Pod解析

Pod是Kubernetes中可以创建的最小部署单元,也是Kubernetes REST API中的顶级资源类型。

什么是Pod

Pod就像豌豆荚一样,它由一个或多个容器组成,它们共享容器存储、网络和容器运行配置项。Pod中的容器总是被同时调度,有共同的运行环境。可以将单个Pod想象成运行独立应用的“逻辑主机”——其中运行着一个或多个紧密耦合的应用容器(在有容器之前,这些应用都是运行在几个相同的物理机或虚拟机上。)

Pod中的容器共享IP地址和端口号,它们之间可以通过localhost互相发现。它们之间可以通过进程间通信,如SystemV信号或者POSIX共享内存。不同Pod之间的容器具有不同的IP地址,不能直接通过IPC通信。

Pod中的容器也有访问共享volume的权限,这些volume会被定义成pod的一部分并挂载到应用容器的文件系统中。

Volume和Pod有相同的生命周期(当其UID存在的时候)。当Pod因为某种原因被删除或者被新创建的相同的Pod取代,它相关的东西(如Volume)也会被销毁和再创建一个新的volume。

Pod的动机

管理

Pod是一个服务的多个进程的聚合单位,pod提供这些模型能够简化应用部署管理,通过提供一个更高级别的抽象的方式。Pod作为一个独立的部署单位,支持横向扩展和复制。共生(协同调度)、命运共同体、协同复制、资源共享、依赖管理,Pod都会自动的为容器处理这些问题。

资源共享和通信

Pod中的应用可以共享网络空间,因此可以通过localhost互相发现。pod中的应用必须协调端口占用,每个pod都有一个唯一的IP地址,和物理机、其他pod都处于一个扁平的网络空间中,它们之间可以直接连通。

Pod的使用

Pod也可以用于垂直应用栈(如LAMP),这样使用的主要动机是为了支持共同调度和协调管理应用程序,例如:

  • 内容管理系统、文件和数据加载器、本地换群管理器等
  • 日志和检查点备份、压缩、旋转、快照等
  • 数据变更观察者、日志和监控适配器、活动发布者等
  • 控制器、管理器、配置器、更新器等

通常单个pod中不会同时运行一个应用的多个实例。

为何不直接在一个容器中运行多个应用程序?

  1. 透明。让Pod中的容器对基础设施可见,以便基础设施能够为这些容器提供服务,例如进程管理和资源监控
  2. 解耦软件依赖。每个容器都可以进行版本管理,独立的编译和发布。
  3. 使用方便。用户不必运行自己的进程管理器,还要担心错误信号传播等
  4. 效率。因为由基础架构提供更多的职责,所以容器可以变得更加轻量级。

为何不支持容器的亲和性的协同调度?

此方法可以提供容器的协同定位,能够根据容器的亲和性进行调度,但是无法使用pod带来的大部分好处,例如资源共享、IPC、保持状态一致性和简化管理等。

Pod的终止

因为Pod作为在集群的节点上运行的进程,所以不再需要的时候能够优雅地终止掉是十分必要的。用户需要能够发起一个删除Pod的请求,并且知道它们何时会被终止,是否被正确的删除。用户想终止程序时发送删除pod的请求,在pod可以被强制删除前会有一个宽限期,会发送一个TERM请求到每个容器的主进程。一旦超时,将向主进程发送KILL信号并从API server中删除。如果kubelet或者container manager在等待进程终止的过程中重启,在重启后仍然会重试完整的宽限期。流程如下:

  1. 用户发送删除pod的命令,默认宽限期是30秒
  2. 在Pod超过该宽限期后API server就会更新Pod的状态为“dead”
  3. 在客户端命令上显示的Pod状态为:terminating
  4. 和第三步同时进行,当kubelet发现pod被标记为“terminating”状态时,开始停止pod进程:
    1. 如果在pod中定义了preStop hook,在停止pod前会被调用。如果在宽限期过后,preStop hook依然在运行,第二步会再增加2秒的宽限期;
    2. 向Pod中的进程发送TERM信息
  5. 和第三步同时进行,该Pod将从该service的端点列表中删除,不再是replication controller的一部分。关闭得慢的pod将继续处理load balancer转发的流量
  6. 过了宽限期后,将向Pod中依然运行的进程发送SIGKILL信号而杀掉进程。
  7. Kubelet会在API server中完成Pod的删除,通过将优雅周期设置为0(立马删除)。Pod在API中消失,并且在客户端也不可见。

删除宽限期默认是30秒。kubelet delete命令支持--grace-period=选项,允许用户设置自己的宽限期。如果设置为0将强制删除Pod。在kubect>=1.5版本的命令中,必须同时使用--force和--grace-period=0来强制删除Pod。

可在yaml文件中通过{{ .spec.spec.terminationGracePeriodSeconds }}来修改此值。

Init容器

这是一种专用的容器,在应用程序容器启动之前运行,用来包含一些应用镜像中不存在的实用工具或安装脚本

Init容器与普通容器的区别

Init容器支持应用容器的全部字段和特性,包括资源限制、数据卷和安全设置。而Init不支持Readliness Probe,因为它们必须在Pod就绪之前运行完成。

如果为一个Pod指定了多个Init容器,那些容器会按顺序一次运行一个。只有当前面的Init容器必须运行成功后,才可以运行下一个Init容器。当所有的Init容器运行完成后,Kubernetes才初始化Pod和运行应用容器。

如果Pod的Init容器失败,Kubernetes会不断地重启该Pod,直到Init容器成功为止。当然,如果Pod对应的重启策略(restartPolicy)为Never,它不会重启。

Init容器能做什么?

因为Init容器具有与应用容器分离的单独镜像,所以它们的启动相关代码具有如下优势:

  • 它们可以包含应用程序镜像中不存在的实用程序或自定义设置代码
  • 应用程序镜像构建者和部署者角色可以独立工作,无需共同构建
  • 它们使用Linux Namespace,所以对应用容器具有不同的文件系统视图。因此,它们可以具有访问Serect的权限,而应用程序不能够访问
  • 它们在应用容器启动之前运行完成,而应用程序容器是并行运行的,所以Init容器能够提供一种简单的阻塞或延迟应用容器的启动分方法,直到满足了一组先决条件。
posted on 2022-04-22 14:55  雷子锅  阅读(159)  评论(0编辑  收藏  举报