k8s-Pod详解

一、Pod的详解

1.1Pod基础概念

Pod 是 Kubernetes 中的最小部署单元,它代表集群中的一个运行进程。一个 Pod 可以包含一个或多个紧密耦合的容器,这些容器共享网络和存储资源。在 Kubernetes 中,Pod 是管理容器的基础结构,其他如 Deployment、StatefulSet、DaemonSet 等控制器对象都围绕 Pod 进行扩展。

1.2 Kubrenetes集群中Pod有如下两种使用方式

单容器 Pod: 最常见的用法,一个 Pod 只包含一个容器。这种情况下,Pod 就相当于容器的封装,Kubernetes 管理的是 Pod,而不是容器。

bash 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: single-container-pod
spec:
  containers:
  - name: nginx
    image: nginx:1.14

多容器 Pod : 一个 Pod 可以包含多个容器,这些容器通常有共同的资源需求,如共享网络和存储,彼此间可以通过 localhost 进行通信。

bash 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: multi-container-pod
spec:
  containers:
  - name: app
    image: my-app:latest
  - name: sidecar
    image: log-collector:latest

1.3 Pause 容器(基础容器)

在每个 Pod 中,都会有一个特殊的容器被称为 Pause 容器,它的主要职责是提供 Pod 的 Linux 命名空间基础。它使得 Pod 内的所有容器共享网络和存储资源。Pause 容器运行时,它会创建一个 Linux 命名空间,其他容器将共享该命名空间来进行网络通信和存储操作。

1.4 Pod 中的共享资源

  • 网络共享 : 每个 Pod 分配一个唯一的 IP 地址,Pod 内的所有容器共享该 IP 和端口。它们能够通过 localhost 进行通信。Pod中的容器与外界通信时,必须分配共享网络资源(例如使用宿主机的端口映射)

    ① 每个pod 分配一个独特IP地址 ② pod 内部所有容器共享这个IP和端口 ,能通过 localhost直接通信 ③ 与外界 通信时, 必须使用宿主机的端口映射

  • 存储共享: Pod 可以指定多个共享的 Volume,这些 Volume 可以被 Pod 内的所有容器访问,确保容器重启后数据不会丢失。

    ① Pod可以指定多个共享的Volume,所有容器都可以访问 ② Volume可以用来持久化存储 ,确保容器重启后数据不会丢失

1.5 小结

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

Pod 包含一个特殊的"基础容器"的Pause容器 ,它负责 pod网络 和存储资源,除了pauser容器 pod还包含多个应用容器,他们可以共同工作。

1.6 Pod的使用场景

  • 单一进程应用:最常见的用法,一个 Pod 用于运行一个容器。

  • 多进程协作:多个容器在同一个 Pod 内共享网络和存储资源,适用于紧密耦合的服务。

1.7 Pod的类型

  • 自主式 Pod: 这种 Pod 不具备自我修复的能力。如果它所在的节点故障,Pod 会被删除,且不会自动恢复。

  • 控制器管理的 Pod: Kubernetes 中通常通过控制器(如 Deployment、StatefulSet)来管理 Pod。控制器提供副本管理、滚动升级、自动修复等功能。

1.8 Pod容器的分类

1.8.1基础容器(infrastructure container)

bash 复制代码
维护整个 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"

1.8.2 初始化容器(initcontainers)

1.8.2.1 Init容器启动过程

Init容器必须在应用程序容器启动之前运行完成,而应用程序容器是并行运行的,所以Init容器能够提供了一种简单的阻塞或延迟应用容器的启动的方法。 Init 容器与普通的容器非常像,除了以下两点:

  • Init 容器总是运行到成功完成为止

    启动 --》运行 --》 结束 --》 退出 成功 再运行下一个INit

  • 每个 Init 容器都必须在下一个 Init 容器启动之前成功完成启动和退出 如果 Pod 的 Init 容器失败,k8s 会不断地重启该 Pod,直到 Init 容器成功为止。然而,如果 Pod 对应的重启策略(restartPolicy)为 Never,它不会重新启动。

1.8.2.2 Init 的容器作用

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

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

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

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

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

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

1.9 应用容器(Maincontainer)

  • 1在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容器的名称必须唯一;与任何其它容器共享同一个名称,会在验证时抛出错误

1.10 配置的核心部分

1.10.1 Pod 的镜像拉取策略

Pod 中的容器需要通过指定镜像来启动,镜像拉取策略有以下几种:

  • IfNotPresent(默认):如果本地已有镜像,不会拉取新的镜像,仅在本地缺失时拉取。

    默认always,若果加版本号则默认ifnotpresent

  • Always:每次启动 Pod 时都会拉取镜像。

  • Never:不拉取镜像,仅使用本地镜像。

1.10.2 Pod 的重启策略(restartPolicy)

Pod 的重启策略定义了容器退出后 Kubernetes 如何处理容器的重启。主要有以下三种策略:

  • Always:无论容器的退出状态如何,都会重新启动。

  • OnFailure:只有容器非正常退出(即退出码非 0)时,才会重启容器。

  • Never:容器退出后不会重启。

二、Pod的进阶

2.1 Pod资源限制

在 Kubernetes 中,为了合理管理集群中的资源,容器的 CPU 和内存资源都可以设置请求值(requests )和限制值(limits)。这些设置确保了容器的资源分配和限制,避免资源争用和过度使用。

资源请求与限制(Request & Limit)

  • 请求(request) :当容器启动时,Kubernetes 会根据容器的资源请求来决定容器应该调度到哪个节点上。这个值表示容器在运行时最少需要的资源。

  • 限制(limit):容器在运行时可以使用的最大资源量。如果容器超过了这个限制,Kubernetes 会采取措施来控制容器的资源使用,防止过度消耗。

bash 复制代码
官网示例:
https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/

//Pod 和 容器 的资源请求和限制:
spec.containers.resources.requests.cpu/memory   //定义创建容器时预分配的CPU/memory资源
spec.containers.resources.limits.cpu/memory     //定义cpu/memory的资源上限

2.2 资源单位

2.2.1 CPU资源单位

在 Kubernetes 中,CPU 的单位表示方式如下:

  • 1 CPU = 1 vCPU(或 1 核心超线程)

  • CPU 请求和限制使用 "m"(毫核)作为单位。

    例如:500m 表示半个 CPU,100m 表示 0.1 个 CPU,1 表示一个完整的 CPU。

  • 带小数的 CPU 也是支持的,表示容器能获得的 CPU 时间片。例如,0.25 表示该容器最多可以使用一个 CPU的四分之一。

2.2.2 内存资源单位

内存的单位有两种表示方式:

  • 二进制单位:1Gi, 1Mi, 1Ki,分别为 1024Mi, 1024Ki。Kubernetes 的内存限制通常使用这些基于 2 的指数单位。

  • 十进制单位:1GB, 1MB 等,表示为以 10 为底的单位。

需要注意的是,在存储设备中,标示的单位(如GB)是基于十进制,而操作系统通常使用二进制单位(如GiB)。因此,1 GiB 的内存比 1 GB 多出大约 73MB。

2.2.3 Pod案例

bash 复制代码
vim pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: frontend
spec:
  containers:
  - name: web
    image: nginx
    env:
    - name: WEB_ROOT_PASSWORD
      value: "password"
    resources:
      requests:
        memory: "64Mi"   # 最少 64Mi 内存
        cpu: "250m"      # 最少 0.25 CPU
      limits:
        memory: "128Mi"  # 最大 128Mi 内存
        cpu: "500m"      # 最大 0.5 CPU
  - name: db
    image: mysql
    env:
    - name: MYSQL_ROOT_PASSWORD
      value: "abc123"
    resources:
      requests:
        memory: "512Mi"  # 最少 512Mi 内存
        cpu: "0.5"       # 最少 0.5 CPU
      limits:
        memory: "1Gi"    # 最大 1Gi 内存
        cpu: "1"         # 最大 1 CPU

分析:

- Web容器:
  - 请求:0.25 CPU和64Mi内存
  - 限制:0.5 CPU和128Mi内存
- DB容器:
  - 请求:0.5 CPU和512Mi内存
  - 限制:1 CPU和1Gi内存

该Pod的总请求资源为:

- 0.75 CPU和576Mi内存

该Pod的总限制资源为:

- 1.5 CPU和1.128Gi内存

2.2.4 调度与资源分配

当 Kubernetes 调度 Pod 时,它会根据容器的资源请求(requests)来选择适合的节点。调度器会尝试确保节点有足够的资源来满足这些请求。如果节点上的资源不够,调度器会将 Pod 调度到其他可用节点。

bash 复制代码
Pod调度实例
kubectl apply -f pod2.yaml
kubectl describe pod frontend

查看pod分配资源情况:
kubectl get pods -o wide  #输出结果将显示Pod是否成功启动,以及它的运行状态。

查看节点资源:
kubectl describe nodes node01  #此命令展示了节点的资源使用情况。你可以看到该节点上各个
Pod的请求与限制占用了多少资源,以及节点剩余的资源。

对DB容器内存资源进行如下修改

bash 复制代码
  - name: db
    image: mysql
    env:
    - name: MYSQL_ROOT_PASSWORD
      value: "abc123"
    resources:
      requests:
        memory: "64Mi"  # 最少 64Mi 内存
        cpu: "0.5"       # 最少 0.5 CPU
      limits:
        memory: "128Mi"    # 最大 128Mi 内存
        cpu: "1"         # 最大 1 CPU

Out of Memory Killed,当容器使用的内存超过了在 limits 中设置的阈值时,节点的内核(Linux Kernel)会触发 OOM Killer 机制,强制杀死这个容器的进程,以保护整个节点的稳定性。

2.2.5 小结

  1. 资源请求与限制:

requests是容器启动时最少需要的资源,调度器依据该值选择节点。

limits是容器能够使用的最大资源值,超出该值的资源请求会被限制。

  1. 自动匹配:

如果未设置requests,Kubernetes 会自动将其设置为与limits相同。

  1. 资源的分配:

Pod 中多个容器的资源请求与限制会被加总,以便监控和调整节点的资源分配。

  1. 资源单位:

CPU使用m(毫核)表示,例如:500m表示0.5个CPU。

内存使用标准的字节单位表示,通常推荐使用基于2的指数单位,如Gi,Mi等。

2.3 健康检测:探针(Probe)

2.3.1 探针的三种规则

  • livenessProbe :判断容器是否正在运行。如果探测失败,则kubelet会杀死容器,并且容器将根据 restartPolicy 来设置 Pod 状态。 如果容器不提供存活探针,则默认状态为Success。

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

  • startupProbe(这个1.17版本增加的):判断容器内的应用程序是否已启动,主要针对于不能确定具体启动时间的应用。如果配置了 startupProbe 探测,在则在 startupProbe 状态为 Success 之前,其他所有探针都处于无效状态,直到它成功后其他探针才起作用。 如果 startupProbe 失败,kubelet 将杀死容器,容器将根据 restartPolicy 来重启。如果容器没有配置 startupProbe, 则默认状态为 Success。 #注:以上规则可以同时定义。在readinessProbe检测成功之前,Pod的running状态是不会变成ready状态的。

2.3.2 Probe支持三种检查方法

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

  • tcpSocket :对指定端口上的容器的IP地址进行TCP检查(三次握手)。如果端口打开,则诊断被认为是成功的。

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

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

  • 成功:容器通过了诊断。

  • 失败:容器未通过诊断。

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

2.3.4 探针配置通用参数

|---------------------|----------------------------------|-----|
| 参数 | 作用说明 | 默认值 |
| initialDelaySeconds | 容器启动后,延迟多久开始第一次探测(单位:秒) | 0 |
| periodSeconds | 探测的间隔时间(单位:秒) | 10 |
| timeoutSeconds | 探测超时时间(超过此时长未响应则判定为失败,单位:秒) | 1 |
| successThreshold | 连续多少次探测成功后,判定为 "成功"(恢复健康 / 就绪状态) | 1 |
| failureThreshold | 连续多少次探测失败后,判定为 "失败"(触发重启 / 移除端点) | 3 |

2.3.4 存活探针(livenessProbe)

exec案例

bash 复制代码
vim exec.yaml
apiVersion: v1
kind: Pod
metadata:
  name: liveness-exec
  namespace: default
spec:
  containers:
  - name: liveness-exec-container
    image: busybox
    imagePullPolicy: IfNotPresent
    command: ["/bin/sh","-c","touch /tmp/live ; sleep 30; rm -rf /tmp/live; sleep 60"]
    livenessProbe:
      exec:
        command: ["test","-e","/tmp/live"]
      initialDelaySeconds: 1
      periodSeconds: 3


[root@master01 ~]# kubectl get pods -w
NAME            READY   STATUS    RESTARTS   AGE
liveness-exec   1/1     Running   0          16s
liveness-exec   1/1     Running   1 (1s ago)   77s
liveness-exec   1/1     Running   2 (1s ago)   2m26s
liveness-exec   1/1     Running   3 (1s ago)   3m35s
liveness-exec   1/1     Running   4 (0s ago)   4m43s

httpGet方式

bash 复制代码
vim httpget.yaml
apiVersion: v1
kind: Pod
metadata:
  name: liveness-httpget
  namespace: default
spec:
  containers:
  - name: liveness-httpget-container
    image: soscscs/myapp:v1
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 80
    livenessProbe:
      httpGet:
        port: http
        path: /index.html
      initialDelaySeconds: 1
      periodSeconds: 3
      timeoutSeconds: 10
	  
kubectl create -f httpget.yaml


#删除html页面测试探针检测后重启
kubectl exec -it liveness-httpget -- rm -rf /usr/share/nginx/html/index.html

[root@master01 ~]# kubectl get pod
NAME               READY   STATUS    RESTARTS        AGE
liveness-httpget   1/1     Running   1 (2m55s ago)   4m46s

tcpSocket方式

bash 复制代码
vim tcpsocket.yaml
apiVersion: v1
kind: Pod
metadata:
  name: probe-tcp
spec:
  containers:
  - name: nginx
    image: soscscs/myapp:v1
    livenessProbe:
      initialDelaySeconds: 5
      timeoutSeconds: 1
      tcpSocket:
        port: 8080
      periodSeconds: 10
      failureThreshold: 2

kubectl create -f tcpsocket.yaml


[root@master01 ~]# kubectl exec -it probe-tcp  -- netstat -natp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1/nginx: master pro


[root@master01 ~]# kubectl get pods -w
NAME        READY   STATUS    RESTARTS   AGE
probe-tcp   0/1     Pending   0          0s
probe-tcp   0/1     Pending   0          0s
probe-tcp   0/1     ContainerCreating   0          0s
probe-tcp   0/1     ContainerCreating   0          1s
probe-tcp   1/1     Running             0          2s
probe-tcp   1/1     Running             1 (1s ago)   22s
probe-tcp   1/1     Running             2 (1s ago)   42s
probe-tcp   1/1     Running             3 (1s ago)   62s
probe-tcp   1/1     Running             4 (1s ago)   82s

2.3.5 就绪探针(readinessProbe)

就绪检测一

bash 复制代码
vim readiness-httpget.yaml
apiVersion: v1
kind: Pod
metadata:
  name: readiness-httpget
  namespace: default
spec:
  containers:
  - name: readiness-httpget-container
    image: soscscs/myapp:v1
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 80
    readinessProbe:
      httpGet:
        port: 80
        path: /index1.html
      initialDelaySeconds: 1
      periodSeconds: 3
    livenessProbe:
      httpGet:
        port: http
        path: /index.html
      initialDelaySeconds: 1
      periodSeconds: 3
      timeoutSeconds: 10

nginx中默认页面为index.html,不存在 /index1.html,就绪探针会一直失败,容器永远不会被加入服务。

bash 复制代码
增加index1.html页面

kubectl exec -it readiness-httpget sh
cd /usr/share/nginx/html/
ls
50x.html    index.html
echo 123 > index1.html 
exit

删除html后测试

bash 复制代码
kubectl exec -it readiness-httpget -- rm -rf /usr/share/nginx/html/index.html

kubectl get pods -w

就绪检测二

bash 复制代码
vim readiness-myapp.yaml
apiVersion: v1
kind: Pod
metadata:
  name: myapp1
  labels:
     app: myapp
spec:
  containers:
  - name: myapp
    image: soscscs/myapp:v1
    ports:
    - name: http
      containerPort: 80
    readinessProbe:
      httpGet:
        port: 80
        path: /index.html
      initialDelaySeconds: 5
      periodSeconds: 5
      timeoutSeconds: 10 
---
apiVersion: v1
kind: Pod
metadata:
  name: myapp2
  labels:
     app: myapp
spec:
  containers:
  - name: myapp
    image: soscscs/myapp:v1
    ports:
    - name: http
      containerPort: 80
    readinessProbe:
      httpGet:
        port: 80
        path: /index.html
      initialDelaySeconds: 5
      periodSeconds: 5
      timeoutSeconds: 10 
---
apiVersion: v1
kind: Pod
metadata:
  name: myapp3
  labels:
     app: myapp
spec:
  containers:
  - name: myapp
    image: soscscs/myapp:v1
    ports:
    - name: http
      containerPort: 80
    readinessProbe:
      httpGet:
        port: 80
        path: /index.html
      initialDelaySeconds: 5
      periodSeconds: 5
      timeoutSeconds: 10 
---
apiVersion: v1
kind: Service
metadata:
  name: myapp
spec:
  selector:
    app: myapp
  type: ClusterIP
  ports:
  - name: http
    port: 80
    targetPort: 80

kubectl get pods,svc,endpoints -o wide
bash 复制代码
删除myapp1中html页面
kubectl exec -it pod/myapp1 -- rm -rf /usr/share/nginx/html/index.html

//readiness探测失败,Pod无法进入READY状态,且端点控制器将从endpoints中剔除删除该Pod的IP地址
kubectl get pods,svc,endpoints -o wide

2.3.6 启动退出动作

bash 复制代码
vim post.yaml
apiVersion: v1
kind: Pod
metadata:
  name: lifecycle-demo
spec:
  containers:
  - name: lifecycle-demo-container
    image: soscscs/myapp:v1
    lifecycle:   #此为关键字段
      postStart:
        exec:
          command: ["/bin/sh", "-c", "echo Hello from the postStart handler >> /var/log/nginx/message"]      
      preStop:
        exec:
          command: ["/bin/sh", "-c", "echo Hello from the poststop handler >> /var/log/nginx/message"]
    volumeMounts:
    - name: message-log
      mountPath: /var/log/nginx/
      readOnly: false
  initContainers:
  - name: init-myservice
    image: soscscs/myapp:v1
    command: ["/bin/sh", "-c", "echo 'Hello initContainers'   >> /var/log/nginx/message"]
    volumeMounts:
    - name: message-log
      mountPath: /var/log/nginx/
      readOnly: false
  volumes:
  - name: message-log
    hostPath:
      path: /data/volumes/nginx/log/
      type: DirectoryOrCreate

   kubectl get pods -o wide
-----------------------------------------------------------------------------
# 1. API 版本和资源类型定义
apiVersion: v1  # 使用的 Kubernetes API 版本(v1 是稳定版本,支持 Pod 等核心资源)
kind: Pod       # 声明要创建的资源类型是 Pod(最小部署单元,包含一个或多个容器)

# 2. Pod 元数据
metadata:
  name: lifecycle-demo  # Pod 的名称(在命名空间内唯一,用于标识该 Pod)

# 3. Pod 规格配置(核心配置区)
spec:
  # 4. 主容器配置(应用运行的主要容器)
  containers:
  - name: lifecycle-demo-container  # 主容器的名称(在 Pod 内唯一)
    image: soscscs/myapp:v1         # 容器使用的镜像(这里是一个 Nginx 基础的应用镜像)
    # 5. 生命周期钩子(容器启动/终止时触发的操作)
    lifecycle:   # 生命周期配置关键字段
      postStart:  # 容器启动后立即执行的钩子
        exec:     # 执行命令的方式(其他方式还有 httpGet、tcpSocket)
          # 启动后执行的命令:向日志文件写入一条消息
          command: ["/bin/sh", "-c", "echo Hello from the postStart handler >> /var/log/nginx/message"]      
      preStop:   # 容器终止前执行的钩子
        exec:
          # 终止前执行的命令:向日志文件写入一条消息
          command: ["/bin/sh", "-c", "echo Hello from the poststop handler >> /var/log/nginx/message"]
    # 6. 存储卷挂载(将定义的卷挂载到容器内的路径)
    volumeMounts:
    - name: message-log  # 关联下面定义的名为 message-log 的存储卷
      mountPath: /var/log/nginx/  # 容器内的挂载路径(日志文件会写在这里)
      readOnly: false  # 允许容器对该路径进行读写操作(默认是 false)

  # 7. 初始化容器(主容器启动前执行的容器)
  initContainers:
  - name: init-myservice  # 初始化容器的名称(在 Pod 内唯一)
    image: soscscs/myapp:v1  # 初始化容器使用的镜像(可与主容器不同,这里复用了同一个)
    # 初始化命令:向日志文件写入一条初始化消息
    command: ["/bin/sh", "-c", "echo 'Hello initContainers'   >> /var/log/nginx/message"]
    # 挂载存储卷(与主容器挂载同一个卷,确保日志写入同一份文件)
    volumeMounts:
    - name: message-log
      mountPath: /var/log/nginx/
      readOnly: false

  # 8. 存储卷定义(持久化存储配置)
  volumes:
  - name: message-log  # 存储卷的名称(供容器挂载时关联)
    hostPath:  # 存储卷类型为 hostPath(将节点的本地目录挂载到 Pod 中)
      path: /data/volumes/nginx/log/  # 节点上的实际目录路径(数据会存在这里)
      type: DirectoryOrCreate  # 目录类型:如果不存在则自动创建该目录

在node02上查看

删除pod后,再在node02上查看

kubectl delete pod lifecycle-demo

2.4 Pod的状态

1、pending:pod已经被系统认可了,但是内部的container还没有创建出来。这里包含调度到node上的时间以及下载镜像的时间,会持续一小段时间。

2、Running:pod已经与node绑定了(调度成功),而且pod中所有的container已经创建出来,至少有一个容器在运行中,或者容器的进程正在启动或者重启状态。--这里需要注意pod虽然已经Running了,但是内部的container不一定完全可用。因此需要进一步检测container的状态。

3、Succeeded:这个状态很少出现,表明pod中的所有container已经成功的terminated了,而且不会再被拉起了。

4、Failed:pod中的所有容器都被terminated,至少一个container是非正常终止的。(退出的时候返回了一个非0的值或者是被系统直接终止)

5、unknown:由于某些原因pod的状态获取不到,有可能是由于通信问题。 一般情况下pod最常见的就是前两种状态。而且当Running的时候,需要进一步关注container的状态

2.5Container生命周期

1、Waiting:启动到运行中间的一个等待状态。

2、Running:运行状态。

3、Terminated:终止状态。 如果没有任何异常的情况下,container应该会从Waiting状态变为Running状态,这时容器可用。

相关推荐
小诸葛的博客4 小时前
k8s localpath csi原理
云原生·容器·kubernetes
小猿姐8 小时前
闲谈KubeBlocks For MongoDB设计实现
mongodb·云原生·kubernetes
thinktik10 小时前
AWS EKS 集成Load Balancer Controller 对外暴露互联网可访问API [AWS 中国宁夏区]
后端·kubernetes·aws
忧郁的橙子.11 小时前
十六、kubernetes 1.29 之 集群安全机制
安全·容器·kubernetes
早睡冠军候选人12 小时前
Ansible学习----Ansible Playbook
运维·服务器·学习·云原生·容器·ansible
三坛海会大神55514 小时前
k8s(六)Pod的资源控制器
云原生·容器·kubernetes
缘的猿14 小时前
Docker 与 K8s 网络模型全解析
docker·容器·kubernetes
运维栈记15 小时前
使用Grafana监控K8S中的异常Pod
docker·kubernetes·grafana
荣光波比15 小时前
K8S(十二)—— Kubernetes安全机制深度解析与实践:从认证到RBAC授权
安全·容器·kubernetes