为了提升系统核心服务的问题性,避免由于K8S网络导致服务间调用的稳定性。目前将系统核心服务的部署方式从Pod Network切换到了Host Network。 Host Network限制了Pod的部署数量,最大情况下只能和主机数量保持一致。因此需要在Deployment中设置一些反亲和性的调度策略。 确保Pod不会被反复注册到相同主机上。
Spring Cloud中每个实例启动时都会产生一个唯一的InstanceID,并且通过InstanceID向Consul中进行注册。不同的InstanceID对于Consul而言就代表着不同的服务实例。但是由于目前将Pod网络方式设置成为了HostNetwork。因此只要是相同主机上启动的服务,其访问地址一定是相同的。 但是反复启动时,Spring Cloud注册会生成不同的InstanceID。 这些对于COnsul而言不同的Instance。 实际指向了一个相同的Pod网络。 在应用反复升级/部署之后,会发现Consul中存在大量的服务实例,而这些服务实例指向的地址都是相同的。对于这些服务Consul会定期调用Health Check去检查服务可用性。 大量的检查项导致Consul性能下降。为此需要一个简单的解决方案,确保在相同主机上运行的Pod实例,在部署/重启/升级后的InstanceID保持一致。
一个简单的方案就是在InstanceID中取出随机值,并且使用当前Pod的IP地址作为标识,例如: service-192-168-1-2。 这种方式可以确保Pod在默认容器网络或者Host网络下可以保持一致的行为。
1 | apiVersion: v1 |
这里通过将当前Pod的IP地址注入到容器实例的环境变量变量中,并且覆盖默认的–spring.cloud.consul.discover.instanceId来确保注册到Consul中的ServieID唯一。
除了podIP以外,K8S还支持从spec,metadata中获取Pod相关的信息:
1 | env: |