首页 资讯 社群 我的社区 搜索

istio1.1(openshift) 流量路由

LM123
2019-05-31 16:58:59

1、准备测试应用

准备两个nginx Pod和一个proxy

创建应用

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

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

# oc create -f app.yaml

准备3个Config Maps 

www-v1

#获取客户端真实IP
set_real_ip_from 10.0.0.0/8;
set_real_ip_from 192.168.0.0/16;
set_real_ip_from 172.16.0.0/12;
set_real_ip_from 100.0.0.0/8;
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 200 'nginx-v1';
    }
}

www-v2

#获取客户端真实IP
set_real_ip_from 10.0.0.0/8;
set_real_ip_from 192.168.0.0/16;
set_real_ip_from 172.16.0.0/12;
set_real_ip_from 100.0.0.0/8;
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 200 'nginx-v2';
    }
}

www-proxy

#获取客户端真实IP
set_real_ip_from 10.0.0.0/8;
set_real_ip_from 192.168.0.0/16;
set_real_ip_from 172.16.0.0/12;
set_real_ip_from 100.0.0.0/8;
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: 80

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: 20
    - destination:
        host: www
        subset: v2
      weight: 80

测试一下

# 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: 80
      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: 80
hostPort: 80
protocol: TCP
- containerPort: 443
hostPort: 443
protocol: TCP
....

下面测试一下

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

 

用户评论