基础概念
Kubernetes
为什么要用Kubernetes
- **提高开发效率:**Kubernetes提供了一种标准化的方法来管理容器化应用程序,使得开发者可以更容易地在不同的环境中部署和管理应用程序,从而提高开发效率。
- **提高应用程序的可靠性:**Kubernetes提供了一种自动化的方式来部署、扩展和管理容器化应用程序,可以自动处理应用程序的故障转移和自动扩展,从而提高应用程序的可靠性。
- **提高应用程序的可扩展性:**Kubernetes提供了一种自动化的方式来部署、扩展和管理容器化应用程序,可以自动处理应用程序的扩展和缩容,从而提高应用程序的可扩展性。
- **提高应用程序的可移植性:**Kubernetes支持多种容器技术,可以运行在多种操作系统上,包括Linux、Windows等,可以轻松地将应用程序从一个环境迁移到另一个环境,从而提高应用程序的可移植性。
- **提高应用程序的安全性:**Kubernetes提供了一种自动化的方式来部署、扩展和管理容器化应用程序,可以自动处理应用程序的安全性,从而提高应用程序的安全性。
Master
master节点是kubernetes集群中的控制中枢;
在master节点上常部署如下组件:
- Kube-APIServer:是集群的控制中枢,各个模块直接的信息交互的模块;同时也是集群管理、资源配置、安全机制的入口;
- Controller-Manager:集群的状态管理器,可以保证Pod或其他资源达到期望值;同时也需要与Kube-APIServer进行通讯;在需要的时候进行Pod的创建、更新或删除Controller-Manager管理的资源;
- Scheduler:集群的调度中心,会根据指定的一系列条件,选择一个或多个最佳节点部署Pod;
- Etcd:集群的存储数据库,用于存放集群的产生的信息;生成环境下建议单独部署,三个以上(奇数)节点,且采用SSD高速盘保证集群的性能;
Node
node节点就是集群中的工作节点,主要用于运行各个应用程序,node节点也可以称为worker节点、minion节点;
在node节点上常部署如下组件:
- Kubelet:主要负责node、Pod的状态,同时负责将节点和节点上Pod的状态上报给master节点;
- Kube-proxy:负责Pod之间的通信和Pod之间的负责均衡;将指定的流量分发到后端正确的机器上;
补充:
- Kubernetes集群常用的转发模式有IPVS和IPtables,可以使用命令“curl 127.0.0.1:10249/proxyMode”查看集群使用的转发模式;
- IPVS的工作模式:IPVS主要监听master节点增加和删除service以及endpoint的消息,然后调用netlink接口创建相应的IPVS规则;通过IPVS规则将流量转发至相应的Pod;
- IPtables的工作模式:IPtables主要监听master节点增加和删除service以及endpoint的消息,对于每一个service都会创建一个相应的IPtables规则,然后将service的集群IP代理到后端对于的Pod;
- 在生成环境中不建议使用IPtables转发模式,IPtables在海量规则下性能会急剧下降,而IPVS是基于内核级的转发,效率会更快;所以推荐使用IPVS规则;
Pod
在Kubernetes集群中,所有资源都是根据namespace(命名空间)来隔离的,在“kube-system”(k8s系统命名空间)下部署了系统使用的Pod;
常部署的Pod如下:
- calico:Calico是一个网络插件,用于给每个Pod生成一个唯一的IP地址;并且把每个节点当做一个路由器;
- coredns:Kubernetes集群内部service的地址解析,可以让Pod把service名称解析成IP地址,然后通过service的IP地址连接到对于的应用上;
Pod
什么是Pod
Pod是kubernetes集群中最小的操作单元,Pod是一组、一个或多个容器组成;
每个Pod在创建时还自动创建了一个Pause容器,Pause容器主要负责僵尸进程的回收管理;
通过Pause容器可以使同一个Pod下的多个容器共享存储、网络、PID、IPC等资源;
为什么要引入Pod
- 使用Pod可以解决Pod中各个容器之间的强依赖性;
- 使用Pod可以解决Pod中各个容器之间的协同工作;
- kubernetes是容器编排工具支持多种容器工具,引入Pod可以兼容更多容器版本;
定义一个Pod
在kubernetes中一般都使用yaml文件来定义资源,也可以使用kubectl命令来创建资源。但是yaml文件更加清晰简介,创建的资源可以有效追溯,并且可以方便查看配置信息;
- yaml定义简单Pod
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: default
labels:
app: nginx
type: web
spec:
containers:
- name: nginx-web-01
image: registry.cn-beijing.aliyuncs.com/publicspaces/nginx:1.22.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8001
name: http
protocol: TCP
workingDir: /usr/local/nginx
restartPolicy: Always
- 创建Pod
kubectl create -f pod-nginx.yaml
- 查看Pod
kubectl get pods
Pod常见状态
状态 | 说明 |
---|---|
Pending(挂起) | Pod已被kubernetes系统接收,但仍有一个或多个容器未被创建,可以通过kubectl describe查看处于Pending状态的原因 |
Running(运行中) | Pod已被绑定到一个节点上,并且所有容器都已经被创建,且至少有一个是运行状态,或者是正在启动或重启,可以通过kubectl logs查看Pod日志 |
Succeeded(成功) | 所有容器执行成功并终止,且不会再次重启,可以通过kubectl logs查看Pod日志 |
Failed(失败) | 所有容器都已终止,且至少有一个容器以失败的方式终止,此容器要么以非零状态退出,要么被系统终止,可以通过kubectl logs查看Pod日志 |
Unknown(未知) | 通常是由于通信问题造成的无法获取Pod状态 |
ImagePullBackOff或ErrImagePull | 镜像拉取失败,一般是由于镜像不存在、网络不同或者要求登录认证引起的,可以使用kubectl describe查看具体原因 |
CrashLoopBackOff | 容器启动失败,可以通过kubectl logs查看具体原因,一般为启动命令不正确,健康检查不通过等原因 |
OOMKilled | 容器内存溢出,一般是容器的内容limits设置的过小,或者程序本身有内存溢出,可以通过kubectl logs查看程序启动日志 |
Terminating | Pod正在被删除,可以通过kubectl describe查看状态 |
SysctlForbidden | Pod自定义了内核配置,但kubectl没有添加内核配置或配置的内核参数不支持,可以通过kubectl describe查看具体原因 |
Completed | 容器内部主进程退出,一般计划任务执行结束会显示该状态,此时可以通过kubectl logs查看容器日志 |
ContainerCreating | Pod正在创建,一般为正在下载镜像,或者有配置不当的地方,可以通过kubectl describe查看具体原因 |
Pod文件扩展
- yaml定义Pod案例
apiVersion: v1 #必选,定义Pod的API版本号
kind: Pod #必选,定义创建资源的类型为Pod
metadata: #必选,定义Pod的元数据
name: nginx #必选,定义Pod的名称,需要符合RFC 1035规范
namespace: default #可选,定义Pod所运行的命名空间,如不指定则资源运行带default命名空间下
labels: #可选,定义Pod的标签,可以通过定义的标签来对资源进行过滤或区分
app: nginx #可选,如定义labels后此处必选,定义标签的key和value,可以指定多个标签
type: web
role: frontend
annotations: #可选,定义Pod的注释列表,可以定义多个
app: nginx #可选,如定义annotations后此处必选
spec: #必选,用于定义Pod中运行容器的详细信息
initContainers: #可选,用于初始化Pod中运行的容器,即在容器启动之前执行的一系列初始化操作,可以配置多个
- name: init-container-1
image: registry.cn-beijing.aliyuncs.com/publicspaces/busybox:1.28.0
imagePullPolicy: IfNotPresent
command:
- sh
- -c
- echo "这是一个初始化容器,用于初始化一些配置"
- name: init-container-2
image: registry.cn-beijing.aliyuncs.com/publicspaces/busybox:1.28.0
imagePullPolicy: IfNotPresent
command:
- sh
- -c
- echo "这是一个初始化容器,用于初始化一些配置"
containers: #必选,用于定义Pod中的容器列表,可以配置多个
- name: nginx-web #必选,用于定义Pod中容器的名称,需要符合RFC 1035规范
image: registry.cn-beijing.aliyuncs.com/publicspaces/nginx:1.22.1 #必选,用于定义Pod中容器使用的镜像
imagePullPolicy: IfNotPresent #可选,用于定义Pod中容器使用镜像的拉取策略,默认拉取策略
command: #可选,用于定义Pod中容器启动执行的命令
- nginx
- -g
- "daemon off;"
workingDir: /usr/local/nginx/ #可选,用于定义Pod中容器的工作目录
volumeMounts: #可选,用于定义Pod中容器的存储卷配置,可以定义多个
- mountPath: /usr/local/nginx/html #可选,用于定义Pod中容器挂载存储卷的路径,如volumeMounts挂载时,此次必选
name: webroot #可选,用于定义Pod中容器挂载存储卷名称,如volumeMounts挂载时,此次必选
- mountPath: /usr/local/nginx/logs
name: weblogs
ports: #可选,用于定义Pod中容器的暴露端口列表,可以定义多个
- containerPort: 80 #可选,用于定义Pod中容器要暴漏的端口号,如果定义了ports,那么此次必选
name: http #可选,用于定义Pod中容器端口的名称,如果定义了ports,那么此次必选
protocol: TCP #可选,用于定义Pod中容器暴露端口号的端口协议,默认协议为TCP,如果定义了ports,那么此次必选
env: #可选,用于定义Pod中容器的环境变量配置列表,可以定义多个
- name: TimeZone #可选,用于定义Pod中容器使用环境变量的名称,如果定义了env,那么此次必选
value: Asia/Shanghai #可选,用于定义Pod中容器使用环境变量的值,如果定义了env,那么此次必选
- name: Lang
value: en_US.utf8
resources: #可选,用于定义Pod中容器的资源限制和资源请求限制
limits: #可选,用于定义Pod中容器的资源最大限制,如果定义了resources,那么此次必选
cpu: 1000m #可选,用于定义Pod中容器的CPU资源最大限制
memory: 1024Mi #可选,用于定义Pod中容器的MEM资源最大限制
requests: #可选,用于定义Pod中容器的启动所需资源限制,如果定义了resources,那么此次必选
cpu: 100m #可选,用于定义Pod中容器的启动所需CPU资源限制
memory: 512Mi #可选,用于定义Pod中容器的启动所需MEM资源限制
# startupProbe: #可选,用于定义Pod中容器的健康检查,三种检查方式同一只能使用一种
# httpGet: #可选,接口级别的监控检测,如果定义了startupProbe,那么此次必选
# port: 80 #可选,指定接口级检查的端口,如果定义了startupProbe,那么此次必选
# path: /api/successStart #可选,指定接口级检查的路径,如果定义了startupProbe,那么此次必选
readinessProbe: #可选,用于定义Pod中容器的健康检查,三种检查方式同一只能使用一种
httpGet: #可选,指定接口级检查的路径,如果定义了readinessProbe,那么此次必选
port: 80 #可选,指定接口级检查的端口,如果定义了readinessProbe,那么此次必选
path: / #可选,指定接口级检查的路径,如果定义了readinessProbe,那么此次必选
livenessProbe: #可选,用于定义Pod中容器的健康检查,三种检查方式同一只能使用一种
# exec: #可选,指定了容器执行命令的检查方式
# command: #可选,指定了容器要执行的命令
# - cat
# - /script/health-chack.sh
# httpGet: #可选,指定了httpGet检查方式
# port: 8080 #可选,指定了健康检查的端口
# path: /script/health-chack.sh #可选,指定了健康检查的脚步
# httpHeaders: #可选,指定了健康检查的请求头信息
# - name: end-user
# value: json
tcpSocket: #可选,定义端口检查方式
port: 80 #可选,指定端口检查的端口号
initialDelaySeconds: 60 #可选,定义初始化时间
timeoutSeconds: 2 #可选,定义超时时间
periodSeconds: 5 #可选,定义检测间隔时间
successThreshold: 1 #可选,表示检查成功2次表示就绪
failureThreshold: 2 #可选,表示检查失败1次表示就绪
lifecycle:
postStart:
exec:
command:
- sh
- -c
- 'mkdir /data/'
preStop:
httpGet:
port: 80
path: /
# exec:
# command:
# - sh
# - -c
# - sleep 9
restartPolicy: Always #可选,指定Pod中容器的重启策略,默认为Always
# nodeSelector: #指定Pod运行在哪个节点
# region: subnet7 #指定节点的标签,以Key: Value的形式定义
imagePullSecrets: #可选,定义拉取镜像时使用的secret(密码配置),可以配置多个
- name: default-dockercfg-86258 #可选,指定secret的名称,如定义了imagePullSecrets,此处必选
hostNetwork: false #可选,指定Pod中容器是否为主机模式,如果指定主机模式,则Pod会占用主机端口。默认为false
volumes: #可选,如指定了volumeMounts,此处必选,用于定义容器存储卷,可以配置多个
- name: webroot #存储卷的名称,哪个volumeMounts用到了,他的name需要与此处保持一致
emptyDir: {} #定义一个空的挂载目录
- name: weblogs #存储卷的名称,哪个volumeMounts用到了,他的name需要与此处保持一致
hostPath: #定义一个宿主机挂载目录
path: /data/nginx/logs #宿主机的目录路径
- RFC 1035规范命名规范
- 由小写字母、数字和连字符(-)组成。
- 名称长度在1到253个字符之间。
- 首字母和尾字母不能是连字符(-)。
- 常用的镜像拉取策略
- Always:无论是否本地存在最新版本的镜像,都会尝试从镜像仓库中拉取最新版本的镜像。
- IfNotPresent:仅在本地不存在指定版本的镜像时才会拉取。
- Never:从不尝试拉取新版本的镜像,即使本地存在较旧的镜像版本。
- 挂载存储卷的策略
- ReadOnly:
- ReadWrite:
- ReadOnlyOnce:卷可以被单个节点以只读模式挂载。
- ReadWriteOnce:卷可以被单个节点以读写模式挂载。
- ReadOnlyMany:卷可以被多个节点以只读模式挂载。
- ReadWriteMany:卷可以被多个节点以读写模式挂载。
- 资源限制策略
- cpu:对CPU的限制,CPU的单位,1表示1个CPU核心,0.5表示1/2个CPU核心;
- memory:对MEM的限制,MEM的单位,
- 监控检测策略
- startupProbe:启动探针,判断容器内程序是否可用。
- readinessProbe:就绪探针,判断容器内程序是否可接收流量。
- livenessProbe:存活探针,判断容器是否可用。
- 容器的重启策略
- Always:终止退出后,总是重启容器(默认策略)
- OnFailure:当容器异常退出(退出状态码非0)时才重启容器
- Never:当容器终止退出从不重启容器
零宕机基础
Pod三种探针
三种探针的基本概念
在kubernetes中Pod的健康检查是通过探针(Probe)来实现的,kubernetes中探针主要分为三种类型:存活探针(Liveness Probe)、就绪探针(Readiness Probe)和启动探针(Startup Probe)
- startupProbe(启动探针)
- kubernetes的1.16版本以后新加的探测方式,用于判断容器内的应用程序是否已经启动。
- 如果设置了这个探针策略他就会先禁用其他探针,就是禁用后面两个探针,只有等startupProbe探针完成以后下面的探针才会开启。
- 如果startup Probe这个探针失败了kebelet会杀死容器,然后根据重启策略进行重启。
- 如果探测成功或者没有设置startup Probe 就为Success。
- 如果没有设置startupProbe,默认探针状态就是success。
- livenessProbe(存活探针)
- 用于检测容器是否真正存活。
- 如果探测失败kubelet会直接杀死容器,并且根据重启策略进行重启。
- 如果没有设置livenessProbe,默认探针状态就是success。
- readinessProbe(就绪探针)
- 用于检测程序运行是否健康,或者健康状态检测,判断容器是否为就绪状态。
- 如果探针容器内程序正常运行,那么这个容器就启动完成,程序就可以接收流量。
- 如果检测失败Endpoints节点控制器会把对应的pod从节点控制器里面清除掉。
- 如果没有设置readinessProbe,默认探针状态就是success。
三种探针的检测方式
三种探针都分别对应三种检测方式,检测方式主要有:命令检查(ExecAction)、端口检查(TCPSocketAction)、接口检查(HTTPGetAction)
- ExecAction
- 在容器内执行一个命令,如果返回值为0,那么任务容器是健康状态。
- TCPSocketAction
- 在容器内通过TCP连接检查端口是否畅通,如果端口通则表示容器是健康状态。
- HTTPGetAction
- 在容器中通过检查应用程序的API地址来判断是否健康,如果状态码在200到400之间则表示容器是健康状态。
注意:
在生产环境中建议存活探针(Liveness Probe)和就绪探针(Readiness Probe)都使用HTTPGetAction的检测方式,接口级的检测方式更能完美的检测服务状态。
探针的检查参数配置
- initialDelaySeconds: 60
- 初始化时间,程序部署好多久后去检查,此处定义60秒;
- 此处时间定义的越长,那么滚动发布的耗时越长;
- timeoutSeconds: 2
- 超时时间,检测的超时时间,此处定义2秒;
- 如HTTPGetAction检测方式中的响应时间为毫秒级,所以此次一般设置为1-2秒;
- periodSeconds: 5
- 检测间隔时间,多久检测一次,此处定义5秒;
- 两次检测之间的间隔时间,不建议设置太长时间;
- successThreshold: 1
- 检测成功次数,连续检测成功几次后定义为就绪;
- failureThreshold: 2
- 检测失败次数,连续检测失败几次后定义为未就绪;
startupProbe
- exec检查方式-举例
#通过exec命令方式检测nginx是否正常运行,从而判断nginx是否启动
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: default
labels:
app: nginx
type: web
spec:
containers:
- name: nginx-web-01
image: registry.cn-beijing.aliyuncs.com/publicspaces/nginx:1.22.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8001
name: http
protocol: TCP
workingDir: /usr/local/nginx
startupProbe:
failureThreshold: 2
exec:
command:
- sh
- -c
- nginx -t
initialDelaySeconds: 10
periodSeconds: 3
successThreshold: 1
timeoutSeconds: 2
restartPolicy: Always
- tcpSocket检查方式-举例
#通过tcpSocket端口方式检测nginx的80端口是否被监听,从而判断nginx是否启动
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: default
labels:
app: nginx
type: web
spec:
containers:
- name: nginx-web-01
image: registry.cn-beijing.aliyuncs.com/publicspaces/nginx:1.22.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8001
name: http
protocol: TCP
workingDir: /usr/local/nginx
startupProbe:
failureThreshold: 2
tcpSocket:
port: 80
initialDelaySeconds: 10
periodSeconds: 3
successThreshold: 1
timeoutSeconds: 2
restartPolicy: Always
- httpGet检查方式-举例
#通过httpGet接口方式检测nginx,从而判断nginx是否启动
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: default
labels:
app: nginx
type: web
spec:
containers:
- name: nginx-web-01
image: registry.cn-beijing.aliyuncs.com/publicspaces/nginx:1.22.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8001
name: http
protocol: TCP
workingDir: /usr/local/nginx
startupProbe:
failureThreshold: 2
httpGet:
port: 80
path: /index.html
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 3
successThreshold: 1
timeoutSeconds: 2
restartPolicy: Always
livenessProbe
- exec检查方式-举例
#通过exec命令方式检测nginx是否正常运行,从而判断nginx是否启动
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: default
labels:
app: nginx
type: web
spec:
containers:
- name: nginx-web-01
image: registry.cn-beijing.aliyuncs.com/publicspaces/nginx:1.22.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8001
name: http
protocol: TCP
workingDir: /usr/local/nginx
livenessProbe:
failureThreshold: 2
exec:
command:
- sh
- -c
- nginx -t
initialDelaySeconds: 10
periodSeconds: 3
successThreshold: 1
timeoutSeconds: 2
restartPolicy: Always
- tcpSocket检查方式-举例
#通过tcpSocket端口方式检测nginx的80端口是否被监听,从而判断nginx是否启动
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: default
labels:
app: nginx
type: web
spec:
containers:
- name: nginx-web-01
image: registry.cn-beijing.aliyuncs.com/publicspaces/nginx:1.22.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8001
name: http
protocol: TCP
workingDir: /usr/local/nginx
livenessProbe:
failureThreshold: 2
tcpSocket:
port: 80
initialDelaySeconds: 10
periodSeconds: 3
successThreshold: 1
timeoutSeconds: 2
restartPolicy: Always
- httpGet检查方式-举例
#通过httpGet接口方式检测nginx,从而判断nginx是否启动
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: default
labels:
app: nginx
type: web
spec:
containers:
- name: nginx-web-01
image: registry.cn-beijing.aliyuncs.com/publicspaces/nginx:1.22.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8001
name: http
protocol: TCP
workingDir: /usr/local/nginx
livenessProbe:
failureThreshold: 2
httpGet:
port: 80
path: /index.html
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 3
successThreshold: 1
timeoutSeconds: 2
restartPolicy: Always
readinessProbe
- exec检查方式-举例
#通过exec命令方式检测nginx是否正常运行,从而判断nginx是否启动
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: default
labels:
app: nginx
type: web
spec:
containers:
- name: nginx-web-01
image: registry.cn-beijing.aliyuncs.com/publicspaces/nginx:1.22.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8001
name: http
protocol: TCP
workingDir: /usr/local/nginx
readinessProbe:
failureThreshold: 2
exec:
command:
- sh
- -c
- nginx -t
initialDelaySeconds: 10
periodSeconds: 3
successThreshold: 1
timeoutSeconds: 2
restartPolicy: Always
- tcpSocket检查方式-举例
#通过tcpSocket端口方式检测nginx的80端口是否被监听,从而判断nginx是否启动
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: default
labels:
app: nginx
type: web
spec:
containers:
- name: nginx-web-01
image: registry.cn-beijing.aliyuncs.com/publicspaces/nginx:1.22.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8001
name: http
protocol: TCP
workingDir: /usr/local/nginx
readinessProbe:
failureThreshold: 2
tcpSocket:
port: 80
initialDelaySeconds: 10
periodSeconds: 3
successThreshold: 1
timeoutSeconds: 2
restartPolicy: Always
- httpGet检查方式-举例
#通过httpGet接口方式检测nginx,从而判断nginx是否启动
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: default
labels:
app: nginx
type: web
spec:
containers:
- name: nginx-web-01
image: registry.cn-beijing.aliyuncs.com/publicspaces/nginx:1.22.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8001
name: http
protocol: TCP
workingDir: /usr/local/nginx
readinessProbe:
failureThreshold: 2
httpGet:
port: 80
path: /index.html
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 3
successThreshold: 1
timeoutSeconds: 2
restartPolicy: Always
应用举例
- 编辑yaml文件
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: default
labels:
app: nginx
type: web
spec:
containers:
- name: nginx-web-01
image: registry.cn-beijing.aliyuncs.com/publicspaces/nginx:1.22.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8001
name: http
protocol: TCP
workingDir: /usr/local/nginx
startupProbe:
exec:
command:
- sh
- -c
- nginx -t
successThreshold: 1
failureThreshold: 3
timeoutSeconds: 2
initialDelaySeconds: 3
periodSeconds: 1
livenessProbe:
tcpSocket:
port: 80
successThreshold: 1
failureThreshold: 3
timeoutSeconds: 2
initialDelaySeconds: 3
periodSeconds: 1
readinessProbe:
httpGet:
port: 80
path: /index.html
scheme: HTTP
successThreshold: 1
failureThreshold: 3
timeoutSeconds: 2
initialDelaySeconds: 3
periodSeconds: 1
restartPolicy: Always
- 创建Pod
kubectl create -f pod-nginx.yaml
Pod生命周期
生命周期概述
- PostStart
- PostStart在容器创建后立即执行,但不能保证是在容器entrypoint之前运行。
- PostStart主要用于资源部署、环境准备等低级别操作,高级别仍有initContainers完成。
- PostStart的执行,相对与容器的代码执行是异步的,只有postStart处理函数执行完毕,容器的状态才会变成 RUNNING。
- 注意:如果PostStart花费时间过长、不能运行或者不能挂起,容器就不能达到Running状态。
- PreStop
- PreStop在容器终止前立即被调用。
- PreStop是阻塞的,所以必须在删除容器的调用触发之前完成,主要用于优雅关闭程序、通知其他系统等。
- PreStop在执行期间挂起,Pod阶段将停留在Running状态并且不会达到failed状态。
- PreStop的执行,相对于SIGTERM信息也是异步的,k8s不会等待PreStop执行完成。
三种检测方式
- exec
- 调用命令操作容器,如果命令结果返回0,表示成功;
tcpSocket(被弃用)调用端口操作容器,如果端口可以正常建立连接,表示成功;
- httpGet
- 调用接口操作容器,如果接口返回200-400之间的状态码,表示成功;
Pod退出流程
- 退出Pod流程图
- 退出Pod详解
- 用户发送删除pod的指令;
- API-Server服务器中的pod对象会随着时间的推移而更新,在宽限期内 terminationGracePeriodSeconds: 30 ; 默认是30秒, Pod 被视为dead;
- 将pod标记为Terminating状态;
- (与第3步同时运行),kubelet 在监控到pod对象转为Terminating状态的同时启动Pod关闭过程;
- (与第3步同时运行),Endpoint控制器监控到Pod对象的关闭行为时将其从所有匹配到此端点的Service资源的端点列表中移除;
- 如果当前pod对象定义了preStop勾子句柄,在其标记为Terminating后会以同步方式启动执行。如若宽限期结束后,preStop仍未执行完,则从新执行第2步并额外获取一个时长为2秒的小宽限期;
- Pod对象中的容器进程收到TERM信号;
- 宽限期结束后,若存在任何一个仍在运行的进程,Pod对象即会收到SIGKILL信号;
- Kubelet请求API-Server将此Pod资源的宽限期设置为0 从而完成删除操作,它变得对用户不再可见;
- 退出Pod总结
删除pod时,Pod状态变为Terminating,kubelet启动关闭过程,Endpoint移除pod, 同时执行preStop里的指令。
postStart
- exec命令操作容器
#在容器启动前检查nginx配置文件,如果返回值为0,表示操作成功可以启动容器
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: default
labels:
app: nginx
type: web
spec:
containers:
- name: nginx-web-01
image: registry.cn-beijing.aliyuncs.com/publicspaces/nginx:1.22.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8001
name: http
protocol: TCP
workingDir: /usr/local/nginx
lifecycle:
postStart:
exec:
command:
- sh
- -c
- nginx -t
restartPolicy: Always
- httpGet接口操作容器
#在容器启动前通过接口操作容器,如果接口返回200-400之间的状态码,表示操作成功可以启动容器
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: default
labels:
app: nginx
type: web
spec:
containers:
- name: nginx-web-01
image: registry.cn-beijing.aliyuncs.com/publicspaces/nginx:1.22.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8001
name: http
protocol: TCP
workingDir: /usr/local/nginx
lifecycle:
postStart:
httpGet:
port: 80
path: /script/start-check.sh
scheme: HTTP
restartPolicy: Always
preStop
- exec命令检测
#在容器关闭前检查nginx配置文件,如果返回值为0,表示操作成功可以关闭容器
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: default
labels:
app: nginx
type: web
spec:
containers:
- name: nginx-web-01
image: registry.cn-beijing.aliyuncs.com/publicspaces/nginx:1.22.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8001
name: http
protocol: TCP
workingDir: /usr/local/nginx
lifecycle:
preStop:
exec:
command:
- sh
- -c
- nginx -t
terminationGracePeriodSeconds: 40
restartPolicy: Always
- httpGet接口检测
#在容器关闭前通过接口操作容器,如果接口返回200-400之间的状态码,表示操作成功可以关闭容器
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: default
labels:
app: nginx
type: web
spec:
containers:
- name: nginx-web-01
image: registry.cn-beijing.aliyuncs.com/publicspaces/nginx:1.22.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8001
name: http
protocol: TCP
workingDir: /usr/local/nginx
lifecycle:
preStop:
httpGet:
port: 80
path: /script/start-check.sh
scheme: HTTP
restartPolicy: Always
- 注意
- 如果preStop中定义的sleep时间超过terminationGracePeriodSeconds时间时,以terminationGracePeriodSeconds时间为基准
应用举例
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: default
labels:
app: nginx
type: web
spec:
containers:
- name: nginx-web-01
image: registry.cn-beijing.aliyuncs.com/publicspaces/nginx:1.22.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8001
name: http
protocol: TCP
workingDir: /usr/local/nginx
lifecycle:
preStop:
exec:
command:
- sh
- -c
- nginx -t
preStop:
exec:
command:
- sh
- -c
- nginx -t
terminationGracePeriodSeconds: 40
restartPolicy: Always
零宕机配置
配置yaml
注意此yaml仅展示使用,由于没有接口设置,所以无法正常创建Pod
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: default
labels:
app: nginx
role: frontend
spec:
containers:
- name: nginx
image: nginx:latest
imagePullPolicy: Always
command:
- nginx
- -g
- "daemon off;"
workingDir: /usr/share/nginx/html
volumeMounts:
- name: webroot
mountPath: /usr/share/nginx/html
readOnly: true
ports:
- name: http
containerPort: 80
protocol: TCP
env:
- name: TZ
value: Asia/Shanghai
- name: LANG
value: en_US.utf8
startupProbe:
httpGet:
path: /api/successStart
port: 80
readinessProbe:
httpGet:
path: /
port: 80
livenessProbe:
exec:
command:
- cat
- /health
initialDelaySeconds: 60
timeoutSeconds: 2
periodSeconds: 5
successThreshold: 1
failureThreshold: 2
lifecycle:
postStart:
exec:
command:
- sh
- -c
- 'mkdir /data/ '
preStop:
httpGet:
path: /
port: 80
restartPolicy: Always
hostNetwork: false
volumes:
- name: webroot
emptyDir: {}
创建零宕机Pod
kubectl create -f pod-nginx.yaml