docker - Kubernetes 服务选择器更改不会对连接的客户端生效
问题描述
我想在部署过程中显示在 Kubernetes 下运行的应用程序的维护页面,在这个“维护”窗口中,我备份数据库,然后应用架构更改,然后部署新版本。
我想也许我可以做的是更改服务选择器,以便它指向一个 nginx 容器,在部署过程中提供一个简单的维护页面。部署成功后,我将切换回选择器以指向执行实际工作的 pod。
我的问题是,除非我关闭并重新打开当前正在查看该站点的浏览器,否则我永远看不到维护页面;我猜浏览器保持连接打开。公共服务地址在整个过程中不会改变。
我正在使用一种类型的 NodePort 在 Docker Kubernetes 安装上进行本地测试。
关于如何让它工作的任何想法,还是我用这种方法鞭打一匹死马?
问候李
解决方案
发生这种情况是由于浏览器和 k8s 服务的工作方式相结合。
浏览器缓存到服务器的 TCP 连接:当请求一个页面时,它们将保持 TCP 连接打开,如果用户稍后从同一个域请求更多页面,浏览器将重用已经打开的 TCP 连接以节省时间。
k8s 服务负载均衡运行在 TCP 层。当接收到一个新的 TCP 连接时,它会从 Service 分配给一个 pod,并在整个 TCP 连接的生命周期内一直与该 pod 通信。
所以,问题是你的浏览器保持 TCP 连接对你的旧 pod 开放,即使你修改了服务。
我们如何解决这个问题?
非解决方案#1:让浏览器不缓存连接。据我所知,没有办法做到这一点,而且你也不想要它,因为它会使你的网站变慢。此外,HTTP 缓存标头对此没有影响。浏览器总是缓存 TCP 连接。无缓存标头将使浏览器再次请求页面,但通过已经打开的连接。
非解决方案#2:在更新服务时让 k8s 终止 TCP 连接。这是不可能的,也是不可取的,因为这种行为是使“正常关闭/请求耗尽”部署策略起作用的原因。见问题。
解决方案 #1:使用第 7 层 (HTTP) 负载平衡而不是第 4 层 (TCP) 负载平衡,例如nginx-ingress。L7 负载平衡将流量路由到“每个 HTTP 请求”而不是“每个 TCP 连接”的 pod,因此即使浏览器保持 TCP 连接打开,您也不会遇到此问题。
解决方案 #2:从您的应用程序而不是 k8s 执行此操作。例如,有一个“in-maintenance”数据库标志,在每个请求上检查它,如果它被设置,则提供维护页面。
推荐阅读
- c# - C#将逗号分隔的字符串转换为动态类型
- python - 将多个 2D DataFrame 转换为一个 3D DataFrame
- c++ - 使用 valgrind 检查我的链表实现中的内存泄漏,让我“肯定丢失:1 个块中的 40 个字节”
- python - python如何为字符串“sample”分配唯一的内存地址?当每个字符存储在不同的位置时
- c# - 如何为调用其他服务的方法编写单元测试
- ruby - 在字符串的特定部分添加字符串
- python - 使用适用于 Windows Kivy-Python 应用程序的 Azure 凭据登录
- linux - 调度程序是否可以通过`sched_setaffinity`自动将亲和性已设置为非常繁忙的cpu的线程迁移到空闲的cpu?
- node.js - 在 JavaScript 中执行存储过程以插入雪花错误
- kotlin - 防止在使用导航组件时重新创建片段