Kubernetes的Pod中进行容器初始化

Kubernetes的Pod中进行容器初始化

在很多应用场景中,应用在启动之前都需要进行如下初始化操作:

  • 等待其他关联组件正确运行(例如数据库或某个后台服务)。

  • 基于环境变量或配置模板生成配置文件。

  • 从远程数据库获取本地所需配置,或者将自身注册到某个中央数据库中。

  • 下载相关依赖包,或者对系统进行一些预配置操作。

Kubernetes 1.3 引入了一个 Alpha 版本的新特性 init container (初始化容器,在 Kubernetes 1.5 时被更新为

Beta版本),用于在启动应用容器(app container)之前启动一个或多个初始化容器,完成应用容器所需的预置

条件,如图所示。

在这里插入图片描述

init container 与应用容器在本质上是一样的,但它们是仅运行一次就结束的任务,并且必须在成功执行完成后,

系统才能继续执行下一个容器。根据 Pod 的重启策略(RestartPolicy),当 init container 执行失败,而且设置了

RestartPolicy=Never 时,Pod 将会启动失败;而设置 RestartPolicy=Always 时,Pod 将会被系统自动重启。

下面以 Nginx 应用为例,在启动 Nginx 之前,通过初始化容器 busybox 为 Nginx 创建一个 index.html 主页文

件。这里为 init container 和 Nginx 设置了一个共享的 Volume,以供 Nginx 访问 init container 设置的

index.html文件。

配置文件 033-nginx-init-containers.yaml 的内容为:

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  annotations:
    name: nginx
spec:
  # These containers are run during pod initialization
  initContainers:
  - name: install
    image: busybox
    command:
    - wget
    - "-O"
    - "/work-dir/index.html"
    - http://www.baidu.com
    volumeMounts:
    - name: workdir
      mountPath: "/work-dir"
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80
    volumeMounts:
    - name: workdir
      mountPath: /usr/share/nginx/html
  dnsPolicy: Default
  volumes:
  - name: workdir
    emptyDir: {} 

创建这个 Pod:

[root@master cha3]# kubectl create -f 033-nginx-init-containers.yaml
pod/nginx created

在运行 init container 的过程中查看 Pod 的状态,可见 init 过程还未完成:

[root@master cha3]# kubectl get pods
NAME    READY   STATUS     RESTARTS   AGE
nginx   0/1     Init:0/1   0          11s

在 init container 成功执行完成后,系统继续启动 Nginx 容器,再次查看 Pod 的状态:

[root@master cha3]# kubectl get pods
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          43s

查看 Pod 的事件,可以看到系统首先创建并运行 init container 容器(名为install),成功后继续创建和运行 Nginx

容器:

[root@master cha3]# kubectl describe pod nginx
Name:         nginx
Namespace:    default
Priority:     0
Node:         slave2/192.168.226.202
Start Time:   Mon, 10 Jul 2023 20:11:18 +0800
Labels:       <none>
Annotations:  name: nginx
Status:       Running
IP:           10.244.140.65
IPs:
  IP:  10.244.140.65
Init Containers:
  install:
    Container ID:  docker://fed219a6b5bd09f383cfbc353a80cf0a718888f581d7cd15d1d967a65ffa25d5
    Image:         busybox
    Image ID:      docker-pullable://busybox@sha256:5acba83a746c7608ed544dc1533b87c737a0b0fb730301639a0179f9344b1678
    Port:          <none>
    Host Port:     <none>
    Command:
      wget
      -O
      /work-dir/index.html
      http://www.baidu.com
    State:          Terminated
      Reason:       Completed
      Exit Code:    0
      Started:      Mon, 10 Jul 2023 20:11:36 +0800
      Finished:     Mon, 10 Jul 2023 20:11:36 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-ml45m (ro)
      /work-dir from workdir (rw)
Containers:
  nginx:
    Container ID:   docker://65d365a441cfed5dc5bcf2baba7d7bf3744bf28a6973d16698a079425d03d450
    Image:          nginx
    Image ID:       docker-pullable://nginx@sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31
    Port:           80/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Mon, 10 Jul 2023 20:11:53 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /usr/share/nginx/html from workdir (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-ml45m (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  workdir:
    Type:       EmptyDir (a temporary directory that shares a pod's lifetime)
    Medium:
    SizeLimit:  <unset>
  kube-api-access-ml45m:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  55s   default-scheduler  Successfully assigned default/nginx to slave2
  Normal  Pulling    54s   kubelet            Pulling image "busybox"
  Normal  Pulled     38s   kubelet            Successfully pulled image "busybox" in 16.36286751s
  Normal  Created    37s   kubelet            Created container install
  Normal  Started    37s   kubelet            Started container install
  Normal  Pulling    37s   kubelet            Pulling image "nginx"
  Normal  Pulled     21s   kubelet            Successfully pulled image "nginx" in 16.261974272s
  Normal  Created    21s   kubelet            Created container nginx
  Normal  Started    20s   kubelet            Started container nginx

启动成功后,登录进 Nginx 容器,可以看到 /usr/share/nginx/html 目录下的 index.html 文件为 init

container所生成,其内容为:

[root@master cha3]# kubectl exec -ti nginx -- bash
Defaulted container "nginx" out of: nginx, install (init)
root@nginx:/# cd /usr/share/nginx/html/
root@nginx:/usr/share/nginx/html# ls
index.html
root@nginx:/usr/share/nginx/html# cat index.html
<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class="bg s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus></span><span class="bg s_btn_wr"><input type=submit id=su value=百度一下 class="bg s_btn"></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>新闻</a> <a href=http://www.hao123.com name=tj_trhao123 class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap class=mnav>地图</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>视频</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>贴吧</a> <noscript> <a href=http://www.baidu.com/bdorz/login.gif?login&amp;tpl=mn&amp;u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>登录</a> </noscript> <script>document.write('<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u='+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ '" name="tj_login" class="lb">登录</a>');</script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: block;">更多产品</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>关于百度</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>&copy;2017&nbsp;Baidu&nbsp;<a href=http://www.baidu.com/duty/>使用百度前必读</a>&nbsp; <a href=http://jianyi.baidu.com/ class=cp-feedback>意见反馈</a>&nbsp;京ICP证030173号&nbsp; <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>
root@nginx:/usr/share/nginx/html# exit
exit

init container 与应用容器的区别如下:

(1)init container 的运行方式与应用容器不同,它们必须先于应用容器执行完成,当设置了多个 init container

时,将按顺序逐个运行,并且只有前一个 init container 运行成功后才能运行后一个 init container。当所有 init

container 都成功运行后,Kubernetes 才会初始化 Pod 的各种信息,并开始创建和运行应用容器。

(2)在 init container 的定义中也可以设置资源限制、Volume 的使用和安全策略,等等。但资源限制的设置与

应用容器略有不同。

  • 如果多个 init container 都定义了资源请求/资源限制,则取最大的值作为所有 init container 的资源请求值/资

    源限制值。

  • Pod 的有效资源请求值/资源限制值取以下二者中的较大值。

    1、所有应用容器的资源请求值/资源限制值之和。

    2、init container的有效资源请求值/资源限制值。

  • 调度算法将基于 Pod 的有效资源请求值/资源限制值进行计算,也就是说 init container 可以为初始化操作预

    留系统资源,即使后续应用容器无须使用这些资源。

  • Pod 的有效 QoS 等级适用于 init container 和应用容器。

  • 资源配额和限制将根据 Pod 的有效资源请求值/资源限制值计算生效。

  • Pod 级别的 cgroup 将基于 Pod 的有效资源请求/限制,与调度机制一致。

(3)init container 不能设置 readinessProbe 探针,因为必须在它们成功运行后才能继续运行在 Pod 中定义的

普通容器。

在 Pod 重新启动时,init container 将会重新运行,常见的 Pod 重启场景如下。

  • init container 的镜像被更新时,init container 将会重新运行,导致 Pod 重启。仅更新应用容器的镜像只会

    使得应用容器被重启。

  • Pod 的 infrastructure 容器更新时,Pod 将会重启。

  • 若 Pod 中的所有应用容器都终止了,并且 RestartPolicy=Always,则 Pod 会重启。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值