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

image-20230913142909761

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

image-20230913170449053

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

image-20231216150007330

image-20231216145820829

例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

image-20231216153311091

例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)查看结果

image-20231216161356111

posted @ 2023-12-20 19:50  suyanhj  阅读(182)  评论(0)    收藏  举报