如何获得一个Istio VirtualService来通过标题和uri改变路由 [英] How to get an Istio VirtualService to vary routes by header along with uri

查看:101
本文介绍了如何获得一个Istio VirtualService来通过标题和uri改变路由的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我仍在与其他几个人一起在开发集群中尝试Istio.我们有一个示例虚拟服务,部署和destinationrule,对指定uri的请求将转到与该部署关联的pod.一切正常.

I'm still experimenting with Istio in a dev cluster, along with a couple of other people. We have a sample virtualservice, deployment, and destinationrule, and requests to the specified uri are going to the pod associated with the deployment. This is working fine.

如果存在特定的标头和值,我尝试将其更改为备用部署.如果未设置标头,或指定的标头值不存在,它将转到原始部署,否则转到备用部署.我最终打算让它检查指定标头的几个不同值,每个值都用于不同的部署.

I am attempting a variation of this that goes to an alternate deployment if a particular header and value are present. If the header is not set, or the specified header value is not present, it will go to the original deployment, otherwise to the alternate deployment. I eventually intend for it to check for several different values of the specified header, each going to different deployments.

我创建了一个部署和目标规则,它们是原始副本的副本,具有一致的变体.我试图使用此备用路由来修改虚拟服务.到目前为止,它无法正常工作.我通过跟踪与每个部署关联的容器的容器日志来确定请求转到哪个部署.当我发送带有指定标头和值的请求时,它确实转到了备用部署.但是,当我发送的请求没有指定的标头或没有匹配的值时,它也将转到备用部署.实际上,我根本无法达到主要部署.

I've created a deployment and destination rule that are copies of the original, with consistent variations. I attempted to modify the virtualservice with this alternate routing. Thus far, it isn't working properly. I determine which deployment a request goes to by tailing the container log of the container associated with each deployment. When I sent a request with the specified header and value, it does go to the alternate deployment. However, when I send the request without the specified header, or without the matching value, it ALSO goes to the alternate deployment. In fact, I can't get it to reach the main deployment at all.

请注意,我知道执行此操作的另一种方法是为默认"路由提供一个虚拟服务,为每个备用路由提供一个附加虚拟服务,并指定不同的标头值.我基本上看到了类似的东西.但是,要获得在单个VirtualService中设置起来应该更简单的内容,这似乎是很多重复的事情.

Note that I understand that another way to do this is to have one virtualservice for the "default" route, and an additional virtualservice for each alternate route, specifying a different header value. I've seen something basically like that working. However, that seems like a lot of duplication to get something that should be simpler to set up in a single VirtualService.

以下是虚拟服务的当前状态,其中有一些省略:

The following is the current state of the virtualservice, with some elisions:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  annotations: {}
  name: fooms-vs-ingress
  namespace: com-example
spec:
  gateways:
  - ingress-gateway
  hosts:
  - '*'
  http:
  - match:
    - uri:
        prefix: /msapi/foo
    - headers:
        ctx-debug-route-fooms:
          exact: myuid-1
    route:
    - destination:
        host: fooms.com-example.svc.cluster.local
        port:
          number: 80
        subset: myuid-1
  - route:
    - destination:
        host: fooms.com-example.svc.cluster.local
        port:
          number: 80
        subset: blue

我可以显示部署和目的地规则,但是我不知道这是否有帮助.

I could show the deployments and destinationrules, but I don't know if that will be helpful.

更新:

自从我撰写本文以来,我发现为了在路由匹配中同时创建两个条件,必须在单个匹配规则中同时具有两个条件.我仍然习惯于YAML的工作方式.我将在此处提供虚拟服务的更新版本,以及网关,目标规则和大部分部署.部署中有很多东西可能无济于事.

Since I wrote this, I discovered that in order to make two conditions AND in a route match, I have to have both conditions in a single match rule. I'm still getting used to how YAML works. I'm going to provide here an updated version of the virtualservice, along with the gateway, destination rule, and much of the deployment. There's a lot of stuff in the deployment that probably isn't helpful.

当我从Postman向服务发送请求时,无论是否带有路由标头,我都会收到503.在进行这些更改以检查路由头之前,它已将请求正确路由到蓝色"实例(我将两个Pod的日志都尾随了).当我第一次尝试进行这些更改时,我无意中定义了两个匹配块,一个带有uri条件,一个带有标头匹配条件.当我这样做时,所有请求都转到了备用吊舱.

When I sent a request to the service from Postman, with or without the routing header, I get a 503 back. Before I made these changes to check for the routing header, it was properly routing requests to the "blue" instance (I am tailing the logs for both pods). When I first tried making these changes, I inadvertently defined two match blocks, one with the uri condition, and one with the header match condition. When I did that, all of the requests were going to the alternate pod.

以下是可能相关的对象的省略版本,其中删除了一些临时属性.

Here are elided versions of the objects that might be relevant, with some transient properties removed.

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  annotations: {}
  name: fooms-vs-ingress
  namespace: com-example
spec:
  gateways:
  - comp-ingress-gateway
  hosts:
  - '*'
  http:
  - match:
    - headers:
        compctx-debug-route-fooms:
          exact: myuid-1
      name: match-myuid-1
      uri:
        prefix: /msapi/foo
    route:
    - destination:
        host: fooms.com-example.svc.cluster.local
        port:
          number: 80
        subset: myuid-1
  - name: default
    route:
    - destination:
        host: fooms.com-example.svc.cluster.local
        port:
          number: 80
        subset: blue

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  annotations: {}
  name: comp-ingress-gateway
  namespace: com-example
spec:
  selector:
    istio: ingressgateway
  servers:
  - hosts:
    - '*'
    port:
      name: http
      number: 80
      protocol: HTTP
  - hosts:
    - '*'
    port:
      name: https
      number: 443
      protocol: HTTPS
    tls:
      mode: SIMPLE
      privateKey: /etc/istio/ingressgateway-certs/tls.key
      serverCertificate: /etc/istio/ingressgateway-certs/tls.crt

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
  labels:
    app: FooMS
    role: blue
    routeoffer: DEFAULT
    seed: COMPv2.2.0
    version: 2.2.0-myuid-1
  name: fooms-myuid-1
  namespace: com-example
spec:
  replicas: 1
  revisionHistoryLimit: 2
  selector:
    matchLabels:
      app: FooMS
      role: blue
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      annotations:
        sidecar.istio.io/inject: "true"
      creationTimestamp: null
      labels:
        app: FooMS
        role: blue
        routeoffer: DEFAULT
        seed: COMPv2.2.0
        version: 2.2.0-myuid-1
    spec:
      containers:
      - env:
        - name: SERVICE_NAME
          value: fooms
        - name: NODE_NAME
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: spec.nodeName
        envFrom:
        - configMapRef:
            name: global-config
        - secretRef:
            name: global-secrets
        image: dockercentral.it....
        imagePullPolicy: Always
        name: fooms
        ports:
        - containerPort: 8080
          name: http
          protocol: TCP
      - image: ...
        imagePullPolicy: IfNotPresent
        name: info
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      serviceAccount: default
      serviceAccountName: default
      terminationGracePeriodSeconds: 30

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  annotations: {}
  name: fooms-destination-myuid-1
  namespace: com-example
spec:
  host: fooms.com-example.svc.cluster.local
  subsets:
  - labels:
      version: 2.2.0-myuid-1
    name: myuid-1
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL

推荐答案

由于我没有该命令提供的所有信息kubectl get pods,ep,svc -o wide我不确定这是目标规则错误,因为我不了解您的Pod的所有信息,ep,svc和您的目标规则适用于只有1个副本的同一部署.

Since I don't have all informations from this command kubectl get pods,ep,svc -o wide i'm not sure that's destination rule error because i don't know everything about your pods,ep,svc and your destination rule applies to same deployment with only 1 replica.

可能是存在目标规则的问题子集

Probably the problem there is destination rule with only 1 subset

根据您的虚拟服务,我认为这就是您的方式目标规则应该看起来

Based on your virtual service i think that's how your destination rule should look

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: fooms-destination-myuid-1
  namespace: com-example
spec:
  host: fooms.com-example.svc.cluster.local
  subsets:
  - labels:
      version: 2.2.0-myuid-1
    name: myuid-1
  subsets:
  - labels:
       role: blue
    name: blue
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL

我举了一个例子,下面说明了一切

I made some example, everything needed to make this below

Kubernetes版本 1.13.11-gke.14

Kubernetes version 1.13.11-gke.14

Istio版本 1.4.1

kubectl label namespace default istio-injection=enabled

部署 1

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx1
spec:
  selector:
    matchLabels:
      run: nginx1
  replicas: 1
  template:
    metadata:
      labels:
        run: nginx1
        app: frontend
    spec:
      containers:
      - name: nginx1
        image: nginx
        ports:
        - containerPort: 80
        lifecycle:
          postStart:
            exec:
              command: ["/bin/sh", "-c", "echo Hello nginx1 > /usr/share/nginx/html/index.html"]

部署 2

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx2
spec:
  selector:
    matchLabels:
      run: nginx2
  replicas: 1
  template:
    metadata:
      labels:
        run: nginx2
        app: frontend
    spec:
      containers:
      - name: nginx2
        image: nginx
        ports:
        - containerPort: 80
        lifecycle:
          postStart:
            exec:
              command: ["/bin/sh", "-c", "echo Hello nginx2 > /usr/share/nginx/html/index.html"]

服务

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: frontend
spec:
  ports:
  - port: 80
    protocol: TCP
  selector:
    app: frontend

网关

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: comp-ingress-gateway
  namespace: default
spec:
  selector:
    istio: ingressgateway
  servers:
  - hosts:
    - '*'
    port:
      name: http
      number: 80
      protocol: HTTP
  - hosts:
    - '*'
    port:
      name: https
      number: 443
      protocol: HTTPS
    tls:
      mode: SIMPLE
      privateKey: /etc/istio/ingressgateway-certs/tls.key
      serverCertificate: /etc/istio/ingressgateway-certs/tls.crt

虚拟服务

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: nginxvirt
spec:
  gateways:
  - comp-ingress-gateway #outside cluster
  - mesh #inside cluster
  hosts:
  - nginx.default.svc.cluster.local #inside cluster
  - nginx.com #outside cluster
  http:
  - name: match-myuid
    match:
    - uri:
        prefix: /msapi
      headers:
        compctx:
          exact: myuid
    rewrite:
      uri: /
    route:
    - destination:
        host: nginx.default.svc.cluster.local
        port:
          number: 80
        subset: v1
  - name: default
    route:
    - destination:
        host: nginx.default.svc.cluster.local
        port:
          number: 80
        subset: v2

目的地规则

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: nginxdest
spec:
  host: nginx.default.svc.cluster.local
  subsets:
  - name: v1
    labels:
      run: nginx1
  - name: v2
    labels:
      run: nginx2
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL

要测试的广告包

apiVersion: v1
kind: Pod
metadata:
  name: ubu1
spec:
  containers:
  - name: ubu1
    image: ubuntu
    command: ["/bin/sh"]
    args: ["-c", "sleep 3000"]

卷曲的结果:

外部:

curl -H "host: nginx.com" -H "compctx: myuid" ingress_gateway_ip/msapi
Hello nginx1
curl -H "host: nginx.com" -H "compctx: myuid" ingress_gateway_ip/msapi
Hello nginx1
curl -H "host: nginx.com" -H "compctx: myuid" ingress_gateway_ip/msapi
Hello nginx1

curl -H "host: nginx.com" ingress_gateway_ip
Hello nginx2
curl -H "host: nginx.com" ingress_gateway_ip
Hello nginx2
curl -H "host: nginx.com" ingress_gateway_ip
Hello nginx2

内部:

kubectl exec -ti ubu1 -- /bin/bash

root@ubu1:/# curl -H "compctx: myuid " nginx/msapi
Hello nginx1
root@ubu1:/# curl -H "compctx: myuid " nginx/msapi
Hello nginx1
root@ubu1:/# curl -H "compctx: myuid " nginx/msapi
Hello nginx1

这篇关于如何获得一个Istio VirtualService来通过标题和uri改变路由的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆