目录
- spec.containers[].resources.requests.cpu //定义创建容器时预分配的CPU资源
- spec.containers[].resources.requests.memory //定义创建容器时预分配的内存资源
- spec.containers[].resources.limits.cpu //定义 cpu 的资源上限
- spec.containers[].resources.limits.memory //定义内存的资源上限
- apiVersion: v1
- kind: Pod
- metadata:
- name: frontend
- spec:
- containers:
- - name: app
- image: images.my-company.example/app:v4
- env:
- - name: MYSQL_ROOT_PASSWORD
- value: "password"
- resources:
- requests:
- memory: "64Mi"
- cpu: "250m"
- limits:
- memory: "128Mi"
- cpu: "500m"
- - name: log-aggregator
- image: images.my-company.example/log-aggregator:v6
- resources:
- requests:
- memory: "64Mi"
- cpu: "250m"
- limits:
- memory: "128Mi"
- cpu: "500m"
-
- 此例子中的 Pod 有两个容器。每个容器的 request 值为 0.25 cpu 和 64MiB 内存,每个容器的 limit 值为 0.5 cpu 和 128MiB 内存。那么可以认为该 Pod 的总的资源 request 为 0.5 cpu 和 128 MiB 内存,总的资源 limit 为 1 cpu 和 256MiB 内存。
- vim pod2.yaml
- apiVersion: v1
- kind: Pod
- metadata:
- name: frontend
- spec:
- containers:
- - name: web
- image: nginx
- env:
- - name: WEB_ROOT_PASSWORD
- value: "password"
- resources:
- requests:
- memory: "64Mi"
- cpu: "250m"
- limits:
- memory: "128Mi"
- cpu: "500m"
- - name: db
- image: mysql
- env:
- - name: MYSQL_ROOT_PASSWORD
- value: "abc123"
- resources:
- requests:
- memory: "512Mi"
- cpu: "0.5"
- limits:
- memory: "1Gi"
- cpu: "1"
-
- kubectl apply -f pod2.yaml
- kubectl describe pod frontend
-
- kubectl get pods -o wide
1、Always:当容器终止退出后,总是重启容器,默认策略
2、OnFailure:当容器异常退出(退出状态码非0)时,重启容器;正常退出则不重启容器
3、Never:当容器终止退出,从不重启容器
注意:K8S 中不支持重启 Pod 资源,只有删除重建
- vim pod3.yaml
- apiVersion: v1
- kind: Pod
- metadata:
- name: foo
- spec:
- containers:
- - name: busybox
- image: busybox
- args:
- - /bin/sh
- - -c
- - sleep 30; exit 3
-
-
- kubectl apply -f pod3.yaml
-
- //查看Pod状态,等容器启动后30秒后执行exit退出进程进入error状态,就会重启次数加1
- kubectl get pods
-
- vim pod3.yaml
- apiVersion: v1
- kind: Pod
- metadata:
- name: foo
- spec:
- containers:
- - name: busybox
- image: busybox
- args:
- - /bin/sh
- - -c
- - sleep 30; exit 3
- restartPolicy: Never
- #注意:跟container同一个级别
-
- kubectl apply -f pod3.yaml
-
- //容器进入error状态不会进行重启
- kubectl get pods -w
- vim pod3.yaml
- apiVersion: v1
- kind: Pod
- metadata:
- name: foo
- spec:
- containers:
- - name: busybox
- image: busybox
- args:
- - /bin/sh
- - -c
- - sleep 30; exit 3
- restartPolicy: Never
- #注意:跟container同一个级别
-
- kubectl apply -f pod3.yaml
-
- //容器进入error状态不会进行重启
- kubectl get pods -w
每次探测都将获得以下三种结果之一
- apiVersion: v1
- kind: Pod
- metadata:
- labels:
- test: liveness
- name: liveness-exec
- spec:
- containers:
- - name: liveness
- image: k8s.gcr.io/busybox
- args:
- - /bin/sh
- - -c
- - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 60
- livenessProbe:
- exec:
- command:
- - cat
- - /tmp/healthy
- failureThreshold: 1
- initialDelaySeconds: 5
- periodSeconds: 5
-
- #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 会杀死这个容器并重新启动它。
- vim exec.yaml
- apiVersion: v1
- kind: Pod
- metadata:
- name: liveness-exec
- namespace: default
- spec:
- containers:
- - name: liveness-exec-container
- image: busybox
- imagePullPolicy: IfNotPresent
- command: ["/bin/sh","-c","touch /tmp/live ; sleep 30; rm -rf /tmp/live; sleep 3600"]
- livenessProbe:
- exec:
- command: ["test","-e","/tmp/live"]
- initialDelaySeconds: 1
- periodSeconds: 3
-
- kubectl create -f exec.yaml
-
- kubectl describe pods liveness-exec
-
- kubectl get pods -w
- apiVersion: v1
- kind: Pod
- metadata:
- labels:
- test: liveness
- name: liveness-http
- spec:
- containers:
- - name: liveness
- image: k8s.gcr.io/liveness
- args:
- - /server
- livenessProbe:
- httpGet:
- path: /healthz
- port: 8080
- httpHeaders:
- - name: Custom-Header
- value: Awesome
- initialDelaySeconds: 3
- periodSeconds: 3
在这个配置文件中,可以看到 Pod 也只有一个容器。initialDelaySeconds 字段告诉 kubelet 在执行第一次探测前应该等待 3 秒。periodSeconds 字段指定了 kubelet 每隔 3 秒执行一次存活探测。kubelet 会向容器内运行的服务(服务会监听 8080 端口)发送一个 HTTP GET 请求来执行探测。如果服务器上 /healthz 路径下的处理程序返回成功代码,则 kubelet 认为容器是健康存活的。如果处理程序返回失败代码,则 kubelet 会杀死这个容器并且重新启动它。
任何大于或等于 200 并且小于 400 的返回代码标示成功,其它返回代码都标示失败。
- vim httpget.yaml
- apiVersion: v1
- kind: Pod
- metadata:
- name: liveness-httpget
- namespace: default
- spec:
- containers:
- - name: liveness-httpget-container
- image: soscscs/myapp:v1
- imagePullPolicy: IfNotPresent
- ports:
- - name: http
- containerPort: 80
- livenessProbe:
- httpGet:
- port: http
- path: /index.html
- initialDelaySeconds: 1
- periodSeconds: 3
- timeoutSeconds: 10
-
- kubectl create -f httpget.yaml
-
- kubectl exec -it liveness-httpget -- rm -rf /usr/share/nginx/html/index.html
-
- kubectl get pods
- apiVersion: v1
- kind: Pod
- metadata:
- name: goproxy
- labels:
- app: goproxy
- spec:
- containers:
- - name: goproxy
- image: k8s.gcr.io/goproxy:0.1
- ports:
- - containerPort: 8080
- readinessProbe:
- tcpSocket:
- port: 8080
- initialDelaySeconds: 5
- periodSeconds: 10
- livenessProbe:
- tcpSocket:
- port: 8080
- initialDelaySeconds: 15
- periodSeconds: 20
这个例子同时使用 readinessProbe 和 livenessProbe 探测。kubelet 会在容器启动 5 秒后发送第一个 readinessProbe 探测。这会尝试连接 goproxy 容器的 8080 端口。如果探测成功,kubelet 将继续每隔 10 秒运行一次检测。除了 readinessProbe 探测,这个配置包括了一个 livenessProbe 探测。kubelet 会在容器启动 15 秒后进行第一次 livenessProbe 探测。就像 readinessProbe 探测一样,会尝试连接 goproxy 容器的 8080 端口。如果 livenessProbe 探测失败,这个容器会被重新启动。
- vim tcpsocket.yaml
- apiVersion: v1
- kind: Pod
- metadata:
- name: probe-tcp
- spec:
- containers:
- - name: nginx
- image: soscscs/myapp:v1
- livenessProbe:
- initialDelaySeconds: 5
- timeoutSeconds: 1
- tcpSocket:
- port: 8080
- periodSeconds: 10
- failureThreshold: 2
-
- kubectl create -f tcpsocket.yaml
-
- kubectl exec -it probe-tcp -- netstat -natp
- kubectl get pods -w
- vim readiness-httpget.yaml
- apiVersion: v1
- kind: Pod
- metadata:
- name: readiness-httpget
- namespace: default
- spec:
- containers:
- - name: readiness-httpget-container
- image: soscscs/myapp:v1
- imagePullPolicy: IfNotPresent
- ports:
- - name: http
- containerPort: 80
- readinessProbe:
- httpGet:
- port: 80
- path: /index1.html
- initialDelaySeconds: 1
- periodSeconds: 3
- livenessProbe:
- httpGet:
- port: http
- path: /index.html
- initialDelaySeconds: 1
- periodSeconds: 3
- timeoutSeconds: 10
-
- kubectl create -f readiness-httpget.yaml
-
- //readiness探测失败,无法进入READY状态
- kubectl get pods
-
- kubectl exec -it readiness-httpget sh
- kubectl get pods
- kubectl exec -it readiness-httpget -- rm -rf /usr/share/nginx/html/index.html
- kubectl get pods -w
- vim readiness-myapp.yaml
- apiVersion: v1
- kind: Pod
- metadata:
- name: myapp1
- labels:
- app: myapp
- spec:
- containers:
- - name: myapp
- image: soscscs/myapp:v1
- ports:
- - name: http
- containerPort: 80
- readinessProbe:
- httpGet:
- port: 80
- path: /index.html
- initialDelaySeconds: 5
- periodSeconds: 5
- timeoutSeconds: 10
- ---
- apiVersion: v1
- kind: Pod
- metadata:
- name: myapp2
- labels:
- app: myapp
- spec:
- containers:
- - name: myapp
- image: soscscs/myapp:v1
- ports:
- - name: http
- containerPort: 80
- readinessProbe:
- httpGet:
- port: 80
- path: /index.html
- initialDelaySeconds: 5
- periodSeconds: 5
- timeoutSeconds: 10
- ---
- apiVersion: v1
- kind: Pod
- metadata:
- name: myapp3
- labels:
- app: myapp
- spec:
- containers:
- - name: myapp
- image: soscscs/myapp:v1
- ports:
- - name: http
- containerPort: 80
- readinessProbe:
- httpGet:
- port: 80
- path: /index.html
- initialDelaySeconds: 5
- periodSeconds: 5
- timeoutSeconds: 10
- ---
- apiVersion: v1
- kind: Service
- metadata:
- name: myapp
- spec:
- selector:
- app: myapp
- type: ClusterIP
- ports:
- - name: http
- port: 80
- targetPort: 80
-
- kubectl create -f readiness-myapp.yaml
- kubectl get pods,svc,endpoints -o wide
- kubectl exec -it pod/myapp1 -- rm -rf /usr/share/nginx/html/index.html
- //readiness探测失败,Pod 无法进入READY状态,且端点控制器将从 endpoints 中剔除删除该 Pod 的 IP 地址
- kubectl get pods,svc,endpoints -o wide
- vim post.yaml
- apiVersion: v1
- kind: Pod
- metadata:
- name: lifecycle-demo
- spec:
- containers:
- - name: lifecycle-demo-container
- image: soscscs/myapp:v1
- lifecycle: #此为关键字段
- 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-myservice
- image: soscscs/myapp:v1
- command: ["/bin/sh", "-c", "echo 'Hello initContainers' >> /var/log/nginx/message"]
- volumeMounts:
- - name: message-log
- mountPath: /var/log/nginx/
- readOnly: false
- volumes:
- - name: message-log
- hostPath:
- path: /data/volumes/nginx/log/
- type: DirectoryOrCreate
-
- kubectl create -f post.yaml
- kubectl get pods -o wide
- kubectl exec -it lifecycle-demo -- cat /var/log/nginx/message
- /在 node01 节点上查看
- [root@node01 ~]# cd /data/volumes/nginx/log/
- [root@node01 log]# ls
- access.log error.log message
- [root@node01 log]# cat message
- Hello initContainers
- Hello from the postStart handler
- #由上可知,init Container先执行,然后当一个主容器启动后,Kubernetes 将立即发送 postStart 事件。
-
- //删除 pod 后,再在 node02 节点上查看
- kubectl delete pod lifecycle-demo
-
- [root@node01 log]# cat message
- Hello initContainers
- Hello from the postStart handler
- Hello from the poststop handler
- #由上可知,当在容器被终结之前, Kubernetes 将发送一个 preStop 事件。
- resources.requests|limits(resources与image字段同一层级)
- resources.requests.cpu|memory|hugepages-
|ephemeral-storage|nvidia.com/gpu(需要第三方插件支持) 设置Pod容器创建时需要预留的资源量 - resources.limits.cpu|memory|hugepages-
|ephemeral-storage|nvidia.com/gpu(需要第三方插件支持) 设置Pod容器能够使用的资源量上限 -
- 如果Pod容器的进程使用的内存资源量超过limits.memory设置的值则会引发内存不足OOM错误
- CPU资源量单位:cpu个数 1 2 0.5 1.25 毫核 1000m 2000m 500m 1250m
- memory|hugepages-
|ephemeral-storage资源量单位:纯整数(默认单位为字节) 2为底数的单位(Ki Mi Gi Ti) 10为底数的单位(K M G T)
Guaranteed:Pod 中的每个容器,包含初始化容器,必须指定内存、CPU 的 requests 和 limits,并且 requests 和 limits 要相等
Burstable:Pod 中至少一个容器具有内存 或 CPU requests
BestEffort:Pod 中的所有容器都没有指定内存 或 CPU 的 requests和 limits
优先级:Guaranteed > Burstable > BestEffort
Guaranteed (QoS) 的 Pod,其优先级最高,在其资源使用量不超过其 limits 的情况下,可以确保不被杀死
在系统内存资源紧张,且集群中没有 QoS 为 Best-Effort 级别的其它 Pod 时,一旦 Burstable (QoS) 的Pod 使用的资源量超过了其 requests,这些 Pod 就容易被杀死
BestEffort (QoS) 的 Pod,其优先级最低,当系统内存资源紧张时,这些 Pod 底层容器中的进程是最先会被杀死的
kubectl describe -n <命名空间> pods <资源名称> 查看Pod中的每个容器的资源限制的配置
kubectl describe node
- initialDelaySeconds:指定容器启动后延迟探测的时间(单位为秒)
- periodSeconds:指定每次探测的间隔时间
- failureThreshold:指定判定探测失败的连续失败次数
- timeoutSeconds:指定探测超时等待的时间
- Pod容器的启动动作和退出动作:lifecycle.postStart|preStop(lifecycle与image字段同一层级)
- lifecycle.postStart 设置Pod容器启动时额外执行的操作,此操作不会作为容器pid=1的主进程
- lifecycle.preStop 设置Pod容器被kubelet杀掉退出时执行的操作