1、准备测试应用

准备两个nginx Pod和一个proxy

创建应用

apiVersion: apps.openshift.io/v1
kind: DeploymentConfig
metadata:
name: www-v1
namespace: dev
spec:
selector:
app: www
replicas:
template:
metadata:
labels:
app: www
version: v1
spec:
containers:
- name: www
image: nginx
ports:
- containerPort:
---
apiVersion: apps.openshift.io/v1
kind: DeploymentConfig
metadata:
name: www-v2
namespace: dev
spec:
selector:
app: www
replicas:
template:
metadata:
labels:
app: www
version: v2
spec:
containers:
- name: www
image: nginx
ports:
- containerPort:
---
apiVersion: apps.openshift.io/v1
kind: DeploymentConfig
metadata:
name: www-proxy
namespace: dev
spec:
selector:
app: www-proxy
replicas:
template:
metadata:
labels:
app: www-proxy
spec:
containers:
- name: www
image: nginx
ports:
- containerPort:
---
apiVersion: v1
kind: Service
metadata:
name: www
namespace: dev
spec:
selector:
app: www
ports:
- name: http
protocol: TCP
port:
targetPort:
---
apiVersion: v1
kind: Service
metadata:
name: www-proxy
namespace: dev
spec:
selector:
app: www-proxy
ports:
- name: http
protocol: TCP
port:
targetPort:

注意Service中的 - name: http一定要加上,后面要匹配流量类型

# oc create -f app.yaml

准备3个Config Maps

www-v1

#获取客户端真实IP
set_real_ip_from 10.0.0.0/;
set_real_ip_from 192.168.0.0/;
set_real_ip_from 172.16.0.0/;
set_real_ip_from 100.0.0.0/;
set_real_ip_from 127.0.0.1;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
#日志相关格式配置
log_format json '{"@timestamp":"$time_local",'
'"podname":"$hostname",'
'"clientip":"$remote_addr",'
'"request":"$request",'
'"status":"$status",'
'"forwarded_proto":"$http_x_forwarded_proto",'
'"scheme":"$scheme",'
'"request_method": "$request_method",'
'"size":"$body_bytes_sent",'
'"request_time":"$request_time",'
'"upstreamtime":"$upstream_response_time",'
'"upstreamhost":"$upstream_addr",'
'"http_host":"$host",'
'"url":"$uri",'
'"forwarded_for":"$http_x_forwarded_for",'
'"referer":"$http_referer",'
'"agent":"$http_user_agent"}'; access_log /dev/stdout json;
error_log /dev/stderr error;
server {
location / {
default_type text/html;
return 'nginx-v1';
}
}

www-v2

#获取客户端真实IP
set_real_ip_from 10.0.0.0/;
set_real_ip_from 192.168.0.0/;
set_real_ip_from 172.16.0.0/;
set_real_ip_from 100.0.0.0/;
set_real_ip_from 127.0.0.1;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
#日志相关格式配置
log_format json '{"@timestamp":"$time_local",'
'"podname":"$hostname",'
'"clientip":"$remote_addr",'
'"request":"$request",'
'"status":"$status",'
'"forwarded_proto":"$http_x_forwarded_proto",'
'"scheme":"$scheme",'
'"request_method": "$request_method",'
'"size":"$body_bytes_sent",'
'"request_time":"$request_time",'
'"upstreamtime":"$upstream_response_time",'
'"upstreamhost":"$upstream_addr",'
'"http_host":"$host",'
'"url":"$uri",'
'"forwarded_for":"$http_x_forwarded_for",'
'"referer":"$http_referer",'
'"agent":"$http_user_agent"}'; access_log /dev/stdout json;
error_log /dev/stderr error;
server {
location / {
default_type text/html;
return 'nginx-v2';
}
}

www-proxy

#获取客户端真实IP
set_real_ip_from 10.0.0.0/;
set_real_ip_from 192.168.0.0/;
set_real_ip_from 172.16.0.0/;
set_real_ip_from 100.0.0.0/;
set_real_ip_from 127.0.0.1;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
#日志相关格式配置
log_format json '{"@timestamp":"$time_local",'
'"podname":"$hostname",'
'"clientip":"$remote_addr",'
'"request":"$request",'
'"status":"$status",'
'"forwarded_proto":"$http_x_forwarded_proto",'
'"scheme":"$scheme",'
'"request_method": "$request_method",'
'"size":"$body_bytes_sent",'
'"request_time":"$request_time",'
'"upstreamtime":"$upstream_response_time",'
'"upstreamhost":"$upstream_addr",'
'"http_host":"$host",'
'"url":"$uri",'
'"forwarded_for":"$http_x_forwarded_for",'
'"referer":"$http_referer",'
'"agent":"$http_user_agent"}'; access_log /dev/stdout json;
error_log /dev/stderr error;
server {
location / {
proxy_http_version 1.1;
proxy_pass http://www;
}
}

挂载

# oc set volume  dc/www-v1 --add --overwrite --name=config-volume --mount-path=/etc/nginx/conf.d --source='{"configMap": { "name": "www-v1"}}'
# oc set volume dc/www-v2 --add --overwrite --name=config-volume --mount-path=/etc/nginx/conf.d --source='{"configMap": { "name": "www-v2"}}'
# oc set volume dc/www-proxy --add --overwrite --name=config-volume --mount-path=/etc/nginx/conf.d --source='{"configMap": { "name": "www-proxy"}}'

为了方便测试www-proxy 需要绑定外部Ingress 比如openshif route

apiVersion: route.openshift.io/v1
kind: Route
metadata:
name: www-proxy
namespace: dev
spec:
host: www-proxy.ingress.com
to:
kind: Service
name: www-proxy
port:
targetPort:

2、路由流量

默认情况下在内网网络访问www应用,可以看出来流量是轮询的

# curl www-proxy.ingress.com
nginx-v2
nginx-v2
nginx-v1
nginx-v2
nginx-v1
nginx-v1

创建istio VirtualService、DestinationRule 路由流量

kind: VirtualService
metadata:
name: www-intranet
namespace: dev
spec:
hosts:
- www
http:
- route:
- destination:
host: www
subset: v2
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: www
namespace: dev
spec:
host: www
subsets:
- labels:
version: v1
name: v1
- labels:
version: v2
name: v2
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN

这里的http要对应Service -name 的值

测试一下,此时应该只会返回"nginx-v2"

# curl www-prxoy.ingress.com
nginx-v2
nginx-v2
nginx-v2
nginx-v2
nginx-v2

根据权重路由流量

spec:
hosts:
- www
http:
- route:
- destination:
host: www
subset: v1
weight:
- destination:
host: www
subset: v2
weight:

测试一下

# curl www-proxy.ingress.com
nginx-v1
nginx-v2
nginx-v2
nginx-v2
nginx-v2
nginx-v1
nginx-v2
nginx-v2

下面介绍不通过www-proxy直接路由外部流量,需要额外创建istio Gateway并和VirtualService绑定

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: default-gateway
namespace: dev
spec:
selector:
istio: ingressgateway
servers:
- hosts:
- '*'
port:
name: http
number:
protocol: HTTP
---
kind: VirtualService
metadata:
name: www
namespace: dev
spec:
gateways:
- default-gateway
hosts:
- www.ingress.com
http:
- route:
- destination:
host: www
subset: v1
---
apiVersion: route.openshift.io/v1
kind: Route
metadata:
labels:
app: istio-ingressgateway
chart: gateways
heritage: Tiller
istio: ingressgateway
release: istio
name: www
namespace: istio-system
spec:
host: www.ingress.com
port:
targetPort: http2
to:
kind: Service
name: istio-ingressgateway

注意如果没有外部ingress 使用NodePort的方式引入流量,并且Gateway和VirtualService任意一个hosts没有*,这时候Gateway无法识别具体的host域名

那么可以修改istio-ingressgateway的Deployment用hostPort直接暴露80和443端口,在把istio-ingressgateway的Pod绑定到固定的节点上运行

...
- containerPort:
hostPort:
protocol: TCP
- containerPort:
hostPort:
protocol: TCP
....

下面测试一下

# curl www.ingress.com
nginx-v1
nginx-v1
nginx-v1
nginx-v1
nginx-v1

istio1.1(openshift) 流量路由的更多相关文章

  1. Istio(五):使用服务网格Istio进行流量路由

    目录 一.模块概览 二.系统环境 三.简单路由 3.1 简单路由 四.Subset和DestinationRule 4.1 Subset 和 DestinationRule 4.2 Destinati ...

  2. 通过 Traefik 使用 Kubernetes Service APIs 进行流量路由 (http,https,金丝雀发布)

    文章转载自:https://mp.weixin.qq.com/s?__biz=MzU4MjQ0MTU4Ng==&mid=2247490229&idx=1&sn=ca817054 ...

  3. Oceanus:美团HTTP流量定制化路由的实践

    背景简述 Oceanus是美团基础架构部研发的统一HTTP服务治理框架,基于Nginx和ngx_lua扩展,主要提供服务注册与发现.动态负载均衡.可视化管理.定制化路由.安全反扒.session ID ...

  4. istio1.0.2配置

    项目的组件相对比较复杂,原有的一些选项是靠 ConfigMap 以及 istioctl 分别调整的,现在通过重新设计的Helm Chart,安装选项用values.yml或者 helm 命令行的方式来 ...

  5. Istio中的流量配置

    Istio中的流量配置 目录 Istio中的流量配置 Istio注入的容器 Istio-init istio-proxy Envoy架构 Pilot-agent生成的初始配置文件 Envoy管理接口获 ...

  6. istio流量管理:非侵入式流量治理

    在服务治理中,流量管理是一个广泛的话题,一般情况下,常用的包括: 动态修改服务访问的负载均衡策略,比如根据某个请求特征做会话保持: 同一个服务有多版本管理,将一部分流量切到某个版本上: 对服务进行保护 ...

  7. Nginx动态路由的新姿势:使用Go取代lua

    导语: 在Nitro 中, 我们需要一款专业的负载均衡器. 经过一番研究之后,Mihai Todor和我使用Go构建了基于Nginx.Redis 协议的路由器解决方案,其中nginx负责所有繁重工作, ...

  8. istio路由配置

    istio路由配置   istio的代理配置参考文档: 中文文档: https://istio.io/zh/docs/reference/config/istio.networking.v1alpha ...

  9. 通过流量清理防御DDoS

    导读 在2018年2月,世界上最大的分布式拒绝服务(DDoS)攻击在发起20分钟内得到控制,这主要得益于事先部署的DDoS防护服务. 这次攻击是针对GitHub–数百万开发人员使用的主流在线代码管理服 ...

随机推荐

  1. CVE-2015-0235

    看了下代码,由于各人能力问题,只是了解了漏洞的起因,知道哪里出了问题,但是不知道怎么用阿... 可怜... 这种漏洞,公布出来,只要不给EXP,估计威胁都不大.或者,就是我脑筋太死??? 首先,是网上 ...

  2. js 删除数组中指定值

    var arr = ['1','2'];delete('1'); function delete(i){ var index = arr.indexOf(i); arr.splice(index, 1 ...

  3. AWS云管理平台

  4. 笔记-ubuntu19共享文件夹

    这篇文章记录ubuntu和windows共享文件夹的步骤,环境是ubuntu19,两种方法,一种是图形化界面,一种是命令行. 图形化界面 打开文件软件,找到需要分享的文件夹,点击右键-属性-本地网络共 ...

  5. 关于Button控件的CommandName属性用法的一个实例

    注:本文分享于悠闲的博客,地址:http://www.cnblogs.com/9999/archive/2009/11/24/1609234.html 1.前台的代码 <%@ Page Lang ...

  6. QVaraint类

    一.QVaraint简介     QVaraint类作为一个包含了大多数Qt普通类型的的联合体类.因为c++联合体没有构造函数和析构函数的,许多继承的Qt类不能够在联合体当中使用.(联合体当中的变量共 ...

  7. leetcode-第五场双周赛-1134-阿姆斯特朗数

    第一次提交: class Solution: def isArmstrong(self, N: int) -> bool: n = N l = len(str(N)) res = 0 while ...

  8. 企业微信开发免登授权时提示scope不能为空,错误代码1001

    企业免登授权提示scope不能为空1001 原因是我们是单页面应用url自带#/在微信里面认为#号后面的参数不被识别 后端开发人员把参数放到跳转 URL地址前面,正确形式是 https://open. ...

  9. VS2010-MFC(对话框:模态对话框及其弹出过程)

    转自:http://www.jizhuomi.com/software/160.html 一.模态对话框和非模态对话框 Windows对话框分为两类:模态对话框和非模态对话框. 模态对话框是这样的对话 ...

  10. php析构函数小结

    l 基本语法 class  类名{ public  function  __destruct(){ //函数体 //析构函数的最重要的作用,就是释放对象创建的资源 //比如 数据库连接, 文件句柄, ...