Kubernetes 如何保障容器可用性?一文介绍探针的使用

有时候,应用因为无限循环或死锁而停止响应,为确保应用在这种情况下可以重新启动,需要有一种机制检查应用程序的运行状况,而不是依赖应用程序内部的检测。

K8s 主要提供了三种探针来针对这种机制:

  • 存活探针:用于检查容器是否正在运行。如果存活探针失败,则 K8s 认为该容器已死亡,并且将尝试重新启动容器。

  • 就绪探针:用于检查容器是否已准备好接收流量。如果容器没有准备好,K8s 将不会将流量路由到该容器。

  • 启动探针:用于检查容器是否已启动。与存活探针不同,启动探针在容器启动时运行一次,而不是在容器运行时持续运行。

探针的检查方法

  • exec:通过在容器内执行指定命令,来判断命令退出时返回的状态码,返回状态码是0表示正常。

  • httpGet:通过对容器的 IP 地址、端口和 URL 路径来发送 GET 请求;如果响应的状态码在 200 ~ 399 间,表示正常。

  • tcpSocket:通过对容器的 IP 地址和指定端口,进行 TCP 检查,如果端口打开,发起 TCP Socket 建立成功,表示正常。

配置项

  • initialDelaySeconds:等待我们定义的时间 结束后便开始探针检查

  • periodSeconds:探针的间隔时间

  • timeoutSeconds:探针的超时时间,当超过我们定义的时间后,便会被视为失败

  • successThreshold:探针的最小连续成功数量

  • failureThreshold:探针的最小连续失败数量

启动探针

 
  
apiVersion: v1        # 必选 API的版本号kind: Pod             # 必选 类型Podmetadata:             # 必选 元数据  name: nginx         # 必选 符合RFC 1035规范的Pod名称  #namespace: default # 可选 Pod所在的命名空间 不指定默认为default 可以使用-n指定namespace  labels:             # 可选 标签选择器 一般用于过滤和区分Pod    app: nginx-readyspec:                  # 必选 用于定义容器的详细信息  containers:          # 必选 容器列表                  - name: nginx        # 必选 符合RFC 1035规范的容器名称    image: nginx:latest   # 必选 容器所用的镜像的地址    imagePullPolicy: Always   # 可选 镜像拉取策略 IfNotPresent:如果宿主机有这个镜像,就不用拉取了 Always:总是拉取 Never:不管存在不存在,都不拉取    ports:             # 可选 容器需要暴露的端口号列表    - name: http       # 端口名称      containerPort: 80   # 端口号      protocol: TCP    # 端口协议 默认TCP    startupProbe:    # 可选 检测容器内进程是否完成启动 注意三种检查方式同时只能使用一种      failureThreshold: 3 # 失败三次算探针失败      exec:         command: ['/bin/sh','-c','echo Hello World']      initialDelaySeconds: 3  # 容器启动完成后首次探测的时间,单位为秒      timeoutSeconds: 2   # 对容器健康检查探测等待响应的超时时间,单位秒,默认1秒      periodSeconds: 1    # 对容器监控检查的定期探测时间设置,单位秒,默认10秒一次      successThreshold: 1 # 成功1次算探针OK      failureThreshold: 3 # 失败三次算探针失败  restartPolicy: Always # 可选 默认Always 容器故障或者没有启动成功 自动重启该容器 Onfailure: 容器以不为0的状态码终止 自动重启该容器 Never:无论何种状态 都不会重启
# kubectl apply -f pod.yaml pod/nginx created
# kubectl get podNAME    READY   STATUS              RESTARTS   AGEnginx   0/1     ContainerCreating   0          4s# kubectl describe pod nginx

就绪探针

# grep -v '^#' pod.yaml apiVersion: v1        # 必选 API的版本号kind: Pod             # 必选 类型Podmetadata:             # 必选 元数据  name: nginx         # 必选 符合RFC 1035规范的Pod名称  #namespace: default # 可选 Pod所在的命名空间 不指定默认为default 可以使用-n指定namespace  labels:             # 可选 标签选择器 一般用于过滤和区分Pod    app: nginx-readyspec:                  # 必选 用于定义容器的详细信息  containers:          # 必选 容器列表                  - name: nginx        # 必选 符合RFC 1035规范的容器名称    image: nginx:latest   # 必选 容器所用的镜像的地址    imagePullPolicy: Always   # 可选 镜像拉取策略 IfNotPresent:如果宿主机有这个镜像,就不用拉取了 Always:总是拉取 Never:不管存在不存在,都不拉取    ports:             # 可选 容器需要暴露的端口号列表    - name: http       # 端口名称      containerPort: 80   # 端口号      protocol: TCP    # 端口协议 默认TCP    readinessProbe:      httpGet:          path: /        port: 80        initialDelaySeconds: 3  # 容器启动完成后首次探测的时间,单位为秒      timeoutSeconds: 2   # 对容器健康检查探测等待响应的超时时间,单位秒,默认1秒      periodSeconds: 1    # 对容器监控检查的定期探测时间设置,单位秒,默认10秒一次      successThreshold: 1 # 成功1次算探针OK      failureThreshold: 3 # 失败三次算探针失败  restartPolicy: Always # 可选 默认Always 容器故障或者没有启动成功 自动重启该容器 Onfailure: 容器以不为0的状态码终止 自动重启该容器 Never:无论何种状态 都不会重启

可以看到端口检测正常

添加 nodeport 类型进行流量访问验证

# grep -v '^#' pod.yaml apiVersion: v1        # 必选 API的版本号kind: Pod             # 必选 类型Podmetadata:             # 必选 元数据  name: nginx         # 必选 符合RFC 1035规范的Pod名称  #namespace: default # 可选 Pod所在的命名空间 不指定默认为default 可以使用-n指定namespace  labels:             # 可选 标签选择器 一般用于过滤和区分Pod    app: nginx-readyspec:                  # 必选 用于定义容器的详细信息  containers:          # 必选 容器列表                  - name: nginx        # 必选 符合RFC 1035规范的容器名称    image: nginx:latest   # 必选 容器所用的镜像的地址    imagePullPolicy: Always   # 可选 镜像拉取策略 IfNotPresent:如果宿主机有这个镜像,就不用拉取了 Always:总是拉取 Never:不管存在不存在,都不拉取    ports:             # 可选 容器需要暴露的端口号列表    - name: http       # 端口名称      containerPort: 80   # 端口号      protocol: TCP    # 端口协议 默认TCP    readinessProbe:      httpGet:          path: /        port: 80        initialDelaySeconds: 3  # 容器启动完成后首次探测的时间,单位为秒      timeoutSeconds: 2   # 对容器健康检查探测等待响应的超时时间,单位秒,默认1秒      periodSeconds: 1    # 对容器监控检查的定期探测时间设置,单位秒,默认10秒一次      successThreshold: 1 # 成功1次算探针OK      failureThreshold: 3 # 失败三次算探针失败  restartPolicy: Always # 可选 默认Always 容器故障或者没有启动成功 自动重启该容器 Onfailure: 容器以不为0的状态码终止 自动重启该容器 Never:无论何种状态 都不会重启---apiVersion: v1kind: Servicemetadata:  name: ready-nodeport  labels:    name: ready-nodeportspec:  type: NodePort  ports:  - port: 88    protocol: TCP    targetPort: 80    nodePort: 30880  selector:    app: nginx-ready

访问验证

# kubectl get podNAME    READY   STATUS    RESTARTS   AGEnginx   1/1     Running   0          15s[root@k8s-master01 ~]# kubectl get svc -owideNAME             TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE   SELECTORkubernetes       ClusterIP   10.96.0.1              443/TCP        72d   ready-nodeport   NodePort    10.96.93.159           88:30880/TCP   20s   app=nginx-ready
[root@k8s-master01 ~]# curl http://192.168.10.10:30880Welcome to nginx!

Welcome to nginx!

If you see this page, the nginx web server is successfully installed andworking. Further configuration is required.

For online documentation and support please refer tonginx.org.
Commercial support is available atnginx.com.

Thank you for using nginx.

修改 httpGet 或 tcpSocket 端口为 81 模拟探针探测失败,探测失败流量会不会分配进入

 
  
# kubectl get podNAME    READY   STATUS    RESTARTS   AGEnginx   0/1     Running   0          22s
# kubectl get svc -owideNAME             TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE   SELECTORkubernetes       ClusterIP   10.96.0.1              443/TCP        72d   ready-nodeport   NodePort    10.96.115.11           88:30880/TCP   25s   app=nginx-ready[root@k8s-master01 ~]# curl http://192.168.10.10:30880curl: (7) Failed connect to 192.168.10.10:30880; 拒绝连接

describe nginx查看

显示81端口不通,ready状态为0,但pod是running的,请求结果为拒绝连接,流量打入失败。就绪探针失败,是不会给该pod打入流量的。

存活探针

# grep -v '^#' pod.yaml apiVersion: v1        # 必选 API的版本号kind: Pod             # 必选 类型Podmetadata:             # 必选 元数据  name: nginx         # 必选 符合RFC 1035规范的Pod名称  #namespace: default # 可选 Pod所在的命名空间 不指定默认为default 可以使用-n指定namespace  labels:             # 可选 标签选择器 一般用于过滤和区分Pod    app: nginx-readyspec:                  # 必选 用于定义容器的详细信息  containers:          # 必选 容器列表                  - name: nginx        # 必选 符合RFC 1035规范的容器名称    image: nginx:latest   # 必选 容器所用的镜像的地址    imagePullPolicy: Always   # 可选 镜像拉取策略 IfNotPresent:如果宿主机有这个镜像,就不用拉取了 Always:总是拉取 Never:不管存在不存在,都不拉取    ports:             # 可选 容器需要暴露的端口号列表    - name: http       # 端口名称      containerPort: 80   # 端口号      protocol: TCP    # 端口协议 默认TCP    livenessProbe:      httpGet:          path: /        port: 80        scheme: HTTP      initialDelaySeconds: 3  # 容器启动完成后首次探测的时间,单位为秒      timeoutSeconds: 2   # 对容器健康检查探测等待响应的超时时间,单位秒,默认1秒      periodSeconds: 1    # 对容器监控检查的定期探测时间设置,单位秒,默认10秒一次      successThreshold: 1 # 成功1次算探针OK      failureThreshold: 3 # 失败三次算探针失败  restartPolicy: Always # 可选 默认Always 容器故障或者没有启动成功 自动重启该容器 Onfailure: 容器以不为0的状态码终止 自动重启该容器 Never:无论何种状态 都不会重启---apiVersion: v1kind: Servicemetadata:  name: ready-nodeport  labels:    name: ready-nodeportspec:  type: NodePort  ports:  - port: 88    protocol: TCP    targetPort: 80    nodePort: 30880  selector:    app: nginx-ready

创建 pod 与 service 并访问测试

 
  
# kubectl apply -f pod.yaml pod/nginx createdservice/ready-nodeport created[root@k8s-master01 ~]# kubectl get podNAME    READY   STATUS    RESTARTS   AGEnginx   1/1     Running   0          4s
# kubectl get svc -owideNAME             TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE   SELECTORkubernetes       ClusterIP   10.96.0.1             443/TCP        72d   ready-nodeport   NodePort    10.96.54.68           88:30880/TCP   12s   app=nginx-ready[root@k8s-master01 ~]# curl 192.168.10.10:30880Welcome to nginx!

Welcome to nginx!

If you see this page, the nginx web server is successfully installed andworking. Further configuration is required.

For online documentation and support please refer tonginx.org.
Commercial support is available atnginx.com.

Thank you for using nginx.

修改检测端口为81,模拟检测失败

探针检测失败会根据 restartPolicy 重启策略操作

默认 Always 容器故障或者没有启动成功 自动重启该容器

重新创建该 pod

# kubectl get podNAME    READY   STATUS    RESTARTS   AGEnginx   1/1     Running   0          4s
# kubectl get svc -owideNAME             TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE     SELECTORkubernetes       ClusterIP   10.96.0.1             443/TCP        72d     ready-nodeport   NodePort    10.96.54.68           88:30880/TCP   7m28s   app=nginx-ready
# curl http://192.168.10.10:30880curl: (7) Failed connect to 192.168.10.10:30880; 拒绝连接

Kubernetes 如何保障容器可用性?一文介绍探针的使用_第1张图片

查看 pod是否进行重启,可以看到pod已经重启5次,状态也变为CrashLoopBackOff

后续

当然,除了探针,Kubernetes 还有以下几种机制来确保容器的可用性:

  • RC 或 ReplicaSet:用于确保在集群中运行指定数量的 Pod。如果 Pod 在节点上失败或被删除,则 RC 或 ReplicaSet 将启动新的 Pod 来代替它们。

  • Deployment:用于管理 Pod 和 ReplicaSet 的更新。Deployment 可以在进行滚动更新时确保应用程序的可用性,并提供回滚机制以恢复到以前的版本。

  • Service:用于将流量路由到运行中的 Pod。Service 为应用程序提供了一个稳定的 IP 地址和 DNS 名称,并可以将流量根据需要负载均衡到多个 Pod 中。

  • Namespace:用于隔离和组织集群中的资源。通过使用 Namespace,可以将不同的应用程序或团队隔离开来,并控制它们可以访问的资源。

你可能感兴趣的:(运维,kubernetes,docker)