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)
blank

相关推荐

  • Abp配置文件设置IdentityServer客户端

    Abp配置文件设置IdentityServer客户端在没有购买商业版,又没实现IdentityServer配置管理页功能时,我们又得配置客户端时。设想通过appsettings.json,临时添加配置,然后执行.DbMigrator迁移数据。这时原

  • Linux查看文件内容的5种方式

    Linux查看文件内容的5种方式Linux查看文件内容的5种方式

  • PhpStorm 2021.5.2 x64 激活码(最新序列号破解)「建议收藏」

    PhpStorm 2021.5.2 x64 激活码(最新序列号破解),https://javaforall.cn/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

  • Bootstrap 时间控件 datetimepicker

    Bootstrap 时间控件 datetimepickerBootstrap的时间控件易用且美观,下面将用法记录一下,大家有需要可以直接看官网的介绍,还是很基础的。网址:http://www.bootcss.com/p/bootstrap-datetimepicker/Bootstrap有两种时间控件:datepicker和datetimepicker,后者是前者的拓展,增加了到时分秒的选择。下面是选用了datetimepicker的…

  • Modelsim license破解中一个不可省略的步骤

    Modelsim license破解中一个不可省略的步骤安装modelsim没有一次顺利的。这一次是彻底搞清楚了.我安装的版本是modelsimse1-6410.1c,操作系统是win1064位.安装完了,按crack的说明去破解,总出现license问题.解决的办法是改变。安装目录中win64下面mgls.dll和mgls64.dll的只读属性。然后再重复一遍crack指导的方法。成功破解…

  • c语言可重入函数_c语言不可重入函数有哪些

    c语言可重入函数_c语言不可重入函数有哪些什么是可重入函数可重入函数指一个可同时被多个任务调用的过程,当一个函数满足下列条件时多为不可重入函数(1)函数中使用了静态的数据结构;(2)函数中使用了malloc()、free()函数;(3)函数汇总调用了标准I/O函数。(如open、read、write、close等系统调用)如何编写可重入函数(1)编写可重入函数时,不应使用static局部变量,应使用auto即缺省…

发表回复

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

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