资源对象的创建
1.命令行 - 调试
2.资源文件 - 生产中
在Kubernetes中,资源对象的定义文件主要有五部分组成:
apiVersion 资源对象的版本号 ------ kubectl api-versions
Kind 资源对象的类型 ------
metadata 定制资源对象的名称和属性
spec 具体资源的期望状态
status 资源对象的实际的运行状态
kubectl explain <object_name>.[属性.子属性.子子属性....] #查看资源属性
vim nginx-test.yml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-test
name: nginx-test
spec:
replicas: 3
selector:
matchLabels:
app: nginx-test
template:
metadata:
labels:
app: nginx-test
spec:
containers:
- image: 10.0.0.19:80/mykubernetes/nginx:1.21.3
name: nginx-test
kubectl create -f nginx-test.yml #应用配置
kubectl apply -f nginx-test.yml #应用配置,立即生效
kubectl edit deployments nginx-test #编辑资源对象
kubectl get deployments nginx-test
kubectl delete -f nginx-test.yml #删除资源
🔣资源对象pod
特点解析
传统主机阶段 - 单台主机
容器环境阶段 - 单个容器
任务编排阶段 - Pod(容器集合) 存储卷隶属于 pod,而非容器
1.pod和容器
一个Pod可以有多个容器,彼此间共享网络和存储资源。
每一个Pod中有一个Pause容器保存所有容器的状态,通过管理pause容器,达到管理pod中所有容器的效果。
只有紧密关系的容器才可以放到一个pod中,不同业务的容器分别放在不同的pod中
2.pod和节点
同一Pod中的容器总会被调度到相同Node节点
不同节点间Pod的通信是基于虚拟二层网络技术实现的
3.pod和pod
普通的Pod和静态Pod(一般不用)
4.pod和应用
每个Pod都是应用的一个(子应用)实例,有专用的ip,与容器暴露的端口组合为一个service的endpoint地址
每个service由kube-proxy转换为本地的ipvs或iptables规则
5.应用和应用
每个service的enpoint地址由coredns组件解析为对应的服务名称,其他service的pod通过访问该名称达到应用间通信的效果
6.外部和pod
外部流量通过节点网卡进入到k8s集群,基于ipvs或iptables规则找到对应的service,进而找到对应pod地址
pod内多容器通信 - 容器间通信(容器模型)
单节点内多Pod通信 - 主机间容器通信(host模型) docker inspect host
多节点内多Pod通信 - 跨主机网络解决方案(overlay模型)
核心思想
1.应用交付
虽然Kubernetes将这些应用的各个子模块单独部署在容器上,但是Kubernetes不再是对一个个子应用容器进行管理,他是将这些子应用容器放在一个逻辑单元中,而这个逻辑单元针对的是应用或服务,通过对逻辑单元的操作,达到对应用快速管理,从而实现业务的快速交付。所以说Pod面向的是应用或服务,而不是具体的应用容器或者子应用容器。
2.资源管理
kubernetes是一个分布式的资源管理平台,分布的特点就是资源分散,所以Kubernetes的应用,肯定会出现业务应用的不同模块被分配到多个Node工作结点,那么随之而来,就会出现两种问题:
①需要设计一个复杂的资源调度算法,根据业务需求,从不同Node上获取所有特定的数据
②强耦合的业务应用,被分配到了不同节点,可能造成不可预测的功能缺失或潜在问题
与其花费大力气解决上述两个问题,还不如把这些功能直接打包到一个逻辑单元pod中
对内:所有的子应用容器可以在Pod内部进行单独管理,即使pod在调度到其他Node节点,Pod内部的所有子应用容器仍可以正常运行。
对外:对于整个业务系统来说,面向的是一个个的应用或业务功能(即Pod),可以轻轻松松实现管理。
3.实现细节
通信机制:Pod内有个Pause容器,它有独立的ip地址,其他子应用容器基于container网络模式实现统一的对外服务,大大简化了关联业务容器之间的通信问题。
存储机制:Pod内有专用的数据存储资源对象,其他子应用容器共享该数据卷,实现多容器数据信息的统一存储。
管理机制:所有子应用容器的信息都保存在pause容器中,通过对pause容器的管理,达到管理所有容器效果。
pod关联对象
工作负载型资源:Pod、Deployment、DaemonSet、Replica、StatefulSet、Job、Cronjob、Operator
服务发现和负载均衡资源:Service、Ingress
配置和存储:configMap、Secret、PersistentVolume、PersistentVolumeChain、DownwardAPI
动态调整资源:HPA、VPA
资源隔离权限控制资源:namespace、nodes、clusterroles、Roles
资源创建
1.命令行方式
kubectl run NAME --image=image [--port=port] [--replicas=replicas]
—dry-run=true 以模拟的方式来进行执行命令
—env=[] 执行的时候,向对象中传入一些变量
—image=’’ 指定容器要运行的镜像
—labels=’’ 设定pod对象的标签
—limits=’cpu=200m,memory=512Mi’ 设定容器启动后的资源配置
—replicas=n 设定pod的副本数量
—port=’’ 设定容器暴露的端口
初始化一个Pod对象,包含一个nginx容器
kubectl run nginx-1 --image=10.0.0.19:80/mykubernetes/nginx:1.21.3
2.配置文件方式
1.文件内容:创建一个Pod,包含一个nginx容器,该容器启动后,会传入一个全局变量
apiVersion: v1
kind: Pod
metadata:
name: nginx-test
spec:
containers:
- name: nginx
image: 10.0.0.19:80/mykubernetes/nginx:1.21.3
env:
- name: HELLO
value: "Hello kubernetes nginx"
注意:资源定义文件中可以同时写多个Pod对象,彼此间使用"---"隔开就可以了。
2.应用资源文件:
kubectl create -f 01-pod-test.yaml 仅仅是创建一个对象,如果对象已存在,则不会重复创建
kubectl apply -f 01-pod-test.yaml 比较前后配置差异 而后作变更,如果不加限制此命令,会引起很大的隐患
3.导出配置信息:kubectl get pod nginx-test -o yaml
4.定制化显示:kubectl get pod nginx-test -o custom-columns=NAME:metadata.name,STATUS:status.phase
5.查看pod对象的全部信息:kubectl describe pod nginx-test
6.修改yaml文件的内容:
kubectl replace -f FILENAME [options] --force 表示强制更新
kubectl edit 是实时修改
7.删除
语法一:kubectl delete pod --all
语法二:kubectl delete deployment --all
语法三:kubectl delete -f nginx-pod.yaml
流程解析
用户通过多种方式向master结点上的API-Server发起创建一个Pod的请求
apiserver将该信息写入etcd
scheduluer检测到api-Server上有建立Pod请求,开始调度该Pod到指定的Node,同时更新信息到etcd
kubelet检测到有新的Pod调度过来,通过Docker引擎运行该Pod对象
kubelet通过containerruntime取到Pod状态,并同步信息到apiserver,由它更新信息到etcd
生命周期
sideCar模式 - 为主容器提供辅助功能
Adapater模式 - 帮助主容器通信过程中的信息格式修正
Ambassador模式 - 利用pod内多容器共享数据的特性,代理后端容器和外部的其他应用进行交流
1.init容器
初始化容器,独立于主容器之外,pod可以拥有任意数量的init容器,init顺序执行。最后一个执行完成后,才启动主容器。它主要是为了为主容器准备应用的功能,比如向主容器的存储卷写入数据,然后将存储卷挂载到主容器上。
合理使用就绪探针(Readiness)
2.生命周期钩子
启动后钩子postStart - 与主进程并行运行
运行中钩子Liveiness - 判断当前容器是否处于存活状态
Readiness - 判断当前容器是否可以正常的对外提供服务
停止前钩子preStop -先执行钩子,并在钩子执行完成后,向容器发送SIGTERM信号。如果没有优雅终止,则会被杀死。
不管执行成功与否,容器都会终止,如果未成功则告警。
3.pod关闭
当API服务器接收到删除pod对象的命令后,按照下面流程进行:
执行停止前钩子,等待它执行完毕
向容器的主进程发送SIGTERM信号, 等待容器优雅关闭或者等待终止宽限期超时
如果容器没有优雅关闭,使用SIGKILL信号强制终止进程
命令:kubectl delete pod mypod --grace-period=5 #设置终止宽限期 spec.terminationGracePeriod,默认为30s
强制:kubectl delete pod --all --grace-period=0 --force
根据我们对上面pod的启动流程的了解,我们发现当容器中的进程启动前或者容器中的进程终止之前都会有一些额外的动作执行,这是由kubelet所设置的,在这里,我们称之为 pod hook。而Kubernetes 为我们提供了两种钩子函数:PostStart和PreStop。
关于钩子函数的执行主要有两种方式:
Exec - 用于执行一段特定的命令,不过要注意的是该命令消耗的资源会被计入容器。
HTTP - 对容器上的特定的端点执行HTTP请求。
状态策略
正常情况:
在Kubernetes集群中,真正工作的是Node节点,所以业务的子应用也就是Pod,肯定会被分配到相应的Node节点上。Pod一旦绑定到Node节点,就永远不会移动,即便Node节点发生重启。
Pod作为一种资源对象,在整个业务生命周期中,会随着操作而出现五种状态:pending,running,succeeded,failed,Unknown
业务应用作为系统的一部分,会有相应的资源对象对它们进行统一管理,所以不建议手工单独创建一个Pod
异常情况:
业务运行过程中不可避免会出现意外,这个时候有三种策略对Pod进行管理:OnFailure,Never和Always(默认)
查看pod状态pods.status.phase
Pending APIserver已经创建该server,但pod内有一个或多个容器的镜像还未创建,可能在下载中
Running Pod内所有的容器已创建,且至少有一个容器处于运行状态,正在启动或重启状态
Succeeded 所有容器均成功执行退出,且不会再重启
Failed Pod内所有容器都已退出,其中至少有一个容器退出失败。
Unknown 由于某种原因无法获取Pod的状态比如网络不通
Error 因为集群配置、安全限制、资源等原因导致Pod启动过程中发生了错误
Evicted 集群节点 系统内存或硬盘资源不足 导致Pod出现异常
CrashLookBackOff k8s曾经启动容器成功,但是后来异常情况下,重启次数过多导致异常终止;容器退避算法:第1次0秒立刻重启,第二次10秒后重启,第三次20秒后重启, …第7次300秒后重启,如仍重启失败则置为 CrashLookBackOff状态;其他的比如镜像获取,就无效了
容器状态:pods.status.containerStatuses.state
Waiting 容器处于 Running 和Terminated 状态之前的状态
Running 容器能够正常的运行状态
Terminated 容器已经被成功的关闭了
流程状态:pods.status.conditions.status
PodScheduled Pod被调度到某一个结点
Ready 准备就绪,Pod可以处理请求
Initialized Pod中所有初始init容器启动完毕
Unschedulable 由于资源等限制,导致pod无法被调度
ContainersReady Pod中所有的容器都启动完毕了
重启策略:pods.spec.containers.imagePullPolicy
Always 容器失效时,即重启
OnFailure 容器终止运行,且退出码不为0 时重启
Never Pod不重启
镜像拉取策略pod.spec.containers.imagePullPolicy
Always 总是拉取新镜像,这是默认值
IfNotPresent 如果本地仓库不存在的话,再拉取新镜像
Never 不获取新镜像
流程实践
1.init实践
apiVersion: v1
kind: Pod
metadata:
name: init-pod
labels:
app: init
spec:
containers:
- name: busybox
image: 10.0.0.19:80/mykubernetes/busybox:v0.1
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
initContainers:
- name: init-myservice
image: 10.0.0.19:80/mykubernetes/busybox:v0.1
command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']
kubectl apply -f 02-pod-init-test.yaml
kubectl describe pod init-pod
kubectl logs init-pod -c init-myservice
apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9257
kubectl apply -f 03-pod-init-service.yaml
2.sidecar容器实践
在一个pod内启动两个容器,访问B容器的时候,都需要经过A容器,只有通过A处理后的数据才会发送给B容器。
在整个过程中,A容器就是B容器应用的代理服务器
apiVersion: v1
kind: Pod
metadata:
name: sidecar-test
spec:
containers:
- name: proxy
image: 10.0.0.19:80/mykubernetes/sidecar:v1.14.1
command: ['sh', '-c', 'sleep 5 && envoy -c /etc/envoy/envoy.yaml']
lifecycle:
postStart:
exec:
command: ["/bin/sh","-c","wget -O /etc/envoy/envoy.yaml http://ilinux.io/envoy.yaml"]
- name: pod-sysctl
image: 10.0.0.19:80/mykubernetes/pod_test:v0.1
env:
- name: HOST
value: "127.0.0.1"
- name: PORT
value: "8080"
wget -O /etc/envoy/envoy.yaml http://ilinux.io/envoy.yaml
kubectl apply -f 04-pod-sidecar-test.yaml
4.poststart实践
对于pod的流程启动,主要有两种钩子:
postStart,容器创建完成后立即运行,不保证一定会于容器中ENTRYPOINT之前运行
preStop,容器终止操作之前立即运行,在其完成前会阻塞删除容器的操作调用
钩子处理器实现方式:Exec 和 HTTP
Exec,在钩子事件触发时,直接在当前容器中运行由用户定义的命令
HTTP,在当前容器中向某Url发起HTTP请求
属性信息:kubectl explain pods.spec.initContainers.lifecycle
apiVersion: v1
kind: Pod
metadata:
name: poststart
spec:
containers:
- name: busybox
image: 10.0.0.19:80/mykubernetes/busybox:v0.1
lifecycle:
postStart:
exec:
command: ["/bin/sh","-c","echo 'lifecycle poststart' > /tmp/poststart.html"]
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
kubectl apply -f 05-pod-poststart.yaml
kubectl exec poststart -- cat /tmp/poststart.html
5.prestop实践
kubectl explain pods.spec.initContainers.lifecycle.preStop
功能:实现pod对象移除之前,我们需要做一些事情
实现方式:
exec <Object>
httpGet <Object>
tcpSocket <Object>
钩子处理程序的日志不会在 Pod 事件中公开。 如果处理程序由于某种原因失败,它将播放一个事件。 对于PostStart,这是FailedPostStartHook 事件,对于 PreStop,这是 FailedPreStopHook 事件。可通过运行 kubectl describe pod <pod_name> 来查看这些事件。
apiVersion: v1
kind: Pod
metadata:
name: prestop-pod
spec:
volumes:
- name: message
hostPath:
path: /tmp
containers:
- name: prestop-pod
image: 10.0.0.19:80/mykubernetes/nginx:1.21.3
volumeMounts:
- name: message
mountPath: /prestop/
lifecycle:
preStop:
exec:
command: ['/bin/sh', '-c', 'echo prestop Handler > /prestop/prestop']
kubectl apply -f 06-pod-prestop.yaml
kubectl delete -f 06-pod-prestop.yaml
到pod运行的结点上查看:cat /tmp/prestop
静态pod
静态pod只能在特定的节点上运行,由特定节点上的kubelet进程来管理,对于集群来说,只能看,不能动。
常常用于某些结点上的一些隐私操作或者核心操作,而且这些操作往往受到特定结点的场景约束,比如某些定向监控、特定操作。
实现方式主要有两种:配置文件或者http方式
所谓的配置文件的方式,其实就是在特定的目录下存放我们定制好的资源对象文件,然后结点上的kubelet服务周期性的检查该目录下的所有内容,对静态pod进行增删改查。
配置目录的路径指定:在/etc/kubernetes/kubelet.conf文件中使用 --pod-manifest-path=
在/var/lib/kubelet/config.yaml文件中定义kubelet的配置参数staticPodPath
其配置方式主要有两步:
1 定制kubelet服务定期检查配置目录---默认/etc/kubernetes/manifests
2 增删定制资源文件---把资源文件放到或移出该目录
http方式:
1 准备http方式提供资源文件的web站点
2 工作结点的kubelet配置–manifest-url=<资源文件的url下载地址>
这两种方式实现的原理基本上是一致的,只不过一个是在本地设置资源对象文件,一个是在别处设置,我们通过http的方式来获取
进入到node1结点的静态目录/etc/kubernetes/manifests创建资源对象 07-pod-static.yaml
apiVersion: v1
kind: Pod
metadata:
name: static-pod
spec:
containers:
- name: web
image: 10.0.0.19:80/mykubernetes/nginx:1.21.3
kubectl get pod -o wide 直接查看
kubectl delete pod static-pod-node1 由于删除pod的增删主要是基于node1上的kubelet来实现的,无法被kubectl删除
mv /etc/kubernetes/manifests/07-pod-static.yaml /tmp/
资源策略
安全上下文
1.用户级别
容器一般是基于 6个命名空间实现资源的隔离,而一个 Pod 就是一个容器集合,包含多个容器,那么在这种情况下,这几者命名空间是按照下面方式来使用的:内部的所有容器共享底层 pause容器的 UTS | Network 量个名称空间资源
可选共享命名空间:IPC,PID
MNT和USER 两个命名空间默认没有让他们共享 -- 细节应用的隔离。
pod在其生命周期中,涉及到多种场景(多容器的关联关系),我们将这种相关的作用关系 称为容器上下文;
涉及到权限、限制等安全相关的内容,我们称其为安全上下文securityContext
我们也可以将其称之为一组用于决定容器是如何创建和运行的约束条件,他们代表创建和运行容器时使用的运行时参数。
它根据约束的作用范围主要包括三个级别:
Pod级别:针对pod范围内的所有容器
容器级别:仅针对pod范围内的指定容器
PSP级别:PodSecurityPolicy,全局级别的Pod安全策略,涉及到准入控制相关知识
apiVersion: v1
kind: Pod
metadata:
name: pod-test
spec:
nodeName: node2
containers:
- name: nginx
image: 10.0.0.19:80/mykubernetes/pod-test
env:
- name: HELLO
value: "Hello kubernetes pod"
kubectl apply -f 01-pod-test.yaml
kubectl exec -it pod-test -- id
kubectl delete -f 01-pod-test.yaml
因为默认情况下,一旦pod创建好后,是不允许对用户归属权限进行任意修改的,所以需要修改的话,必须先关闭,再开启
添加安全属性
apiVersion: v1
kind: Pod
metadata:
name: pod-test
spec:
containers:
- name: pod-test
image: 10.0.0.19:80/mykubernetes/pod_test:v0.1
env:
- name: HELLO
value: "Hello kubernetes pod"
securityContext:
runAsUser: 1001
runAsGroup: 1001
kubectl apply -f 08-pod-securityContext.yml
kubectl exec -it pod-test -- id
2.资源能力
相关的资源能力
CAP_CHOWN:改变UID和GID;
CAP_MKNOD:mknod(),创建设备文件;
CAP_NET_ADMIN:网络管理权限;
CAP_SYS_ADMIN:大部分的管理权限;
CAP_SYS_TIME:更改系统的时钟
CAP_SYS_MODULE:装载卸载内核模块
CAP_NET_BIND_SERVER:允许普通用户绑定1024以内的特权端口
apiVersion: v1
kind: Pod
metadata:
name: pod-capabilities
spec:
containers:
- name: pod-capabilities
image: 10.0.0.19:80/mykubernetes/pod_test:v0.1
command: ['/bin/sh', '-c']
args: ["/sbin/iptables -t nat -A PREROUTING -p tcp --dport 8080 -j REDIRECT --to-port 80 && /usr/bin/python3 /usr/local/bin/demo.py"]
securityContext:
capabilities:
add: ["NET_ADMIN"] #add后面的权限能力必须使用双引号"",不要使用单引号''
drop: ["CHOWN"] #文件权限不能随意的更改了
kubectl apply -f 09-pod-capabilities.yml
kubectl exec -it pod-capabilities -- iptables -vnL -t nat
kubectl exec -it pod-capabilities -- ifconfig
curl 10.244.1.8:8080
3.特权模式
默认情况下,pod的容器在启动的时候是具备了特权用户权限的。比如我们知道 kubeproxy 会将pod启动时候的一些规则转换成对应的iptable或者ipvs规则 -- 这就涉及到宿主机内核级别的操作。
对于pod内部的容器名称空间的内核级别(不是系统级别)的参数调整,pod支持三个:
kernel.shm_rmid_forced
net.ipv4.ip_local_port_range
net.ipv4.tcp_syncookies,
而对于这些内核参数的修改,必须要所有的node节点上让 kubelet服务支持
--allowed-unsafesysctls=net.core.somaxconn,net.ipv4.ip_unprivileged_port_start等相关内核参数才行,否则无法更改容器的内核参数
apiVersion: v1
kind: Pod
metadata:
name: pod-sysctl
spec:
securityContext:
sysctls:
- name: net.core.somaxconn
value: "6666"
- name: net.ipv4.ip_unprivileged_port_start
value: "0"
- name: kernel.shm_rmid_forced
value: "0"
containers:
- name: pod-sysctl
image: 10.0.0.19:80/mykubernetes/pod_test:v0.1
securityContext:
runAsUser: 1001
runAsGroup: 1001
kubectl apply -f 10-pod-sysctl.yml
kubectl get pod -o wide
kubectl describe pod pod-sysctl #默认情况下,普通用户是不允许修改命名空间里相关内核参数的
Message: Pod forbidden sysctl: "net.core.somaxconn" not whitelisted
修改 kubelet的配置文件(如果文件不存在的话,可以自己手工创建)
vim /etc/default/kubelet
KUBELET_EXTRA_ARGS='--allowed-unsafe-sysctls=net.core.somaxconn,net.ipv4.ip_unprivileged_port_start'
net.core.somaxconn 网卡入栈的最大连接数
net.ipv4.ip_unprivileged_port_start 非特权用户可以使用的端口起始值,默认是1024
在所有的node角色节点上配置该文件,然后重启该服务systemctl restart kubelet
kubectl apply -f 10-pod-sysctl.yml
kubectl get pod -o wide
kubectl exec -it pod-sysctl -- id
探测机制
根据我们对Docker的学习,我们知道,以镜像打包技术为基础的容器技术环境,它运行起来的效果就类似于一个”黑盒”,默认情况下我们不知道里面是一种什么样的运行环境,我们为了实时的监控容器应用环境的运行状态,容器提供了inspect的方法,让我们主动来采集相关的状态数据,但是这种方式太繁琐了。实际上,我们需要一种可以及时的获取容器的各种运行状态数据,所以对于容器任务编排的环境下,他们都应该考虑到一种场景:主动的将容器运行的相关数据暴露出来 — 数据暴露接口。常见的就是 包含大量metric指标数据的API接口。
对于k8s内部的pod环境来说,常见的这些API接口有:
process health 状态健康检测接口
metrics 监控指标接口
readiness 容器可读状态的接口
liveness 容器存活状态的接口
tracing 全链路监控的埋点(探针)接口
logs 容器日志接口
检测相关属性
- LivenessProbe 周期性检测,检测未通过时,kubelet会根据restartPolicy的定义来决定是否会重启容器;未定义时Kubelet认为容器未终止为健康;
ReadinessProbe 周期性检测,检测未通过时,与该Pod关联的Service,会将该Pod从Service的后端可用端点列表中删除;
直接再次就绪,重新添加回来。未定义时,只要容器未终止,即为就绪;
StartupProbe 实现用户自定义的一些探测机制,效果等同于livenessProbe,区别在于应用不同的参数或阈值;
探针类型
对于Pod中多容器的场景,只有所有容器就绪,才认为Pod就绪,kubelet定期执行livenessProbe探针来诊断Pod的健康状况,Pod探针的实现方式有很多,常见的有如下三种:(每种检测机制都支持这三种探针机制)
ExecAction 直接执行命令,命令成功返回表示探测成功;
TCPSocketAction 端口能正常打开,即成功
HTTPGetAction 向指定的path发HTTP请求,2xx, 3xx的响应码表示成功
livenessProbe:
exec <Object> # 命令式探针
httpGet <Object> # http GET类型的探针
tcpSocket <Object> # tcp Socket类型的探针
initialDelaySeconds <integer> # 发起初次探测请求的延后时长
periodSeconds <integer> # 请求周期
timeoutSeconds <integer> # 超时时长,默认是1。
successThreshold <integer> # 连续成功几次,才表示状态正常,默认值是1
failureThreshold <integer> # 连续失败几次,才表示状态异常,默认值是3
这里面仅仅罗列的livenessProbe ,readnessProbe 的属性与livenessProbe一样
1.exec模式
apiVersion: v1
kind: Pod
metadata:
name: liveness-exec-pod
namespace: default
spec:
containers:
- name: liveness-exec-container
image: 10.0.0.19:80/mykubernetes/busybox:v0.1
imagePullPolicy: IfNotPresent
command: ["/bin/sh","-c","touch /tmp/healthy; sleep 3; rm -rf /tmp/healthy;sleep 3600"]
livenessProbe:
exec:
command: ["test", "-e","/tmp/healthy"]
initialDelaySeconds: 1
periodSeconds: 3
kubectl apply -f 11-pod-health-cmd.yaml
kubectl get pods -w
apiVersion: v1
kind: Pod
metadata:
name: liveness-exec-demo
namespace: default
spec:
containers:
- name: demo
image: 10.0.0.19:80/mykubernetes/pod_test:v0.1
imagePullPolicy: IfNotPresent
livenessProbe:
exec:
command: ['/bin/sh', '-c', '[ "$(curl -s 127.0.0.1/livez)" == "OK" ]']
initialDelaySeconds: 5
timeoutSeconds: 1
periodSeconds: 5
这里面的/livez 接口是容器自定义的接口地址,不是所有容器都支持的
当前的/livez支持post方法,用于更改接口的状态,从而来模拟容器的检测效果
kubectl apply -f 11-pod-health-cmd.yaml
curl -XPOST -d 'livez=FAIL' 10.244.6.51/livez #模拟失败
2.http方式
通过对容器内容开放的web服务特性,进行http方法的请求探测,如果探测成功,那么表示我们的http服务是正常的,否则就是失败的。
apiVersion: v1
kind: Pod
metadata:
name: liveness-httpget-pod
spec:
containers:
- name: liveness-httpget-container
image: 10.0.0.19:80/mykubernetes/pod_test:v0.1
ports:
- name: http
containerPort: 80
livenessProbe:
httpGet:
port: http
path: /index.html
initialDelaySeconds: 1
periodSeconds: 3
kubectl apply -f 13-pod-liveness-httpget.yaml
资源限制
申请配额(Requests):业务运行时最小的资源申请使用量,该参数的值必须满足,若不满足,业务运行不起来。
最大配额(Limits):业务运行时最大的资源允许使用量,该参数的值不能被突破,否则该业务的资源对象会被重启或删除等意外操作
apiVersion: v1
kind: Pod
metadata:
name: nginx-test
spec:
containers:
- name: nginx
image: 10.0.0.19:80/mykubernetes/nginx:1.21.3
imagePullPolicy: IfNotPresent
resources:
requests:
memory: "1900Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
apiVersion: v1
kind: LimitRange
metadata:
name: limit-mem-cpu-per-container
spec:
limits:
- max:
cpu: "800m"
memory: "1Gi"
min:
cpu: "100m"
memory: "99Mi"
default:
cpu: "700m"
memory: "900Mi"
defaultRequest:
cpu: "110m"
memory: "111Mi"
type: Container
kubectl apply -f 20-pod-limitrange.yaml
kubectl get limitranges
kubectl describe limitranges limit-mem-cpu-per-container
服务质量QoS
QoS是作用在 Pod 上的一个配置,当 Kubernetes 创建一个 Pod 时,它就会给这个 Pod 分配一个 QoS等级,可以是以下等级之一:
高优先级-Guaranteed:Pod内的每个容器同时设置了CPU和内存的requests和limits 而且值必须相等。
中优先级-Burstable: pod至少有一个容器设置了cpu或内存的requests和limits,不满足 Guarantee 等级的要求。
低优先级-BestEffort: 没有任何一个容器设置了requests或limits的属性。(最低优先级)
apiVersion: v1
kind: Pod
metadata:
name: qos-demo
namespace: qos-example
spec:
containers:
- name: qos-demo-ctr
image: 10.0.0.19:80/mykubernetes/nginx:1.21.3
resources:
limits:
memory: "200Mi"
cpu: "700m"
requests:
memory: "200Mi"
cpu: "700m"