Istio开启mtls请求503问题分析

WenDangXia
• 阅读 1701

背景

为测试Istio流量管理,将两个服务sleep、flaskapp的两个版本v1、v2(部署文件见参考链接)部署到Istio环境中,通过sleep-v1向flaskapp发起调用http://flaskapp/env/version,正常结果会交替打印出结果v1和v2,然而在调用过程中报错503 reset reason: connection failure,故将问题的步骤、现象、分析、验证整理于此。

步骤

部署sleep、flaskapp应用,同时Istio平台开启mTls,命名空间kangxzh开启自动注入,部署如下图所示:

kubectl apply -f sleep.istio.yaml -n kangxzh
kubectl apply -f flask.isito.yaml -n kangxzh

#查看pod创建情况
kubectl -n kangxzh get pod -w

flaskapp-v1-775dbb9b79-z54fj   2/2     Running           0          13s
flaskapp-v2-d454cdd47-mdb8s    2/2     Running           0          14s
sleep-v1-7f45c6cf94-zgdsf      2/2     Running           0          19h
sleep-v2-58dff94b49-fz6sj      2/2     Running           0          19h 


现象

在sleep应用中发起http请求,调用flaskapp,curl http://flaskapp/env/version,如下所示:

#
export SOURCE_POD=$(kubectl get pod -l app=sleep,version=v1 -o jsonpath={.items..metadata.name})
# 进入sleep发起http请求
kubectl -n kangxzh exec -it -c sleep $SOURCE_POD bash
bash-4.4# curl http://flaskapp/env/version
# 响应
upstream connect error or disconnect/reset before headers. reset reason: connection failure 

背景

1.检测flaskapp tls 配置,如下:

[root@kubernetes-master flaskapp]# istioctl authn tls-check flaskapp-v1-775dbb9b79-z54fj flaskapp.kangxzh.svc.cluster.local
HOST:PORT                                 STATUS     SERVER     CLIENT     AUTHN POLICY     DESTINATION RULE
flaskapp.kangxzh.svc.cluster.local:80     OK         mTLS       mTLS       default/         default/istio-system 

STATUS OK 证明flaskapp tls配置正确。

进入sleep istio-proxy向flaskapp发起http请求:

kubectl -n kangxzh exec -it -c istio-proxy $SOURCE_POD bash
# 发起请求
curl http://flaskapp/env/version
# 响应
v1 

2.发现通过istio-proxy可以得到相应,因为开启了mtls,通过istio-proxy直接请求是需要添加istio相关证书的,此时没有加入证书也可请求,所以想到检查flaskapp iptables配置,如下所示:

# 获取进程号
PID=$(docker inspect --format {{.State.Pid}} $(docker ps | grep flaskapp-v1 | awk '{print $1}' | head -n 1))
# 查看iptables 规则
nsenter -t ${PID} -n iptables -t nat -L -n -v
# 输出
Chain PREROUTING (policy ACCEPT 477 packets, 28620 bytes)
 pkts bytes target     prot opt in     out     source               destination
  487 29220 ISTIO_INBOUND  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0

Chain INPUT (policy ACCEPT 487 packets, 29220 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 220 packets, 20367 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0   480 ISTIO_OUTPUT  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0

Chain POSTROUTING (policy ACCEPT 220 packets, 20367 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain ISTIO_INBOUND (1 references)
 pkts bytes target     prot opt in     out     source               destination
   10   600 ISTIO_IN_REDIRECT  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80    #是没有的,修改后增加

Chain ISTIO_IN_REDIRECT (1 references)
 pkts bytes target     prot opt in     out     source               destination
   10   600 REDIRECT   tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            redir ports 15001

Chain ISTIO_OUTPUT (1 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 ISTIO_REDIRECT  all  --  *      lo      0.0.0.0/0           !127.0.0.1
    8   480 RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0            owner UID match 1337
    0     0 RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0            owner GID match 1337
    0     0 RETURN     all  --  *      *       0.0.0.0/0            127.0.0.1
    0     0 ISTIO_REDIRECT  all  --  *      *       0.0.0.0/0            0.0.0.0/0

Chain ISTIO_REDIRECT (2 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 REDIRECT   tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            redir ports 15001 

证明envoy没有劫持到flaskapp 80的流量,也就是说上述第2步是sleep-istio-proxy直接请求flaskapp,没有经过flaskapp-istio-proxy 转发。

  1. 此时才检查flaskapp deployment,如下所示:

...

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: flaskapp-v1
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: flaskapp
        version: v1
    spec:
      containers:
      - name: flaskapp
        image: dustise/flaskapp
        imagePullPolicy: IfNotPresent
        ports:
          - name: http
            containerPort: 80  #缺少containerPort
        env:
        - name: version
          value: v1
... 

官网说明https://istio.io/docs/setup/k...

Pod ports: Pods must include an explicit list of the ports each container listens on. Use a containerPort configuration in the container specification for each port. Any unlisted ports bypass the Istio proxy.
# 未列出来来的端口都会绕过istio proxy 

同时describe flaskapp pod 如下所示:

kubectl describe pod flaskapp-v1-6df8d69fb8-fb5mr -n kangxzh
#
istio-proxy:
    ... 省略若干
    Args:
      ...
      --concurrency
      2
      --controlPlaneAuthPolicy
      MUTUAL_TLS
      --statusPort
      15020
      --applicationPorts
      "" #为空 

在deployment中增加containerPort: 80后,如下所示:

istio-proxy:
    ... 省略若干
    Args:
      ...
      --concurrency
      2
      --controlPlaneAuthPolicy
      MUTUAL_TLS
      --statusPort
      15020
      --applicationPorts
      80 
注意:在Istio1.2版本以后也可通过设置Pod annotation 中 traffic.sidecar.istio.io/includeInboundPorts来达到同样的目的,缺省值为Pod的containerPorts列表,逗号分隔的监听端口列表,这些流量会被重定向到 Sidecar,* 会重定向所有端口,具体详情参见官网1.2新特性(见参考链接)

验证

sleep 发起请求:

[root@kubernetes-master flaskapp]# kubectl -n kangxzh exec -it -c sleep $SOURCE_POD bash
bash-4.4# curl http://flaskapp/env/version
#响应
v1 

sleep-istio-proxy 未携带证书,发起请求:

kubectl -n kangxzh exec -it -c istio-proxy $SOURCE_POD bash
istio-proxy@sleep-v1-7f45c6cf94-zgdsf:/$ curl http://flaskapp/env/version
#响应
curl: (56) Recv failure: Connection reset by peer 
sleep-istio-proxy 携带证书,发起请求
istio-proxy@sleep-v1-7f45c6cf94-zgdsf:/$ curl https://flaskapp:80/env/version --key /etc/certs/key.pem --cert /etc/certs/cert-chain.pem --cacert /etc/certs/root-cert.pem -k
#响应
v1 


参考链接

https://github.com/fleeto/sleep

https://github.com/fleeto/fla...

https://istio.io/docs/setup/k...

https://preliminary.istio.io/...

点赞
收藏
评论区
推荐文章
Stella981 Stella981
4年前
Service Mesh 最火项目: Istio 架构解析
Istio是一个开源的服务网格,可为分布式微服务架构提供所需的基础运行和管理要素。随着各组织越来越多地采用云平台,开发者必须使用微服务设计架构以实现可移植性,而运维人员必须管理包含混合云部署和多云部署的大型分布式应用。Istio采用一种一致的方式来保护、连接和监控微服务,降低了管理微服务部署的复杂性。从架构设计上来看,Istio服务网格在逻辑上分为
Stella981 Stella981
4年前
Istio 流量管理
Istio流量管理本文来自于:https://preliminary.istio.io/zh/docs/concepts/trafficmanagement/(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fpreliminary.istio.io%
Stella981 Stella981
4年前
Istio技术与实践6:Istio如何为服务提供安全防护能力
凡是产生连接关系,就必定带来安全问题,人类社会如此,服务网格世界,亦是如此。今天,我们就来谈谈Istio第二主打功能\保护服务。那么,便引出3个问题:l Istio(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.huaweicloud.com
Stella981 Stella981
4年前
Istio Helm Chart 详解 —— 概述
前言Helm是目前Istio官方推荐的安装方式,除去安装之外,还可以利用对输入值的一些调整,完成对Istio的部分配置工作。官方提供了Istio的Helm部署方式,侧重于快速启动,而这一组文章将会采用由上至下的顺序,基于Istio1.0.2版本的HelmChart做一系列的讲解。Istio的HelmCha
Stella981 Stella981
4年前
Istio的性能实测@KubeCon 2019 Day2
大魏说:Topic的Speaker是IBM的两位专家。、Istio是一个迭代非常快的开源项目,在2019年初1.0版本发布,如今最新版本已经是1.2。在1.1版本中,我进行过一些测试,Istio绝大多数的功能是没问题的。但在测试限流的时候,有时候不生效。Istio1.1的限流需要借助于memqouta或redisqouta。前者不能做
Stella981 Stella981
4年前
Kubernetes初学者实操教程:五步轻松调试K8s服务
下周二晚上8点,为你全面解读Istio最新发布的两个新版本!包括Istio架构演化、新架构解读以及新特性的实战demo噢!点击【阅读原文】或访问以下链接即可预约报名!http://zmz.cn/1BGJE在Kubernetes中,服务是一个核心概念。在本文中,将介绍如何调试K8S服务,这些服务是由多个Pod组成的工作负载的抽象接
Stella981 Stella981
4年前
Istio入门实战与架构原理——使用Docker Compose搭建Service Mesh
本文将介绍如何使用DockerCompose搭建Istio。Istio号称支持多种平台(不仅仅Kubernetes)。然而,官网上非基于Kubernetes的教程仿佛不是亲儿子,写得非常随便,不仅缺了一些内容,而且还有坑。本文希望能补实这些内容。我认为在学习Istio的过程中,相比于Kubernetes,使用DockerCompose部署更能深刻地理解I
Stella981 Stella981
4年前
Slime:让 Istio 服务网格变得更加高效与智能
Slime是网易数帆旗下轻舟微服务团队开源的服务网格组件(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fgithub.com%2Fslimeio%2Fslime),它可以作为Istio的CRD管理器,旨在通过更为简单的配置实现Istio/Envoy的高阶功能。目前sli
Stella981 Stella981
4年前
Knative 实战:一个微服务应用的部署
!file(https://oscimg.oschina.net/oscnet/552da4b91eb64f39e2cdb0b44d426332fdc.jpg)作者|元毅阿里云智能事业群高级开发工程师在Istio中提供了一个Bookinfo的示例,用于演示微服务之间的调用,那么如何在Knative中部署这个示例呢?本文将会给大家
Stella981 Stella981
4年前
Google、IBM和Lyft开源的微服务管理框架Istio安装与试用
Istio是Google、IBM和Lyft联合开源的微服务ServiceMesh框架,旨在解决大量微服务的发现、连接、管理、监控以及安全等问题。Istio的主要特性包括:HTTP、gRPC和TCP网络流量的自动负载均衡丰富的路由规则,细粒度的网络流量行为控制流量加密、服务间认证,以及强身份声明全范围(Fleet
服务网格的基本概念
服务网格(ServiceMesh)由服务治理创建并托管Istio的控制平面。具备简单、低成本、高可用、无需运维管理Istio控制平面的特点。
WenDangXia
WenDangXia
Lv1
仍怜故乡水,万里送行舟。
文章
4
粉丝
0
获赞
0