istio解决了什么问题(istio k8s)

问题简述通过istio实现灰度发布,浏览器访问报404错误,但是通过curl传递一个Host请求头就能访问成功。问题复现RancherUI界面启动Istio,并开启ingress网关命名空间启动Istio自动注入部署nginx应用###deploy-nginx-v1.yamlapiVersion:apps/v1kind:Deploymentmetadata:labels:app:nginxversion:v1name:nginx-v1n

大家好,又见面了,我是你们的朋友全栈君。

问题简述

通过istio实现灰度发布,浏览器访问报404错误,但是通过curl传递一个Host请求头就能访问成功。

问题复现

Rancher UI界面启动Istio,并开启ingress网关

image-20200429120505161

命名空间启动Istio自动注入

image-20200429120612538

部署nginx应用

###deploy-nginx-v1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
    version: v1
  name: nginx-v1
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
      version: v1
  template:
    metadata:
      labels:
        app: nginx
        version: v1
    spec:
      containers:
      - image: satomic/nginx:v1
        imagePullPolicy: IfNotPresent
        name: nginx
        ports:
        - containerPort: 80
          name: 80tcp02
          protocol: TCP
---      
##deploy-nginx-v2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
    version: v2
  name: nginx-v2
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
      version: v2
  template:
    metadata:
      labels:
        app: nginx
        version: v2
    spec:
      containers:
      - image: satomic/nginx:v2
        imagePullPolicy: IfNotPresent
        name: nginx
        ports:
        - containerPort: 80
          name: 80tcp02
          protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx
    service: nginx
  name: nginx
  namespace: default
spec:
  ports:
  - name: 80tcp02
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx
  type: ClusterIP
---                
##gw.yaml 
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: mynginx-gateway
  namespace: default
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - hosts:
    - 'web1.com'
    port:
      name: http
      number: 80
      protocol: HTTP
---
##vs-nginx.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: nginx
  namespace: default
spec:
  gateways:
  - mynginx-gateway
  hosts:
  - 'web1.com'
  http:
  - match:
    - uri:
        exact: /index.html
    route:
    - destination:
        host: nginx
        subset: dr-nginx-v1
      weight: 50
    - destination:
        host: nginx
        subset: dr-nginx-v2
      weight: 50
##dr-nginx.yaml
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: nginx
  namespace: default
spec:
  host: nginx
  subsets:
  - labels:
      version: v1
    name: dr-nginx-v1
  - labels:
      version: v2
    name: dr-nginx-v2
  trafficPolicy:
    loadBalancer:
      simple: ROUND_ROBIN

浏览器访问:http://web1.com:31380/index.html,访问报错

# windows添加主机映射,C:\Windows\System32\drivers\etc\hosts
172.16.0.211 web1.com

172.16.0.211 为访问主机,31380则是ingressGateway使用NodePort映射 端口

image-20200429122013810

curl访问,直接curl访问失败,带上Host请求头,访问成功

# Linux添加主机映射,/etc/hosts
172.16.0.211 web1.com

image-20200429122221917

排查思路

查看默认发送的请求头

[root@node02 ~]# curl -v http://web1.com:31380/index.html
* About to connect() to web1.com port 31380 (#0)
*   Trying 172.16.0.211...
* Connected to web1.com (172.16.0.211) port 31380 (#0)
> GET /index.html HTTP/1.1
> User-Agent: curl/7.29.0
> Host: web1.com:31380
> Accept: */*
> 
< HTTP/1.1 404 Not Found
< date: Wed, 29 Apr 2020 04:28:41 GMT
< server: istio-envoy
< content-length: 0
< 
* Connection #0 to host web1.com left intact

可以看到请求的Hostweb1.com:31380,而我们virtualservice的hosts写的是web.com,所以请求的地址不对,自然就没法访问

问题处理

既然请求的Host不对,那么就要修改成相对应的Host才能访问,可以有以下几种处理方式。

1 请求头(Request Header)手动指定Host字段

如果是应用内部自己调用,例如代码或者脚本,可以手动指定Host请求头,但是这种就无法再浏览器上访问

[root@node02 ~]# curl -v -H Host:web1.com http://web1.com:31380/index.html
* About to connect() to web1.com port 31380 (#0)
*   Trying 172.16.0.211...
* Connected to web1.com (172.16.0.211) port 31380 (#0)
> GET /index.html HTTP/1.1
> User-Agent: curl/7.29.0
> Accept: */*
> Host:web1.com
> 
< HTTP/1.1 200 OK
< server: istio-envoy
< date: Wed, 29 Apr 2020 04:37:21 GMT
< content-type: text/html
< content-length: 7
< last-modified: Wed, 25 Mar 2020 15:18:37 GMT
< etag: "5e7b764d-7"
< accept-ranges: bytes
< x-envoy-upstream-service-time: 1
< 
app v2
* Connection #0 to host web1.com left intact

2 在VirtualService中设置authority来支持port访问

istio目前暂时还不支持直接添加DOMAIN+PORT,可以通过设置authority来支持PORT访问

在gateway和virtualservice设置hosts为"*",并在virtualservice设置authority

## gateway
spec:
  - hosts:
    - '*'
---
## virtualservice
spec:
  hosts:
  - '*'
  http:
    - authority:
        exact: "web2.com:31380"

完整示例

##gw.yaml 
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: mynginx-gateway
  namespace: default
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - hosts:
    - '*'
    port:
      name: http
      number: 80
      protocol: HTTP
---
##vs-nginx.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: nginx
  namespace: default
spec:
  gateways:
  - mynginx-gateway
  hosts:
  - '*'
  http:
  - match:
    - uri:
        exact: /index.html
      authority:
        exact: "web2.com:31380"
    route:
    - destination:
        host: nginx
        subset: dr-nginx-v1
      weight: 50
    - destination:
        host: nginx
        subset: dr-nginx-v2
      weight: 50

kubectl apply刷新配置后,就可以在浏览器上访问了

image-20200429125624700

并且我们也可以看到,Host请求头是web1.com:31380,如果使用web1.com Host请求头访问,则会失败

[root@node02 ~]# curl -v http://web1.com:31380/index.html
* About to connect() to web1.com port 31380 (#0)
*   Trying 172.16.0.211...
* Connected to web1.com (172.16.0.211) port 31380 (#0)
> GET /index.html HTTP/1.1
> User-Agent: curl/7.29.0
> Host: web1.com:31380
> Accept: */*
> 
< HTTP/1.1 200 OK
< server: istio-envoy
< date: Wed, 29 Apr 2020 05:34:12 GMT
< content-type: text/html
< content-length: 7
< last-modified: Wed, 25 Mar 2020 15:18:37 GMT
< etag: "5e7b764d-7"
< accept-ranges: bytes
< x-envoy-upstream-service-time: 1
< 
app v2
* Connection #0 to host web1.com left intact
[root@node02 ~]# curl -v -H Host:web1.com http://web1.com:31380/index.html
* About to connect() to web1.com port 31380 (#0)
*   Trying 172.16.0.211...
* Connected to web1.com (172.16.0.211) port 31380 (#0)
> GET /index.html HTTP/1.1
> User-Agent: curl/7.29.0
> Accept: */*
> Host:web1.com
> 
< HTTP/1.1 404 Not Found
< date: Wed, 29 Apr 2020 05:34:25 GMT
< server: istio-envoy
< content-length: 0
< 
* Connection #0 to host web1.com left intact

3 设置ingressGateway使用LoadBalancer

ingressGateway使用LoadBancer,设置好对应的地址即可

image-20200429143039440

参考

相关issue参考:https://github.com/istio/istio/issues/11828

官方istio VirtualService设置选项:https://istio.io/zh/docs/reference/config/networking/virtual-service/#HTTPMatchRequest

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/127507.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • phpStudy本地环境测试,打开网页很慢的解决办法!

    phpStudy本地环境测试,打开网页很慢的解决办法!

    2021年10月16日
  • EVE模拟器使用说明

    EVE模拟器使用说明本着分享和共同学习的态度,希望能给有需要的人带来帮助。 转载于:https://blog.51cto.com/dashu666/1971728

  • UML时序图(Squence diagram)的设计介绍[通俗易懂]

    UML时序图(Squence diagram)的设计介绍[通俗易懂]本文以starUML工具为例。一、概念UML时序图,也叫顺序图,是一种详细表示对象之间以及对象与参与者实例之间交互的图,它由一组协作的对象(或参与者实例)以及它们之间可发送的消息组成,它强调消息之间的顺序。它详细而直观地表现了一组相互协作的对象在执行一个(或少量几个)用例时的行为依赖关系,以及操作和消息的时序关系。类图是反映类、对象、接口等事物之间的依赖、继承、实现关系等,主要是静…

  • android 课程格子源码,课程格子Android客户端产品体验报告[通俗易懂]

    android 课程格子源码,课程格子Android客户端产品体验报告[通俗易懂]概览手机:魅族MX3操作系统:FlymeOS3.5.2(A19220)体验产品:课程格子Android客户端软件版本:6.1需求分析目标人群:在校大学生使用场景:大学生课前查看课程,课堂做笔记,课下在BBS灌水。用户需求:课程导入便利,显示准确,操作便捷,功能新颖有趣。产品分析1.信息架构2.页面视图A.课程格子菜单栏放在顶部,按钮也并不大,在子页面中也都是同样的设计,没有分出导航栏或状态栏(…

  • java输入输出流实例代码

    java输入输出流实例代码1.编写一个程序,读取源代码文件的内容并在控制台输出。如果源文件不存在,则显示相应的错误信息。packagesrc;importjava.io.File;importjava.io.FileNotFoundException;importjava.io.FileReader;importjava.io.IOException;publicclasstest01{

  • pycharm导出依赖包_pycharm快速倒包

    pycharm导出依赖包_pycharm快速倒包一般你在pycharm本身库里面导入一个外部没有的包这个时候pycharm里面就会报错,所以你要先下载好你想要导入的包,步骤如下:

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号