k8s Istio不支持http1.0导致微信回调失败问题处理

493 阅读3分钟

系统架构

image-20230317093349071

问题描述

image-20230317093946878

在公众号token验证,通过此域名一直请求不到服务器,报token check fail,但是通过浏览器、终端访问此url均可以访问成功,

image-20230317094151154

问题定位

  1. 询问运维是否对SLB加了白名单,运维答复没加白名单限制

  2. 是不是微信回调不支持我们的域名格式,tmp.xxxxx.com,在我们内部进行验证可以支持

  3. 以上2个假设都没问题,于是查找公众号验证相关资料看看有什么线索,发现微信发送的请求是http1.0,所以可能是这块导致的问题,于是写了一个程序进行了验证

public class MyTest {
    public void get(String url) throws Exception {
        // 创建HttpClient实例
        HttpClient client =  HttpClientBuilder.create().build();
        // 根据URL创建HttpGet实例
        HttpGet get = new HttpGet(url);
        //指定http1.0
        get.setProtocolVersion(HttpVersion.HTTP_1_0);
        // 执行get请求,得到返回体
        HttpResponse response = client.execute(get);
        // 判断是否正常返回
        if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            // 解析数据
            String data = EntityUtils.toString(response.getEntity(), Charsets.UTF_8);
            System.out.println("-----"+data+"----------");
        }
        String data = EntityUtils.toString(response.getEntity(), Charsets.UTF_8);
        System.out.println("-----"+response+"----------");
    }

    /**
     * 申请SLB测试
     * @throws Exception
     */
    @Test
    public void test4() throws Exception {
        get("http://tmp.xxxxx.com/s-park/middle/wechat/api/portal/xxxx");
    }
}

执行以上脚本,返回以下结果

image-20230317100124885

修改http版本为1.1,再次进行测试

image-20230317100238295

通过以上的定位可以确定是由于istio不支持http1.0导致

问题处理

目前已经定位到问题是由于istio不支持 http1.0导致,所以解决此问题也有几种方式

  1. 通过slb把http1.0转成http1.1

image-20230317101103163

  1. 如果slb不支持,通过在slb到k8s之间搭建nginx进行协议版本转换

    image-20230317101122798

  2. 修改istio,支持http1.0

由于第三种方式,是最方便也是最通用的解决方式,所以先优先按照第三种方式去处理,如果支持不了,在考虑其他二种处理方法。

修复 istio 支持http1.0

查看资料istio相关资料,了解Istio 中负责流量转发的是 Envoy,Envoy 中可以设置支持 HTTP/1.0,Istio 负责分配“规则”的是 Pilot,Pilot 的环境变量 PILOT_HTTP10 默认为 0,即不支持 HTTP/1.0,如果要支持,需要修改PILOT_HTTP10的属性为1即可支持http1.0

于是查看怎么指定此属性,由于我们是通过helm安装的istio,于是查看chart相关参数,发现有pilot.env应该可以指定参数

image-20230317102030541

再次确认此属性的引用是在manifests/charts/istio-control/istio-discovery/templates/deployment.yaml的pilot的env中,应该没问题

image-20230317101907167

由于istio已经安装完成,所以只能通过修改的方式进行更新

image-20230317102923382

执行以下命令进行更新

helm upgrade istiod manifests/charts/istio-control/istio-discovery \
    --set global.hub="docker.io/istio" \
    --set global.tag="1.15.1" \
    --set pilot.env.PILOT_HTTP10=1  \
    -n istio-system 

执行完成,检查PILOT_HTTP10是否配置成功,执行以下命令,可以看到结果返回为1,开启成功

kubectl describe deployment istiod -n istio-system | grep PILOT_HTTP10

image-20230317103001922

结果验证

  1. 再次执行http1.0请求测试脚本,查看是否请求成功,可以看到有响应结果,请求成功

image-20230317103235811

  1. 在公众号配置回调验证,一次成功。。。

image-20230317103457348

总结

  1. 由于微信返回的信息实在有限,导致这个问题排查耗费了好几天,建议微信能把对应调用方的响应结果返回来,这样可以快速解决问题,正好微信社区里有人提到http1.0的问题,所以才能最终定位到问题,不然我们可能还在排查中

  2. 此问题也验证了我们对k8s的一些细节不了解,以及对k8s运维监控不到位,应该加强对这方面的研究