Istio: upstream connect error or disconnect/reset before header

本文记录了在Kubernetes集群中使用Istio时遇到的网络连接问题,具体表现为访问productpage服务时出现连接错误。通过调整日志级别,发现Envoy在尝试访问istio-policy和istio-telemetry服务时超时。最终问题定位为iptables FORWARD策略设置为DROP,导致容器间通信失败。通过修改iptables策略为ACCEPT,网络问题得以解决。

按照官方文档跑 bookinfo 例子,访问 productpage 的时候提示: upstream connect error or disconnect/reset before header

通过命令查看 productpage 的 istio proxy 的日志,日志都是 info 级别,通过调整 level 可以查看到更多 Envoy 的详细日志,打开方式可以通过 port-forward 来访问:

kubectl port-forward productpage-v1-6c5578cc4-z8dgq 15000:15000

curl 命令强制开启 trace 日志:

curl -X POST 127.0.0.1:15000/logging?level=trace

在此访问 productpage 页面,并查看 istio proxy 的日志,可以发现如下错误:

[2018-10-07 15:00:51.379][29][debug][router] external/envoy/source/common/router/router.cc:252] [C0][S13874950066935357807] cluster 'outbound|9091||istio-telemetry.istio-system.svc.cluster.local' match for URL '/istio.mixer.v1.Mixer/Report'                                                                    
[2018-10-07 15:00:51.379][29][debug][router] external/envoy/source/common/router/router.cc:303] [C0][S13874950066935357807] router decoding headers:      
':method', 'POST'                                                                                                                                         
':path', '/istio.mixer.v1.Mixer/Report'                                                                                                                   
':authority', 'mixer'                                                                                                                                     
':scheme', 'http'                                                                                                                                         
'te', 'trailers'                                                                                                                                          
'grpc-timeout', '5000m'                                                                                                                                   
'content-type', 'application/grpc'                                                                                                                        
'x-istio-attributes', 'CkMKCnNvdXJjZS51aWQSNRIza3ViZXJuZXRlczovL3Byb2R1Y3RwYWdlLXYxLTZjNTU3OGNjNC16OGRncS5kZWZhdWx0'                                      
'x-envoy-internal', 'true'                                                                                                                                
'x-forwarded-for', '10.1.1.100'                                                                                                                           
'x-envoy-expected-rq-timeout-ms', '5000'                                                                                                                  
                                                                                                                                                          
[2018-10-07 15:00:51.379][29][debug][client] external/envoy/source/common/http/codec_client.cc:25] [C67] connecting                                       
[2018-10-07 15:00:51.379][29][debug][connection] external/envoy/source/common/network/connection_impl.cc:572] [C67] connecting to 10.1.1.59:9091  

并且提示 timeout:

[2018-10-07 15:00:52.382][29][debug][pool] external/envoy/source/common/http/http2/conn_pool.cc:174] [C67] connect timeout   

并且通过查看 Envoy 的配置(通过 curl 10.1.1.100:15000/config_dump 获取):

         "http_filters": [                                                                                                                              
            {                                                                                                                                             
             "name": "mixer",                                                                                                                             
             "config": {                                                                                                                                  
              "transport": {                                                                                                                              
               "check_cluster": "outbound|9091||istio-policy.istio-system.svc.cluster.local",                                                             
               "network_fail_policy": {                                                                                                                   
                "policy": "FAIL_CLOSE"                                                                                                                    
               },                                                                                                                                         
               "report_cluster": "outbound|9091||istio-telemetry.istio-system.svc.cluster.local",                                                         
               "attributes_for_mixer_proxy": {                                                                                                            
                "attributes": {                                                                                                                           
                 "source.uid": {                                                                                                                          
                  "string_value": "kubernetes://productpage-v1-6c5578cc4-z8dgq.default"                                                                   
                 }                                                                                                                                        
                }                                                                                                                                         
               }                                                                                                                                          
              },                                                                                                                                          
              "service_configs": {                                                                                                                        
               "default": {}                                                                                                                              
              },                                                                                                                                          
              "default_destination_service": "default",                                                                                                   
              "mixer_attributes": {                                                                                                                       
               "attributes": {                                                                                                                            
                "destination.port": {                                                                                                                     
                 "int64_value": "9080"                                                                                                                    
                },                                                                                                                                        
                "context.reporter.uid": {                                                                                                                 
                 "string_value": "kubernetes://productpage-v1-6c5578cc4-z8dgq.default"                                                                    
                },                                                                                                                                        
                "destination.namespace": {                                                                                                                
                 "string_value": "default"                                                                                                                
                },                                                                                                                                        
                "destination.ip": {                                                                                                                       
                 "bytes_value": "AAAAAAAAAAAAAP//CgEBZA=="                                                                                                
                },                                                                                                                                        
                "destination.uid": {                                                                                                                      
                 "string_value": "kubernetes://productpage-v1-6c5578cc4-z8dgq.default"        

根据 listener 的 filter 和日志可以判断出,Envoy 再访问 istio-policyistio-telemetry 的时候超时,通过 kubectl exec -it 登录到 istio-policyistio-telemetry 容器里面查看 ip ,也验证 10.1.1.59 是容器 ip,再 productpageistio-proxy 容器里无法访问到 istio-policy 的容器 ip,而直接 ping istio-policy.istio-system.svc.cluster.local 得到的 ip 却是 10.152.183.219 ,令人费解。

初步推断是 networking 出问题了。

可以查看 bridge

sudo brctl show

可以看到信息:

bridge name     bridge id               STP enabled     interfaces
cbr0            8000.c64875066a1c       no              veth019bd18c
                                                        veth1c0d2c9b
                                                        veth1c61c1f5
                                                        veth354f63c2
                                                        veth3dcf1b58
                                                        veth5e48d40c
                                                        veth5ecef8bd
                                                        veth64c402e3
                                                        veth6cdd40a2
                                                        veth734c71a0
                                                        veth83002aa8
                                                        veth84f9ea9e
                                                        veth89b6dca2
                                                        veth9a2e7811
                                                        vetha39fd5f9
                                                        vethaa60e8e9
                                                        vethb049a2ee
                                                        vethb1790152
                                                        vethbcfdb892
                                                        vethcb714c1d
                                                        vethce18a83b
                                                        vethcee858ed
                                                        vethd59ca64b
                                                        vethe7e21373
docker0         8000.02428d87c40c       no

cbr0 是存在的,基本说明是 bridge 出问题了,搜索 syslog

grep -i cni /var/log/syslog

可以看到错误信息:

Oct  9 07:36:27 pzhang microk8s.daemon-kubelet[27091]: W1009 07:36:27.967830   27091 cni.go:188] Unable to update cni config: No networks found in /etc/cni/net.d
Oct  9 07:36:33 pzhang microk8s.daemon-kubelet[27299]: W1009 07:36:33.291419   27299 cni.go:188] Unable to update cni config: No networks found in /etc/cni/net.d

所以需要解决为什么 microk8snetwork-plugin 出问题,需要继续 Google …

Google 到官方文档: https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/ kubenet 并不会创建 CNI ,所以上面的 warning 无关紧要。

通过 sudo nsenter -p <container-pid> -n ping 10.1.1.53 在一个 container 去 ping 另外一个 container 是不通的,通过 tcpdump 也只能看到信息: 1412 14:27:46.087292 10.1.1.50 10.1.1.53 ICMP 98 Echo (ping) request id=0x3ed4, seq=29/7424, ttl=64 (no response found!)

最后要给 microk8s 提交 issue 的时候,被告知要提交 microk8s.inspect 的结果,出现警告:

WARNING:  IPtables FORWARD policy is DROP. Consider enabling traffic forwarding with: sudo iptables -P FORWARD ACCEPT

执行 iptables -L

Chain FORWARD (policy DROP)                                                                                                                               
target     prot opt source               destination                                                                                                      
DOCKER-ISOLATION  all  --  anywhere             anywhere                                                                                                  
DOCKER     all  --  anywhere             anywhere                                                                                                         
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED                                                                 
ACCEPT     all  --  anywhere             anywhere                                                                                                         
ACCEPT     all  --  anywhere             anywhere                                                                                                         
DOCKER-USER  all  --  anywhere             anywher

执行 sudo iptables -P FORWARD ACCEPT 打开 FORWARD 后,网络就一切 OK 了。

估计因为安装的是 ubuntu-server 版本,默认 iptables 开启了防火墙规则,以后碰到网路问题多注意 iptables

解决 “upstream connect error or disconnect/reset before headers” 错误的方法因不同的错误原因而有所不同,以下是几种常见原因及对应的解决办法: - **TLS 证书验证失败**:当出现 “TLS error:268435581:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED” 时,可能是由于证书验证失败。需排查证书配置、有效期以及证书链是否正确,更新或配置有效的证书来解决此问题[^1]。 - **微服务升级时容器未就绪**:在使用 Istio 升级微服务时,Kubernetes 可能会在真正的微服务容器还未启动时就将流量引入 Pod,导致 istio - proxy 返回 503 错误。解决办法是对 Pod 中其他容器加上 readinessProbe(就绪探针),使得 Kubernetes 确认容器准备就绪后再进行流量转发。可参考如下示例在 Pod 模板中添加: ```yaml livenessProbe: httpGet: path: /healthz port: 80 httpHeaders: initialDelaySeconds: 10 periodSeconds: 3 ``` 就绪探针的详细参考:https://k8smeetup.github.io/docs/tasks/configure - pod - container/configure - liveness - readiness - probes/ [^2]。 - **请求和返回的协议版本不一致**:若 “reset reason: protocol error”,可能是请求和返回的协议版本不一致导致的。需检查并确保请求和返回使用的协议版本一致,可参考以下代码优化: ```java public void getSSOIcon(HttpServletResponse response){ String api = "xxx"; ResponseEntity<byte[]> responseEntity = restTemplate.exchange( api, HttpMethod.GET, null, byte[].class ); try { HttpHeaders headers = responseEntity.getHeaders(); response.setContentType(Objects.requireNonNull(headers.getContentType()).getType()); response.setContentLength((int) headers.getContentLength()); response.getOutputStream().write(Objects.requireNonNull(responseEntity.getBody())); } catch (IOException e) { log.error("获取头像异常",e); } } ``` [^3]。 - **协议解析错误**:若将 svc 的 ports 的 name 错误配置,导致 k8s 协议解析错误,如后端是 socket 协议却被解析为 http 协议,会出现 400 错误。解决办法是将 svc 的 ports 的 name 改回正确配置,并重启服务[^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值