一、健康检查
Probe有以下两种类型:
livenessProbe
如果检查失败,将杀死容器,根据Pod的restartPolicy来操作。Liveness 探测可以告诉 Kubernetes 什么时候通过重启容器实现自愈
readinessProbe
如果检查失败,Kubernetes会把Pod从service endpoints中剔除。Readiness 探测则是告诉 Kubernetes 什么时候可以将容器加入到 Service 负载均衡池中,对外提供服务。
下面对 Liveness 探测和 Readiness 探测做个比较:
Liveness 探测和 Readiness 探测是两种 Health Check 机制,如果不特意配置,Kubernetes 将对两种探测采取相同的默认行为,即通过判断容器启动进程的返回值是否为零来判断探测是否成功。
两种探测的配置方法完全一样,支持的配置参数也一样。不同之处在于探测失败后的行为:Liveness 探测是重启容器;Readiness 探测则是将容器设置为不可用,不接收 Service 转发的请求。
Liveness 探测和 Readiness 探测是独立执行的,二者之间没有依赖,所以可以单独使用,也可以同时使用。用 Liveness 探测判断容器是否需要重启以实现自愈;用 Readiness 探测判断容器是否已经准备好对外提供服务。
1、Health Check 在 Scale Up 中的应用
对于多副本应用,当执行 Scale Up 操作时,新副本会作为 backend 被添加到 Service 的负责均衡中,与已有副本一起处理客户的请求。考虑到应用启动通常都需要一个准备阶段,比如加载缓存数据,连接数据库等,从容器启动到正真能够提供服务是需要一段时间的。我们可以通过 Readiness 探测判断容器是否就绪,避免将请求发送到还没有 ready 的 backend。
2、Health Check 另一个重要的应用场景是 Rolling Update
试想一下下面的情况,现有一个正常运行的多副本应用,接下来对应用进行更新(比如使用更高版本的 image),Kubernetes 会启动新副本,然后发生了如下事件:
正常情况下新副本需要 10 秒钟完成准备工作,在此之前无法响应业务请求。
但由于人为配置错误,副本始终无法完成准备工作(比如无法连接后端数据库)。
因为新副本本身没有异常退出,默认的 Health Check 机制会认为容器已经就绪,进而会逐步用新副本替换现有副本,其结果就是:当所有旧副本都被替换后,整个应用将无法处理请求,无法对外提供服务。如果这是发生在重要的生产系统上,后果会非常严重。
如果正确配置了 Health Check,新副本只有通过了 Readiness 探测,才会被添加到 Service;如果没有通过探测,现有副本不会被全部替换,业务仍然正常进行。
Probe支持以下三种检查方法:
httpGet,发送HTTP请求,返回200-400范围状态码为成功。
apiVersion: apps/v1 kind: Deployment metadata: name: nginx1-deployment namespace: default spec: replicas: 3 selector: matchLabels: app: nginx1 template: metadata: labels: app: nginx1 spec: nodeSelector: app: dev containers: - name: nginx1 image: nginx:1.15 livenessProbe: #健康检查 httpGet: #发送http请求,请求uri和端口 path: / port: 8080 initialDelaySeconds: 3 #容器启动后3秒开始检查 periodSeconds: 3 #检查周期3秒 timeOutSeconds: 3 #超时时间 ports: - containerPort: 80
readinessProbe: httpGet: path: / port: 80 initialDelaySeconds: 3 periodSeconds: 3
exec,执行Shell命令返回状态码是0为成功
livenessProbe: exec: command: - cat - /tmp/healthy initialDelaySeconds: 5 periodSeconds: 5 readinessProbe: exec: command: - cat - /tmp/healthy initialDelaySeconds: 5 periodSeconds: 5
tcpSocket,发起TCP Socket建立成功
readinessProbe: tcpSocket: port: 8080 initialDelaySeconds: 5 periodSeconds: 10 timeOutSeconds: 3 livenessProbe: tcpSocket: port: 8080 initialDelaySeconds: 15 periodSeconds: 20 timeOutSeconds: 3
二、调度约束
apiVersion: v1 kind: Pod metadata: name: pod-example labels: app: nginx spec: nodeName: 192.168.31.65 containers: - name: nginx image: nginx:1.15
#给node设置标签
kubectl label nodes k8s-node03 app=dev
查看标签
[root@k8s-master01-etcd01 ~]# kubectl get node --show-labels NAME STATUS ROLES AGE VERSION LABELS k8s-node01 Ready <none> 4d5h v1.16.0 app=dev,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node01,kubernetes.io/os=linux k8s-node02 Ready <none> 4d5h v1.16.0 app=dev,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node02,kubernetes.io/os=linux k8s-node03 Ready <none> 4d5h v1.16.0 app=ingress-nginx,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node03,kubernetes.io/os=linux k8s-node04 Ready <none> 4d3h v1.16.0 app=ingress-nginx,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node04,kubernetes.io/os=linux
配置调度
apiVersion: v1
kind: Pod
metadata:
name: pod-example
spec:
nodeSelector:
env_role: dev
containers:
- name: nginx
image: nginx:1.15