kubernetes中pod的管理及优化

目录

[2 资源管理方式](#2 资源管理方式)

[2.1 命令式对象管理](#2.1 命令式对象管理)

[2.2 资源类型](#2.2 资源类型)

[2.2.1 常用的资源类型](#2.2.1 常用的资源类型)

[2.2.2 kubectl常见命令操作](#2.2.2 kubectl常见命令操作)

[2.3 基本命令示例](#2.3 基本命令示例)

[2.4 运行和调试命令示例](#2.4 运行和调试命令示例)

[2.5 高级命令示例](#2.5 高级命令示例)

[3 pod简介](#3 pod简介)

[3.1 创建自主式pod(生产环境不推荐)](#3.1 创建自主式pod(生产环境不推荐))

[3.1.1 优缺点](#3.1.1 优缺点)

[3.1.2 创建自主式pod示例](#3.1.2 创建自主式pod示例)

[3.2 利用控制器管理pod(推荐)](#3.2 利用控制器管理pod(推荐))

[3.2.1 优点](#3.2.1 优点)

[3.2.2 控制器管理pod示例](#3.2.2 控制器管理pod示例)

[3.2.3 应用版本更新和回滚](#3.2.3 应用版本更新和回滚)

[3.3 利用yaml文件部署应用](#3.3 利用yaml文件部署应用)

[3.3.1 用yaml文件部署应用有以下优点](#3.3.1 用yaml文件部署应用有以下优点)

[3.3.2 资源清单参数](#3.3.2 资源清单参数)

[3.3.2.1 如何获取资源帮助](#3.3.2.1 如何获取资源帮助)

[3.3.3 编写示例](#3.3.3 编写示例)

[3.3.3.1 运行简单的单个容器pod](#3.3.3.1 运行简单的单个容器pod)

[3.3.3.2 运行多个容器pod](#3.3.3.2 运行多个容器pod)

[3.3.3.3 理解pod间的网络整合](#3.3.3.3 理解pod间的网络整合)

[3.3.3.4 端口映射](#3.3.3.4 端口映射)

[3.3.3.5 设定环境变量](#3.3.3.5 设定环境变量)

[3.3.3.6 资源限制](#3.3.3.6 资源限制)

[3.3.3.7 容器启动管理](#3.3.3.7 容器启动管理)

[3.3.3.8 选择运行的节点](#3.3.3.8 选择运行的节点)

[3.3.3.9 共享宿主机网络](#3.3.3.9 共享宿主机网络)

[4 pod的生命周期](#4 pod的生命周期)

[4.1 INIT容器](#4.1 INIT容器)

[4.1.1 INIT容器的功能](#4.1.1 INIT容器的功能)

[4.1.2 INIT容器示例](#4.1.2 INIT容器示例)

[4.2 探针](#4.2 探针)

[4.2.1 探针是由kubelet对容器执行的定期诊断](#4.2.1 探针是由kubelet对容器执行的定期诊断)

[4.2.2 Kubelet 可以选择是否执行在容器上运行的三种探针执行和做出反应](#4.2.2 Kubelet 可以选择是否执行在容器上运行的三种探针执行和做出反应)

[4.2.3 ReadinessProbe 与 LivenessProbe 的区别](#4.2.3 ReadinessProbe 与 LivenessProbe 的区别)

[4.2.4 StartupProbe 与 ReadinessProbe、LivenessProbe 的区别](#4.2.4 StartupProbe 与 ReadinessProbe、LivenessProbe 的区别)

[4.2.5 探针实例](#4.2.5 探针实例)

[4.2.5.1 存活探针示例](#4.2.5.1 存活探针示例)

[4.2.5.2 就绪探针示例](#4.2.5.2 就绪探针示例)


1 资源管理介绍

  1. 在kubernetes中,所有内容都抽象为资源,用户需要通过操作资源来管理kubernetes
  2. kubernetes的本质是一个集群系统,用户可以在集群中部署各种服务
  3. 所谓的部署服务,就是在kubernetes集群中运行一个个容器,并将指定程序跑在容器中
  4. kubernetes的最小管理单元是pod而不是容器,只能将容器放在pod中
  5. kubernetes一般不会直接管理pod,而是通过pod控制器来管理pod
  6. pod中服务的访问是由kubernetes提供的service资源来实现
  7. pod中程序的数据需要持久化是由kubernetes提供的各种存储系统来实现

2 资源管理方式

  • 命令式对象管理:直接使用命令去操作kubernetes资源

    kubectl run nginx-pod --image nginx:latest --port=80

  • 命令式对象配置:通过命令配置和配置文件去操作kubernetes资源

    kubectl create/patch -f nginx-pod.yml

  • 声明式对象配置:通过apply命令和配置文件去操作kubernetes资源

    kubectl apply -f nginx-pod.yml

|---------|------|---------|-------------------|
| 类型 | 适用环境 | 优点 | 缺点 |
| 命令式对象管理 | 测试 | 简单 | 只能操作活动对象,无法审计、跟踪 |
| 命令式对象配置 | 开发 | 可以审计、跟踪 | 项目较大时,配置文件较多,操作麻烦 |
| 声明式对象配置 | 开发 | 支持目录操作 | 意外情况下难以调试 |

2.1 命令式对象管理

kubectl是kuberneter集群的命令工具,通过对集群本身进行管理,并能够在集群上进行容器化应用部署

kubectl命令语法如下:

复制代码
kubectl [comand] [type] [name] [flags]
  • comand:指定要对资源执行的操作,如:create\get\delete
  • type:指定资源类型,如:deployment\pod\service
  • name:指定资源的名称,名称大小写敏感
  • flags:指定额外的可选参数
bash 复制代码
# 查看所有pod
kubectl get pod

# 查看某个pod
kubectl get pod pod_name

# 查看某个pod,并以yaml格式展示
kubectl get pod pod_name -o yaml

2.2 资源类型

kubernetes中所有的内容都抽象为资源

bash 复制代码
kubectl api-resources

2.2.1 常用的资源类型

2.2.2 kubectl常见命令操作

2.3 基本命令示例

kubectl详细命令说明请参考:https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commandshttps://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands

1.显示集群版本

复制代码
kubectl version

2.显示集群信息

复制代码
kubectl cluster-info

3.创建一个webcluster控制器,控制器pod期望为2

复制代码
kubectl create deployment webcluseter --image nginx --replicas 2

4.查看控制器

复制代码
kubectl get deployments.apps

5.查看资源帮助

复制代码
kubectl explain deployment

6.查看控制器帮助参数

复制代码
kubectl explain deployment.spec

7.编辑控制器配置

复制代码
kubectl edit deployments.apps webcluseter

8.利用补丁更改控制器配置

复制代码
kubectl patch  deployments.apps webcluseter -p '{"spec":{"replicas":4}}'

9.删除资源

复制代码
kubectl delete deployments.apps webcluseter

2.4 运行和调试命令示例

1.运行pod

复制代码
kubectl run testpod --image nginx

2.暴漏端口

复制代码
kubectl expose pod testpod --port 80 --target-port 80

3.查看资源详细信息

复制代码
kubectl describe pod testpod

4.查看资源日志

复制代码
kubectl logs pods/testpod

5.运行非交互式pod

复制代码
kubectl run nginx --image nginx

6.运行交互式pod

复制代码
kubectl run -it testpod --image busybox

7.进入到已经运行的容器,且容器有交互式环境

复制代码
kubectl attach pods/testpod -it

8.在已经运行的pod中运行指定命令

复制代码
kubectl exec -it pods/nginx /bin/bash

9.复制日志文件到pod中

复制代码
kubectl cp anaconda-ks.cfg nginx:/

10.复制pod中的文件到本机

复制代码
kubectl cp nginx:/anaconda-ks.cfg anaconda-ks.cfg

2.5 高级命令示例

1.利用命令生成yaml模板文件

复制代码
kubectl create deployment --image nginx webcluster --dry-run=client -o yaml > webcluster.yml

2.管理资源标签

复制代码
kubectl get pod/nginx --show-labels

3.更改标签(--overwrite:覆盖已存在的同名标签

复制代码
kubectl label pod nginx app=webcluster --overwrite

4.删除pod上的标签(控制器会重启启动新pod)

复制代码
kubectl label pod nginx app-

3 pod简介

  1. pod是kuberneter可以创建和管理的最小单元
  2. 一个pod代表着集群中运行的一个进程,每个pod都有唯一的ip
  3. 一个pod类似于一个豌豆荚,包含一个或多个容器(通常是docker)
  4. 多个容器间共享IPC、Network和UTC namespace

3.1 创建自主式pod(生产环境不推荐)

3.1.1 优缺点

优点:

灵活性高:可以精确控制pod的各种配置参数,包括容器的镜像、资源限制、环境变量、命令和参数等,满足特定的应用需求

学习和调试方便:对于学习kubernetes的原理和机制非常有帮助,通过手动创建pod可以深入了解pod的结构和配置方式。在调试问题时,可以更直接地观察和调整pod的设置

适用于特殊场景:在一些特殊情况下,如进行一次性任、快速验证概念或在资源受限的环境中进行特定配置时,手动创建pod可能是一种有效的方式

缺点:

管理复杂:如果需要管理大量的pod,手动创建和维护会变得非常繁琐和耗时,难以实现自动化的扩容缩容、故障恢复等操作

缺乏高级功能:无法自动享受kubernetes提供的高级功能,如自动部署、滚动更新、服务发现等。这可能导致应用的部署和管理效率低下

可维护性差:手动创建的pod在更新应用版本或修改配置时需要手动干预,容易出现错误,并且难以保证一致性。相比之下,通过声明式配置或使用kubernetes的部署工具可以更方便的进行应用的维护和更新

3.1.2 创建自主式pod示例

1.查看所有pod

复制代码
kubectl get pods

2.建立pod

复制代码
kubectl run timinglee --image nginx

3.显示pod较为详细的信息

复制代码
kubectl get pods -o wide

3.2 利用控制器管理pod(推荐)

3.2.1 优点

1.高可用和可靠:

自动故障恢复:如果一个pod失败或被删除,控制器会自动创建新的pod来维持期望的pod数量。确保应用始终处于可用状态,减少因单个pod故障导致的服务中断

健康检测和自愈:可以配置控制器对pod进行健康检查(如存活探针和就绪探针)。如果pod不健康,控制器会采取适当的行动,如重启pod或删除并重新创建它,以保证应用的正常运行

2.可扩展性:

轻松扩缩容:可以通过简单的命令或配置更改来增加或减少pod的数量,以满足不同工作负载的需求。例如,在高流量期间可以快速扩展以处理更多请求,在低流量期间可以缩容以节省资源

水平自动扩缩容(HPA):可以基于自定义指标(如CPU利用率,内存使用情况或应用特定指标)自动调整pod的数量,实现动态的资源分配和成本优化

3.版本管理和更新:

滚动更新:对于deployment等控制器,可以执行滚动更新来逐步替换旧版本的pod为新版本,确保应用在更新过程中始终保持可用。可以控制更新的速率和策略,以减少对用户的影响

回滚:如果新版本出现问题,可以轻松回滚到上一个稳定版本,保证应用的稳定性和可靠性

4.声明式配置:

简洁的配置方式:使用yaml或json格式的声明式配置文件来定义应用的部署需求。这种方式使得配置易于理解、维护和版本控制,同时也方便团队协作

期望状态管理:只需要定义应用的期望状态(如副本数量、容器镜像等),控制器会自动调整实际状态与期望状态保持一致。无需手动管理每一个pod的创建和删除,提高了管理效率

5.服务发现和负载均衡:

自动注册和发现:kubernetes中的服务(service)可以自动发现用控制器管理的pod,并将流量路由到pod。这使得应用的服务发现和负载均衡变得简单可靠,无需手动配置负载均衡器

流量分发:可以根据不同的策略(如轮询、随机等)将请求分发到不同的pod,提高应用的性能和可用性

6.多环境一致性:

一致的部署方式:在不同的环境(如开发、测试、生产)中,可使用相同的控制器和配置来部署应用,确保应用在不同环境的一致行为。这有助于减少部署差异和错误,提高开发和运维效率

3.2.2 控制器管理pod示例

复制代码
# 建立控制器并自动运行pod
kubectl create deployment timinglee --image nginx

# 为timinglee扩容
kubectl scale deployment timinglee --replicas 4

# 为timinglee缩容
kubectl scale deployment timinglee --replicas 2

# 删除控制器,恢复实验环境
kubectl delete deployments.apps timinglee

3.2.3 应用版本更新和回滚

复制代码
# 利用控制器创建pod,期望为2
kubectl create deployment myapp --image myapp:v1 --replicas 2

# 查看pod状态,是否创建成功
kubectl get pod

# 暴漏pod端口,让外部客户能够访问内部pod
kubectl expose deployment myapp --port 80 --target-port 80

# 查看端口是否暴漏成功
kubectl get service myapp

# 访问服务myapp:v1
curl 10.105.155.12

# 查看历史版本
kubectl rollout history deployment myapp

# 更新控制器镜像为myapp:v2
kubectl set image deployments/myapp myapp=myapp:v2

# 查看历史版本,确认是否更新成功
kubectl rollout history deployment myapp

# 访问服务myapp:v2
curl 10.105.155.12

# 版本回滚
kubectl rollout undo deployment myapp --to-revision 1

# 查看回滚是否成功
curl 10.105.155.12

3.3 利用yaml文件部署应用

3.3.1 用yaml文件部署应用有以下优点

1.声明式配置:

  • 清晰表达期望状态:以声明式方式描述应用的部署需求,包括副本数量、容器配置、网络设置等。这使得配置易于理解和维护,并且可以方便的查看应用的预期状态。
  • 可重复性和版本控制:配置文件可以被版本控制,确保在不同环境中的部署一致性。可以轻松回滚到以前的版本或不同环境中重复使用相同的配置。
  • 团队协作:便于团队成员之间共享和协作,大家可以对配置文件进行审核和修改,提高部署的可靠性和稳定性。

2.灵活性和可扩展性:

  • 丰富的配置选项:可以通过yaml文件详细的配置各种kubernetes资源,如Deployment、Service、ConfigMap、Secret等。可以根据应用的特定需求进行高度定制化。
  • 组合和扩展:可以将多个资源的配置组合在一个或多个yaml文件中,实现复杂的应用部署架构。同时,可以轻松的添加新的资源或修改现有资源以满足不断变化的需求。

3.与工具集成:

  • 与CI/CD流程集成:可以将yaml配置文件与持续集成和持续部署(CI/CD)工具集成,实现自动化的应用部署。例如,可以在代码提交后自动触发部署流程,使用配置文件来部署应用到不同的环境。
  • 命令行工具支持:Kubernetes的命令行工具kubectl对yaml配置文件有很好的支持,可以方便的应用、更新和删除配置。同时,还可以使用其它工具来验证和分析yaml配置文件,确保正确性和安全性。

3.3.2 资源清单参数

|------------------------------------------------|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 参数名称 | 类型 | 参数说明 |
| version | String | 这里是指k8s API的版本,目前基本是v1,可以用kubernetes api-versions命令查询 |
| kind | String | 这里指的是yaml文件定义的资源类型和角色,比如pod |
| metadata | Object | 元数据对象,固定值就写metadata |
| metadata.name | String | 元数据对象的名字,这里由我们编写,比如命名pod的名字 |
| metadata.namespace | String | 元数据对象的命名空间,由我们自身定义,默认default |
| Spec | Object | 详细定义对象,固定值就写Spec |
| spec.containers[] | list | 这里是Spec对象的容器列表定义,是个列表 |
| spec.containers[].name | String | 这里定义容器的名字 |
| spec.containers[].image | String | 这里定义用到镜像的名字 |
| spec.containers[].imagePullPolicy | String | 定义镜像拉取策略,有三个值可选:1.Always:每次都尝试重新拉取镜像 2.IfNotPresent:如果本地有镜像就使用本地镜像 3.Never:表示仅使用本地镜像 |
| spec.containers[].command[] | list | 指定容器运行时启动的命令,若未指定则运行容器打包时指定的命令 |
| spec.containers[].args[] | list | 指定容器运行参数,可以指定多个 |
| spec.containers[].workingDir | String | 指定容器工作目录 |
| spec.containers[].volumeMounts[] | list | 指定容器内部的存储卷配置 |
| spec.containers[].volumeMounts[].name | String | 指定可以被容器挂载的卷的名称 |
| spec.containers[].volumeMounts[].mountPath | String | 指定可以被容器挂载的存储卷的路径 |
| spec.containers[].volumeMounts[].readOnly | String | 设置存储卷路径的读写模式,ture或false,默认为写模式 |
| spec.containers[].ports[] | list | 指定容器需要用到的端口列表 |
| spec.containers[].name | String | 指定端口名称 |
| spec.containers[].containerPort | String | 指定容器需要监听的端口号 |
| spec.containers[].ports[].hostPort | String | 指定容器所在主机需要监听的端口号,默认跟上面containerPort相同,注意设置了hostPort同一台主机无法启动该容器的相同副本(因为主机的端口号不能相同,这样会冲突) |
| spec.containers[].ports[].protocol | String | 指定端口协议支持TCP和UDP默认值为TCP |
| spec.containers[].env[] | list | 指定容器运行前需要设置的环境变量列表 |
| spec.containers[].env[].name | String | 指定环境变量名称 |
| spec.containers[].env[].value | String | 指定环境变量值 |
| spec.containers[].resources | Object | 指定资源限制和资源请求的值(这里开始就是设置容器的资源上限) |
| spec.containers[].resources.limits | Object | 指定设置容器运行时资源的运行上限 |
| spec.containers[].resources.limits.cpu | String | 指定CPU的限制,单位为核心数,1=1000m |
| spec.containers[].resources.limits.memory | String | 指定MEM内存的限制,单位为MIB、GiB |
| spec.containers[].resources.requests | Object | 指定容器启动和调度时的限制设置 |
| spec.containers[].resources.requests.cpu | String | CPU请求,单位为核心数,容器启动时初始化可用数量 |
| spec.containers[].resources.requests.memory | String | 内存请求,单位为MIB、GIB,容器启动的初始化可用数量 |
| spec.restartPolicy | string | 定义pod的重启策略,默认值为Always 1.Always:只要容器终止(无论退出状态码是什么),kubelet 都会自动重启容器。 2.OnFailure:仅当容器异常终止 (退出状态码非 0)时,kubelet 才会重启容器;若容器正常终止(退出状态码为 0),则不会重启。 3.Never:无论容器以何种状态终止(正常或异常),kubelet 都不会重启容器。 |
| spec.nodeSelector | Object | 定义Node的Lable过滤标签,以key:value格式指定 |
| spec.imagePullSecrets | Objest | 定义pull镜像时使用secret名称,以name:secretkey格式指定 |
| spec.host.Network | Boolean | 定义是否使用主机网络模式,默认值为false。设置true表示使用宿主机网络,不使用docker网桥,同时设置了true将无法在同一台宿主机上启动第二个副本 |

3.3.2.1 如何获取资源帮助
复制代码
kubectl explain pod.spec.containers

3.3.3 编写示例

3.3.3.1 运行简单的单个容器pod

使用命令获取yaml模板

复制代码
kubectl run timinglee --image myapp:v1 --dry-run=client -o yaml > pod.yml

apiVersion: v1
kind: Pod
metadata:
  labels:
    run: timinglee    # pod标签
  name: timinglee
spec:
  containers:
  - image: myapp:v1    # pod镜像
    name: timinglee    # 容器名称
3.3.3.2 运行多个容器pod

注意:如果多个容器运行在一个pod中,资源共享的同时在使用相同资源时也会干扰,比如端口

1.端口干扰示例:

复制代码
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: timinglee
  name: timinglee
spec:
  containers:
  - image: myapp:v1
    name: web1

  - image: myapp:v2
    name: web2

2.在一个pod中开启多个容器时一定要确保容器彼此不能互相干扰

复制代码
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: timinglee
  name: timinglee
spec:
  containers:
  - image: myapp:v1
    name: web1

  - image: myapp:v2
    name: web2
    command:
      - /bin/sh
      - -c
      - sleep 100000
3.3.3.3 理解pod间的网络整合

1.同一个pod中的容器使用同一个网络

复制代码
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: timinglee
  name: timinglee
spec:
  containers:
  - image: myapp:v1
    name: web1

  - image: myapp:v2
    name: web2
    command:
      - /bin/sh
      - -c
      - sleep 100000
3.3.3.4 端口映射
复制代码
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: timinglee
  name: timinglee
spec:
  containers:
  - image: myapp:v1
    name: web1
    ports:
    - name: http         # 端口名称(自定义,用于标识端口用途)
      containerPort: 80  # 容器内部监听的端口(容器内应用实际使用的端口)
      hostPort: 80       # 宿主机(节点)暴露的端口(外部访问容器的入口)
      protocol: TCP      # 协议类型(默认 TCP,可选 UDP)
3.3.3.5 设定环境变量
复制代码
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: timinglee
  name: timinglee
spec:
  containers:
  - image: myapp:v1
    name: web1
    command:
      - /bin/sh
      - -c
      - echo $NAME;sleep 300000
    env:
      - name: NAME
        value: timinglee
3.3.3.6 资源限制

资源限制会影响pod的Qos Class资源优先级,资源优先级分为Guaranteed > Burstable > BestEffort

QoS(Quality of Service)即服务质量

资源设定 优先级类型
资源限定未设定 BestEffort
资源限定设定且最大和最小不一致 Burstable
资源限定设定且最大和最小一致 Guaranteed
复制代码
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: timinglee
  name: timinglee
spec:
  containers:
  - image: myapp:v1
    name: web1
    resources:
      limits:            # pod使用资源的最高限制
        cpu: 500m
        memory: 100M

      requests:          # pod期望使用的资源量,不能大于limits
        cpu: 500m
        memory: 100M

kubectl describe pod timinglee
3.3.3.7 容器启动管理
复制代码
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: timinglee
  name: timinglee
spec:
  restartPolicy: Always
  containers:
  - image: myapp:v1
    name: web1
3.3.3.8 选择运行的节点
复制代码
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: timinglee
  name: timinglee
spec:
  restartPolicy: Always
  nodeSelector:
    kubernetes.io/hostname: node2
  containers:
  - image: myapp:v1
    name: web1
3.3.3.9 共享宿主机网络
复制代码
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: timinglee
  name: timinglee
spec:
  restartPolicy: Always
  hostNetwork: true    # 共享宿主机网络
  containers:
  - image: myapp:v1
    name: web1
    command:
      - /bin/sh
      - -c
      - sleep 100000

4 pod的生命周期

4.1 INIT容器

官方文档:Pod | Kubernetes生产级别的容器编排系统https://kubernetes.io/zh/docs/concepts/workloads/pods/

Pod 可以包含多个容器,应用运行在这些容器里面,同时 Pod 也可以有一个或多个先于应用容器启动的 Init 容器。

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

  • 它们总是运行到完成
  • init 容器不支持 Readiness,因为它们必须在 Pod 就绪之前运行完成,每个 Init 容器必须运行成功,下一个才能够运行。

如果Pod的 Init 容器失败,Kubernetes 会不断地重启该 Pod,直到 Init 容器成功为止。但是,如果 Pod 对应的 restartPolicy 值为 Never,它不会重新启动。

4.1.1 INIT容器的功能

  • Init 容器可以包含一些安装过程中应用容器中不存在的实用工具或个性化代码。

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

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

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

  • 由于 Init 容器必须在应用容器启动之前运行完成,因此 Init 容器提供了一种机制来阻塞或延迟应用容器的启动,直到满足了一组先决条件。一旦前置条件满足,Pod内的所有的应用容器会并行启动。

特性 init 容器 主容器(containers
启动时机 主容器启动前,按顺序执行 init 容器全部成功后才启动
生命周期 一次性执行,成功退出后不再运行 持续运行(除非异常终止或被重启)
资源占用 轻量(通常用 busybox 等小镜像) 按应用需求占用资源(如 CPU、内存)
失败影响 导致主容器无法启动,Pod 可能重试 主容器失败会按 restartPolicy 重启

4.1.2 INIT容器示例

复制代码
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: initpod
  name: initpod
spec:
  containers:
  - image: myapp:v1
    name: myapp
  initContainers:
    - name: init-myservice
      image: busybox
      command:
        - sh
        - -c
        - until test -e /testfile; do echo wating for myservice; sleep 2; done
  • test -e /testfile :检查 /testfile 文件是否存在(-e 表示 "存在即返回成功")

  • until ...; do ...; done :循环执行 do 后的命令,直到 until 后的条件(/testfile 存在)满足才退出循环

  • echo wating for myservice; sleep 2:每次循环输出 "等待 myservice" 的日志,并休眠 2 秒,避免频繁检查占用资源

    kubectl exec pods/initpod -c init-myservice -- /bin/sh -c "touch /testfile"

效果:

init 容器 init-myservice 中的循环命令 until test -e /testfile; do ... 会检测到 /testfile 已存在,循环终止,init 容器会正常退出

  • kubectl exec:在运行的 Pod 容器中执行命令
  • pods/initpod:指定目标 Pod 名称为 initpod
  • -c init-myservice:指定要操作的容器为 init 容器 init-myservice(因为 Pod 可能包含多个容器,必须明确指定)
  • -- /bin/sh -c "touch /testfile":在容器内执行的命令,通过 touch 命令创建 /testfile 文件

4.2 探针

4.2.1 探针是由kubelet对容器执行的定期诊断

每次探测都将获得以下三种结果之一:

成功:容器诊断通过

失败:容器未通过诊断

未知:诊断失败,因此不会采取任何行动

4.2.2 Kubelet 可以选择是否执行在容器上运行的三种探针执行和做出反应

  • ExecAction:在容器内执行指定命令,如果命令退出时返回码为 0 则认为诊断成功。

  • TCPSocketAction:对指定端口上的容器的 IP 地址进行 TCP 检查,如果端口打开,则诊断被认为是成功的

  • HTTPGetAction:对指定的端口和路径上的容器的 IP 地址执行 HTTP Get 请求,如果响应的状态码大于等于200 且小于 400,则诊断被认为是成功的

  • livenessProbe:指示容器是否正在运行。如果存活探测失败,则 kubelet 会杀死容器,并且容器将受到其重启策略的影响。如果容器不提供存活探针,则默认状态为 Success。

  • readinessProbe:指示容器是否准备好服务请求。如果就绪探测失败,端点控制器将从与 Pod 匹配的所有 Service 的端点中删除该 Pod 的 IP 地址。初始延迟之前的就绪状态默认为Failure。如果容器不提供就绪探针,则默认状态为 Success。

  • startupProbe: 指示容器中的应用是否已经启动。如果提供了启动探测(startup probe),则禁用所有其他探测,直到它成功为止。如果启动探测失败,kubelet 将杀死容器,容器服从其重启策略进行重启。如果容器没有提供启动探测,则默认状态为成功Success。

4.2.3 ReadinessProbe 与 LivenessProbe 的区别

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

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

4.2.4 StartupProbe 与 ReadinessProbe、LivenessProbe 的区别

  • 如果三个探针同时存在,先执行 StartupProbe 探针,其他两个探针将会被暂时禁用,直到 pod 满足 StartupProbe 探针配置的条件,其他 2 个探针启动,如果不满足按照规则重启容器。

  • 另外两种探针在容器启动后,会按照配置,直到容器消亡才停止探测,而 StartupProbe 探针只是在容器启动后按照配置满足一次后,不在进行后续的探测。

4.2.5 探针实例

4.2.5.1 存活探针示例
复制代码
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: liveness
  name: liveness
spec:
  containers:
    - image: myapp:v1
      name: myapp
      livenessProbe:
        tcpSocket:
          port: 8080            # 检测端口存在性
        initialDelaySeconds: 3  # 容器启动后等待3s后探针开始工作
        periodSeconds: 1        # 执行探测的时间间隔,默认10s
        timeoutSeconds: 1       # 探针执行检测请求后,等待响应的超时时间,默认1s

8080端口不存在,存活探针检测失败,容器未通过诊断

4.2.5.2 就绪探针示例
复制代码
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: readiness
  name: readiness
spec:
  containers:
    - image: myapp:v1
      name: myapp
      readinessProbe:
        httpGet:
          path: /test.html
          port: 80
        initialDelaySeconds: 1
        periodSeconds: 3
        timeoutSeconds: 1

kubectl describe pod/readiness

404 错误 表示:容器内的 Web 服务(myapp:v1)在 http://<容器IP>:80/test.html 路径下不存在该文件,导致探针判定容器 "未就绪"。

执行命令在容器内创建 /test.html 文件

复制代码
kubectl exec pods/readiness -c myapp -- /bin/sh -c "echo test > /usr/share/nginx/html/test.html"

路径 /usr/share/nginx/html 是 Nginx 等 Web 服务的默认根目录,创建 test.html 后,http://<容器IP>:80/test.html 可正常访问(返回 200 状态码)

就绪探针检测到 /test.html 存在且返回 200,判定容器 "就绪",Pod 状态更新为 READY 1/1

再次查看 Service 时,Endpoints 字段显示 Pod 的 IP 和端口

此时 Service 可正常将外部流量路由到 Pod,实现服务访问

到此kubernetes中pod的管理及优化介绍完毕!

相关推荐
Dobby_052 小时前
【Ansible】变量与敏感数据管理:Vault加密与Facts采集详解
linux·运维·云原生·ansible
记忆不曾留2 小时前
unbuntu 20.04 docker 部署wordpress
运维·docker·容器·wordpress·独立站建站
你的人类朋友3 小时前
说说你对go的认识
后端·云原生·go
三五a3 小时前
Kubernetes
云原生·容器·kubernetes
照物华5 小时前
深入理解Kubernetes核心:标签与标签选择器实战解析
云原生·容器·kubernetes·k8s
dexianshen8 小时前
k8s中的微服务
微服务·容器·kubernetes
xiaoye37088 小时前
微服务之间的调用关系如何处理,才能防止循环依赖
微服务·云原生·架构
裸奔的大金毛8 小时前
K8S - NetworkPolicy的使用
容器·kubernetes·k8s
蒋星熠10 小时前
全栈开发:从LAMP到云原生的技术革命
微服务·云原生·职场和发展·架构·系统架构·web·devops