监控数据的可视化分析神器 Grafana 的告警实践
1058
2022-10-12
kubernetes之初始容器(init container)
1、简介
一个pod里可以运行多个容器,它也可以运行一个或者多个初始容器,初始容器先于应用容器运行,除了以下两点外,初始容器和普通容器没有什么两样:
它们总是run to completion。一个初始容器必须成功运行另一个才能运行。
如果pod中的一个初始容器运行失败,则kubernetes会尝试重启pod直到初始容器成功运行,如果pod的重启策略设置为从不(never),则不会重启。
创建容器时,在podspec里添加initContainers字段,则指定容器即为初始容器,它们的返回状态作为数组保存在.status.initContainerStatuses里(与普通容器状态存储字段.status.containerStatuses类似)。
2、初始容器和普通容器的不同
初始容器支持所有普通容器的特征,包括资源配额限制和存储卷以及安全设置.但是对资源申请和限制处理初始容器略有不同,下面会介绍.此外,初始容器不支持可用性探针(readiness probe),因为它在ready之前必须run to completion。
如果在一个pod里指定了多个初始容器,则它们会依次启动起来(pod内的普通容器并行启动),并且只有上一个成功下一个才能启动.当所有的初始容器都启动了,kubernetes才开始启动普通应用容器。
[root@yygh-de huqi]# vim init.yaml apiVersion: v1 kind: Pod metadata: annotations: hello: world labels: app: nginx name: nginx-pod-initc namespace: k8s-master spec: volumes: -emptyDir: {} name: ourfile containers: -image: nginx imagePullPolicy: Always name: nginx ports: -containerPort: 80 name: http80 protocol: TCP volumeMounts: -mountPath: usr/share/nginx/html name: ourfile initContainers: -image: alpine name: initc-1 command: ["/bin/sh","-c","sleep 30;date > html/index.html"] volumeMounts: -name: ourfile mountPath: html
初始化容器不算容器,运行起来的只有一个容器
[root@yygh-de huqi]# kubectapply -f init.yaml pod/nginx-pod-initc created [root@yygh-de huqi]# kubectl get pod -n k8s-master -w NAME READY STATUS RESTARTS AGE nginx-pod-initc 0/1 Init:0/1 0 1s nginx-pod-initc 0/1 Init:0/1 0 6s nginx-pod-initc 0/1 PodInitializing 0 36s # 睡眠30秒 nginx-pod-initc 1/1 Running 0 43s
3、本次演示使用busybox镜像作为init镜像,应用程序使用nginx进行演示,通过挂载的方式将init镜像获取到文件挂载到nginx html目录,这样我们访问的nginx 默认index.html就是我们init提前拉取出来的地址
[root@yygh-de huqi]# vim init.yaml --- apiVersion: v1 kind: Pod metadata: name: init-demo labels: app: init spec: initContainers: -name: init image: busybox command: -wget -"-O" -"/tmp/index.html" -http://k.i4t.com volumeMounts: -name: initdir mountPath: "/tmp" containers: -name: nginx image: nginx ports: -containerPort: 80 volumeMounts: -name: initdir mountPath: usr/share/nginx/html volumes: -name: initdir emptyDir: {}
使用命令直接创建即可,init也可以使用命名空间,我这里就使用默认的default进行演示
#创建 [root@yygh-de huqi]# kubectl apply -f init.yaml pod/init-demo created #此时init容器进行启动工作 [root@yygh-de huqi]# kubectl get pod NAME READY STATUS RESTARTS AGE init-demo 0/1 Init:0/1 0 5s #当init容器完成后,应用容器启动并进行工作 [root@yygh-de huqi]# kubectl get pod NAME READY STATUS RESTARTS AGE init-demo 1/1 Running 0 62m
当我们Pod正常Running之后,我们可以通过kubectl describe pod [pod-name]查看到init容器的一个状态
如果失败init容器默认会在State中显示CrashLoopBackOff (重启/异常),在Reason会显示Error
接下来我们进行验证挂在Pod正常
[root@yygh-de huqi]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES init-demo 1/1 Running 0 66m 10.244.66.87 yygh-te
我们还可以进入容器进行查看
[root@yygh-de huqi]# kubectl get pod NAME READY STATUS RESTARTS AGE init-demo 1/1 Running 0 67m [root@yygh-de huqi]# kubectl exec -it init-demo /bin/bash root@init-demo:/# cat /usr/share/nginx/html/index.html
4、注意事项
一个正在初始化中的容器。status = PENDING 但是还会有一个Reason : PodInitiating。如果一个Pod被重启了,那么初始化的过程还是要一个不剩的全部走一遍。尝试修改初始化容器的镜像将会导致整个容器全部重启。正是由于重新执行初始化的可能性,因此初始化过程中留下的痕迹要确保对下一次初始化没有影响,避免因为上一次初始化留下的痕迹使得本次初始化失败。使用livenessProbe以及 activeDeadlineSeconds 避免初始化过程永远失败。app名以及容器名必须做到不重复。
参考文献:https://i4t.com/4434.html
发表评论
暂时没有评论,来抢沙发吧~