最近关于EurekaServer、EurekaClient以及Ingress的一些使用心得
要点
最近工作中对EurekaServer、EurekaClient、Ingress又做了一些优化,主要分一下几个场景:
1、集群中存在大量NodePort,项目早期比较偷懒所以就用这个方式,导致通信矩阵复杂,管理麻烦,如何解决?
2、EurekaServer上实例注册后,此时请求SpringBoot服务请求超时/失败,要过一会儿才能好,怎么办?
3、EurekaClient配置的prefer-ip-address明明是false,为何在EurekaServer的apps接口查询仍然看到hostName是ip地址而不是主机名?
针对以上三个场景做了一些调研,包括过程中识别到的一些问题,本文做个总结。
使用Ingress的方式替代NodePort,同时支持IP白名单
原来集群的NodePort,本质上是服务通过iptable对外暴露,这个暴露的过程是通过k8s的kube-proxy实现,为了集中对NodePort进行管理,那么就需要所有通过NodePort的请求具备统一的特征,同时增加一个ingress,在ingress中配置nginx的路由规则,将匹配这个规则的请求直接转发到K8S对应的svc,而不是转发给默认的(backend)网关。经过调查,ingress也可以直接配置ip-white-list,这样也就能和NodePort开防火墙一样做到安全隔离。
下面是一个支持固定路由规则同时支持ip-white-list配置:
apiVersion: extendsions/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/whitelist-source-range: 'xx.xx.xx.xx/32'
name: node-port-ingress
namespaces: xxxx
spec:
rules:
- http:
paths:
- backend:
serviceName: usermgt
servicePort: 8080
path: /usermgt/nodeport/(/|$)(.*)
每次配置ingress都非常痛苦,本身没有对nginx做过太多的了解,ingress的配置实际上是被ingress-controller翻译成了nginx的配置,支持热加载,所以对nginx的配置不熟悉的话,就会非常费劲,网上对ingress-controller的配置方法也不是很系统,至少我暂时没找到。
说一下我理解的rewrite-target: /$2参数含义,这个$2是一个通配符,是指在下面配置的rules里匹配的对应(.*),所以rewrite到了去除所有前缀的route,比如你原本的请求是
http://www.baidu.com:30011/usermgt/getuser
你希望不用30011了,而是直接用80到ingress,所以你的请求将会是
http://www.baidu.com/usermgt/nodeport/getuser
那么经过匹配后,你的请求将会被重定向到
http://usermgt/getuser
域名没有了的原因是ingress转发的时候是直接发给你配置的serviceName: usermgt,此时相当于请求直接由集群内通过svc转发,走的是kube-dns,而上面的通配符$2的作用就是获取你真正有用的/getuser接口名,而whitelist-source-range的配置就比较简单了,可以写固定ip或ip端,注意ip掩码的控制就行。
上次处理ingress的时候就很费劲,这次和上次一样,最后搞不清楚的时候,还是要进入ingress-controller的pod里去看实际的nginx配置,通过比对最后排除错误,麻烦。
理解EurekaClient的心跳机制并让healthCheck生效
之前对EurekaServer上instance的状态更新有个误区,认为只要是EurekaClient定时上报心跳,就能在EurekaServer上看到对应的UP状态可用instance,然而通过这次实践发现并非如此,几个配置先理解一下:
eureka.client.healthcheck.enabled = true
是否生效EurekaClient的健康检查,单一理解这个配置项会很坑,首先就算你配置成true,EurekaClient还是会每次上报UP状态,因为本身这个属性是直接作用于actuator组件的,组件内只是提供了用以实现自定义健康检查的接口,并没有真正对健康检查状态进行定义,下面看一个例子(来源:https://blog.csdn.net/zhizhuodewo6/article/details/81985787)。
package com.example.eurekaclientconsumerribbon.health;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;
@Component
public class MyHealthChecker implements HealthIndicator {
private boolean up = true;
@Override
public Health