Translating Ingress resource to Istio VirtualService or ServiceEntry

4/15/2020

I have an application with an Ingress resource shown below.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: {{ $fullName }}-stateful
  labels: 
    app: oxauth
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.org/ssl-services: "oxtrust"
    nginx.ingress.kubernetes.io/app-root: "/identity"
    nginx.ingress.kubernetes.io/affinity: "cookie"
    nginx.ingress.kubernetes.io/session-cookie-name: "route"
    nginx.ingress.kubernetes.io/session-cookie-hash: "sha1"
    nginx.ingress.kubernetes.io/proxy-next-upstream: "error timeout invalid_header http_500 http_502 http_503 http_504"
spec:
{{- if .Values.ingress.tls }}
  tls:
  {{- range .Values.ingress.tls }}
    - hosts:
      {{- range .hosts }}
        - {{ . | quote }}
      {{- end }}
      secretName: {{ .secretName }}
  {{- end }}
{{- end }}
  rules:
  {{- range .Values.ingress.hosts }}
    - host: {{ . | quote }}
      http:
        paths:
          - path: /identity
            backend:
              serviceName: oxtrust
              servicePort: 8080
          - path: /idp
            backend:
              serviceName: oxshibboleth
              servicePort: 8080
          - path: /passport
            backend:
              serviceName: oxpassport
              servicePort: 8090

I would like to translate that into a VirtualService to be used by Istio gateway. But once I do that the service oxpassport always returns a 503 error in the logs. That means the deployment can't be reached.

Below is the Service definition

apiVersion: v1
kind: Service
metadata:
  creationTimestamp: "2020-04-15T18:21:12Z"
  labels:
    app: oxpassport
    app.kubernetes.io/instance: kk
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/version: 4.1.0_01
    helm.sh/chart: oxpassport-1.0.0
  name: oxpassport
  namespace: test
spec:
  clusterIP: 10.111.71.120
  ports:
  - name: tcp-oxpassport
    port: 8090
    protocol: TCP
    targetPort: 8090
  selector:
    app: oxpassport
    release: kk
  type: ClusterIP
status:
  loadBalancer: {}

And finally the VS I am trying to use:

VirtualService

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: {{ include "istio.fullname" . }}-oxpassport
  namespace: {{ .Release.Namespace }}
spec:
  hosts:
    - oxpassport.{{ .Release.Namespace }}.svc.cluster.local
  gateways:
    - {{ .Release.Name }}-global-gtw
  http:
  - match:
    - uri:
        prefix: /passport
    rewrite:
      uri: /identity
    route:
    - destination:
        host: oxpassport.{{ .Release.Namespace }}.svc.cluster.local
        port:
          number: 8090

Gateway snippet:

  - port:
      number: 8090
      name: tcp-oxpassport
      protocol: HTTP
    hosts:
    - oxpassport.{{ .Release.Namespace }}.svc.cluster.local

Things to note:

  1. There is a backend app with these labels. And that has it's own VS and it's working:

     labels: 
        app: oxauth
  2. Oxpassport has a deployment with labels

      labels: 
         app: oxpassport

I know it's a long post but it's a blocker for quite some days now. If it is possible, please explain.

Thanks

-- Shammir
istio
kubernetes
kubernetes-ingress

1 Answer

4/21/2020

Gateway should be in the same namespace as virtual service, if it´s not in the same namespace as virtual service, you should add it like in below example.

Check the spec.gateways section

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: bookinfo-Mongo
  namespace: bookinfo-namespace
spec:
  gateways:
  - some-namespace/my-gateway 

In your ingress you have 3 paths then virtual service based on that ingress should look like there

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: {{ include "istio.fullname" . }}-oxpassport
  namespace: {{ .Release.Namespace }}
spec:
  hosts:
    - oxpassport.{{ .Release.Namespace }}.svc.cluster.local
  gateways:
    - {{ .Release.Name }}-global-gtw
  http:
  - name: a
    match:
    - uri:
        prefix: /identity
    route:
    - destination:
        host: oxtrust.{{ .Release.Namespace }}.svc.cluster.local
        port:
          number: 8080
  - name: b
    match:
    - uri:
        prefix: /idp
    route:
    - destination:
        host: oxshibboleth.{{ .Release.Namespace }}.svc.cluster.local
        port:
          number: 8080
  - name: c
    match:
    - uri:
        prefix: /passport
    route:
    - destination:
        host: oxpassport.{{ .Release.Namespace }}.svc.cluster.local
        port:
          number: 8090  

Cases with answers worth to check when problem 503 appears.


EDIT


Did you consider this nginx.ingress.kubernetes.io/app-root: "/identity"?

Missed that /identity app root, you can always rewrite all of them like you did.

Also, is there a particular reason why we can separate that whole - big - vs into different VS files?

No, you should be able to create seperate smaller virtual services instead of the big one, I just copied the ingress you provided.

-- jt97
Source: StackOverflow