linux12企业实战 -- 09VirtualService(虚拟服务)
Posted FikL-09-19
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux12企业实战 -- 09VirtualService(虚拟服务)相关的知识,希望对你有一定的参考价值。
文章目录
一、VirtualService(虚拟服务)
VirtualService中文名称虚拟服务,是istio中一个重要的资源, 它定义了一系列针对指定服务的流量路由规则。每个路由规则都针对特定协议的匹配规则。如果流量符合这些特征,就会根据规则发送到服务注册表中的目标服务(或者目标服务的子集或版本)。
二、VirtualService和k8s service的区别
如果没有 Istio virtual service,仅仅使用 k8s service 的话,那么只能实现最基本的流量负载均衡转发,但是就不能实现类似按百分比来分配流量等更加复杂、丰富、细粒度的流量控制了。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: my-namespace
spec:
hosts:
- "svc.test.com"
http:
- match:
- uri:
prefix: /
route:
- destination:
host: nginx-web-svc.default.svc.cluster.local # 代理的SVC
三、exportTo 生效命名空间
1、当前名称空间有效
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: my-namespace
spec:
exportTo:
- "."
hosts:
- "svc.test.com"
http:
- match:
- uri:
prefix: /
route:
- destination:
host: nginx-web-svc.default.svc.cluster.local # 代理的SVC
2、所有名称空间有效
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: my-namespace
spec:
exportTo:
- "*"
hosts:
- "svc.test.com"
http:
- match:
- uri:
prefix: /
route:
- destination:
host: nginx-web-svc.default.svc.cluster.local # 代理的SVC
3、VirtualService + Gateway
Gateway 名称列表,Sidecar 会据此使用路由。VirtualService 对象可以用于网格中的 Sidecar,也可以用于一个或多个 Gateway。这里公开的选择条件可以在协议相关的路由过滤条件中进行覆盖。保留字 mesh 用来指代网格中的所有 Sidecar。当这一字段被省略时,就会使用缺省值(mesh),也就是针对网格中的所有 Sidecar 生效。如果提供了 gateways 字段,这一规则就只会应用到声明的 Gateway 之中。要让规则同时对 Gateway 和网格内服务生效,需要显式的将 mesh 加入 gateways 列表。
1、单个gateway
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: web-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: httpd
protocol: HTTP
hosts:
- "svc.test.com"
- port:
number: 80
name: nginx
protocol: HTTP
hosts:
- "svc.test.com"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: my-namespace
spec:
hosts:
- "svc.test.com"
gateways:
- web-gateway
http:
- match:
- uri:
prefix: /
route:
- destination:
host: nginx-web-svc.default.svc.cluster.local
port:
number: 80
2、 测试结果
/ # while true; do wget -q -O- http://svc.test.com:32623 ;sleep 1; done
<html><body><h1>It works!</h1></body></html>
<h1>Welcome to nginx!</h1>
<h1>Welcome to nginx!</h1>
<html><body><h1>It works!</h1></body></html>
3、多个Gateway
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: web-gateway-nginx
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: nginx
protocol: HTTP
hosts:
- "svc.test.com"
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: web-gateway-httpd
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: httpd
protocol: HTTP
hosts:
- "svc.test.com"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: my-namespace
spec:
hosts:
- "svc.test.com"
gateways:
- web-gateway-nginx
- web-gateway-httpd
http:
- match:
- uri:
prefix: /
route:
- destination:
host: nginx-web-svc.default.svc.cluster.local
port:
number: 80
4、 测试结果
/ # while true; do wget -q -O- http://svc.test.com:32623 ;sleep 1; done
<html><body><h1>It works!</h1></body></html>
<html><body><h1>It works!</h1></body></html>
<html><body><h1>It works!</h1></body></html>
<h1>Welcome to nginx!</h1>
<html><body><h1>It works!</h1></body></html>
<h1>Welcome to nginx!</h1>
<html><body><h1>It works!</h1></body></html>
4、不同命名空间下的Gateway
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: web-gateway-httpd
namespace: test
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: httpd
protocol: HTTP
hosts:
- "svc.test.com"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: my-namespace
spec:
hosts:
- "svc.test.com"
gateways:
- test/web-gateway-httpd
http:
- match:
- uri:
prefix: /
route:
- destination:
host: httpd-web-svc.test.svc.cluster.local
port:
number: 80
5、省略gateways跨域
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: nginx-web
labels:
app: nginx
deploy: nginx
server: web
spec:
selector:
matchLabels:
app: nginx
deploy: nginx
server: web
template:
metadata:
labels:
app: nginx
deploy: nginx
server: web
spec:
containers:
- name: nginx
image: alvinos/nginx:v1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-web-svc
labels:
app: nginx-web-svc
deploy: nginx-web-svc
spec:
ports:
- port: 80
targetPort: 80
name: nginx
protocol: TCP
selector:
server: web
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: web-gateway-nginx
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: nginx
protocol: HTTP
hosts:
- "svc.test.com"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: allow
spec:
hosts:
- "svc.test.com"
gateways:
- default/web-gateway-nginx
http:
- corsPolicy:
allowCredentials: true # 响应头表示是否可以将对请求的响应暴露给页面。返回true则可以,其他值均不可以。
allowOrigins: # 响应头指定了该响应的资源是否被允许与给定的origin共享。
- exact: "http://svc.test.com:32623" # 完全匹配
match:
- uri:
prefix: /
route:
- destination:
host: nginx-web-svc.default.svc.cluster.local
port:
number: 80
6、allowOrigins prefix(前缀匹配)
http:
- corsPolicy:
allowCredentials: true # 响应头表示是否可以将对请求的响应暴露给页面。返回true则可以,其他值均不可以。
allowOrigins: # 响应头指定了该响应的资源是否被允许与给定的origin共享。
- prefix: "http://svc.test.com"
8、allowOrigins regex(正则匹配)
http:
- corsPolicy:
allowCredentials: true # 响应头表示是否可以将对请求的响应暴露给页面。返回true则可以,其他值均不可以。
allowOrigins: # 响应头指定了该响应的资源是否被允许与给定的origin共享。
- regex: ".*"
9、设置exposeHeaders
http:
- corsPolicy:
allowCredentials: true
allowOrigins:
- prefix: "http://localhost"
exposeHeaders: # 响应头指定了该响应首部添加响应header头
- test
- test2
10、设置allowHeaders
allowHeaders:
- X-Custom-Header
- content-type
11、设置allowMethods
allowMethods:
- GET
- DELETE
12、长短fqdn
# 在default名称空间创建vs
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: my-fqdn
spec:
hosts:
- "nginx.default.svc.cluster.local" # 长fqdn
- "nginx" # 短fqdn
http:
- match:
- uri:
prefix: /
route:
- destination:
host: nginx-web-svc.default.svc.cluster.local
port:
number: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
ports:
- port: 80
name: http
selector:
app: nginx
四、基于TLS的HTTPS请求
一个有序列表,对应的是透传 TLS 和 HTTPS 流量。路由过程通常利用 ClientHello 消息中的 SNI 来完成。TLS 路由通常应用在 https-、tls- 前缀的平台服务端口,或者经 Gateway 透传的 HTTPS、TLS 协议端口,以及使用 HTTPS 或者 TLS 协议的 ServiceEntry 端口上。注意:没有关联 VirtualService 的 https- 或者 tls- 端口流量会被视为透传 TCP 流量。
1、创建证书
# 因为是测试环境,我在这里手动签发证书,如果是生产环境最好在云服务商哪里购买证书
[root@kubernetes-master-01 cert]# openssl genrsa -out tls.key 2048
[root@kubernetes-master-01 cert]# openssl req -new -x509 -key tls.key -out tls.crt -subj /C=CN/ST=ShangHai/L=ShangHai/O=Ingress/CN=svc.test.com
2、创建secret
[root@kubernetes-master-01 cert]# kubectl -n default create secret tls nginx-tls --cert=tls.crt --key=tls.key
secret/nginx-tls created
[root@kubernetes-master-01 cert]# kubectl get secrets
NAME TYPE DATA AGE
nginx-tls kubernetes.io/tls 2 19s
3、创建Nginx配置文件
---
kind: ConfigMap
apiVersion: v1
metadata:
name: tls
labels:
app: tls
data:
nginx.conf: |
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
events
worker_connections 1024;
http
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
include /etc/nginx/mime.types;
default_type application/octet-stream;
server
listen 443 ssl;
ssl_certificate /etc/nginx-server-certs/tls.crt;
ssl_certificate_key /etc/nginx-server-certs/tls.key;
server_name _;
location /
root /usr/share/nginx/html;
index index.html;
4、创建Deployment资源
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: tls
spec:
selector:
matchLabels:
app: tls
template:
metadata:
labels:
app: tls
spec:
containers:
- name: nginx
imagePullPolicy: IfNotPresent
image: nginx
volumeMounts:
- mountPath: /etc/nginx/nginx.conf
name: nginxconfig
readOnly: true
subPath: nginx.conf
- mountPath: /etc/nginx-server-certs
name: nginx-tls
readOnly: true
volumes:
- name: nginxconfig
configMap:
name: tls
items:
- key: nginx.conf
path: nginx.conf
- name: nginx-tls
secret:
secretName: nginx-tls
---
kind: Service
apiVersion: v1
metadata:
name: tls
labels:
app: tls
spec:
ports:
- port: 443
targetPort: 443
name: tls
selector:
app: tls
5、创建Gateway资源
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: tls
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: tls
protocol: HTTPS
hosts:
- "svc.test.com"
tls:
mode: PASSTHROUGH
6、创建VirtualService资源
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: nginx
spec:
hosts:
- tls.test.com
gateways:
- tls
tls:
- match:
- port: 443
sniHosts:
- tls.test.com
route:
- destination:
host: tls.default.svc.cluster.local
port:
number: 443
五、 基于TCP的各种服务
一个针对透传 TCP 流量的有序路由列表。TCP 路由对所有 HTTP 和 TLS 之外的端口生效。进入流量会使用匹配到的第一条规则。
1、创建基础服务
---
apiVersion: v1
kind: Service
metadata:
name: tcp-echo
labels:
app: tcp-echo
service: tcp-echo
spec:
ports:
- name: tcp
port: 3306
selector:
app: tcp-echo
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: tcp-echo
spec:
replicas: 1
selector:
matchLabels:
app: tcp-echo
version: v1
template:
metadata:
labels:
app: tcp-echo
version: v1
spec:
containers:
- name: tcp-echo
image: mysql:5.7
imagePullPolicy: IfNotPresent
env:
- name: MYSQL_ROOT_PASSWORD
value: "123456"
ports:
- containerPort: 3306
2、创建网关服务
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: tcp-echo-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 31400
name: tcp
protocol: TCP
hosts:
- "mysql.test.com"
3、创建VirtualService资源
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: tcp-echo
spec:
hosts:
- "mysql.test.com"
gateways:
- tcp-echo-gateway
tcp:
- match:
- port: 31400
route:
- destination:
host: tcp-echo
port:
number: 3306
4、部署结果
以上是关于linux12企业实战 -- 09VirtualService(虚拟服务)的主要内容,如果未能解决你的问题,请参考以下文章
linux12企业实战 -- 17queue messages