k8s-init容器学习

发布于:2025-09-14 ⋅ 阅读:(19) ⋅ 点赞:(0)

1. 什么是Init容器

Init容器会在业务容器启动之前运行一些初始化动作,Pod可以包含一个或者多个Init容器,只有所有的Init容器运行成功后,业务容器才会运行,如果期间有Init容器运行失败,kubelet 会不断地重启该 Init 容器直到该容器成功为止,如果Pod 对应的 restartPolicy 值为 “Never”,并且 Pod 的 Init 容器失败, 则 Kubernetes 会将整个 Pod 状态设置为失败。

在这里插入图片描述

2. Init容器和普通容器有什么区别

Init容器不支持lifecyclelivenessProbestartupProbereadinessProbe这些粗活就绪探针,因为Init容器完成任务就退出了。

3. 同时存在Init和业务容器Pod资源如何申请

如下场景,下面只包含内存一种资源

spec:
  # Init容器:按顺序执行,全部完成后才启动业务容器
  initContainers:
  - name: init-container-a
    image: busybox:1.35
    command: ["/bin/sh", "-c", "echo 'Init Container A running'; sleep 10"]  # 模拟初始化操作
    resources:
      requests:
        memory: "20M"  # 申请20M内存
      limits:
        memory: "100M"  # 限制最大使用100M内存
  - name: init-container-b
    image: busybox:1.35
    command: ["/bin/sh", "-c", "echo 'Init Container B running'; sleep 15"]  # 模拟初始化操作
    resources:
      requests:
        memory: "100M"  # 申请100M内存
      limits:
        memory: "200M"  # 限制最大使用200M内存

  # 业务容器:并行启动
  containers:
  - name: app-container-a
    image: nginx:alpine
    ports:
    - containerPort: 80
    resources:
      requests:
        memory: "2G"  # 申请2G内存
      limits:
        memory: "8G"  # 限制最大使用8G内存
  - name: app-container-b
    image: redis:alpine
    ports:
    - containerPort: 6379
    resources:
      requests:
        memory: "1G"  # 申请1G内存
      limits:
        memory: "2G"  # 限制最大使用2G内存

  # 重启策略:默认Always,Init容器失败会自动重启
  restartPolicy: Always

资源申请如下:

init-container-a: 
request.memory: 20M
limits.memory: 100M

init-container-b:
request.memory: 100M
limits.memory: 200M

app-container-a:
request.memory: 2G
limits.memory: 8G

app-container-b:
request.memory: 1G
limits.memory: 2G

Pod申请资源原理:取Init或者业务容器limit 或 request 的最大值,下面计算一下:

Init是串行,所以资源不需要累加:
request.memory: 100M
limits.memory: 200M
如上是Init所需的最大request和limits

业务容器是并行的,所以资源需要累加:
request.memory: 3G
limits.memory: 10G

Pod在申请资源时一定要保证Init容器可以正常运行,所以Init和业务容器谁的request,limits大就按照谁的资源申请配置取申请资源。

4. 创建Init容器

下面将创建一个卷,使用Init容器将业务容器nginx的index文件修改掉
在这里插入图片描述

nginx-po.yaml:

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
    
    ports:
    - containerPort: 80
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
    resources:
     requests:
       cpu: "50M"
       memory: "64Mi"
     limits:
       cpu: "100m"
       memory: "128Mi"
  # 通过initContainers创建Init容器,和普通容器创建一样,Init容器名和业务容器名必须唯一。
  initContainers:
  - name: install
    image: busybox:1.28
    imagePullPolicy: IfNotPresent
    command:
    - /bin/sh
    - -c
    - |
      echo "This is an experimental test of the Init container." > /usr/share/nginx/html/index.html
    volumeMounts:
    - name: html
      mountPath: "/usr/share/nginx/html"
    resources:
      requests:
        cpu: "10m"
        memory: "16Mi"
      limits:
        cpu: "20m"
        memory: "32Mi"
  volumes:
  - name: html
    emptyDir: {}
kubectl apply -f nginx-po.yaml

查看Pod状态:

kubectl get pod
NAME    READY   STATUS     RESTARTS   AGE
nginx   0/1     Init:0/1   0          29s

可以看出有一个Init容器正在执行,查看一下事件:

kubectl describe pod nginx
Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  2m58s  default-scheduler  Successfully assigned default/nginx to k8s-node01
  Normal  Pulling    2m23s  kubelet            Pulling image "busybox:1.28"
  Normal  Pulled     99s    kubelet            Successfully pulled image "busybox:1.28" in 44.089s (44.089s including waiting). Image size: 1146369 bytes.
  Normal  Created    99s    kubelet            Created container: install
  Normal  Started    99s    kubelet            Started container install
  Normal  Pulling    98s    kubelet            Pulling image "nginx"
  Normal  Pulled     95s    kubelet            Successfully pulled image "nginx" in 2.763s (2.763s including waiting). Image size: 192385289 bytes.
  Normal  Created    95s    kubelet            Created container: nginx
  Normal  Started    95s    kubelet            Started container nginx

查看Init容器状态

kubectl describe pod nginx
Init Containers:
  install:
    Container ID:  docker://0f6b2f03b7820a7c7358d64f97bf8e3ae018cb993f21868cddff57515a1f0527
    Image:         busybox:1.28
    Image ID:      docker-pullable://busybox@sha256:141c253bc4c3fd0a201d32dc1f493bcf3fff003b6df416dea4f41046e0f37d47
    Port:          <none>
    Host Port:     <none>
    Command:
      /bin/sh
      -c
      echo "This is an experimental test of the Init container." > /usr/share/nginx/html/index.html

    State:          Terminated
      Reason:       Completed
      Exit Code:    0
      Started:      Fri, 12 Sep 2025 09:10:40 +0800
      Finished:     Fri, 12 Sep 2025 09:10:41 +0800
    Ready:          True
    Restart Count:  0
    Limits:
      cpu:     20m
      memory:  32Mi
    Requests:
      cpu:        10m
      memory:     16Mi
    Environment:  <none>
    Mounts:
      /usr/share/nginx/html from html (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-4lzl2 (ro)

通过字段State下的ReasonExit Code可以看出Init容器已经完成退出了,且返回值为0。