容器探针
上面已经讲到容器状态,那么这些容器的状态是怎么检测到的呢?实际上在pod中有三种探针,存活探针(livenessProbe)、就绪探针(readinessProbe)和启动探针(startupProbe)。
- livenessProbe,叫做存活探针,是为了检测容器是否正在运行,是否活着(如果探测失败就会杀死容器根据重启策略选择是否重启);
- readinessProbe,叫做就绪探针,是为了检测容器是否准备就绪,是否能接受客户端请求;它会指示容器是否准备好为请求提供服务。如果就绪态探测失败, EndpointSlice 控制器将从与该 Pod 匹配的所有 Service 的EndpointSlice 中删除该 Pod 的 IP 地址(为了防止我们正常的服务访问这个错误的Pod导致业务崩溃)。
- startupProbe,叫做启动探针,用于判断容器进程是否已经启动,一旦判断成功就会失效不再判断,一般用于那些启动很久的程序。指示容器中的应用是否已经启动。如果提供了启动探针,则所有其他探针都会被 禁用,直到此探针成功为止(可以见得,启动探针的优先级还是很高的)。如果启动探测失败,
kubelet
将杀死容器, 而容器依其重启策略进行重启。
实际上容器探针收集到这些数据后就汇报给我们的控制平面了(kubernetes的大脑),我们看到的容器状态就是从这里来的(如Running/NotReady)
小知识-控制平面
控制平面(control plane)既前面介绍过的kube-apiserver
,kube-controller-manager
,kube-scheduler
,etcd
这几个组件组成。他们互相协作就实现了对整个k8s集群进行有效有序的管理。
Pod实战
声明式模型&命令模式
命令模式:顾名思义就是直接在服务器和平常敲命令一样,直接命令执行创建Pod(不推荐)
声明式:编写一个yaml文件,其中包含了我们期望Pod的状态,比如包含几个容器,容器镜像是什么,pod名字叫什么等等
虽然给出了两种方式,但是绝对不推荐命令模式,我们目前在k8s集群,遇到的pod可能是巨大数量的,并且pod也会经常改变,可想而知,敲命令到手软,并且多了你自己也记不住谁是谁了吧,维护起来让人头疼,所以命令模式绝对不是好的选择。
部署第一个pod
在部署之前我们来理一下思路,这里以声明式模型来讨论
- 首先我们编写一个yaml文件,包含了我们期望的pod状态的内容
- 然后我们将这个文件post到api-server
- api-server经过一系列验证后返回一个响应后,由其他组件监听到后进行创建pod与调度pod到合适的node节点
那么大致流程就像下图:
那么我们实战开始:
编写pod清单文件
vi pod.ymlapiVersion: v1
kind: Pod
metadata:name: holle-podlabels:zone: prodversion: v1
spec:containers:- name: hello-ctrimage: nginx:1.22.1ports:- containerPort: 8080
kubectl命令将清单文件post到api-server
kubectl apply -f pod.yml# 查看pod状态
kubectl get pod -o wide
这里已经可以看见我们的pod已经READY了,并且状态为Running,NODE项说明这个pod实际运行在node01节点上,集群内部访问ip为10.244.2.98
验证pod
由于我们在清单文件定义pod中运行nginx镜像,所以访问上面pod给出的ip应该是可以出现nginx的欢迎页(注意关闭node01的防火墙与selinux)
至此,我们的第一个pod已经创建成功并运行起来了,不过它目前似乎只能在集群内部访问,外部访问不了,那是因为我们并未配置暴露服务给外部,这一部分后续再说。
删除pod
由于我们是直接定义的pod文件,所以删除pod可以有两种方式
第一种:kubectl delete holle-pod
(注意这里的holle-pod
是上面我们查询pod状态的NAME字段)
第二种:kubectl delete -f pod.yml
(注意这里的pod.yml
是我们编写的pod清单文件)
可以看见我们删除后再次查看pod状态已经提示未找到了