当前位置: 代码网 > it编程>编程语言>Java > 【kubernetes】关于云原生之k8s集群的pod理论详解

【kubernetes】关于云原生之k8s集群的pod理论详解

2024年07月28日 Java 我要评论
Pod是kubernetes中最小的资源管理组件,Pod也是最小化运行容器化应用的资源对象。

目录

一、pod基础概念


一、pod基础概念

1.1什么是pod?

  • pod是kubernetes中最小的资源管理组件,pod也是最小化运行容器化应用的资源对象
  • 一个pod代表着集群中运行的一个进程。
  • kubernetes中其他大多数组件都是围绕着pod来进行支撑和扩展pod功能的

例如,用于管理pod运行的statefulset和deployment等控制器对象,用于暴露pod应用的service和ingress对象,为pod提供存储的persistentvolume存储资源对象等。

pod和pod之间通过localhost通信、pod与pod跨主机通信借助cni网络插件,网络插件有两个

 1.2在k8s集群中pod有如下两种使用方式

1.2.1一个pod中运行一个容器

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

1.2.2在一个pod中同时运行多个容器

一个pod中也可以同时封装几个需要紧密耦合互相协作的容器,它们之间共享资源。这些在同一个pod中的容器可以互相协作成为一个service单位,比如一个容器共享文件,另一个“sidecar”容器来更新这些文件。pod将这些容器的存储资源作为一个实体来管理。

 举例:sidecar如用于收集日志的filebeat 或者收集监控数据zabbix agent的容器

 1.3pod中运行容器的原则

pause容器有两个核心的功能
  • 一是它提供整个pod的linux命名空间的基础。
  • 二来启用pid命名空间,它在每个pod中都作为pid为1进程(init进程),并回收僵尸进程

●网络:

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

 ●存储:

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

 

 kubernetes中的pause容器主要为每个容器提供以下功能:

  • 在pod中担任linux命名空间(如网络命令空间)共享的基础;
  • 启用pid命名空间,开启init进程。

协调他的容器生命周期、提供健康检查和生存探针 

kubernetes设计这样的pod概念和特殊组成结构有什么用意?????
原因一:在一组容器作为一个单元的情况下,难以对整体的容器简单地进行判断及有效地进行行动。比如,一个容器死亡了 那么引入与业务无关的pause容器作为pod的基础容器,以它的状态代表着整个容器组的状态,这样就可以解决该问题。
原因二:pod里的多个应用容器共享pause容器的ip,共享pause容器挂载的volume,这样简化了应用容器之间的通信问题,也解决了容器之间的文件共享问题。

 1.4通常把pod分为两类

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

 创建自主式pod

kubectl run pod-zzz01 --image=nginx:1.18 --port=80

 

1.4.2控制器管理的pod

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

基于pod控制器创建pod:

kubectl create deployment pod-zzz02 --image=nginx:1.18 --port=80 --replicas=2

 

删除pod验证会被重新拉起 

 因为deployment通常用于管理pod的副本集,而不是单个pod。

二、pod容器的分类

启动顺序:基础容器------>init初始化容器------>应用容器 

2.1基础容器(infrastructure container)

维护整个 pod 网络和存储空间
node 节点中操作
//启动一个pod时,k8s会自动启动一个基础容器
cat /opt/kubernetes/cfg/kubelet
......
--pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google-containers/pause-amd64:3.0"

每次创建 pod 时候就会创建,运行的每一个pod都有一个 pause-amd64 的基础容器自动会运行,对于用户是透明的
docker ps -a
registry.cn-hangzhou.aliyuncs.com/google-containers/pause-amd64:3.0   "/pause"

2.2初始化容器(initcontainers)

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

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

init 容器总是运行到成功完成为止
每个 init 容器都必须在下一个 init 容器启动之前成功完成启动和退出

 

 2.3应用容器(maincontainer)

并行启动

应用容器(业务容器/main container):提供应用程序业务

应用容器是在所有init容器都成功的完成启动退出后才会启动;如果pod定义了多个应用容器,它们是并行启动的

三、实战-------启动两个init容器

 

3.2编辑demo1

定义了一个具有 2 个 init 容器的简单 pod。 第一个等待 myservice 启动, 第二个等待 mydb 启动。 一旦这两个 init容器都启动完成,pod 将启动 spec 中的应用容器。

apiversion: v1
kind: pod
metadata:
  name: myapp-pod
  labels:
    spp: 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;']

 

kubectl apply  -f demo1.yaml #构建资源
 
kubectl get pods|grep myapp

 

3.3解决问题 

过滤出myapp

查看pod详细信息

 查看日志信息查看日志信息

 我们发现是无法解析myservice,查看coredns是否正常

kubectl get pod -n kube-system

 再查看service是否正常 、发现没有init的service服务,需要创建一个server

apiversion: v1
kind: service
metadata:
  name: myservice
spec:
  ports:
  - protocol: tcp
    port: 80
    targetport: 80
  selector:
    name: zzz

创建资源

    启动文件后,再次查看pod有相应服务

 使用同样的方法修改init-mydb的配置

kubectl describe pod myapp-pod

  查看日志信息

kubectl logs myapp-pod -c init-mydb

编辑svc-demo1文件

这边只需要名字修改即可

 

执行文件后,需要等pod创建完

先运行init初始化容器,init初始化容器成功后,应用容器就启动成功了

init容器无论写哪里,都先执行初始化容器,init容器按写的上下顺序执行

 关于pod容器启动说明,

3.4pod容器分类汇总

pause容器(基础容器/父容器/根容器):
给pod容器组做环境初始化,功能具体见上
pause容器是pod最先启动的容器
                                     
init容器(初始化容器/init container):
可以在应用容器启动前,为应用容器提供运行依赖环境或工具包;还可以阻塞或延迟应用容器的启动
init容器是在pause容器之后启动的;如果pod定义了多个init容器,它们是串行启动的,即要在上一个init容器成功的完成启动退出后才会启动下一个init容器
 
应用容器(业务容器/main container):
提供应用程序业务
应用容器是在所有init容器都成功的完成启动退出后才会启动;如果pod定义了多个应用容器,它们是并行启动的

四、镜像拉取策略(image pullpolicy) 

  • ifnotpresent:在镜像已经存在的情况下,kubelet 将不再去拉取镜像,仅当本地缺失时才从仓库中拉取,默认的镜像拉取策略
  • always:每次创建 pod 都会重新拉取一次镜像;
  • never:pod 不会主动拉取这个镜像,仅使用本地镜像。
  • 注意:对于标签为“:latest”的镜像文件,其默认的镜像获取策略即为“always”;而对于其他标签的镜像,其默认策略则为“ifnotpresent”。

 nginx:latest

4.1配置always 

apiversion: v1
kind: pod
metadata:
  name: pod-test1
spec:
  containers:
    - name: nginx
      image: nginx
      imagepullpolicy: always
      command: [ "echo", "success"]

 

  默认拉取nginx镜像,镜像重启策略为always,会一直重启;此时 pod 的状态异常,原因是 echo 执行完进程终止,容器生命周期也就结束了

kubectl describe pod pod-test1

可以发现 pod 中的容器在生命周期结束后,由于 pod 的重启策略为 always,容器再次重启了,并且又重新开始拉取镜像

 4.2配置ifnotpresent

注意:

image nginx:latest或nginx 镜像的标签为latest或者无标签时,默认拉取镜像策略为always

nginx:1.14 镜像的标签为非latest时,默认的镜像为获取策略为ifnotpresent
apiversion: v1
kind: pod
metadata:
  name: pod-test1
spec:
  containers:
    - name: nginx
      image: nginx:1.18
    # imagepullpolicy: always
      command: [ "echo", "success"]

4.3配置never 

apiversion: v1
kind: pod
metadata:
  name: pod-test1
spec:
  containers:
    - name: nginx
      image: nginx:1.18
      imagepullpolicy: never
      command: [ "echo", "success"]

 

 这里我们可以看到拉取nginx:1.18镜像失败

设置镜像为空 

apiversion: v1
kind: pod
metadata:
  name: pod-test1
spec:
  containers:
    - name: nginx
      image: nginx
    # imagepullpolicy: always
      command: [ "echo", "success"]

kubectl delete pod pod-test1 
 
kubectl apply -f demo2.yaml 

 

 五、重启策略(restartpolicy)

默认重启策略是:always 

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

 5.1配置always

查看pod状态,等容器启动后30秒后执行exit退出进程进入error状态,就会重启次数加1 

apiversion: v1
kind: pod
metadata:
  name: foo
spec:
  containers:
  - name: busybox
    image: busybox
    args:
    - /bin/sh
    - -c
    - sleep 30;

 

  查看重启策略

 

总是重启,无论正常退出还是异常退出 都会重启容器

5.2配置onfailure 

 

在kubernetes的pod定义文件中,exit 3是不合法的命令,因为pod中的容器不应该主动退出。相反,容器应该运行需要的服务或应用程序,并保持运行状态直到其完成或被终止。 

apiversion: v1
kind: pod
metadata:
  name: foo
spec:
  containers:
  - name: busybox
    image: busybox
    args:
    - /bin/sh
    - -c
    - sleep 10; exit 3
  restartpolicy: onfailure

 

kubectl get pod -w

可以动态监测

过滤重启策略

验证正常退出 不重启 

apiversion: v1
kind: pod
metadata:
  name: foo
spec:
  containers:
  - name: busybox
    image: busybox
    args:
    - /bin/sh
    - -c
    - sleep 10;
  restartpolicy: onfailure

5.3配置never 

异常退出 不重启

apiversion: v1
kind: pod
metadata:
  name: foo
spec:
  containers:
  - name: busybox
    image: busybox
    args:
    - /bin/sh
    - -c
    - sleep 10; exit 3
  restartpolicy: never

 

 

kubectl get pod foo -o yaml|grep -i restart #不区分大小过滤重启策略

验证正常退出也不重启

 

 

 completed 表示正常退出的

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com