k8s之Pod及Probe 探针机制(健康检查机制)
Pod 是一组(一个或多个) 容器(docker容器)的集合 (就像在豌豆荚中);这些容器共享存储、网络、以及怎样运行这些容器的声明我们一般不直接创建Pod,而是创建一些工作负载由他们来创建Pod临时容器:线上排错有些容器基础镜像。线上没法排错。使用临时容器进入这个Pod。临时容器共享了Pod的所有。临时容器有Debug的一些命令,拍错完成以后,只要exit退出容器,临时容器自动删除临时容器需要开
文章目录
1、Pod
1.1、定义
- Pod 是一组(一个或多个) 容器(docker容器)的集合 (就像在豌豆荚中);这些容器共享存储、网络、以及怎样运行这些容器的声明
- - 我们一般不直接创建Pod,而是创建一些工作负载由他们来创建Pod
1.2、Pod的形式
- Pod对容器有自恢复能力(Pod自动重启失败的容器)
- Pod自己不能恢复自己,Pod如果被删除就真的没了,还是希望k8s集群能自己在其他地方再启动这个Pod
- 单容器Pod
- 多容器协同Pod。我们可以把另外的容器称为 SideCar(为应用赋能)
- Pod 天生地为其成员容器提供了两种共享资源:网络和 存储
一个Pod由一个Pause容器设置好整个Pod里面所有容器的网络、名称空间等信息
systemctl status可以观测到,Pod和容器进程关系
kubelet启动一个Pod,准备两个容器,一个是Pod声明的应用容器(nginx),另外一个是
Pause,Pause给当前应用容器设置好网络空间
1.3、Pod的使用
- 可以编写deploy等各种工作负载的yaml文件,最终创建出pod,也可以直接创建
- Pod的模板如下
#这里是 Pod 模版
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: hello
image: busybox
command: ['sh', '-c', 'echo "Hello, Kubernetes!" && sleep 3600']
restartPolicy: OnFailure
#以上为 Pod 模版
1.4、 Pod生命周期
- Pod启动,会先依次执行所有初始化容器,有一个失败,则Pod不能启动
- 接下来启动所有的应用容器(每一个应用容器都必须能一直运行起来),Pod开始正式工作,一个启动失败就会尝试重启Pod内的这个容器,Pod只要是NotReady,Pod就不对外提供服务了
1.5、初始化容器
apiVersion: v1
kind: Pod
metadata:
name: "pod-life-02"
namespace: default
labels:
app: "pod-life-02"
spec:
volumes:
- name: content-vol
emptyDir: {}
initContainers: ## Pod在启动containers之前,先要【运行完】initContainers的所有容器,所以这些容器必须有终结,不能一直运行
- name: init-c-01
image: alpine ### 必须有终结的那个时刻,一般不要用一直启动的镜像
command: ["/bin/sh","-c","echo 12222222 > /app/index.html;sleep 30;"]
volumeMounts:
- name: content-vol
mountPath: /app
# - name: init-c-02
# image: alpine ### 必须有终结的那个时刻,一般不要用一直启动的镜像
# command: ["/bin/sh","-c","echo 12222222 > /app/index.html;sleep 30;"]
# volumeMounts:
# - name: content-vol
# mountPath: /app
containers:
### docker run alpine 没有在后台一直启动的程序
- name: pod-life-01
image: "nginx" # 默认的启动命令是启动nginx。nginx启动在后台一直有了
volumeMounts:
- name: content-vol
mountPath: /usr/share/nginx/html
- name: pod-life-02
image: "alpine" #pod里面的containers都必须能启动起来,Pod会不断的重启这个容器
command: ["/bin/sh","-c","sleep 30"]
1.6、临时容器
1.6.1、定义
临时容器:线上排错
有些容器基础镜像。线上没法排错。使用临时容器进入这个Pod。临时容器共享了Pod的所有。临时容器有Debug的一些命令,拍错完成以后,只要exit退出容器,临时容器自动删除
临时容器需要开启特性门控 --feature-gates=“EphemeralContainers=true”
在所有组件,api-server、kubelet、scheduler、controller-manager都得配置
1.6.2、使用临时容器的步骤
# 1、声明一个临时容器。准备好json文件
{
"apiVersion": "v1",
"kind": "EphemeralContainers",
"metadata": {
"name": "my-nginx666" //指定Pod的名字
},
"ephemeralContainers": [{
"command": [
"sh"
],
"image": "busybox", //jre的需要jdk来调试
"imagePullPolicy": "IfNotPresent",
"name": "debugger",
"stdin": true,
"tty": true,
"terminationMessagePolicy": "File"
}]
}
# 2、使用临时容器,应用一下即可
kubectl replace --raw /api/v1/namespaces/default/pods/my-nginx666【pod
名】/ephemeralcontainers -f ec.json
1.7、静态Pod
在 /etc/kubernetes/manifests 位置放的所有Pod.yaml文件,机器启动kubelet自己就把他启动起来,静态Pod一直守护在他的这个机器上
创建一个 k8s-pod-static.yaml的文件,放置在 /etc/kubernetes/manifests 位置上
apiVersion: v1
kind: Pod
metadata:
name: "static-pod"
namespace: default
labels:
app: "MYAPP"
spec:
containers:
- name: nginx
image: "nginx"
最终效果:
1.8、创建带标签的pod
apiVersion: v1
kind: Pod
metadata:
name: "my-nginx-labels"
namespace: hello666
labels:
aa: "bb"
cc: "dd"
app: "my-nginx"
spec:
containers:
- name: my-nginx
image: "nginx"
查看pod携带的标签属性:kubectl get pod --show-labels
1.9、容器生命周期回调
postStart:这个回调在容器被创建之后立即被执行。 但是,不能保证回调会在容器入口点(ENTRYPOINT)之前执行,没有参数传递给处理程序
preStop:在容器因 API 请求或者管理事件(诸如存活态探针、启动探针失败、资源抢占、资源竞争等) 而被终止之前,此回调会被调用。 如果容器已经处于已终止或者已完成状态,则对 preStop 回调的调用将失败。 在用来停止容器的 TERM 信号被发出之前,回调必须执行结束。 Pod 的终止宽限周期在 PreStop 回调被执行之前即开始计数, 所以无论回调函数的执行结果如何,容器最终都会在 Pod 的终止宽限期内被终止。 没有参数会被传递给处理程序
apiVersion: v1
kind: Pod
metadata:
name: "pod-lifecycle"
namespace: hello666
labels:
aa: "bb"
cc: "dd"
app: "v1"
spec:
containers:
- name: nginx
image: "nginx"
lifecycle:
postStart:
# exec:
httpGet:
host: "10.244.85.196" # 容器启动了立即向这个地址发送"/"请求,启动以后的自动回调
path: "/"
port: 80
scheme: "HTTP"
preStop:
httpGet:
host: "10.244.85.196" # 容器删除了立即向这个地址发送"/preStop"请求,删除容器后的自动回调
path: "/preStop"
port: 80
scheme: "HTTP"
1.10、容器镜像使用秘钥从私有仓库下载
1. 使用 Docker Config 创建 Secret(前提:需要知道用于向仓库进行身份验证的用户名、密码和客户端电子邮件地址,以及它的主机名)
kubectl create secret -n <名称空间> docker-registry <生成的密钥名字> \
--docker-server=DOCKER_REGISTRY_SERVER \
--docker-username=DOCKER_USER \
--docker-password=DOCKER_PASSWORD \
--docker-email=DOCKER_EMAIL # 邮箱可以不指定
2. 查看生成的密钥信息: kubectl get secret -n hello666 (-n 后面写你的名称空间)
3. 在 Pod 中引用 ImagePullSecrets
apiVersion: v1
kind: Pod
metadata:
name: "pod-secret-nginx"
namespace: hello666
labels:
aa: bb
cc: dd
app: "nginx-secret"
spec:
imagePullSecrets:
- name: 密钥名字(这个就是填第一步里生成的密钥名字,多个容器可以配置多个密钥名字,k8s可以自己判断启动不同的容器去使用不同的密钥)
containers:
# 第一组容器(私有的)
- name: pod-secret-nginx
image: "这里写你的私有镜像地址"
imagePullPolicy: Always # 拉取策略
# 第二组容器(官方下载的,k8s知道官方的镜像不需要用密钥下载,通过镜像名称的前缀区分)
- name: my-tomcat
image: tomcat
4. 最终这个pod里面会生成两个容器
1.11、多容器协同工作
实现效果:
准备两个容器,一个是alpine,一个是nginx,利用卷挂载出nginx的index.html页面,然后使用alpine一直往这个index.html页面里打印当前时间,访问这个容器就显示最新的时间信息
apiVersion: v1
kind: Pod
metadata:
name: "multicontainer-pod"
namespace: hello666
labels:
app: "multicontainer-pod"
spec:
volumes:
- emptyDir: {} # 类似于docker的匿名挂载, 外部创建一个位置
name: "nginx-vol"
containers:
- name: nginx-container
image: "nginx"
volumeMounts:
- name: "nginx-vol"
mountPath: "/usr/share/nginx/html"
- name: "content-container"
image: "alpine"
command: ["/bin/sh","-c","while true;do sleep 1; date > /app/index.html;done;"]
volumeMounts:
- name: "nginx-vol"
mountPath: "/app"
最终效果:
2、Probe 探针机制(健康检查机制)
2.1、探针分类
- 每个容器三种探针(Probe)
- 启动探针**(后来才加的)** 一次性成功探针。 只要启动成功了
- kubelet 使用启动探针,来检测应用是否已经启动。如果启动就可以进行后续的探测检
查。慢容器一定指定启动探针。一直在等待启动 - 启动探针 成功以后就不用了,剩下存活探针和就绪探针持续运行
- kubelet 使用启动探针,来检测应用是否已经启动。如果启动就可以进行后续的探测检
- 存活探针
- kubelet 使用存活探针,来检测容器是否正常存活。(有些容器可能产生死锁【应用程序在运行,但是无法继续执行后面的步骤】), 如果检测失败就会**重新启动这个容器 **
- initialDelaySeconds: 3600(长了导致可能应用一段时间不可用) 5(短了陷入无限启
动循环)
- 就绪探针
- kubelet 使用就绪探针,来检测容器是否准备好了可以接收流量。当一个 Pod 内的所有
容器都准备好了,才能把这个 Pod 看作就绪了。用途就是:Service后端负载均衡多个
Pod,如果某个Pod还没就绪,就会从service负载均衡里面剔除
- kubelet 使用就绪探针,来检测容器是否准备好了可以接收流量。当一个 Pod 内的所有
- 谁利用这些探针探测
- kubelet会主动按照配置给Pod里面的所有容器发送响应的探测请求
- 启动探针**(后来才加的)** 一次性成功探针。 只要启动成功了
2.2、Probe配置项
- initialDelaySeconds :容器启动后要等待多少秒后存活和就绪探测器才被初始化,默认
是 0 秒,最小值是 0。这是针对以前没有
- periodSeconds :执行探测的时间间隔(单位是秒)。默认是 10 秒。最小值是 1。
- successThreshold :探测器在失败后,被视为成功的最小连续成功数。默认值是 1。
- 存活和启动探针的这个值必须是 1。最小值是 1。
- failureThreshold :当探测失败时,Kubernetes 的重试次数。 存活探测情况下的放弃就
意味着重新启动容器。 就绪探测情况下的放弃 Pod 会被打上未就绪的标签。默认值是 3。最
小值是 1。
- timeoutSeconds :探测的超时后等待多少秒。默认值是 1 秒。最小值是 1。
2.3、编写yaml测试探针机制
apiVersion: v1
kind: Pod
metadata:
name: "nginx-start-probe"
namespace: default
labels:
app: "nginx-start-probe"
spec:
volumes:
- name: nginx-vol
hostPath:
path: /app
- name: nginx-html
hostPath:
path: /html
containers:
- name: nginx
image: "nginx"
ports:
- containerPort: 80
startupProbe:
exec:
command: ["/bin/sh","-c","cat /app/abc"] ## 返回不是0,那就是探测失败
# initialDelaySeconds: 20 ## 指定的这个秒以后才执行探测
periodSeconds: 5 ## 每隔几秒来运行这个
timeoutSeconds: 5 ## 探测超时,到了超时时间探测还没返回结果说明失败
successThreshold: 1 ## 成功阈值,连续几次成才算成功
failureThreshold: 3 ## 失败阈值,连续几次失败才算真失败
volumeMounts:
- name: nginx-vol
mountPath: /app
- name: nginx-html
mountPath: /usr/share/nginx/html
livenessProbe: ## nginx容器有没有 /abc.html,就绪探针
# httpGet:
# host: 127.0.0.1
# path: /abc.html
# port: 80
# scheme: HTTP
# periodSeconds: 5 ## 每隔几秒来运行这个
# successThreshold: 1 ## 成功阈值,连续几次成才算成功
# failureThreshold: 5 ## 失败阈值,连续几次失败才算真失败
exec:
command: ["/bin/sh","-c","cat /usr/share/nginx/html/abc.html"] ## 返回不是0,那就是探测失败
# initialDelaySeconds: 20 ## 指定的这个秒以后才执行探测
periodSeconds: 5 ## 每隔几秒来运行这个
timeoutSeconds: 5 ## 探测超时,到了超时时间探测还没返回结果说明失败
successThreshold: 1 ## 成功阈值,连续几次成才算成功
failureThreshold: 3 ## 失败阈值,连续几次失败才算真失败
readinessProbe: ## 就绪检测,都是http
httpGet:
# host: 127.0.0.1 ## 不用指定host
path: /abc.html ## 给容器发请求
port: 80
scheme: HTTP ## 返回不是0,那就是探测失败
initialDelaySeconds: 2 ## 指定的这个秒以后才执行探测
periodSeconds: 5 ## 每隔几秒来运行这个
timeoutSeconds: 5 ## 探测超时,到了超时时间探测还没返回结果说明失败
successThreshold: 3 ## 成功阈值,连续几次成才算成功
failureThreshold: 5 ## 失败阈值,连续几次失败才算真失败
# livenessProbe:
# exec: ["/bin/sh","-c","sleep 30;abc "] ## 返回不是0,那就是探测失败
# initialDelaySeconds: 20 ## 指定的这个秒以后才执行探测
# periodSeconds: 5 ## 每隔几秒来运行这个
# timeoutSeconds: 5 ##探测超时,到了超时时间探测还没返回结果说明失败
# successThreshold: 5 ## 成功阈值,连续几次成才算成功
# failureThreshold: 5 ## 失败阈值,连续几次失败才算真失败
健康检查+优雅停机 = 0宕机
start完成以后,liveness和readness并存。 liveness失败导致重启。readness失败导致不给Service负载均衡网络中加,不接受流量。 kubectl exec -it 就进不去,可以利用 kubectl describe 检查
更多推荐
所有评论(0)