k8s加速部署-来自同一Pod的CSS

时间:2019-06-04 06:18:43

标签: kubernetes continuous-deployment

我有一个webapp在2个Pod上的Kubernetes上运行。

我使用从webapp:v1webapp:v2的新映像版本编辑部署。

我认为在推广过程中存在问题...

podA is v2
podB is still v1

html is served from podA
with a <link> to styles.css

styles.css is served from podB
with v1 styles

=> html v2 + css v1 = ?

如何保证所有后续请求都可以从同一pod或与html服务版本相同的pod进行?

4 个答案:

答案 0 :(得分:4)

  

如何保证所有后续请求都可以从同一pod或与html服务版本相同的pod进行?

即使执行此操作,仍然会遇到问题。特别是如果您的应用程序是单页应用程序。考虑一下:

  • 用户进入您的网站,获得index.html v1
  • 您发布了webapp:v2。几分钟后,所有Pod都在运行v2。
  • 用户仍使用index.html v1打开网络应用
  • 用户在应用中导航。这需要加载styles.css。用户获得styles.css v2。繁荣,您在混合版本,失败。

我在生产中遇到了这个问题,解决起来很痛苦。以我的经验,最好的解决方案是:

  • 使用版本后缀(例如styles.css-> styles-v1.css或文件内容styles-39cf1a0b.css的哈希)标记所有资源(css,js,imgs等)。许多工具(例如webpack,gulp等)都可以自动执行此操作。
  • index.html未标记,但确实引用了带有正确标记的其他资源。
  • 在部署时,请勿删除旧版本的资源,只需将它们与最新版本合并即可。确保拥有旧index.html的客户仍然可以成功获得他们。
  • 经过一段时间或更长时间之后(可能是1周?),请删除一些或更旧的资源。

有了这个,上面的方案现在可以正常工作了!

  • 用户进入您的网站,获得index.html v1
  • 您发布了webapp:v2。这将替换index.html,但将所有js / css保留在原处,并添加带有新版本后缀的新js / css。
  • 用户仍使用index.html v1打开网络应用
  • 用户在应用中导航。这需要加载styles-v1.css,该加载成功且与index.html版本匹配。没有版本混合=很好!
  • 下次用户重新加载页面时,他们将获得index.html v2,该v2指向新的styles-v2.css,依此类推。仍然没有版本混用!

使用kubernetes进行操作有点棘手,您需要使映像构建过程从一些较旧的映像中获取文件并将它们包含在新映像中,这有点奇怪。

另一种解决方案是停止从Pod提供您的html / css / js,而改为从Blob存储提供它。 (Amazon S3,Google Cloud Storage等)。这样,部署只需复制所有文件,这些文件将与旧文件合并,从而为您提供所需的行为。

答案 1 :(得分:3)

这似乎不是滚动升级的材料。 kubernetes无法自行解决此问题(假设它是最纯粹的最小形式)。

也就是说,例如,如果您使用nginx入口控制器,则可以查看https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/nginx-configuration/annotations.md#session-affinity,以使用户尽可能地保持在同一上游。

答案 2 :(得分:3)

这是有关部署更新策略的不错的article,您可以考虑使用Blue / Green部署,而不是Ramped。

升级速度缓慢,使用新映像修补部署后将创建新的副本集,直到达到所需的副本数,它会缓慢终止旧的replists pod,那么正常的话,您可以使用此功能版本问题,同时滚动更新。

蓝色/绿色,与渐进策略不同,一旦确认新版本正常,将更改“新版本服务”。 Here您可以找到此策略的示例部署

希望有帮助!

答案 3 :(得分:3)

感觉您的问题与label and selectors有关……您描述的行为不太可能(除非选择器本身无法满足您的需求)。

让我们以这个流程为例(在该说明中,入口是一次性的,只是为了说明它对应用程序的访问):

Ingress -> Service -> [endpoints] -> Pods

  1. 入口将路由到已定义的服务;
  2. 该服务具有类型和选择器,这是generate the endpoint的规则,该规则基于要路由请求的pod上的标签;
  3. 该端点将代表您的Pod的内部IP地址。

在第2项中,如果您只是为包含app: webapp的广告连播添加新标签,那么我认为您正在使用两个版本(例如version)上存在的标签的选择器,那么您可以将服务更改为仅选择指定版本(version: v1 || version: v2)上的广告连播,这样就不会再报告不一致的情况了。