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

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

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

(0)
上一篇 2022年4月16日 下午8:00
下一篇 2022年4月16日 下午8:00


相关推荐

  • python format()函数的用法

    python format()函数的用法Pythonformat()函数的用法复制自博主 chunlaipiupiupiu 的博客,如有侵权,请联系删除python中format函数用于字符串的格式化通过关键字

    2022年7月6日
    26
  • Python和sendfile[通俗易懂]

    Python和sendfile[通俗易懂]sendfile(2)isaUNIXsystemcallwhichprovidesa“zero-copy”wayofcopyingdatafromonefiledescriptor(afile)toanother(asocket).Becausethiscopyingisdoneentirelywithinthekernel,sen…

    2022年5月3日
    52
  • 成果被他人窃取_工作窃取模式

    成果被他人窃取_工作窃取模式什么是ForkJoin、ForkJoin分支合并、ForkJoin工作窃取、ForkJoin大数据求和计算什么是ForkJoin?ForkJoin:分支合并ForkJoin特点:工作窃取如何让使用ForkJoinForkJoin求和计算Demo什么是ForkJoin?ForkJoin(分支合并)是jdk1.7之后出来的,并行执行任务,提高效率,用在大数据量场景下。大数据:MapReduce(把大任务拆分成多个小任务,怎么拆分用到了二分算法),每个小任务得出自己的结果,之后再把结果汇总,汇总的过程就是

    2025年11月11日
    4
  • “养龙虾”席卷AI圈 OpenClaw走红背后安全风险待解

    “养龙虾”席卷AI圈 OpenClaw走红背后安全风险待解

    2026年3月13日
    2
  • ZMQ简介

    ZMQ简介一 ZeroMQ 的背景介绍官方 ZMQ 以下 ZeroMQ 简称 ZMQ 是一个简单好用的传输层 像框架一样的一个 socketlibrar 他使得 Socket 编程更加简单 简洁和性能更高 是一个消息处理队列库 可在多个线程 内核和主机盒之间弹性伸缩 ZMQ 的明确目标是 成为标准网络协议栈的一部分 之后进入 Linux 内核 现在还未看到它们的成功 但是 它无疑是极具前景的 并且是人们更加需要的 传

    2026年3月16日
    4
  • Py之Scipy:Scipy库(高级科学计算库)的简介、安装、使用方法之详细攻略

    Py之Scipy:Scipy库(高级科学计算库)的简介、安装、使用方法之详细攻略Scipy 是世界上著名的 开源的高级科学计算库 Scipy 是基于 Numpy 构建的一个集成了多种数学算法和方便的函数的 Python 模块 通过给用户提供一些高层的命令和类来操作和可视化数据 SciPy 在 python 交互式会话中 大大增加了操作和可视化数据的能力 通过 SciPy Python 的交互式会话变成了一个数据处理和一个系统原型 system prototyping 环境 可以与 MATLAB IDL Octave R Lab 和 SciLab 等系统相匹敌

    2026年3月20日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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