【云原生 | 从零开始学Kubernetes】十二、k8spod的生命周期与容器钩子

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器镜像服务 ACR,镜像仓库100个 不限时长
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
简介: Pod 里面可以有一个或者多个容器,部署应用的容器可以称为主容器,在创建 Pod 时候,Pod 中 可以有一个或多个先于主容器启动的Init 容器,这个 init 容器就可以成为初始化容器,初始化容器一旦执行完,它从启动开始到初始化代码执行完就退出了,它不会一直存在,所以在主容器启动之前执行初始化,初始化容器可以有多个,多个初始化容器是要串行执行的,先执行初始化容器 1,在执行初始化容器 2等,等初始化容器执行完初始化就退出了,然后再执行主容器,主容器一退出,pod 就结束了,主容器退出的时间点就是 pod 的结束点,它俩时间轴是一致的

42.png

Init 容器


Pod 里面可以有一个或者多个容器,部署应用的容器可以称为主容器,在创建 Pod 时候,Pod 中 可以有一个或多个先于主容器启动的Init 容器,这个 init 容器就可以成为初始化容器,初始化容器一旦执行完,它从启动开始到初始化代码执行完就退出了,它不会一直存在,所以在主容器启动之前执行初始化,初始化容器可以有多个,多个初始化容器是要串行执行的,先执行初始化容器 1,在执行初始化容器 2等,等初始化容器执行完初始化就退出了,然后再执行主容器,主容器一退出,pod 就结束了,主容器退出的时间点就是 pod 的结束点,它俩时间轴是一致的;


Init 容器就是做初始化工作的容器。可以有一个或多个,如果多个按照定义的顺序依次执行,只有所有的初始化容器执行完后,主容器才启动。由于一个 Pod 里的存储卷是共享的,所以 Init Container 里产生的数据可以被主容器使用到,Init Container 可以在多种 K8S 资源里被使用到,如 Deployment、DaemonSet, StatefulSet、Job 等,但都是在 Pod 启动时,在主容器启动前执行,做初始化工作。


Init 容器与普通的容器区别是:


1、Init 容器不支持 Readiness,因为它们必须在 Pod 就绪之前运行完成


2、每个 Init 容器必须运行成功,下一个才能够运行


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


[root@k8smaster node]# vim init.yaml
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  containers:
  - name: myapp-container
    image: busybox:1.28
    command: ['sh', '-c', 'echo The app is running! && sleep 3600']
  initContainers:
  - name: init-myservice
    image: busybox:1.28
    command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
  - name: init-mydb
    image: busybox:1.28
    command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]
#上面两段长的是myservice的svc和mydb的svc
[root@k8smaster node]# kubectl apply -f init.yaml 
pod/myapp-pod created
[root@k8smaster node]# kubectl get pods 
NAME                    READY   STATUS     RESTARTS   AGE
myapp-pod               0/1     Init:0/2   0          7s
#发现一直在初始化,查看一下日志
[root@k8smaster node]# kubectl logs myapp-pod
Error from server (BadRequest): container "myapp-container" in pod "myapp-pod" is waiting to start: PodInitializing
#有个container是waiting状态,去yaml看看
until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; 
#这是在解析myservice的svc,解析到才成功,不然就会一直循环,我们没有创建,所以一直卡在这里!
[root@k8smaster node]# vim service.yaml
---
apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9376
---
apiVersion: v1
kind: Service
metadata:
  name: mydb
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9377
[root@k8smaster node]# kubectl apply -f service.yaml 
service/myservice created
service/mydb created
[root@k8smaster node]# kubectl get pods 
NAME                    READY   STATUS    RESTARTS   AGE
myapp-pod               1/1     Running   0          4m46s
#成功启动
[root@k8smaster node]# kubectl logs myapp-pod
The app is running!
[root@k8smaster node]# kubectl describe pods myapp-pod
#也可以看启动了哪些容器 在下面


主容器


容器钩子


初始化容器启动之后,开始启动主容器,在主容器启动之前有一个 post start hook(容器启动后钩子)和 pre stop hook(容器结束前钩子),无论启动后还是结束前所做的事我们可以给它放两个钩子,这个钩子就表示用户可以用它来钩住一些命令,来执行它,做开场前的预设,结束前的清理,如 awk 有 begin,end,和这个效果类似。


postStart: 该钩子在容器被创建后立刻触发,通知容器它已经被创建。如果该钩子对应的 hook handler 执行失败,则该容器会被杀死,并根据该容器的重启策略决定是否要重启该容器,这个钩子不需要传递任何参数。


preStop: 该钩子在容器被删除前触发,其所对应的 hook handler 必须在删除该容器的请求发送 给 Docker daemon 之前完成。在该钩子对应的 hook handler 完成后不论执行的结果如何,Docker daemon 会发送一个 SGTERN 信号量给 Docker daemon 来删除该容器,这个钩子不需要传递任何参数。


在 k8s 中支持两类对 pod 的检测


第一类叫做 livenessprobe(pod 存活性探测): 存活探针主要作用是,用指定的方式检测 pod 中的容器应用是否正常运行,如果检测失败,则认为容器不健康,那么 Kubelet 将根据 Pod 中设置的 restartPolicy 来判断 Pod 是否要进行重启操作,如果容器配置中没有配置 livenessProbe,Kubelet 将认为存活探针探测一直为成功状态。 get pods里的status就是存活探测


第二类是状态检 readinessprobe(pod 就绪性探测):用于判断容器中应用是否启动完成,当探测成功后才使 Pod 对外提供网络访问,设置容器 Ready 状态为 true,如果探测失败,则设置容器的 Ready 状态为 false。


创建 pod 需要经过哪些阶段?


当用户创建 pod 时,这个请求给 apiserver,apiserver 把创建请求的状态保存在 etcd 中;接下来 apiserver 会请求 scheduler 来完成调度,如果调度成功,会把调度的结果(如调度到哪个节点上了,运行在哪个节点上了,把它更新到 etcd 的 pod 资源状态中)保存在 etcd 中,一旦存到 etcd 中并且完成更新以后,如调度到 k8snode1 上,那么 node1 节点上的 kubelet 通过 apiserver 当中的状态变化知道有一些任务被执行了,所以此时此 kubelet 会拿到用户创建时所提交的清单,这个清单会在当前节点上运行或者启动这个 pod,如果创建成功或者失败会有一个当前状态,当前这个状态会发给 apiserver,apiserver 在存到 etcd 中;在这个过程 中,etcd 和 apiserver 一直在打交道,不停的交互,scheduler 也参与其中,负责调度 pod 到合适的 node 节点上,这个就是 pod 的创建过程.


pod 在整个生命周期中有非常多的用户行为:


1、初始化容器完成初始化


2、主容器启动后可以做启动后钩子


3、主容器结束前可以做结束前钩子


4、在主容器运行中可以做一些健康检测,如 liveness probe,readness probe


Pod 容器探测和钩子


容器钩子:postStart 和 preStop


postStart:容器创建成功后,运行前的任务,用于资源部署、环境准备等。


preStop:在容器被终止前的任务,用于优雅关闭应用程序、通知其他系统等。


...... 
containers: 
- image: sample
 name: war 
 lifecycle: 
  postStart:  #钩子
   exec: 
   command:  #命令
    - “cp” 
    - “/sample.war” 
    - “/app”
 prestop:   #钩子
  httpGet:    #httpget的探针
   host: monitor.com  
   path: /waring 
  port: 8080 
  scheme: HTTP 
...... 
以上示例中,定义了一个 Pod,包含一个 JAVA 的 web 应用容器,其中设置了 PostStart
和PreStop 回调函数。即在容器创建成功后,复制/sample.war 到/app 文件夹中。而在容器
终止之前,发送 HTTP 请求到 http://monitor.com:8080/waring,即向监控系统发送警告。 
#可以看帮助文档
[root@k8smaster node]# kubectl explain pods.spec.containers.lifecycle


优雅的删除资源对象


当用户请求删除含有 pod 的资源对象时(如 RC、deployment 等),K8S 为了让应用程序优雅关闭(即让应用程序完成正在处理的请求后,再关闭软件),K8S 提供两种信息通知:


默认:K8S 通知 node 执行 docker stop 命令,docker 会先向容器中 PID 为 1 的进程发送系统信号 SIGTERM,然后等待容器中的应用程序终止执行,如果等待时间达到设定的超时时间,或者默认超时时间(30s),会继续发送 SIGKILL 的系统信号强行 kill 掉进程。


使用 pod 生命周期(利用 PreStop 回调函数),它执行在发送终止信号之前。

默认情况下,所有的删除操作的优雅退出时间都在 30 秒以内。kubectl delete 命令支持–grace-period=的选项,以运行用户来修改默认值。0 表示删除立即执行,并且立即从 API 中删除 pod。在节点上,被设置了立即结束的的 pod,仍然会给一个很短的优雅退出时间段,才会开始被强制杀死。如下:


spec: 
 containers: 
 - name: nginx-demo 
 image: centos:nginx 
 lifecycle: 
 preStop: #钩子
 exec: 
 command: ["/usr/local/nginx/sbin/nginx","-s","quit"]  #删除之前会先停掉nginx再删除容器
 ports: 
 - name: http 
 containerPort: 80


相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
1天前
|
Kubernetes Cloud Native 开发者
探秘云原生计算:Kubernetes与Docker的协同进化
在这个快节奏的数字时代,云原生技术以其灵活性和可扩展性成为了开发者们的新宠。本文将带你深入了解Kubernetes和Docker如何共同塑造现代云计算的架构,以及它们如何帮助企业构建更加敏捷和高效的IT基础设施。
|
9天前
|
Kubernetes 安全 Cloud Native
云上攻防-云原生篇&K8s安全-Kubelet未授权访问、API Server未授权访问
本文介绍了云原生环境下Kubernetes集群的安全问题及攻击方法。首先概述了云环境下的新型攻击路径,如通过虚拟机攻击云管理平台、容器逃逸控制宿主机等。接着详细解释了Kubernetes集群架构,并列举了常见组件的默认端口及其安全隐患。文章通过具体案例演示了API Server 8080和6443端口未授权访问的攻击过程,以及Kubelet 10250端口未授权访问的利用方法,展示了如何通过这些漏洞实现权限提升和横向渗透。
云上攻防-云原生篇&K8s安全-Kubelet未授权访问、API Server未授权访问
|
9天前
|
安全 Cloud Native Shell
云上攻防:云原生篇&Docker容器逃逸
本文介绍了Docker的基本概念及其对渗透测试的影响,重点讲解了容器逃逸的方法。Docker是一种轻量级的容器技术,与虚拟机相比,具有更高的便携性和资源利用率。然而,这也带来了安全风险,特别是容器逃逸问题。文章详细描述了三种常见的容器逃逸方法:不安全的配置、相关程序漏洞和内核漏洞,并提供了具体的检测和利用方法。此外,还介绍了几种特定的漏洞(如CVE-2019-5736和CVE-2020-15257)及其复现步骤,帮助读者更好地理解和应对这些安全威胁。
云上攻防:云原生篇&Docker容器逃逸
|
13天前
|
Kubernetes Cloud Native Docker
云原生入门:Kubernetes和Docker的协同之旅
【10月更文挑战第4天】在这篇文章中,我们将通过一次虚拟的旅行来探索云原生技术的核心——Kubernetes和Docker。就像乘坐一艘由Docker驱动的小船启航,随着波浪(代码示例)起伏,最终抵达由Kubernetes指挥的宏伟舰队。这不仅是一段技术上的旅程,也是理解现代云架构如何支撑数字世界的冒险。让我们扬帆起航,一探究竟!
|
13天前
|
Kubernetes Cloud Native 云计算
云原生之旅:构建你的第一个容器化应用
【8月更文挑战第75天】在数字化浪潮中,云原生技术成为推动企业创新和效率提升的关键动力。本篇文章将引导你开启云原生之旅,通过一个简易的步骤指南,帮助你构建并部署第一个容器化应用。我们将一起探索Docker容器的魅力,以及如何利用Kubernetes进行集群管理,实现服务的自动化部署、扩展和管理。无论你是云原生新手还是希望深化理解,这篇文章都将为你提供实践操作的启示和深入思考的契机。
|
11天前
|
Kubernetes Cloud Native 调度
深入探讨容器化技术:Kubernetes 的魅力
【10月更文挑战第6天】深入探讨容器化技术:Kubernetes 的魅力
27 0
|
13天前
|
运维 Kubernetes Cloud Native
云原生时代的容器编排:Kubernetes入门与实践
【10月更文挑战第4天】在云计算的浪潮中,云原生技术以其敏捷、可扩展和高效的特点引领着软件开发的新趋势。作为云原生生态中的关键组件,Kubernetes(通常被称为K8s)已成为容器编排的事实标准。本文将深入浅出地介绍Kubernetes的基本概念,并通过实际案例引导读者理解如何利用Kubernetes进行高效的容器管理和服务部署。无论你是初学者还是有一定经验的开发者,本文都将为你打开云原生世界的大门,并助你一臂之力在云原生时代乘风破浪。
|
15天前
|
Kubernetes Cloud Native 流计算
Flink-12 Flink Java 3分钟上手 Kubernetes云原生下的Flink集群 Rancher Stateful Set yaml详细 扩容缩容部署 Docker容器编排
Flink-12 Flink Java 3分钟上手 Kubernetes云原生下的Flink集群 Rancher Stateful Set yaml详细 扩容缩容部署 Docker容器编排
57 0
|
2天前
|
存储 Docker 容器
docker中挂载数据卷到容器
【10月更文挑战第12天】
14 5
|
7天前
|
存储 运维 云计算
探索Docker容器化:从入门到实践
在这个快速发展的云计算时代,Docker容器化技术正在改变应用的开发、部署和管理方式。本文旨在为初学者提供一个关于Docker的全面入门指南,并通过实践案例展示Docker在实际开发中的应用。我们将一起了解Docker的核心概念、基本操作、网络和存储,以及如何构建和部署一个简单的Web应用。无论你是开发者还是运维人员,本文都会帮助你快速掌握Docker的核心技能。

相关产品

  • 容器服务Kubernetes版