目录
[1.2.1静态Pod------Static Pod](#1.2.1静态Pod——Static Pod)
一.认识Pod
1.1什么是Pod?
1.概念 :Pod是Kubernetes集群中可以创建和管理的最小部署单元,一个Pod代表集群中运行的一个进程,且一个Pod共享一个IP。
我们知道,Docker 是创建和管理 Container 容器的工具,而与之对应的 Kubernetes(k8s)则负责创建和管理 Pod。你可以把 Pod 理解为一个容器,也可以把它理解为多个容器的集合,Pod 允许并能够统一管理这些容器,让它们协作完成同一个任务。简单来说,Pod 就是能够一次性管理一个或多个容器(Container),且多个容器间共享 IPC、 Network 和 UTS namespace,即共享同一网络(IP、端口)、共享 IPC 通信机制(消息队列、内存)以及同一主机名。

1.2Pod类型
说明 :常见的Pod主要分为三类:静态Pod、业务Pod和Pause容器。
1.2.1静态Pod------Static Pod
概念 :静态Pod是由节点上的守护进程Kubelet直接创建和管理的,而不是通过ApiServer创建和管理的。这些Pod在节点的特定目录中定义(如:/etc/kubernets/mainfests)Kubelet会监视和管理这些Pod的生命周期。
特点:
1. 无控制器管理:不由 Deployment、ReplicaSet 等控制器管理;
2. 节点级别:仅存在于定义它们的特定节点上;
3. API 服务器可见:可在集群中通过 kubectl get pods 查看;
4. 无法通过 kubectl 管理:只能通过修改节点上的配置文件进行操作;
5. 高优先级:在控制器管理的 Pod 之前启动。
1.2.2业务Pod
概念 :这些Pod受Kubectl管理,是真正运行业务的Pod,直接承载应用服务的核心工作负载单元。
1.2.3Pause容器
概念 :Pause 容器(也称为 Infra 容器或基础容器)是 Pod 的核心基础设施组件,目的是为 Pod 内的所有容器提供共享的运行时环境。它被用作 Pod 网络命名空间中的一个占位符。每个 Pod 都有一个 pause 容器,用户不需要显式地定义它。主要作用是确保****Pod 中的所有容器可以共享网络栈。Pause容器是Pod容器中第一个创建,最后一个退出的容器,一经创建,就会立即进入休眠状态,所以不用担心它占用资源。
作用 :核心目的是为了实现网络空间隔离。当Pod中的容器状态出错时,如果没有pause,schedule会为这个pod分配一个新的node去创建,会骚扰我们的寄存器。因此我们需要有pause,告诉集群是这个容器有问题,我的pod没有问题,这样就会先在自己的node上去重启我们的容器了,而不需要调度器。
每个Pod里面包含一个或者多个容器,为了确保这些Pod间实现网络隔离,每个Pod都拥有自己独立的网络命名空间。Pause容器负责创建和维护网络命名空间,Pod内部的容器共享这个网络命名空间,使他们能够通信,而不会受到其他容器的网络干扰。
特点:
1.进程隔离:Pause 容器保持一个轻量级的进程运行,即使 Pod 中 的其他容器都停止了。这个进程实际上不执行任何有用的工作,但它的存在确保了 Pod 不会在没有容器运行的情况下被删除。**当其他容器停止时,**Pause 容器仍在运行,以维持 Pod 的生命周期。
2.IP 地址维护:Pause 容器负责维护 Pod 的 IP 地址。Pod 的 IP 地址通常是动态分配的,但由于 Pause 容器一直在运行,可以维护 Pod 的 IP 地址,以便其他容器可以通过该地址进行通信。确保 Pod 的 IP 地址在整个 Pod 的生命周期内保持一致。
3.生命周期管理:Pause 容器的生命周期与 Pod 的生命周期相同。当 Pod 创建时, Pause 容器被创建;当 Pod 删除时,Pause 容器也会被删除。确保 Pod 整个生命周期都由 Kubernetes 进行管理,包括创建、扩展、缩放和删除。
1.3镜像拉取策略
1.概述 :指定K8S节点如何从镜像仓库中拉取容器镜像的策略。通过设定yaml文件中,spec.containers\[\].imagePullPolicy 参数即可指定拉取策略。
2.分类:共有三类:Always,Never和IfNotPresent。
Always :总是查询你的docker仓库。每次创建容器时,Kubernetes都会尝试从镜像仓库中拉取镜像。当你的镜像是latest标签,且ImagePullPolicy没有指定时,会默认策略为Always。
Never :从不查询你的docker仓库。不论本地是否存在镜像,始终不去拉取镜像仓库里的镜像,即使Pod启动失败。
IfNotPresent :会首先查看你的本地镜像,如果本地不存在,则会拉取镜像仓库里的镜像。
当你指定了镜像标签后,默认策略是IfNotPresent。
1.4Pod的各种状态
1. Pending :Pod 已被Kubernetes 系统接收,但仍有一个或多个容器未被创建,可以通过 kubectl describe 查看处于 Pending 状态的原因(有可能请求的资源过大,无法调度;有可能挂载的东西不存在;有可能没有可用的节点;有可能节点异常)。
2. Running :Pod 已经被绑定到一个节点上,并且所有的容器都已经被创建,而且至少有一个是运行状态,或者是正在启动或者重启,可以通过 kubectl logs查看 Pod 的日志。
3. Failed :所有容器都已终止,并且至少有一个容器以失败的方式终止,也就是说这个容器要么以非零状态退出,要么被系统终止,可以通过 logs和describe 查看 Pod 日志和状态。
4. Succeeded :所有容器执行成功并终止,并且不会再次重启,可以通过 kubectl logs查看 Pod 日志。
5. Unknown :通常是由于通信问题造成的无法获得 Pod 的状态。
6. ImagePullBackOff ErrlmagePull :镜像拉取失败,一般是由于镜像不存在、网络不通或者需要登录认证引起的,可以使用describe 命令查看具体原因。
7. CrashLoopBackOff :容器启动失败,可以通过 logs命令查看具体原因,一般为启动命令不正确,健康检查不通过等。
8. OOMKilled :容器内存溢出,一般是容器的内存 Limit 设置的过小,或者程序本身有内存溢出,可以通过 logs查看程序启动日志。
9. Terminating :Pod 正在被删除,可以通过describe 查看状态。
10.SysctlForbidden: Pod 自定义了内核配置,但 kubelet 没有添加内核配置或配置的内核参数不支持,可以通过describe 查看具体原因。
11.Completed :容器内部主进程退出,一般计划任务执行结束会显示该状态,此时可以
通过 logs查看容器日志。
12.ContainerCreating :Pod 正在创建,一般为正在下载镜像,或者有配置不当的地方,可以通过describe 查看具体原因。
13.Waiting:处于
Waiting状态的容器仍在运行它完成启动所需要的操作。例如, 从某个容器镜像仓库拉取容器镜像,或者向容器应用Secret数据等等
二.Pod资源清单
2.1简单介绍
概述 :Pod资源清单(Manifest)通过yaml文件描述Pod期望状态的配置文件。我们通过这个资源 清单配置和创建Pod。
default是K8S集群的默认命名空间,当你没有指定命名空间时,资源都会在这个默认命名空间中创建和生效。
资源清单一般包含以下内容:
bash
apiVersion: group/version //指明api 资源属于哪个群组和版本,同一个组可以有多个版本
kind: //标记创建的资源类型,k8s 主要支持以下资源类别Pod,ReplicaSet,Deployment,StatefulSet,DaemonSet,Job,Cronjob
metadata: //元数据
name: //对像名称
namespace: //对象属于哪个命名空间,如果不指定,默认为default
labels: //指定资源标签,标签是一种键值数据
spec: //定义目标资源的期望状态
使用命令查看pod资源:
bash
kubectl explain pod

2.2创建Pod
2.2.1创建流程

第一步:发送请求:用户在客户端向k8s端的APIServer发送创建Pod请求。
第二步:验证请求:APIServer验证请求的合法性,如果验证成功则将该Pod对象持久化存储到etcd中,etcd写入成功后,返回给APIServer,之后向客户端返回创建成功的响应。
第三步:寻找合适的node:Schedule监听到APIServer上有一个新Pod,如果该Pod未被分配,则通过预设的调度策略,得出部署该Pod的最合适的node节点并绑定,将绑定的node的节点名传输给APIServer,并持久化保存到etcd中。
第四步:创建Pod:Kubelet监听APIServer,要在自己的节点上创建Pod。
1.首先准备存储卷,如果该Pod需要,则通过CSI接口将存储卷挂载到Pod上。
2.接着检查本地和私有仓库中是否存在pause基础镜像,通过CRI接口 创建Pod沙箱。Pause容器为pod提供网络和PID命名空间。
3.然后kubelet对该Pod配置网络,通过CNI接口调用网络插件,为Pod分配IP地址,设置防火墙规则和网络路由,将网络接口添加到网络命名空间中
4.kubelet检查pod镜像是否存在,接着拉取镜像,通过CRI接口创建并运行pod,并监测Pod的自身状态
第五步 :持久化Pod状态:kubelet将监听到的Pod状态发送给APIServer,APIServer将Pod状态信息,保存给etcd,持久化存储。
2.2.2实例
说明 :下面我会创建一个简单的Pod,该Pod会在内部创建两个容器,一个前端和一个后端,我们能通过前端访问到后端MySQL服务器,并详细讲解Pod内部的各个组件。
bash
mkidr yml && cd yml
mkidr pod && cd pod
说明:由于K8s的所有组件基本都是由yaml文件创建的,为了便于管理和查找,建议将yaml文件放在对应的目录下。
bash
vim pod-bigapp.yml #创建Pod
Pod的yaml文件如下:
说明:yaml文件对格式特别敏感,注意不要写错格式。同时,粘贴代码时记得删掉注释,以防执行失败。
注意 :确保docker私有仓库中存在所需的镜像文件
bash
apiVersion: "v1" #设置API版本
kind: "Pod" #设置资源类型,这里是Pod
metadata: #设置元数据
name: "bigapp" #设置Pod名称
labels: #设置标签,标签是k8s集群中重要的标识符,用于区分和筛选各个Pod
app: "bigapp" #标签为app=bigapp
spec: #下面设置Pod的期望状态,K8s集群会确保Pod处于下面的期望状态
containers: #设置容器属性
- name: "db-backend" #容器名为db-backend,充当后端数据库
image: "reg.westos.org/library/mysql" #拉取的仓库镜像,Pod里面创建的容器都是拉取的仓库里的镜像
env: #设置容器内部的环境变量
- name: MYSQL_ROOT_PASSWORD #设置MYSQL的登录密码
value: "redhat" #密码为redhat
ports: #设置容器的暴露接口
- containerPort: 3306 #容器接口为3306
- name: "web-frontend"#容器名:web-frontend
image: "reg.westos.org/library/httpd:webapp" #拉取镜像
ports: #容器暴露接口
- containerPort: 80

2.3运行Pod
2.3.1使用apply运行Pod
bash
kubectl apply -f bigapp.yaml
声明式:我希望这个Pod是这个状态。当Pod不存在时,则创建它。当Pod存在时,则更新它的状态。
2.3.2使用create运行pod
bash
kubectl create -f bigapp.yaml
命令式:创建一个Pod。当该Pod存在时,执行该命令会弹出Pod已存在,不会去更新状态。

2.4创建证书------secret
说明:证书是访问仓库中私有项目的钥匙,没有这个钥匙,就无法访问到私有项目。
注意:证书需要指定命名空间,并在所属的命名空间内部生效,如果没有指定命名空间,则默认会存在defalut中。
2.4.1创建证书
bash
kubectl create secret docker-registry myregkey --docker-server=reg.westos.org --docker-username=admin --docker-password=123456
参数介绍:
myregkey:密钥名,自定义即可
--docker-server:仓库名称
--docker-username:登录用户名
--docker-password:用户名密码
-n:指定命名空间,不指定时默认是default

2.4.2查看证书
bash
kubectl get sercet
kubectl get sercet -o yaml #转成yaml格式,信息更详细


2.4.3为Pod添加证书
编辑Pod的yaml文件:
bash
vim pod-bigapp.yml
尾行添加以下内容:
bash
imagePullSecrets: #镜像拉取证书,前面我们知道docker仓库里存在私有项目,需要配对证书才可以拉取
- name: myregkey #所需的证书,需要我们自行创建

如果你拉取的镜像位于harbor的私有项目中且不配对证书,则会出现下面的错误:
bash
kubectl get pod bigapp
kubectl describe pod bigapp #查看Pod的详细信息


解决方法:配置完证书后,重启pod
bash
kubectl replace --force -f pod-bigapp.yaml #重启Pod
kubectl get pod
kubectl describe pod bigapp


2.4.4添加服务账户
说明 :当你的证书加入到服务账户中,当你在这个命名空间中创建的所有资源,都会自动添加证书,而不需要你再手动写入yaml文件中。
bash
kubectl get secrets #查看证书,secret
kubectl get sa #查看服务账户

添加secret到服务账户中:
1.命令添加
说明:如果想加到其他命名空间,需要使用-n指名
bash
kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "myregkey"}]}'

查看secret:
bash
kubectl describe sa default

2.文件添加:编写yaml文件,绑定secret和sa账户
bash
vim sa-registry.yml

添加以下内容:
bash
apiVersion: v1
kind: ServiceAccount
metadata:
name: default
imagePullSecrets:
- name: myregkey

运行文件:
bash
kubectl apply -f sa-registry.yml


2.5回收Pod
2.5.1回收流程

第一步:发送请求:用户向APIServer发送删除Pod请求
第二步 :验证请求:APIServer验证请求的合法性(授权、认证等),APIServer验证成功后,更新etcd中Pod的状态为Terminating。此时,Pod处于正在删除的状态,依然存在。
第三步 :删除Pod:
1.首先kubelet收到删除请求,如果Pod上配置有钩子,首先运行钩子。钩子指的是一段容器内的命令或者发送到指定http端点的请求。
2.kubelet通过CRI接口,发送终止信号(SIGTERM),优雅删除容器进程。如果超过默认的30s后,进程仍未删除,则会发送强制删除信号(SIGKILL),暴力删除容器进程。
3.调用CRI容器运行时,删除容器里面的所有资源
4.如果Pod配对了Readiness探针,则该Pod不会再进入调度列表中。
5.kubelet更新Pod状态为已删除,向APIServer发送Pod已经被删除
第四步:移除Pod存储:APIServer删除etcd中存储的Pod的定义和数据,至此,Pod被完全删除。
2.5.2按yaml文件删除
bash
kubectl delete -f bigapp.yaml #删除由bigapp.yaml文件创建的容器

2.5.2按资源删除
bash
kubectl delete pod bigapp #pod为资源类型
三.进入容器内部
3.1进入Pod内部
说明:进入Pod是指进入Pod内部的容器,当Pod中存在多个容器时且没有指定容器时,会默认进入一个容器中
bash
kubectl exec -it bigapp -- bash #以bash环境进入bigapp内部

3.2进入指定容器
1.说明:指定进入webapp容器内
bash
kubectl exec -it bigapp -c webapp -- bash #指定进入webapp容器
参数介绍:
-c:指定进入的容器名

1.1查看容器的IPC资源
bash
ipcs #查看系统的IPC(进程间通信)资源

注意:所有者存在时,才会显示名称,否则显示uid

1.2查看容器的IP
bash
ip a #查看容器网络

1.3查看当前容器的进程
bash
ps -ef
参数:
-e:查看当前系统的全部用户进程
-f:显示完整格式

**2.说明:**指定进入db-backend容器内
说明:同一Pod中的容器共享主机名
bash
kubectl exec -it db-backend -- bash

2.1查看容器的IPC资源
说明:同一Pod中的容器共享IPC资源
bash
ipcs


2.2查看IP
说明:同一Pod中的容器共享IP网络
bash
ip a

2.3查看进程
bash
ps -ef
说明 :同一Pod内部的容器进程相互隔离

四.访问Pod的内部应用
说明 :前面,我们已经说明在Pod内部存在两个容器,即两个应用,那么我们应该如何做到访问呢。因为容器创建使用的网段与K8s集群处于同一个网段,所以所有K8S集群节点都可以访问到容器内部,但集群外不行,需要我们暴露容器IP。
4.1获取PodIP
bash
kubectl get bigapp -o wide #显示Pod的网络IP资源

4.2访问Pod应用
1.集群内部访问
访问前端:
bash
curl 10.244.109.94 #访问容器,我这里用的nginx应用


访问后端数据库
1.先修改action配置文件
bash
kubectl exec -it db-backend -- bash
vi /var/www/cgi-bin/action
action文件内容如下:
python
#!/usr/bin/python
# -*- coding: utf-8 -*-
import MySQLdb as mdb
import os
con = mdb.connect(os.getenv('DATABASE_SERVICE_SERVICE_HOST','127.0.0.1'), 'root', 'redhat', 'mysql') #连接后端数据库
with con:
cur = con.cursor()
cur.execute("SELECT User FROM user")
rows = cur.fetchall()
print 'Content-type:text/html\r\n\r\n'
print '<html>'
print '<head>'
print '<title>My Application</title>'
print '</head>'
print '<body>'
print '<h1>' + 'Here comes the list of database users:' + '</h1>'
for row in rows:
print '<h2>' + row[0] + '</h2>'
print '</body>'
print '</html>'

2.访问后端数据库
bash
curl 10.244.109.94/cgi-bin/action

2.集群外无法访问容器应用
说明:集群外的虚拟机与容器不处于同一网段
bash
curl 10.244.109.94 #访问容器,我这里用的nginx应用

bash
curl 10.244.109.94/cgi-bin/action

五.实现Pod间的通信
5.1容器的网络模式
1.概念 :容器的网络模式分为三类:Host Mode、Container Mode和None Mode模式。
1.Host Mode :宿主机网络模式,容器与宿主机共享网络资源。
2.Container Mode :不创建网络空间,与另一个容器共享网络资源。
3.None Mode:仅有本地环回网络
2.与docker的区别:如果没有容器使用IP,则该IP会被释放。而k8s中,如果该IP之前被某一个pod使用过,当这个Pod再次被创建时,依然会使用这个IP,就是这个IP会被暂时保留给以前使用过的Pod。
5.2查看节点上的所有资源IP
bash
kubectl get pod -o wide -A

5.3实现两个pod间的通信
1.创建后端数据库pod
bash
cd pod
vim pod-db.yml

添加以下内容:
bash
apiVersion: "v1"
kind: "Pod"
metadata:
name: "database"
labels:
app: "db"
spec:
containers:
- name: "db-backend"
image: "reg.westos.org/library/mysql"
env:
- name: MYSQL_ROOT_PASSWORD
value: redhat
ports:
- containerPort: 3306

运行Pod:
bash
kubectl apply -f pod-db.yml

2.创建前端服务
bash
cd pod
vim pod-web.yml
添加以下内容:
bash
apiVersion: "v1"
kind: "Pod"
metadata:
name: "webserver"
labels:
app: "web"
spec:
containers:
- name: "apache-frontend"
image: "reg.westos.org/library/httpd:dns"
ports:
- containerPort: 80

运行Pod:
bash
kubectl apply -f pod-web.yml


3.修改前端服务的action文件,修改成数据库的IP
说明:通过访问前端PodIP,访问后端数据库Pod
进入前端容器:
bash
kubectl exec -it webserver -- bash

修改action文件:
bash
cd /var/www/cgi-bin/
vi action
修改数据库名称为database的IP:
bash
#!/usr/bin/python
# -*- coding: utf-8 -*-
import MySQLdb as mdb
import os
con = mdb.connect('10.244.219.22', 'root', 'redhat', 'mysql') #将IP改为数据库IP
with con:
cur = con.cursor()
cur.execute("SELECT User FROM user")
rows = cur.fetchall()
print 'Content-type:text/html\r\n\r\n'
print '<html>'
print '<head>'
print '<title>My Application</title>'
print '</head>'
print '<body>'
print '<h1>' + 'Here comes the list of database users:' + '</h1>'
for row in rows:
print '<h2>' + row[0] + '</h2>'
print '</body>'
print '</html>'

4.访问后端数据库:
bash
curl 10.244.109.100/cgi-bin/action

六.Pod的生命周期
说明:Pod 生命周期 指的是一个 Pod 从被创建到最终被删除的完整过程,以及在这个过程中它所经历的不同阶段(Phase) 和状态条件(Condition)
6.1Init容器
说明 :Init容器是Pod中最先执行的容器,如果这个容器没有启动成功,后面的容器都不会启动。常规的 In it 容器不支持 lifecycle、livenessProbe、readinessProbe 或 startupProbe字段。Init 容器必须在 Pod 准备就绪之前完成运行。
创建yaml文件:
bash
vim pod-init
编写yaml文件内容:
说明 :定义了一个具有 2 个 Init 容器的简单 Pod。 第一个等待 myservice 启动, 第二个等待 mydb 启动。 一旦这两个 Init 容器都启动完成,Pod 将启动 spec 节中的应用容器。
bash
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app.kubernetes.io/name: MyApp
spec:
containers:
- name: myapp-container
image: reg.westos.org/library/busybox
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
initContainers: #下面为定义的初始化容器内容,优先启动下面的容器
- name: init-myservice
image: reg.westos.org/library/busybox
command: ['sh', '-c', "until nslookup myservice.default.svc.cluster.local; do echo waiting for myservice; sleep 2; done"] #用一个 busybox 容器反复解析 myservice 的 DNS,解析成功就退出,意思就是等待myservice服务运行,才会进入下一个阶段
- name: init-mydb
image: reg.westos.org/library/busybox
command: ['sh', '-c', "until nslookup mydb.default.svc.cluster.local; do echo waiting for mydb; sleep 2; done"] #不断解析mydb服务

运行Pod:
bash
kubectl apply -f pod-init.yaml

查看容器情况:
bash
kubectl get pod myapp-pod
kubectl logs myapp-pod


运行myservice服务,完成第一个初始化:
bash
vim service.yaml

添加以下内容:
bash
---
apiVersion: v1
kind: Service
metadata:
name: myservice #创建一个名为myservice的service类型
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9376
#---
#apiVersion: v1
#kind: Service
#metadata:
# name: mydb
#spec:
# ports:
# - protocol: TCP
# port: 80
# targetPort: 9377

创建myservice:
bash
kubectl apply -f service.yaml
kubectl get svc myservice
kubectl get pod myapp-pod


运行mydb服务,完成第二个初始化:
bash
vim service.yaml #去掉注释内容

去掉注释:
bash
---
apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9376
---
apiVersion: v1
kind: Service
metadata:
name: mydb #创建mydb服务
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9377

创建mydb服务:
bash
kubectl apply -f service.yaml
kubectl get svc
kubectl get pod

6.2Pod重启策略
说明 :该策略定义了Pod中的容器在失败或终止后的重启行为 ,可以使用spec.restart Policy 指定重启策略,策略如下:
1.Always:默认策略,无论容器的退出状态如何,都会重启。
2.OnFailure: 仅当容器以非零退出码(表示失败)终止后,重启Pod。
3.Never: 容器终止后,始终不会重启
6.3探针------Probe
说明 :探针(Probe)用于检测****Pod 中容器的健康状态和生命周期管理。探针可以帮助 Kubernetes 确保应用程序在运行中的健康状态,并在需要时采取适当的动作(如重启容器、将流量切换到健康的容器等)。
Kubernetes 对 Pod 的健康状态可以通过三类探针来检查:LivenessProbe、ReadinessProbe 及 StartupProbe ,其 中 最 主 要 的 探 针 为 LivenessProbe 与 ReadinessProbe ,kubelet 会定期执行这两类探针来诊断容器的健康状况。
6.3.1启动探针------StratupProbe
1.StartupProbe(启动探针) :用于判断容器内应用程序是否已经启动。某些应用会遇到启动比较慢****的情况,例如应用程序启动时需要与远程服务器建立网络连接,或者遇到网络访问较慢等情况时,会造成容器启动缓慢,因为这属于"有且仅有一次"的超长延时,可以通过StartupProbe 探针解决该问题。如果配置了startupProbe,就会先禁止其他的探针,直到它成功为止,成功后将不在进行探测。如果探针失败,kubelet 则杀死容器,并且按照预先在资源清单中设定的重启策略重启容器。(启动探针)只会在容器启动****时进行健康检查,且优先级最高。如果探测成功才会继续执行其他两种方式的探针。启动探针,那么在容器的剩余生命周期中不在执行此探针。
2.创建启动探针:
bash
vim startup-pod.yaml
添加以下内容:
bash
apiVersion: v1
kind: Pod
metadata:
name: custom-app
spec:
containers:
- name: custom-app
image: reg.westos.org/library/busybox
command: ["/bin/sh", "-c", "sleep 20; touch /tmp/ready; tail -f /dev/null"] #模拟启动20秒时间
#启动策略如下
startupProbe:
exec:
command: ["test", "-f", "/tmp/ready"] #检查文件是否存在,判断容器是否启动成功
failureThreshold: 4 #允许探针连续失败的4次,启动失败超过4 * 5=20s,容器启动失败
periodSeconds: 5 #探针执行周期,没5s检查一次

运行启动探针:
bash
kubectl apply -f startup-pod.yaml
kubectl get pod custom-app


6.3.2存活探针------LivenessProbe
1.LivenessProbe(存活探针) :用于探测容器是否运行,如果探测失败,kubelet 会根据配置的重启策略进行相应的处理。若没有配置该探针,默认就是success。(**存活探针,探针失败;**按照预先在资源清单中设定的重启策略重启容器)
2.创建存活探针
bash
vim liveness-pod.yaml
添加以下内容:
bash
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-http
spec:
containers:
- name: liveness
image: reg.westos.org/library/nginx
#存活探针
livenessProbe:
tcpSocket:
port: 80 #监测端口是否存在,判断容器是否存活
initialDelaySeconds: 3 #容器启动后,等3s开始监测是否存活
periodSeconds: 3 #每3s监测一次

运行存活探针:
bash
kubectl apply -f liveness-pod.yaml
kubectl get pod liveness-http



6.3.3就绪探针------ReadinessProbe
1.ReadinessProbe(就绪探针) :用于判断容器服务是否可用(Ready 状态),达到 Ready 状态的Pod 才可以接收请求。并且程序已经是可以接受流量的状态。对于被Service管理的 Pod,Service Pod Endpoint 的关联关系也将基于Pod 是否Ready 进行设置。如果****在运行过程中 Ready 状态变为 False,则系统自动将其从Service 的后端 Endpoint列表中隔离出去,后续再把恢复到 Ready 状态的 Pod 加回后端 Endpoint **列表。**这样就能保证客户端在访问Service时不会被转发到服务不可用的Pod 实例上。需要注意的是,ReadinessProbe 也是定期触发执行的,存在于Pod 的整个生命周期中。(就绪探针,探针失败不会重启 pod)
2.创建就绪探针
bash
vim liveness-pod.yaml
添加以下内容:
bash
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-http
spec:
containers:
- name: liveness
image: reg.westos.org/library/nginx
livenessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 3
periodSeconds: 3
#就绪探针
readinessProbe:
httpGet:
path: /test.html #检查http的默认发布目录下是否这个文件是否存在
port: 80 #检查端口是否存活
initialDelaySeconds: 5 #启动后5s开始监测
periodSeconds: 5 #每隔5s监测一次

运行就绪探针:
bash
kubectl apply -f liveness-pod.yaml
kubectl get pod liveness-http


bash
kubectl logs pod liveness-http #查看日志

注意:启动不成功,因为test.html文件不存在
容器内部创建test.yaml文件,容器启动成功:
bash
kubectl exec -it liveness-http -- touch /usr/share/nginx/html/test.html
kubectl get pod liveness-http

6.3.4启动探针与存活探针的区别
说明:StartupProbe 用于检测容器的启动是否完成,特别适用于启动时间较长的应用程序。在应用程序启动时间较长,可能超过默认的 LivenessProbe 超时时间,以防止应用程序在启动过程中被误判为不健康并被杀死。而StartupProbe 可以预先设置推迟存活检测时间,如果配置了 StartupProbe,在其成功之前,LivenessProbe 将被禁用。一旦 StartupProbe 成功,LivenessProbe 开始工作。如果 StartupProbe 失败,容器将被重启。其中最重要的一个作用StartupProbe在第一次探针完成后后续将不再执行探针,但是 LivenessProbe 将在容器的整个生命周期循环执行。
StartupProbe :专注于应用程序启动阶段,防止应用程序启动时间较长时被误判为不健康。LivenessProbe:专注于应用程序的运行阶段,确保应用程序在运行过程中保持健康。