目录

  • 一、问题
  • 二、Istio 1.7及其之后版本的解决方案
    • 2.1 方式1:安装Istio时全局设置
    • 2.2 方式2:在应用Deployment通过annotation设置
    • 2.3 holdApplicationUntilProxyStarts启用效果
  • 三、Istio 1.7之前的解决方案

一、问题

线上应用集成了Spring Cloud K8S Config模块,在应用启动时会读取K8S ConfigMap作为配置,最近观察到线上应用在启动时报如下异常日志(偶发,并不是一直出现),提示应用无法获取K8S ConfigMap配置,并且K8s ConfigMap中的配置也没有实际生效。

2023-02-28 11:18:16.950+0800 [main] WARN  o.s.c.k.f.c.Fabric8ConfigMapPropertySource -
`Can't read configMap with name: [my-app] in namespace: [my-app-ns]. Ignoring.`
io.fabric8.kubernetes.client.KubernetesClientException:
`Operation: [get]  for kind: [ConfigMap]  with name: [my-app]  in namespace: [my-app-ns]  failed`.
...
Caused by: java.net.ConnectException: `Failed to connect to /10.96.0.1:443`at okhttp3.internal.connection.RealConnection.connectSocket(RealConnection.kt:297)
...
Caused by: java.net.ConnectException: `Connection refused (Connection refused)`at java.base/java.net.PlainSocketImpl.socketConnect(Native Method)at java.base/java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
...

在排除了K8S RBAC权限配置问题、K8S集群网络问题后,最终注意到该后端应用部署时集成了Istio,也即自动注入了Istio Sidecar。
由于pod内容器按照spec.containers中的声明顺序依次启动,而initContainers会在所有容器启动前执行,故容器的启动顺序如下:

#mermaid-svg-YqCjdQ18yU6qjpHq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-YqCjdQ18yU6qjpHq .error-icon{fill:#552222;}#mermaid-svg-YqCjdQ18yU6qjpHq .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-YqCjdQ18yU6qjpHq .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-YqCjdQ18yU6qjpHq .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-YqCjdQ18yU6qjpHq .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-YqCjdQ18yU6qjpHq .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-YqCjdQ18yU6qjpHq .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-YqCjdQ18yU6qjpHq .marker{fill:#333333;stroke:#333333;}#mermaid-svg-YqCjdQ18yU6qjpHq .marker.cross{stroke:#333333;}#mermaid-svg-YqCjdQ18yU6qjpHq svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-YqCjdQ18yU6qjpHq .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-YqCjdQ18yU6qjpHq .cluster-label text{fill:#333;}#mermaid-svg-YqCjdQ18yU6qjpHq .cluster-label span{color:#333;}#mermaid-svg-YqCjdQ18yU6qjpHq .label text,#mermaid-svg-YqCjdQ18yU6qjpHq span{fill:#333;color:#333;}#mermaid-svg-YqCjdQ18yU6qjpHq .node rect,#mermaid-svg-YqCjdQ18yU6qjpHq .node circle,#mermaid-svg-YqCjdQ18yU6qjpHq .node ellipse,#mermaid-svg-YqCjdQ18yU6qjpHq .node polygon,#mermaid-svg-YqCjdQ18yU6qjpHq .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-YqCjdQ18yU6qjpHq .node .label{text-align:center;}#mermaid-svg-YqCjdQ18yU6qjpHq .node.clickable{cursor:pointer;}#mermaid-svg-YqCjdQ18yU6qjpHq .arrowheadPath{fill:#333333;}#mermaid-svg-YqCjdQ18yU6qjpHq .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-YqCjdQ18yU6qjpHq .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-YqCjdQ18yU6qjpHq .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-YqCjdQ18yU6qjpHq .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-YqCjdQ18yU6qjpHq .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-YqCjdQ18yU6qjpHq .cluster text{fill:#333;}#mermaid-svg-YqCjdQ18yU6qjpHq .cluster span{color:#333;}#mermaid-svg-YqCjdQ18yU6qjpHq div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-YqCjdQ18yU6qjpHq :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

istio-init
app
istio-proxy

即istio-init修改pod内iptables令istio-proxy接管pod内所有流量(令app内的所有网络请求都需要经过istio-proxy),而app启动的过程中若发起网络请求,此时istio-proxy有可能还没有启动完成,导致网络异常。
也即是应用读取K8S ConfigMap时,istio-proxy还没启动完成导致网络连接被拒绝。
以上问题的解决方案就是使应用容器在istio-proxy启动成功后再启动,如此便可避免网络异常问题。

二、Istio 1.7及其之后版本的解决方案

在istio 1.7的change notes中宣布支持values.global.proxy.holdApplicationUntilProxyStarts配置选项以支持设置sidecar优先启动,
values.global.proxy.holdApplicationUntilProxyStarts默认关闭,可通过如下设置开启:

--set values.global.proxy.holdApplicationUntilProxyStarts=true

2.1 方式1:安装Istio时全局设置

# 默认使用default profile(可通过--set profile=default|demo|...调整)
istioctl install
# 设置sidecar优先启动(且sidecar启动成功后再启动其他应用容器) - 1.7新特性
--set values.global.proxy.holdApplicationUntilProxyStarts=true

2.2 方式2:在应用Deployment通过annotation设置

注:
此种方式暂未实际测试,暂无Istio 1.7+环境,根据Istio官方文档整理而来,
具体Istio官方文档说明参见:
https://istio.io/latest/docs/reference/config/istio.mesh.v1alpha1/#ProxyConfig

核心annotations如下:

annotations:# 重点:配置proxy - 设置proxy启动成功后再启动其他应用proxy.istio.io/config: |holdApplicationUntilProxyStarts: true

具体设置如下:

apiVersion: apps/v1
kind: Deployment
metadata:name: my-applabels:app: my-appversion: v1
spec:selector:matchLabels:app: my-appversion: v1replicas: 1template:metadata:labels:app: my-appversion: v1annotations:# 开启Istio Sidecar自动注入sidecar.istio.io/inject: true# 重点:配置proxy - 设置proxy启动成功后再启动其他应用proxy.istio.io/config: |holdApplicationUntilProxyStarts: truespec:containers:- name: appimage: registry/app:latestports:- name: http-portcontainerPort: 8080protocol: TCP

2.3 holdApplicationUntilProxyStarts启用效果

启用holdApplicationUntilProxyStarts为true,实际效果如下:
(1)将sidecar istio-proxy容器放到pod containers中的第一位(即最先启动);

(2)设置istio-proxy lifecycle已保证sidecar容器启动成功前一直阻塞(阻塞pod内其他容器启动);

三、Istio 1.7之前的解决方案

Istio 1.7之前的版本并未提供holdApplicationUntilProxyStarts配置,可结合K8S lifecycle达到同样目的,
即阻塞应用容器,使应用容器监听istio-proxy启动端口,若监听istio-proxy启动端口不通,则重启应用容器(直到istio-proxy启动就绪)。
具体说明可参见:https://github.com/istio/istio/issues/11130#issuecomment-506659562

核心配置如下:

# 注:此处配置需结合Istio Sidecar注入一起使用,若未开启Istio Sidecar,则移除此配置
lifecycle:postStart:httpGet:path: /healthz/readyport: 15020scheme: HTTP

具体设置如下:

apiVersion: apps/v1
kind: Deployment
metadata:name: my-applabels:app: my-appversion: v1
spec:selector:matchLabels:app: my-appversion: v1replicas: 1template:metadata:labels:app: my-appversion: v1annotations:# 开启Istio Sidecar自动注入sidecar.istio.io/inject: truespec:containers:- name: appimage: registry/app:latestports:- name: http-portcontainerPort: 8080protocol: TCP# 阻塞app容器,使app容器监听sidecar启动端口,若监听sidecar启动端口不通,则重启app容器(直到sidecar启动就绪)lifecycle:postStart:httpGet:path: /healthz/readyport: 15020

实际部署时,可以观察到之前无法读取K8S ConfigMap的日志也会出现,出现此日志则说明Istio Sidecar还未启动成功(网络不通),之后K8S会重启应用容器,再次观察日志则读取K8S ConfigMap成功(无报错日志)。如此通过让应用容器监听Istio Sidecar Readiness Probe,以迫使应用容器在Istio Sidecar未启动成功前反复重启应用容器自身,以保证最终应用容器启动后Istio Sidecar已经启动完成。


参考:
控制pod内container执行顺序的几种姿势
Istio 1.7 是如何保证sidecar的启动顺序的
Github - issues - App container unable to connect to network before sidecar is fully running #11130

Istio Sidecar启动顺序 - 导致的应用容器网络不通相关推荐

  1. Kubernetes 上容器的启动顺序如何把控?

    作者 | AddoZhang       责编 | 欧阳姝黎 为什么要做容器启动顺序控制?我们都知道 Pod 中除了 init-container 之外,是允许添加多个容器的.类似 TektonCD ...

  2. docker开放的端口_docker-5-解决宿主机没有开放81端口却可以直接访问docker启动的81端口nginx容器的问题...

    我以为经过前面四篇博文的学习,自己对docker的了解最起码入门了,但是当我用docker启动一个81端口的nginx后(宿主机:容器/81:80),在宿主机的firwall防火墙没有添加81端口的情 ...

  3. 服务网格规模化应用下的Istio Sidecar配置管理挑战与实践|IstioCon 2022

    服务网格是服务间通信的基础设施层, 服务网格 Istio 近期已经宣布了加入云原生计算基金会(CNCF)的意向,今后会得到更多开发者的信任和应用.阿里云内部很早就开始调研并实践 ServiceMesh ...

  4. 虚拟服务器启动顺序,认识VPC2007的虚拟机系统启动顺序

    如果在VPC2007下虚拟机启动时候按下DEL键,可以进入虚拟机BIOS,修改系统的启动顺序.Virtual PC 2007 BIOS支持系统启动顺序的调整.如果其中一种方式启动失败,会自动进入下一种 ...

  5. 【Oracle】RAC11gR2Grid启动顺序及启动故障诊断思路

    转自:https://www.2cto.com/database/201605/507269.html 图片来自:https://blog.csdn.net/zwjzqqb/article/detai ...

  6. ASP.NET Core 3.x控制IHostedService启动顺序浅探

    想写好中间件,这是基础.   一.前言 今天这个内容,基于于ASP.NET Core 3.x. 从3.x开始,ASP.NET Core使用了通用主机模式.它将WebHostBuilder放到了通用的I ...

  7. linux 修改hba参数,更改Raid卡和HBA卡在linux下的启动顺序

    更改Raid卡和HBA卡在linux下的启动顺序 发布时间:2006-01-11 10:13:07来源:红联作者:新新 当server安装好RHEL3系统以后,如果又添加了HBA卡,准备连接光纤存储的 ...

  8. Docker系列教程26-Docker Compose控制服务启动顺序

    为什么80%的码农都做不了架构师?>>>    原文:http://www.itmuch.com/docker/26-docker-compose-controller-startu ...

  9. citra 图形设置_bios怎么设置硬盘启动顺序 bios设置硬盘启动方法

    电脑在启动的时候,会从硬盘中寻找引导文件从而启动系统,如果果硬盘不是第一启动项,或者有两个硬盘的话就会导致系统无法启动,那么就需要进入bios设置硬盘启动顺序,该怎么操作呢,本文就给大家讲解一下bio ...

最新文章

  1. PHP: How to print a debug log?
  2. bzoj4429: [Nwerc2015] Elementary Math小学数学
  3. mysql当前用户user()与current_user()
  4. 在Python中操纵json数据的最佳方式
  5. SAP ABAP实用技巧介绍系列之Debug XSLT transformation
  6. oracle之数据处理之约束2
  7. SQL取最大值编码(自动编码)
  8. ECCV 2020 谷歌论文盘点—Poster 篇
  9. 新加坡科技设计大学招收全奖博士,以及Research Assistant/Postdoc
  10. JAVA学习笔记-this隐式参数
  11. MySQL进阶之SQL优化
  12. Leetcode: Pascal's Triangle II
  13. (2016弱校联盟十一专场10.2) E.Coins
  14. Facebook KeyHash生成方法
  15. 工程伦理2021秋期末考答案|网课期末考答案|学堂在线|清华大学李正风教授
  16. EXCEL VBA 入门与实用例子
  17. 全链路日志追踪系统介绍与思考
  18. 【存档】双向可控硅的工作原理
  19. 2022-01-05 网工基础(十九)NAT基本原理与配置
  20. 重点推荐:看乾隆“上书房”求学记,哈哈

热门文章

  1. 基于JAVA动漫论坛系统计算机毕业设计源码+数据库+lw文档+系统+部署
  2. 福昕阅读器无法注释与高亮
  3. RK3568移植AP6256
  4. SAP部分支付和剩余支付清账的区别剩余支付清账时不影响账龄的配置
  5. 电脑突然无法拖动文件
  6. DataGridView 选中行
  7. 【一步一个脚印】Tomcat+MySQL为自己的APP打造服务器(2-1)Servlet的使用
  8. chm文件打开后,只能看到目录,不显示内容解决方法
  9. Dynamo_在Revit参数间复制数据
  10. three.js使用CubeCamera创建反光效果,动态环境贴图实现,立方体全景贴图(vue中使用three.js83)