Kubernetes集群——Pod篇

目录

一.认识Pod

1.1什么是Pod?

1.2Pod类型

[1.2.1静态Pod------Static Pod](#1.2.1静态Pod——Static Pod)

1.2.2业务Pod

1.2.3Pause容器

1.3镜像拉取策略

1.4Pod的各种状态

二.Pod资源清单

2.1简单介绍

2.2创建Pod

2.2.1创建流程

2.2.2实例

2.3运行Pod

2.3.1使用apply运行Pod

2.3.2使用create运行pod

2.4创建证书------secret

2.4.1创建证书

2.4.2查看证书

2.4.3为Pod添加证书

2.4.4添加服务账户

2.5回收Pod

2.5.1回收流程

2.5.2按yaml文件删除

2.5.2按资源删除

三.进入容器内部

3.1进入Pod内部

3.2进入指定容器

四.访问Pod的内部应用

4.1获取PodIP

4.2访问Pod应用

五.实现Pod间的通信

5.1容器的网络模式

5.2查看节点上的所有资源IP

5.3实现两个pod间的通信

六.Pod的生命周期

6.1Init容器

6.2Pod重启策略

6.3探针------Probe

6.3.1启动探针------StratupProbe

6.3.2存活探针------LivenessProbe

6.3.3就绪探针------ReadinessProbe

6.3.4启动探针与存活探针的区别


一.认识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:专注于应用程序的运行阶段,确保应用程序在运行过程中保持健康。

相关推荐
wzq11_6662 小时前
Kubernetes集群——命令篇
云原生·容器·kubernetes
小白的码BUG之路3 小时前
Docker -- 构建ruoyi-gateway镜像
docker·容器·gateway
小白的码BUG之路3 小时前
Docker -- 构建ruoyi-system镜像
运维·docker·容器
LRL_4 小时前
【云原生】Oracle Linux 9.6 离线(Air-Gapped)环境下安装 Longhorn 及其底层依赖(iSCSI/NFS)完全指南
linux·云原生·oracle
小白的码BUG之路4 小时前
Docker -- 构建redis镜像
运维·docker·容器
江湖有缘4 小时前
Docker实战 | 使用Docker部署EspoCRM开源客户关系管理平台
docker·容器·开源
Henry-SAP4 小时前
SAP MMBE跨工厂库存层级展示解析
人工智能·云原生·sap·erp
小白的码BUG之路5 小时前
Docker -- 构建ruoyi-auth镜像
运维·docker·容器
troy1288 小时前
K8s 平台测试清单:深度分析与实战指南
云原生·容器·kubernetes