一、资源限制
1.1 资源限制的定义
当定义Pod时可以选择性地为每个容器设定所需要的资源数量。 最常见的可设定资源是CPU和内存大小,以及其他类型的资源。
当为Pod中的容器指定了request资源时,调度器就使用该信息来决定将Pod调度到哪个节点上。当还为容器指定了limit资源时,kubelet就会确保运行的容器不会使用超出所设的limit资源量。kubelet还会为容器预留所设的request资源量, 供该容器使用。
如果Pod运行所在的节点具有足够的可用资源,容器可以使用超出所设置的request资源量。不过,容器不可以使用超出所设置的limit资源量。
如果给容器设置了内存的limit值,但未设置内存的request值,Kubernetes会自动为其设置与内存limit相匹配的request值。 类似的,如果给容器设置了CPU的 limit值但未设置CPU的request 值,则Kubernetes自动为其设置CPU的request值并使之与CPU的limit值匹配。
官方示例:https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/
1.2 Pod和容器的资源请求和限制
spec.containers[].resources.requests.cpu | 定义创建容器时预分配的CPU资源 |
---|---|
spec.containers[].resources.requests.memory | 定义创建容器时预分配的内存资源 |
spec.containers[].resources.limits.cpu | 定义 cpu 的资源上限 |
spec.containers[].resources.limits.memory | 定义内存的资源上限 |
1.3 CPU资源单位
CPU资源的request和limit以cpu为单位。Kubernetes中的一个cpu相当于1个vCPU(1个超线程)。
Kubernetes也支持带小数 CPU 的请求。spec.containers[].resources.requests.cpu为0.5的容器能够获得一个cpu的 、一半CPU资源(类似于Cgroup对CPU资源的时间分片)。表达式0.1等价于表达式100m(毫核),表示每1000毫秒内容器可以使用的CPU时间总量为 0.1*1000 毫秒。
Kubernetes不允许设置精度小于1m的CPU资源。
1.4 内存资源单位
内存的request和limit以字节为单位。可以以整数表示,或者以10为底数的指数的单位(E、P、T、G、M、K)来表示, 或者以2为底数的指数的单位(Ei、Pi、Ti、Gi、Mi、Ki)来表示。
1.5 实验操作
1.5.1 OOM资源不足被干掉
apiVersion: v1
kind: Pod
metadata:name: ky-web-db
spec:containers:- name: webimage: nginxenv:- name: WEB_ROOT_PASSWORDvalue: "password"resources:requests:memory: "64Mi"cpu: "250m"limits:memory: "128Mi"cpu: "500m"- name: dbimage: mysqlenv:- name: MYSQL_ROOT_PASSWORDvalue: "abc123"resources:requests:memory: "64Mi"cpu: "0.25"limits:memory: "128Mi"cpu: "500m"
资源不足第一个进程被杀死,注意如果节点上有资源会拉取节点资源创建,可先把节点关闭
查看日志信息,db因资源不足被干掉
1.5.2 资源充足
apiVersion: v1
kind: Pod
metadata:name: ky-web-db
spec:containers:- name: webimage: nginxenv:- name: WEB_ROOT_PASSWORDvalue: "password"resources:requests:memory: "64Mi"cpu: "250m"limits:memory: "128Mi"cpu: "500m"- name: dbimage: mysqlenv:- name: MYSQL_ROOT_PASSWORDvalue: "abc123"resources:requests:memory: "64Mi"cpu: "0.5"limits:memory: "1Gi"cpu: "1"
给足资源后,状态为running
查看日志信息后,调度给了node01
查看node01详细信息,可以看到资源详细情况
二、探针
2.1 探针的定义
健康检查:又称为探针(Probe) ,探针是由kubelet对容器执行的定期诊断。
2.2 探针的规则
- 存活探针(livenessProbe):判断容器是否运行正常,如果探测失败则杀死容器(不是pod),容器根据容器策略决定是否重启
- 就绪探针(readinessProbe):判断pod是否能进入ready状态,做好接受请求的准备。如果探针失败会进入not ready状态且从service自愿的endpoints中剔除,service将不会再把访问请求转发给pod
- 启动探针(startupProbe):判断容器内的应用是否启动成功,在检测成功状态为success真会玩,其他的探针都会处于失效状态
2.3 Probe三种检查方式
- exec:通过command设置,执行在容器内执行的linux命令来进行探测,如果返回码为0,则为探测成功,非0就为探测失败
- httpget:通过http get请求访问制定容器端口和url路径,如果访问状态吗为>=200且<=400(2xx 300),则认为探测成功
- tcpsocket:通过制定的端口发送TCP连接,如果端口无误且三次握手成功(TCP连接成功),则认为探测成功
2.4 探测的结果
- 成功:容器通过了诊断。
- 失败:容器未通过诊断。
- 未知:诊断失败,因此不会采取任何行动
2.5 实验部署
2.5.1 exec方式——liveness
apiVersion: v1
kind: Pod
metadata:labels:test: livenessname: liveness-exec
spec:containers:- name: livenessimage: busyboximagePullPolicy: IfNotPresentargs: ###启动容器参数- /bin/sh- -c- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 60livenessProbe: #定义了容器的就绪探针exec: #在容器内执行指定命令。如果命令退出时返回码为0则认为诊断成功。command: #指定了执行的命令- cat- /tmp/healthyfailureThreshold: 1 #就绪探针在连续失败一次后被视为失败initialDelaySeconds: 5 #延迟5秒启动容器periodSeconds: 5 #每隔5秒探测一次
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 60
创建一个名为
/tmp/healthy
的文件,暂停执行脚本,等待 30 秒钟,删除后,再次暂停执行脚本,等待额外的 60 秒钟
initialDelaySeconds:指定kubelet在执行第一次探测前应该等待5秒,即第一次探测是在容器启动后的第6秒才开始执行。默认是0秒,最小值是0。
periodSeconds:指定了kubelet应该每5秒执行一次存活探测。默认是10秒。最小值是1。
failureThreshold: 当探测失败时,Kubernetes将在放弃之前重试的次数。 存活探测情况下的放弃就意味着重新启动容器。就绪探测情况下的放弃Pod会被打上未就绪的标签。默认值是 3。最小值是1。
timeoutSeconds:探测的超时后等待多少秒。默认值是1秒。最小值是1。(在Kubernetes 1.20版本之前,exec探针会忽略timeoutSeconds探针会无限期地持续运行,甚至可能超过所配置的限期,直到返回结果为止。)总结:可以看到Pod中只有一个容器。kubelet在执行第一次探测前需要等待5秒,kubelet会每5秒执行一次存活探测。kubelet 在容器内执行命令cat /tmp/healthy来进行探测。如果命令执行成功并且返回值为0,kubelet 就会认为这个容器是健康存活的。 当到达第31秒时,这个命令返回非0值,kubelet会杀死这个容器并重新启动它。
探针失败
/tmp/healthy文件不存在,探测失败
2.5.2 httpGet方式
apiVersion: v1
kind: Pod
metadata:name: liveness-httpgetnamespace: default
spec:containers:- name: liveness-httpget-containerimage: soscscs/myapp:v1 #soscscs:nginx1.12imagePullPolicy: IfNotPresent #拉取策略ports:- name: httpcontainerPort: 80livenessProbe: #探针httpGet:port: httppath: /index.htmlinitialDelaySeconds: 1 #延迟1秒开始探测periodSeconds: 3 #每3秒探测一次timeoutSeconds: 10 #超时时间10秒
删除index.html页面,报错404,探针失败
httpget:通过http get请求访问制定容器端口和url路径,如果访问状态吗为>=200且<=400(2xx 300),则认为探测成功
当我们删除页面后会404报错,然后就会探测失败,最后会重启
2.5.3 tcpSocket方式
apiVersion: v1
kind: Pod
metadata:name: xzq-tcp-live
spec:containers:- name: nginximage: soscscs/myapp:v1livenessProbe:initialDelaySeconds: 5 #第一次探测延迟5秒,第6秒开始timeoutSeconds: 1tcpSocket:port: 8080periodSeconds: 10 #每10秒探测一次failureThreshold: 2 #允许2次失败
2.5.4 就绪检测——readiness
apiVersion: v1
kind: Pod
metadata:name: readiness-httpgetnamespace: default
spec:containers:- name: readiness-httpget-containerimage: soscscs/myapp:v1imagePullPolicy: IfNotPresentports:- name: httpcontainerPort: 80readinessProbe:httpGet:port: 80path: /index1.htmlinitialDelaySeconds: 1periodSeconds: 3livenessProbe:httpGet:port: httppath: /index.htmlinitialDelaySeconds: 1periodSeconds: 3timeoutSeconds: 10
有实例在运行,但是就绪失败
探针http,404报错
bash可能是权限不足,用sh进入写一个页面
kubectl describe pod readiness-httpget
2.5.5 就绪检测2——readiness
apiVersion: v1
kind: Pod
metadata:name: myapp1labels:app: myapp
spec:containers:- name: myappimage: soscscs/myapp:v1ports:- name: httpcontainerPort: 80readinessProbe:httpGet:port: 80path: /index.htmlinitialDelaySeconds: 5periodSeconds: 5timeoutSeconds: 10
---
apiVersion: v1
kind: Pod
metadata:name: myapp2labels:app: myapp
spec:containers:- name: myappimage: soscscs/myapp:v1ports:- name: httpcontainerPort: 80readinessProbe:httpGet:port: 80path: /index.htmlinitialDelaySeconds: 5periodSeconds: 5timeoutSeconds: 10
---
apiVersion: v1
kind: Pod
metadata:name: myapp3labels:app: myapp
spec:containers:- name: myappimage: soscscs/myapp:v1ports:- name: httpcontainerPort: 80readinessProbe:httpGet:port: 80path: /index.htmlinitialDelaySeconds: 5periodSeconds: 5timeoutSeconds: 10
---
apiVersion: v1
kind: Service
metadata:name: myapp
spec:selector:app: myapptype: ClusterIPports:- name: httpport: 80targetPort: 80
查看集群中服务、pod和端点的信息
删除页面看效果,readiness探测失败,Pod无法进入READY状态,且端点控制器将从 endpoints中剔除删除该Pod的IP地址
2.5.6 启动、退出动作
apiVersion: v1
kind: Pod
metadata:name: lifecycle-demo
spec:containers:- name: lifecycle-demo-containerimage: soscscs/myapp:v1lifecycle: #此为关键字段,定义容器的生命周期postStart: #容器启动后立即执行的操作exec: #允许容器启动后执行特定的命令command: ["/bin/sh", "-c", "echo Hello from the postStart handler >> /var/log/nginx/message"] preStop: #容器停止后立即执行的命令exec:command: ["/bin/sh", "-c", "echo Hello from the poststop handler >> /var/log/nginx/message"]volumeMounts: #将存储卷挂载到容器指定路径上- name: message-log #存储卷名字mountPath: /var/log/nginx/readOnly: false #可以读和写initContainers:- name: init-myserviceimage: soscscs/myapp:v1command: ["/bin/sh", "-c", "echo 'Hello initContainers' >> /var/log/nginx/message"]volumeMounts:- name: message-logmountPath: /var/log/nginx/readOnly: falsevolumes:- name: message-loghostPath: #hostPath类型,将存储卷挂载到主机上path: /data/volumes/nginx/log/ #主机路径type: DirectoryOrCreate #类型为目录,如无目录,会自动创建
创建后去node01查看日志
进入到日志路径下,日志瞎看到先初始化后才探针
在node01下删除pod
关闭探针=关闭生命周期
cat message