Node 重伤之后

很多人都知道 Kubernetes 能自动维护失效 Pod、防止服务中断、剔除故障节点 BLABLA 的一堆高大上功能。但节点故障之后,会对运行在故障节点上的容器、以及依赖容器的服务造成什么影响,是应该了解的,这样才能有针对性的进行监控设置、部署安排、故障处理等工作。

水平有限,这里不谈原理,只说说症状和一些相关的调整。

测试环境

  • Kubernetes 1.7.10,三节点,其中 Master 节点被 Taint.
    • 10.211.55.11(Master)
    • 10.211.55.12
    • 10.211.55.13
  • CentOS 7
  • Docker 1.12.3

实验设计

Docker、Kubelet 以及 Kube-Proxy 是 Node 的标准组件,我们准备一个 2 Replicas 的 Deployment 作为测试目标,使用 NodePort 方式暴露 HTTP 端口。具体代码见附录。

使用 systemctl 关停目标服务,使用 watch -n5 kubectl get pods,nodes,deploy 以及 watch -n5 kubectl "describe svc httpbin | grep -i endp" 命令持续检查相关工作负载的情况。同时可以使用 curl 命令检查服务是否存活。

Kube-Proxy

选择登录一个节点,例如 10.211.55.12,使用 kubectl stop kube-proxy 关闭之后可以看到,各个 kubectl get 命令返回结果都正常,似乎未受影响;然而使用 curl 进行逐个节点的 NodePort 进行验证的时候,会发现停掉 Proxy 的地址是无法提供服务的。

监控

除了监控进程/服务之外,Kube-Proxy 还提供了几个可以用于监控的参数

  • --healthz-bind-address:健康检测地址和端口,缺省为 0.0.0.0:10256
  • --healthz-port:健康检测端口,缺省 10256,设置为 0 则关闭。

curl http://127.0.0.1:10256/healthz | jq 会看到返回的健康数据:

{
  "lastUpdated": "2017-12-19 16:05:27.333531431 +0800 CST",
  "currentTime": "2017-12-19 16:05:33.73732624 +0800 CST"
}

--metrics-bind-address 用于提供监控指标的地址和端口,缺省为 127.0.0.1:10249,返回内容可用于 Prometheus。例如:curl -s http://127.0.0.1:10249/metrics | more会看到:

......
# HELP http_request_size_bytes The HTTP request sizes in bytes.
# TYPE http_request_size_bytes summary
http_request_size_bytes{handler="prometheus",quantile="0.5"} 64
http_request_size_bytes{handler="prometheus",quantile="0.9"} 64
http_request_size_bytes{handler="prometheus",quantile="0.99"} 64
http_request_size_bytes_sum{handler="prometheus"} 192
http_request_size_bytes_count{handler="prometheus"} 3
......

Kubelet

Kubelet 情况比 kube-proxy 复杂一些。

  1. 首先使用kubectl get po -o wide,确认 Pod 所在节点。
  2. 使用systemctl stop kubelet停止 kubelet 服务。
  3. 观察

首先我们会看到,经过约半分钟以后,该节点变为NotReady状态。Deploy 对象的 Available 字段数字会减 1,服务的Endpoints列表减少一个。;但是 Pod 状态保持在Running

五分钟左右,Pod 进入Unknown状态,开始尝试启动新 Pod。

存活检测和就绪检测

测试中我们使用的 yaml 中并没有设置这两个内容,事实上,这两个检测是由 kubelet 执行的,对上述行为并无影响。

参数调整

真正影响上面的行为的是kube-controller-manager的两个参数:

  • --pod-eviction-timeout:缺省为 5m,五分钟,在 Pod 驱逐行为的超时时间。
  • --node-monitor-grace-period:缺省为 40s,也就是 40 秒,无响应 Node 在标记为 NotReady 之前的等候时间。

监控

  • --healthz-bind-address:健康监测地址,缺省为127.0.0.1
  • --healthz-port:健康检测端口,缺省为 10248。

curl 访问该地址,会得到响应:ok

另外如果使用kube-metrics exporter进行集群监控,可以关注 RC、Deploy 等对象的可用实例数量。

Docker

Docker 的情况其实跟 Kubelet 类似,但是结果会更严重:在 Endpoint 被排除之前,路由到故障节点的流量会发生故障。

测试之外

  1. 多 Pod 不仅对性能有好处,在极端情况下能降低故障节点对服务整体效果的影响。
  2. 建议采用节点互斥的方式进行部署。
  3. 对关键组件的监控,应该建立从进程到指标的多级监控,减小服务故障的时间窗口。
  4. Pod 的存活和健康监测,对于容器内的应用是有效的,应该推荐。

附录

workload.yaml


apiVersion: v1
kind: Service
metadata:
  name: httpbin
  labels:
    app: httpbin
spec:
  ports:
  - name: http
    port: 80
    nodePort: 30080
  selector:
    app: httpbin
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: httpbin-v1
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: httpbin
        version: v1
    spec:
      containers:
      - image: httpd
        imagePullPolicy: IfNotPresent
        name: httpbin
        ports:
        - containerPort: 80
Avatar
崔秀龙

简单,是大师的责任;我们凡夫俗子,能做到清楚就很不容易了。

comments powered by Disqus
下一页
上一页

相关