kubernetes
1. service 对应的 endpoint 列表会新增或移除endpoint,更新期间可能让部分连接异常,主要原因是
- pod 被创建,还没完全启动就被 endpoint controller 加入到 service 的 endpoint 列表,然后 kube-proxy 配置对应的路由规则(iptables/ipvs),如果请求被路由到还没完全启动完成的 pod,这时 pod 还不能正常处理请求,就会导致连接异常
- 针对第一种情况,可以给 pod 里的 container 加 readinessProbe (就绪检查),这样可以让容器完全启动了才被endpoint controller加进 service 的 endpoint 列表,然后 kube-proxy 再更新路由规则,这时请求被转发到的所有后端 pod 都是正常运行,避免了连接异常
2. pod 被销毁,但是从 endpoint controller watch 到变化并更新 service 的 endpoint 列表到 kube-proxy 更新路由规则这期间有个时间差,pod可能已经完全被销毁了,但是路由 规则还没来得及更新,造成请求依旧还能被转发到已经销毁的 pod ip,导致连接异常最佳实践
- 针对第二种情况,可以给 pod 里的 container 加 preStop hook,让 pod 真正销毁前先 sleep 等待一段时间,留点时间给 endpoint controller 和 kube-proxy 清理 endpoint 和路由规则,这段时间 pod 处于 Terminating 状态,在路由规则更新完全之前如果有请求转发到这个被销毁的 pod,请求依然可以被正常处理,因为它还没有被真正销毁
1 apiVersion: extensions/v1beta1 2 kind: Deployment 3 metadata: 4 name: nginx 5 spec: 6 replicas: 1 7 selector: 8 matchLabels: 9 component: nginx 10 template: 11 metadata: 12 labels: 13 component: nginx 14 spec: 15 containers: 16 - name: nginx 17 image: "nginx" 18 ports: 19 - name: http 20 hostPort: 80 21 containerPort: 80 22 protocol: TCP 23 readinessProbe: 24 httpGet: 25 path: /healthz 26 port: 80 27 httpHeaders: 28 - name: X-Custom-Header 29 value: Awesome 30 initialDelaySeconds: 15 31 timeoutSeconds: 1 32 lifecycle: 33 preStop: 34 exec: 35 command: ["/bin/bash", "-c", "sleep 30"]
2. Kubernetes中Service、Ingress与Ingress Controller的作用与关系
- Service 是后端真实服务的抽象,一个 Service 可以代表多个相同的后端服务
- Ingress 是反向代理规则,用来规定 HTTP/S 请求应该被转发到哪个 Service 上,比如根据请求中不同的 Host 和 url 路径让请求落到不同的 Service 上
- Ingress Controller 就是一个反向代理程序,它负责解析 Ingress 的反向代理规则,如果 Ingress 有增删改的变动,所有的 Ingress Controller 都会及时更新自己相应的转发规则,当 Ingress Controller 收到请求后就会根据这些规则将请求转发到对应的 Service。
Kubernetes 并没有自带 Ingress Controller,它只是一种标准,具体实现有多种,需要自己单独安装,常用的是 Nginx Ingress Controller 和 Traefik Ingress Controller。 所以 Ingress 是一种转发规则的抽象,Ingress Controller 的实现需要根据这些 Ingress 规则来将请求转发到对应的 Service,我画了个图方便大家理解: