istio集群外流量治理
istio外部流量治理
将k8s集群外部的服务,引入到集群内,当做网格治理
适用于业务迁移到服务网格的中间阶段,此时可能部分服务已经迁移到网格,一部分还是vm、物理机在运行,就需要对外部的这部分做流量治理
ServiceEntry资源
sidecar egress侦听器在allow_any策略下,在网格中请求未定义的外部流量,使用的是tcp透传,无法做网络治理,但有时又需要治理外部服务,则需要使用ServiceEntry资源,将外部资源注册到istio中,实现手动添加外部服务到网格中
ServiceEntry资源向istio的服务注册表添加1个ServiceEntry后(相当于svc),网格中的envoy可将流量发给注册的这个svc,也可做相关治理(配合vs、dr)
功能:
- 重定向和转发外部目标流量
- 为外部的目标添加重试、超时、故障注入、断路器等功能,实现与集群内服务网格一样的治理功能
- 将vm添加到网格中,可实现在vm上运行网格服务
- 将不同集群中的服务添加到网格中,在k8s上配置多集群的istio网格
注意:
- 访问外部服务时,sidecar envoy默认使用透传方式,访问外部服务,se只是做锦上添花的功能
- 具体完成高级治理功能,还需要配合vs、dr资源一起使用
不能自动添加到网格的服务类型
- 网格外部服务:运行在k8s中,但非istio网格管理的命名空间中的pod,或直接运行在物理机和虚拟机的服务,这些服务在ServiceEntry中称为:mesh_external
- 网关内但未注册服务:没有svc的pod等,在ServiceEntry中称为:mesh_internal
配置
se引入外部服务时,内容主要包括:服务dns、ip、端口、协议、端点等
端点获取方式:
- dns解析
- 静态指定
- 使用workload selector:直接用k8s标签选择器选择pod,或者由WorkloadEntry资源引入外部端点到网格内
语法:
kubectl explain se

apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
spec:
addresses: [str] #指定ip,与hosts项同时配置时,会直接访问ip。对应k8s的svc的ip。与hosts同时配置时,只有其中1g
exportTo: [str] #限定配置生效后,哪些命名空间可以访问
- '.' #当前命名空间可见,其他命名空间无法访问此se
- '*' #所有命名空间可见,默认配置
hosts: [str] #匹配在vs和dr中定义的主机,一般是dns域名(http中是host/authority标头,https/tls中是sni)。对应envoy的虚拟主机名,k8s的svc名,指定名称后可不用写addresses
location: str #服务的位置
#MESH_EXTERNAL,服务在网格外,需要用api访问接口。不支持mtls
#MESH_INTERNAL,服务在网格内,支持mtls
ports: #服务使用端口
- name: str #se使用端口,svc自己使用的端口
number: int
protocol: str
targetPort: int #指定目标端口,svc代理的后端服务端口。当se监听端口与后端代理端口不同时,必须配置
resolution: str #服务解析方式,解析与服务关联的各个后端端点的ip地址
#NONE,无,假设已经被解析为ip地址
#STATIC,使用endpoint字段中指定的静态ip地址
#DNS,异步查询dns解析ip,与envoy的STRICT_DNS类似
#DNS_ROUND_ROBIN,异步查询dns解析ip,类似envoy的LOGICAL_DNS
subjectAltNames: [str] #STATIC时使用
endpoints: #静态指定后端端点,与envoy静态指定集群端点一样
- address: str
labels: {}
locality: str
network: str
ports:
协议: 端口
serviceAccount: str
weight: int
workloadSelector: #标签选择器,选择se要用到的后端端点(we、wg资源、k8s集群上特定pod),与endpoint项互斥
labels: {}
workloadEntry资源
workloadEntry简写we
se只解决了将外部资源定义为svc的功能,但具体到endpoint就不能详细显示,因此引入v1.6引入新资源workloadEntry资源,将非k8s内的服务,如vm、物理机当做k8s上的pod,并具备网络治理功能
se资源可根据we资源中定义的标签,使用标签选择选择vm,将功能分离。在v1.8版本后,对vm由做了增强:
- vm自动注册:wg资源,将vm自动注册为we
- 智能dns代理:使用sidecar dns proxy,缓存网格中endpoint(包含se创建的endpoint),vm访问网格中的服务就不用手动配置/etc/hosts文件
配置
kubectl explain we
apiVersion: networking.istio.io/v1beta1
kind: WorkloadEntry
metadata:
spec:
address: str #外部地址
labels: {} #设置标签
locality: str
network: str
ports:
协议: 端口
serviceAccount: str #与sa账号关联
weight: int
workloadGroup资源
workloadGroup简写wg,用于将we定义为1个组,通过wg管理组内we
可以对we资源做健康检测
配置
kubectl explain wg

apiVersion: networking.istio.io/v1beta1
kind: WorkloadGroup
metadata:
spec:
metadata: #wg添加注解、标签
annotations: {}
labels: {}
probe: #就绪探针探测集群外部服务,并基于下面定义的模板,生成we资源
exec:
command: [str]
httpGet:
host: str
httpHeaders:
- name: str
value: str
path: str
port: int
scheme: str
tcpSocket:
host: str
port: int
initialDelaySeconds: int
failureThreshold: int
periodSeconds: int
successThreshold: int
timeoutSeconds: int
template: #we内容
address: str
labels: str
locality: str
network: str
ports: {}
serviceAccount: str
weight: int
egress gateway资源
se、we定义外部资源后,流量实际上是sidecar直接与外部访问,如果需要对这个部分流量做治理,则需要使用egress gateway
最终流量路径为:
请求 --> sidecar --> se(svc) --> egress-gw --> 服务
注:由于egress-gw会处理所有出站流量,可能导致它成为性能瓶颈,一般不会选择做2级处理,而是通过se直接发出去,除非特别要求
egress gateway实际上还是使用gw资源,只不过在网关控制器上选择egress-gw即可,参考前面ingress-gw配置
案例:
例1:注册k8s集群外服务到服务网格
1)物理机配置nginx
yum install -y nginx
#配置ngx
mkdir /opt/web
echo ngx.hj.com > /opt/web/index.html
cat > /etc/nginx/conf.d/ngx.hj.com.conf <<EOF
server {
listen 80;
server_name ngx.hj.com;
root /opt/web;
}
EOF
systemctl start nginx
curl -H 'host: ngx.hj.com' 127.0.0.1
2)注册web服务到服务网格
cat <<EOF |kubectl apply -f -
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
labels:
app: nginx
name: ngx-external-se
spec:
hosts:
- ngx.hj.com
addresses:
- '2.2.2.25'
ports:
- name: http
number: 80
protocol: HTTP
location: MESH_EXTERNAL
resolution: STATIC
endpoints:
- address: 2.2.2.25
ports:
http: 80
EOF
3)为注册的se做流量治理
cat <<EOF |kubectl apply -f -
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: ngx-dr
spec:
host: ngx.hj.com
trafficPolicy:
loadBalancer:
consistentHash:
httpHeaderName: x-user
connectionPool:
tcp:
maxConnections: 10000
connectTimeout: 10ms
tcpKeepalive:
time: 7200s
interval: 75s
http:
http2MaxRequests: 1000
maxRequestsPerConnection: 10
outlierDetection:
maxEjectionPercent: 50
consecutive5xxErrors: 5
interval: 2m
baseEjectionTime: 1m
minHealthPercent: 40
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: ngx-vs
spec:
hosts:
- ngx.hj.com
http:
- name: default
route:
- destination:
host: ngx.hj.com
EOF
4)测试
istioctl pc cluster admin
curl -H 'host: ngx.hj.com' 2.2.2.17


例2:结合we再管理外部ngx
根据例1演进
1)结合we配置se
cat <<EOF |kubectl apply -f -
apiVersion: networking.istio.io/v1beta1
kind: WorkloadEntry
metadata:
name: ngx-we
labels:
version: v1.0
spec:
address: "2.2.2.25"
ports:
http: 80
labels:
app: nginx
version: v1.0
instance-id: nginx
---
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
name: ngx-external-se
spec:
hosts:
- ngx.hj.com
ports:
- number: 80
name: http
protocol: HTTP
location: MESH_EXTERNAL
resolution: STATIC
workloadSelector:
labels:
app: nginx
EOF
2)vs+dr做流量治理
cat <<EOF |kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: ngx-dr
spec:
host: ngx.hj.com
subsets:
- name: v10
labels:
version: v1.0
app: nginx
trafficPolicy:
loadBalancer:
consistentHash:
httpHeaderName: x-user
connectionPool:
tcp:
maxConnections: 10000
connectTimeout: 10ms
tcpKeepalive:
time: 7200s
interval: 75s
http:
http2MaxRequests: 1000
maxRequestsPerConnection: 10
outlierDetection:
maxEjectionPercent: 50
consecutive5xxErrors: 5
interval: 2m
baseEjectionTime: 1m
minHealthPercent: 40
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: ngx-vs
spec:
hosts:
- ngx.hj.com
http:
- name: default
route:
- destination:
host: ngx.hj.com
subset: v10
weight: 100
EOF
3)测试
while : ;do curl -H 'host: ngx.hj.com' 2.2.2.17; sleep .7; done

例3:配合egress-gw,管理发往外部的流量
基于例2
1)配置gw、vs资源
cat <<EOF |kubectl apply -f -
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: ngx-egress-gw
namespace: istio-system
spec:
selector:
istio: egressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- '*'
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: ngx-vs
spec:
hosts:
- ngx.hj.com
gateways:
- istio-system/ngx-egress-gw
- mesh
http:
- match:
- gateways:
- mesh
route:
- destination:
host: istio-egressgateway.istio-system.svc.cluster.local
- match:
- gateways:
- istio-system/ngx-egress-gw
route:
- destination:
host: ngx.hj.com
subset: v10
weight: 100
EOF
2)查看结果


浙公网安备 33010602011771号