pod介绍之 容器分类与重启策略

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: pod介绍之 容器分类与重启策略

一   pod 基础概念介绍

1,pod 是什么

Pod是kubernetes中最小的资源管理组件Pod也是最小化运行容器化应用的资源对象。一个Pod代表着集群中运行的一个进程。kubernetes中其他大多数组件都是围绕着Pod来进行支撑和扩展Pod功能的,例如,用于管理Pod运行的StatefulSet和Deployment等控制器对象,用于暴露Pod应用的Service和Ingress对象,为Pod提供存储的PersistentVolume存储资源对象等。

 

2,Pod使用方式

一个Pod中运行一个容器。“每个Pod中一个容器”的模式是最常见的用法;在这种使用方式中,你可以把Pod想象成是单个容器的封装,kuberentes管理的是Pod而不是直接管理容器。

在一个Pod中同时运行多个容器。一个Pod中也可以同时封装几个需要紧密耦合互相协作的容器,它们之间共享资源。这些在同一个Pod中的容器可以互相协作成为一个service单位,比如一个容器共享文件,另一个“sidecar”容器来更新这些文件。Pod将这些容器的存储资源作为一个实体来管理。(只适用于收集日志,监控

3,如何解决一个pod 多容器通信

pause容器

一个Pod下的容器必须运行于同一节点上。现代容器技术建议一个容器只运行一个进程,该进程在容器中PID命令空间中的进程号为1,可直接接收并处理信号,进程终止时容器生命周期也就结束了。若想在容器内运行多个进程,需要有一个类似Linux操作系统init进程的管控类进程,以树状结构完成多进程的生命周期管理。运行于各自容器内的进程无法直接完成网络通信,这是由于容器间的隔离机制导致,k8s中的Pod资源抽象正是解决此类问题,Pod对象是一组容器的集合,这些容器共享Network、UTS及IPC命令空间,因此具有相同的域名、主机名和网络接口,并可通过IPC直接通信。

 

4,pod 组成

pause容器(理解为 pod 里的 管理员) 也可以叫基础容器 父容器

每个Pod都有一个特殊的被称为“基础容器”的Pause容器。Pause容器对应的镜像属于Kubernetes平台的一部分,除了Pause容器,每个Pod还包含一个或者多个紧密相关的用户应用容器。

 

5, k8s 中的 pod

  1. containerPort:
  • 定义: 这是指定在 Pod 规格(spec)中容器级别的端口,代表容器内部应用程序监听的端口。它告诉 Kubernetes 容器正在监听哪个端口以便接收网络请求。
  • 用途: 当 Kubernetes 管理容器时,会用到此信息来了解容器期望接收网络连接的端口,尽管它并不直接用于 Service 路由,但它对于理解容器的网络需求是必要的。
  1. targetPort:
  • 定义: 这是 Service 定义的一部分,指定 Service 应该如何将接收到的流量路由到后端 Pods 的具体端口上。它可以是一个数字或一个字符串(对应于 PodSpec 中的端口名称)。
  • 用途: 即便 targetPort 可以与 containerPort 相同,但它提供了灵活性,允许你将 Service 流量定向到容器的不同端口,或者在复杂的配置中使用端口名称进行路由。
  1. port(或称为servicePort):
  • 定义: 这是在 Service 定义中指定的逻辑端口,用于集群内部的通信。它是 Service 的一部分,集群内的其他组件可以通过这个端口访问 Service,而无需知道后端 Pod 的具体细节。
  • 用途: 作为 Service 的内部访问点,它简化了服务发现过程,使得服务调用方只需要知道 Service 的名字和这个端口,而不需要关心后端 Pod 的 IP 地址或端口。
  1. nodePort:
  • 定义: 当 Service 类型设置为 NodePort 时,Kubernetes 会在每个节点上开放一个特定范围内的静态端口(默认通常是 30000-32767),并将其绑定到 Service 的 port 上。
  • 用途: nodePort 允许外部流量通过任意节点的 IP 地址加上这个端口直接访问到 Service。这为集群外部的客户端提供了一种访问 Service 的方式,而无需设置更复杂的负载均衡器或入口控制器。

总结起来,这四个概念描述了 Kubernetes 中网络流量从外部到容器内部的路由路径,以及集群内部的服务发现机制。containerPort 关注容器自身,targetPortport 服务于 Service 的定义和内部路由,而 nodePort 则扩展了服务的可访问性至集群外部。

二   pause容器

1,pause容器 是什么

Pod资源中针对各容器提供网络命令空间等共享机制的是底层基础容器pause,基础容器(也可称为父容器)pause就是为了管理Pod容器间的共享操作,这个父容器需要能够准确地知道如何去创建共享运行环境的容器,还能管理这些容器的生命周期。为了实现这个父容器的构想,kubernetes中,用pause容器来作为一个Pod中所有容器的父容器。这个pause容器有两个核心的功能,一是它提供整个Pod的Linux命名空间的基础。二来启用PID命名空间,它在每个Pod中都作为PID为1进程(init进程),并回收僵尸进程。

 

2,pause容器作用

pause容器使得Pod中的所有容器可以共享两种资源:网络和存储。

网络

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

存储

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

3, pause容器功能

  • 在pod中担任Linux命名空间(如网络命令空间)共享的基础;
  • 启用PID命名空间,开启init进程。
  • 协调他的容器生命周期
  • 提供健康检查和生存探针

4, pause容器 的意义

●原因一:在一组容器作为一个单元的情况下,难以对整体的容器简单地进行判断及有效地进行行动。比如,一个容器死亡了 那么引入与业务无关的Pause容器作为Pod的基础容器,以它的状态代表着整个容器组的状态,这样就可以解决该问题。

●原因二:Pod里的多个应用容器共享Pause容器的IP,共享Pause容器挂载的Volume,这样简化了应用容器之间的通信问题,也解决了容器之间的文件共享问题。

三   Pod 分类

1,自主式Pod

这种Pod本身是不能自我修复的,当Pod被创建后(不论是由你直接创建还是被其他Controller),都会被Kuberentes调度到集群的Node上。直到Pod的进程终止、被删掉、因为缺少资源而被驱逐、或者Node故障之前这个Pod都会一直保持在那个Node上。Pod不会自愈。如果Pod运行的Node故障,或者是调度器本身故障,这个Pod就会被删除。同样的,如果Pod所在Node缺少资源或者Pod处于维护状态,Pod也会被驱逐。(没有存到etcd

 

2,控制器管理的Pod

Kubernetes使用更高级的称为Controller的抽象层,来管理Pod实例。Controller可以创建和管理多个Pod,提供副本管理、滚动升级和集群级别的自愈能力。例如,如果一个Node故障,Controller就能自动将该节点上的Pod调度到其他健康的Node上。虽然可以直接使用Pod,但是在Kubernetes中通常是使用Controller来管理Pod的。

 

四   pod 如何通信

1,同一个主机中的Pod通信

  1. 共享网络环境:所有Pod都处在同一个物理主机上,因此它们共享主机的网络栈,但各自拥有独立的IP地址。
  2. 虚拟网络设备:每个Pod有自己的网络空间(网络命名空间),并通过虚拟以太网接口(veth pair)与主机的网络环境相连。这就像每个Pod有一根“虚拟网线”连接到一起。
  3. 直接IP通信:当一个Pod需要与同主机上的另一个Pod通信时,它直接使用对方Pod的IP地址发送数据包。因为它们都在同一台机器上,所以数据不需要离开主机就能到达目标Pod。
  4. 系统自动路由:操作系统会根据目标IP地址识别出这是同主机内的通信,然后通过内部的虚拟网络路径直接将数据传递给目标Pod,这个过程对于用户和应用来说是透明的。

简单来说,就像是住在同一栋楼里的两户人家,他们虽然门牌号不同(各自有独立IP),但因为同在一栋楼(同一主机),可以直接按门牌号(IP地址)互寄信件(发送数据),无需走出大楼。

可以通过localhost(即127.0.0.1)或者直接使用Pod的IP地址进行通信,因为它们共享网络命名空间。但推荐使用Kubernetes提供的Pod的IP地址进行通信

2,不同主机间的Pod通信

对于跨节点的Pod通信,通常需要通过Kubernetes Service来实现:

  1. Cluster IP Service:Kubernetes会为每个定义的Service自动分配一个虚拟IP地址(Cluster IP),并通过iptables或其他网络插件(如Calico、Flannel等)将流量路由到后端Pod上。不同节点上的Pod可以通过这个Cluster IP访问到服务,而无需关心后端Pod的实际位置或IP地址。
  2. NodePort Service:如果需要从集群外部访问Pod,可以使用NodePort类型的服务,它会在每个节点上开放一个特定的端口,通过这个端口可以路由到Service对应的Pod上。
  3. LoadBalancer Service(云环境)或ExternalIP(本地或自建集群):在需要更高水平的负载均衡时,可以使用LoadBalancer Service(适用于云提供商),它会在公有云上创建一个负载均衡器,并将流量分发到多个节点。对于非云环境,可以手动配置ExternalIP来达到类似效果。

3,同一个Pod内部容器间通信

pause 容器

在同一个Pod中的多个容器之间通信非常直接,因为它们共享同一个网络命名空间。这意味着它们本质上是在同一个“网络环境下”,可以像在同一台机器上的进程一样互相通信。下面是几个关键点:

  1. 共享网络栈:Pod中的所有容器共享同一个网络栈,包括IP地址、端口空间、以及网络设备。因此,容器间可以使用localhost或者Pod的IP地址进行通信。
  2. 端口访问:容器可以绑定到不同的端口,但因为它们共享网络命名空间,可以从任一容器通过localhost加上对应的端口号访问其他容器的服务。
  3. 通信示例:如果容器A运行了一个web服务在端口8080上,容器B可以直接通过http://localhost:8080来访问容器A的服务,无需任何特殊的网络配置。
  4. 共享卷通信:虽然不是直接的网络通信方式,但通过共享卷(Volumes),容器之间也可以交换文件或状态信息,实现数据层面的通信。
  5. 无需额外配置:由于网络命名空间的共享,容器间通信无需配置额外的网络路由或服务发现机制,这也是将紧密相关的服务放在同一Pod中的优势之一。

总结来说,在同一个Pod内的容器通信十分简便,几乎就如同它们是运行在同一台机器上的不同进程,可以直接通过本地环回地址(localhost)或者Pod的IP来互相通信。

五   Pod中  容器的分类

1,基础容器(infrastructure container)

每次创建 Pod 时候就会创建,运行的每一个Pod都有一个 pause-amd64 的基础容器自动会运行,对于用户是透明的   用于维护整个 Pod 网络和存储空间

2,初始化容器(initcontainers)

2.1 初始化容器是什么

Init容器必须在应用程序容器启动之前运行完成,而应用程序容器是并行运行的,所以Init容器能够提供了一种简单的阻塞或延迟应用容器的启动的方法。

 

2.2 初始化容器特点

Init 容器与普通的容器非常像,除了以下两点:

●Init 容器总是运行到成功完成为止 (循环)

●每个 Init 容器都必须在下一个 Init 容器启动之前成功完成启动和退出

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

 

2.3 Init 的容器作用

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

●Init 容器可以包含一些安装过程中应用容器中不存在的实用工具或个性化代码。例如,没有必要仅为了在安装过程中使用类似 sed、 awk、 python 或 dig 这样的工具而去FROM 一个镜像来生成一个新的镜像。

●Init 容器可以安全地运行这些工具,避免这些工具导致应用镜像的安全性降低。

●应用镜像的创建者和部署者可以各自独立工作,而没有必要联合构建一个单独的应用镜像。

●Init 容器能以不同于Pod内应用容器的文件系统视图运行。因此,Init容器可具有访问 Secrets 的权限,而应用容器不能够访问

●由于 Init 容器必须在应用容器启动之前运行完成,因此 Init 容器提供了一种机制来阻塞或延迟应用容器的启动, (打个比方,tomcat 必须基于jdk)

直到满足了一组先决条件。一旦前置条件满足,Pod内的所有的应用容器会并行启动。

 

3,  应用容器(Maincontainer)

并行启动

 

六     Init容器实例

1,官网示例

https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/init-containers/

 

2,演示Init容器

2.1 写一个 yaml 文件

不管顺序 都是先看初始化容器

初始化容器 从上往下

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  containers:
  - name: myapp-container
    image: busybox:1.28
    command: ['sh', '-c', 'echo The app is running! && sleep 3600']
  initContainers:
  - name: init-myservice
    image: busybox:1.28
    command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']
  - name: init-mydb
    image: busybox:1.28
    command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']

这段YAML配置文件定义了一个Kubernetes Pod资源对象,详细解释如下:

  • apiVersion: v1:指定了该资源对象使用的API版本是v1,这是Kubernetes核心API的一个稳定版本,用于定义基础资源如Pods。
  • kind: Pod:声明了资源的对象类型是Pod,Pod是Kubernetes中最小的可部署的单元,可以包含一个或多个共享网络和存储空间的容器。
  • metadata:部分提供了关于此Pod的元数据:
  • name: myapp-pod:为Pod指定了一个名称,即myapp-pod
  • labels: 定义了一组标签(key-value对),这里只有一个标签app: myapp,用于标识Pod属于哪个应用,便于通过标签选择器(label selectors)进行操作或配置Service等资源。
  • spec:部分描述了Pod期望的状态配置:
  • containers:列表定义了Pod中运行的主容器集合。
  • 第一个容器:
  • name: myapp-container:容器的名称。
  • image: busybox:1.28:指定容器使用的镜像是busybox:1.28,这是一个轻量级的Linux发行版,常用于测试和基础命令行操作
  • command: ['sh', '-c', 'echo The app is running! && sleep 3600']:容器启动时执行的命令,这里先打印一条消息,然后让容器睡眠3600秒(1小时),模拟一个持续运行的服务。
  • initContainers:列表定义了初始化容器集合,这些容器会在应用容器启动之前运行,并且必须全部成功退出后,应用容器才会启动
  • init-myservice:等待名为myservice的服务解析成功,通过nslookup命令检查,如果服务未就绪则每隔2秒重试。
  • init-mydb:与上述类似,但等待的是名为mydb的服务。

通过这样的配置,Pod定义了一个主要的容器myapp-container来运行应用,并且在启动应用容器之前,会先执行两个初始化容器来确保依赖的服务(myservicemydb)已经准备就绪。这种方式确保了服务间的依赖关系得到妥善处理,提高了应用部署的健壮性。

2.2 执行yaml  查看结果

执行

查看pod 信息 kubectl describe pod myapp-pod

或者 直接看日志   可以看到一直在等待 init 容器

也可以查看pod 状态   看到

2.3  准备 service
apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9376

查看pod   显示init 容器已经准备好一个

2.4 准备mydb
apiVersion: v1
kind: Service
metadata:
  name: mydb
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9377

查看pod 应用容器running

3,  特别说明

●在Pod启动过程中,Init容器会按顺序在网络和数据卷初始化之后启动。每个容器必须在下一个容器启动之前成功退出。

●如果由于运行时或失败退出,将导致容器启动失败,它会根据Pod的restartPolicy指定的策略进行重试。然而,如果Pod的restartPolicy设置为Always,Init容器失败时会使用RestartPolicy策略。

●在所有的Init容器没有成功之前,Pod将不会变成Ready状态。Init容器的端口将不会在Service中进行聚集。正在初始化中的Pod处于Pending状态,但应该会将Initializing状态设置为true。

●如果Pod重启,所有Init容器必须重新执行。

●对Init容器spec的修改被限制在容器image字段,修改其他字段都不会生效。更改Init容器的image字段,等价于重启该Pod。

●Init容器具有应用容器的所有字段。除了readinessProbe,因为Init容器无法定义不同于完成(completion)的就绪(readiness)之外的其他状态。这会在验证过程中强制执行。

●在Pod中的每个app和Init容器的名称必须唯一;与任何其它容器共享同一个名称,会在验证时抛出错误。

 

六   镜像拉取策略(image PullPolicy)

Pod 的核心是运行容器,必须指定容器引擎,比如 Docker,启动容器时,需要拉取镜像,k8s 的镜像拉取策略可以由用户指定

1,镜像拉取策略有哪些

IfNotPresent:在镜像已经存在的情况下,kubelet 将不再去拉取镜像,仅当本地缺失时才从仓库中拉取,默认的镜像拉取策略

Always:每次创建 Pod 都会重新拉取一次镜像

Never:Pod 不会主动拉取这个镜像,仅使用本地镜像

注意:对于标签为“:latest”的镜像文件,其默认的镜像获取策略即为“Always”;而对于其他标签的镜像,其默认策略则为“IfNotPresent”。

 

2, yaml 语法

imagePullPolicy: Always

apiVersion: v1
kind: Pod
metadata:
  name: private-image-test-1
spec:
  containers:
    - name: uses-private-image
      image: $PRIVATE_IMAGE_NAME
      imagePullPolicy: Always
      command: [ "echo", "SUCCESS" ]

七    重启策略(restartPolicy)

当 Pod 中的容器退出时通过节点上的 kubelet 重启容器。适用于 Pod 中的所有容器。

1,重启策略 有哪些

Always:当容器终止退出后,总是重启容器,默认策略

OnFailure:当容器异常退出(退出状态码非0)时,重启容器;正常退出则不重启容器

(比如 exit 3 非正常代码 echo$? 非0 是非正常退出 )

Never:当容器终止退出,从不重启容器

#注意:K8S 中不支持重启 Pod 资源,只有删除重建

 

2,yaml 语法

restartPolicy: Never

#注意:跟container同一个级别

apiVersion: v1
kind: Pod
metadata:
  name: foo
spec:
  containers:
  - name: busybox
    image: busybox
    args:
    - /bin/sh
    - -c
    - sleep 30; exit 3
  restartPolicy: Never

文章知识点与官方

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
28天前
|
存储 Kubernetes Cloud Native
【阿里云云原生专栏】云原生容器存储:阿里云CSI与EBS的高效配合策略
【5月更文挑战第29天】阿里云提供云原生容器存储接口(CSI)和弹性块存储(EBS)解决方案,以应对云原生环境中的数据存储挑战。CSI作为Kubernetes的标准接口简化存储管理,而EBS则提供高性能、高可靠性的块存储服务。二者协同实现动态供应、弹性伸缩及数据备份恢复。示例代码展示了在Kubernetes中使用CSI和EBS创建存储卷的过程。
160 3
|
1月前
|
运维 Kubernetes 网络协议
Kubernetes详解(十六)——Pod容器探测
Kubernetes详解(十六)——Pod容器探测
70 1
|
1月前
|
运维 Kubernetes 网络协议
Kubernetes详解(十六)——Pod容器探测
Kubernetes详解(十六)——Pod容器探测
38 0
|
30天前
|
运维 监控 Kubernetes
构建高效自动化运维体系:基于容器技术的持续部署策略
【5月更文挑战第27天】 在现代IT基础设施的管理中,自动化运维已成为提升效率、保障稳定性的关键因素。本文将探讨如何利用容器技术实现服务的快速部署和可靠运行,以及构建一个高效的自动化运维体系。通过深入分析容器化的优势与挑战,并提出一个切实可行的持续部署策略,旨在帮助运维团队优化现有流程,应对快速变化的业务需求。
|
13天前
|
算法 容器
【经典LeetCode算法题目专栏分类】【第1期】左右双指针系列:盛最多水的容器、接雨水、回文子串、三数之和
【经典LeetCode算法题目专栏分类】【第1期】左右双指针系列:盛最多水的容器、接雨水、回文子串、三数之和
|
1月前
|
存储 Kubernetes Docker
容器服务Kubernetes版产品使用合集之集群节点和 pod 实现自动扩缩容如何解决
容器服务Kubernetes版,作为阿里云提供的核心服务之一,旨在帮助企业及开发者高效管理和运行Kubernetes集群,实现应用的容器化与微服务化。以下是关于使用这些服务的一些建议和合集,涵盖基本操作、最佳实践、以及一些高级功能的使用方法。
|
27天前
|
Linux Docker 容器
蓝易云 - 【Linux】如何在linux系统重启或启动时执行命令或脚本(也支持docker容器内部)
以上就是在Linux系统和Docker容器中设置启动时运行命令或脚本的方法。希望对你有所帮助。
97 0
|
30天前
|
监控 安全 云计算
云端防御战线:云计算环境下的网络安全策略构建高效稳定的Docker容器监控体系
【5月更文挑战第27天】 在数字化时代的浪潮中,云计算已成为企业与个人存储和处理数据的重要平台。然而,随着云服务使用率的飙升,网络威胁也愈发狡猾且复杂。本文将深入探讨在云计算环境中维护网络安全的挑战及策略,重点分析信息安全的关键组成部分,并提出多层次防御模型以增强云环境的数据保护能力。通过剖析最新的安全技术与实践,我们旨在为读者提供一套全面的网络安全解决方案蓝图。
|
10天前
|
NoSQL 关系型数据库 Redis
Docker的通俗理解和通过宿主机端口访问Redis容器的实例
本文目标:引导初学者入门Docker,理解镜像、容器和宿主机概念,学习常用Docker命令,特别是如何创建并从Redis容器通过宿主机端口访问。 关键点: - Docker核心:镜像(类)、容器(实例)、宿主机(运行环境)。 - `docker pull` 拉取镜像,如 `redis:3.0`。 - `docker run -d --name` 后台运行容器,如 `my-redis`。 - `-p` 参数做端口映射,如 `6379:6379`。 - `docker exec -it` 交互式进入容器,如 `bash` 或执行命令。
|
7天前
|
前端开发 安全 数据库
Web架构&前后端分离站&Docker容器站&集成软件站&建站分配
Web架构&前后端分离站&Docker容器站&集成软件站&建站分配