前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Istio边界流量-Ingress Gateway

Istio边界流量-Ingress Gateway

作者头像
王先森sec
发布2023-04-24 17:38:58
6510
发布2023-04-24 17:38:58
举报
文章被收录于专栏:王先森

Ingress Gateway简介

传统上,Kubernetes使用Ingress控制器来处理从外部进入集群的流量。使用Istio时,情况不再如此。 Istio已用新的GatewayVirtualServices资源替换了熟悉的Ingress资源。它们协同工作,将流量路由到网格中。在网格内部,不需要Gateway,因为服务可以通过集群本地服务名称相互访问。

Istio流量分发控制

环境准备

主机名

IP

角色

k8s-master

eth0:10.1.1.100、docker:172.17.100.0/24

K8S-master

k8s-node1

eth0:10.1.1.120、docker:172.17.120.0/24

K8S-node

k8s-node2

eth0:10.1.1.130、docker:172.17.130.0/24

K8S-node

nginx-proxy

eth0:10.1.1.11

代理节点

场景模型图

目前我们实现了后台服务层面,前端front调用后端service的流量策略,现在实现下客户访问前端的流量策略注入,区别是前端界面访问需要配置ingress域名。

准备资源配置清单

创建前端UI v2版本以及SVC资源配置清单

  • Front-tomcat v2
  • Service
代码语言:javascript
复制
$ cat > front-tomcat-v2-dpl.yaml <<EOF 
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: front-tomcat
    version: v2
  name: front-tomcat-v2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: front-tomcat
      version: v2
  template:
    metadata:
      labels:
        app: front-tomcat
        version: v2
    spec:
      containers:
      - image: tomcat:9.0-jdk11
        name: front-tomcat
        command: ["/bin/sh", "-c", "mkdir /usr/local/tomcat/webapps/ROOT;echo '这是tomcat-v2版本:<iframe name=\"footer\" marginwidth=0 marginheight=0 width=100% height=50 src=\"http://bill.istio.com/\" frameborder=0></iframe>'>/usr/local/tomcat/webapps/ROOT/index.html;/usr/local/tomcat/bin/catalina.sh run;"]
EOF
代码语言:javascript
复制
$ cat > front-tomcat-service.yaml <<EOF
apiVersion: v1
kind: Service
metadata:
  labels:
    app: front-tomcat
  name: front-tomcat
spec:
  ports:
  - name: http
    port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    app: front-tomcat
  type: ClusterIP
EOF

准备流量调度资源配置清单

将v1版本接入90%的流量,v2版本接入10%的流量

  • VirtualService
  • DestinationRule
代码语言:javascript
复制
$ cat > front-tomcat-virtualservice.yaml <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: front-tomcat
spec:
  hosts:
  - front-tomcat
  http:
  - name: front-tomcat-route
    route:
    - destination:
        host: front-tomcat
        subset: v1
      weight: 90
    - destination:
        host: front-tomcat
        subset: v2
      weight: 10
EOF
代码语言:javascript
复制
$ cat > front-tomcat-destinationrule.yaml <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: front-tomcat
spec:
  host: front-tomcat
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
EOF

应用资源配置清单

代码语言:javascript
复制
$ kubectl apply -f front-tomcat-service.yaml
$ kubectl apply -f <(istioctl kube-inject -f front-tomcat-v2-dpl.yaml)
$ kubectl apply -f front-tomcat-virtualservice.yaml
$ kubectl apply -f front-tomcat-destinationrule.yaml

访问网格内服务

使用Ingress来访问网格服务]

代码语言:javascript
复制
cat > front-tomcat-ingress.yaml <<EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: front-tomcat
spec:
  rules:
  - host: tomcat.istio.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service: 
            name: front-tomcat
            port:
              number: 8080
EOF

使用浏览器访问查看效果。

注意:只有网格内部访问会遵从virtualservice的规则,在宿主机中直接访问Service的ClusterIP还是按照默认的规则转发。此时还是各0.5权重,没有调度到istio。

Ingress:对接ingress controller,实现外部流量进入集群内部,只适用于 HTTP 流量,使用方式也很简单,只能对 service、port、HTTP 路径等有限字段匹配来路由流量,这导致它无法路由如 MySQLRedis 和各种私有 RPC 等 TCP 流量。要想直接路由南北向的流量,只能使用 Service 的 LoadBalancerNodePort,前者需要云厂商支持,后者需要进行额外的端口管理。有些 Ingress controller支持暴露 TCP 和 UDP 服务,但是只能使用 Service 来暴露,Ingress 本身是不支持的,例如 nginx ingress controller,服务暴露的端口是通过创建 ConfigMap 的方式来配置的。

IngressGateway访问网格服务

对于入口流量管理,您可能会问: 为什么不直接使用 Kubernetes Ingress API ? 原因是 Ingress API 无法表达 Istio 的路由需求。 Ingress 试图在不同的 HTTP 代理之间取一个公共的交集,因此只能支持最基本的 HTTP 路由,最终导致需要将代理的其他高级功能放入到注解(annotation)中,而注解的方式在多个代理之间是不兼容的,无法移植。

Istio Gateway 通过将 L4-L6 配置与 L7 配置分离的方式克服了 Ingress 的这些缺点。 Gateway 只用于配置 L4-L6 功能(例如,对外公开的端口,TLS 配置),所有主流的L7代理均以统一的方式实现了这些功能。 然后,通过在 Gateway 上绑定 VirtualService 的方式,可以使用标准的 Istio 规则来控制进入 Gateway 的 HTTP 和 TCP 流量。

代码语言:javascript
复制
cat > front-tomcat-gateway.yaml <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: front-tomcat-gateway
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - tomcat.istio.com
EOF

效果是在Istio的ingress网关上加了一条规则,允许`tomcat.istio.com 的外部http流量进入到网格中,但是只是接受访问和流量输入,当流量到达这个网关时,它还不知道发送到哪里去。

网关已准备好接收流量,我们必须告知它将收到的流量发往何处,这就用到了前面使用过的VirtualService

要为进入上面的 Gateway 的流量配置相应的路由,必须为同一个 host 定义一个 VirtualService,并使用配置中的 gateways 字段绑定到前面定义的 Gateway

代码语言:javascript
复制
cat > front-tomcat-gateway-virtualservice.yaml <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: gateway-front-tomcat
spec:
  gateways:
  - front-tomcat-gateway
  hosts:
  - tomcat.istio.com
  http:
  - name: front-tomcat-route
    route:
    - destination:
        host: front-tomcat
        subset: v1
      weight: 90
    - destination:
        host: front-tomcat
        subset: v2
      weight: 10
EOF

该网关列表指定,只有通过我们指定的网关 front-tomcat-gateway 的流量是允许的。所有其他外部请求将被拒绝,并返回 404 响应。

请注意,在此配置中,来自网格内部的其他服务请求不受这些规则约束。

代码语言:javascript
复制
$ kubectl apply -f front-tomcat-gateway-virtualservice.yaml
$ kubectl apply -f front-tomcat-gateway.yaml
# 验证
$ kubectl get vs gateway-front-tomcat 
NAME                   GATEWAYS                   HOSTS                  AGE
gateway-front-tomcat   ["front-tomcat-gateway"]   ["tomcat.istio.com"]   1h

$ kubectl get gw front-tomcat-gateway
NAME                   AGE
front-tomcat-gateway   1h

模拟访问:

此时我们已经走到ingressgateway上面了,所以要访问需要确认这里的svc是哪个映射端口,如下ingress映射80:80;ingressgateway映射80:32000,所以要访问域名:32000

代码语言:javascript
复制
$ kubectl get svc -n istio-system istio-ingressgateway 
NAME                   TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)                                                                      AGE
istio-ingressgateway   LoadBalancer   192.168.231.83   <pending>     15021:30789/TCP,80:32000/TCP,443:31504/TCP,31400:30737/TCP,15443:32222/TCP   22h

# 也可以直接获取ingressgateway的nodeport
$ kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}'
32000

# 访问
$ curl  -HHost:tomcat.istio.com 10.1.1.100:32000/

访问流程图:

浏览器访问: http://tomcat.istio.com:30779/

配置Nginx转发域名请求

如何实现不加端口访问网格内服务?

在集群外Nginx配置

代码语言:javascript
复制
$ cat > /etc/nginx/conf.d/istio.com.conf <<EOF
upstream default_backend_istio {
        server 10.1.1.120:32000 max_fails=3 fail_timeout=10s;
        server 10.1.1.100:32000 max_fails=3 fail_timeout=10s;
        server 10.1.1.130:32000 max_fails=3 fail_timeout=10s;
    }
server {
    server_name *.istio.com;
  
    location / {
        proxy_pass http://default_backend_istio;
        proxy_http_version 1.1;   # Istio 默认只支持 HTTP/1.1 以上协议版本,并不支持 HTTP/1.0 
        proxy_set_header Host       $http_host;
        proxy_set_header x-forwarded-for $proxy_add_x_forwarded_for;
    }
}
EOF

在集群内Nginx配置

代码语言:javascript
复制
# 在K8S集群中使用一台80端口未被占用的机器中,如ip为10.1.1.100
$ docker run -d --restart=always -p 80:80 --name istio-nginx nginx:alpine

# 在容器的/etc/nginx/conf.d/目录中,新增配置文件
$ docker exec -it  istio-nginx sh
$ cat > /etc/nginx/conf.d/front-tomcat.conf <<EOF
upstream front-tomcat {
        server 192.168.231.83:80;
}
server {
    listen       80;
    listen  [::]:80;
    server_name  tomcat.istio.com;

    location / {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_http_version 1.1;
        proxy_pass http://front-tomcat;
    }
}
EOF
$ nginx -s reload

绑定hosts

win本地配置hosts,注意配置nginx部署的机器,而不是k8s集群ingress-nginx服务的机器

代码语言:javascript
复制
10.1.1.11 tomcat.istio.com

访问结果:

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-02-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Ingress Gateway简介
  • Istio流量分发控制
    • 环境准备
      • 场景模型图
        • 准备资源配置清单
          • 准备流量调度资源配置清单
            • 应用资源配置清单
            • 访问网格内服务
              • 使用Ingress来访问网格服务]
                • IngressGateway访问网格服务
                  • 配置Nginx转发域名请求
                    • 在集群外Nginx配置
                    • 在集群内Nginx配置
                    • 绑定hosts
                相关产品与服务
                服务网格
                服务网格(Tencent Cloud Mesh, TCM),一致、可靠、透明的云原生应用通信网络管控基础平台。全面兼容 Istio,集成腾讯云基础设施,提供全托管服务化的支撑能力保障网格生命周期管理。IaaS 组网与监控组件开箱即用,跨集群、异构应用一致发现管理加速云原生迁移。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档