How it works

Istio installs its services on k8s and make itself as k8s components. It creates VirtualService, DestinationRuleand ExternalService as CustomResourceDefinition, to define routing policy(redirect rule). There are 2 methods Istio uses to provide service currently, 1 is to use Istio Gateway it created under CustomResourceDefinition and all LB policy and routing definition are done on the VirtualService; 2 is to use k8s ingress API, istio only functions as an addon of k8s ingress, the major LB port and svc definition are all done on the Ingress, routing policy are done on VirtualService. Apparently, using Gateway is much easier for management.

Follow this page to install sidcar. Install Sidcar When installing sidcar and enabling automatic injection on pods, it defines pods under namespace with label: istio-injection=enabled will be injected with sidecar containors. Sidecar acts as agents, reporting and proxying traffic for istio. Injection occurs at pod creation time, recreating pods after adding label on namespace will result in injection creation.

Use Istio Gateway

This method is not currently available for 0.71.

Create Gateway

cat <<EOF | kubectl create -f -
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: httpbin-gateway
spec:
  servers:
  - port:
      number: 80
      name: http
  - port:
      number: 443
      name: https
    tls:
      mode: SIMPLE
      serverCertificate: /tmp/tls.crt
      privateKey: /tmp/tls.key
EOF

Define how it redircet traffic

This way we don’t need to use k8s ingress to define redirect action.

cat <<EOF | kubectl create -f -
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: httpbin
spec:
  hosts:
  - httpbin
  gateways:
  - httpbin-gateway
  http:
  - match:
      uri:
        prefix: /status
    route:
    - destination:
        port:
          number: 8000
        name: httpbin
  - match:
      uri:
        prefix: /delay
    route:
    - destination:
        port:
          number: 8000
        name: httpbin
EOF

Use k8s ingress API

To reuse k8s ingress as istio underlay, we need to install istio as addons.

Istio CustomResourceDefinition on k8s

VirtualService = VIP DestinationRule = Server Farm or Server Pool ExternalService = list of IPs not being affected by Istio, so that pods can reach external sites

apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: virtualservices.networking.istio.io
spec:
  group: networking.istio.io
  names:
    kind: VirtualService
    listKind: VirtualServiceList
    plural: virtualservices
    singular: virtualservice
  scope: Namespaced
  version: v1alpha3
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: destinationrules.networking.istio.io
spec:
  group: networking.istio.io
  names:
    kind: DestinationRule
    listKind: DestinationRuleList
    plural: destinationrules
    singular: destinationrule
  scope: Namespaced
  version: v1alpha3
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: externalservices.networking.istio.io
spec:
  group: networking.istio.io
  names:
    kind: ExternalService
    listKind: ExternalServiceList
    plural: externalservices
    singular: externalservice
  scope: Namespaced
  version: v1alpha3

Istio ingress service

Create regular ingress svc with label istio: ingress. Notice this svc only listens on 80/443 and selector points to pods with labels istio: ingress.

apiVersion: v1
kind: Service
metadata:
  name: istio-ingress
  namespace: istio-system
  labels:
    istio: ingress
spec:
  type: LoadBalancer
  ports:
  - port: 80
    name: http
  - port: 443
    name: https
  selector:
    istio: ingress

Istio ingress deployment

Create deployment for istio-ingress service with sidecar.istio.io/inject: "false", which means it will not be considered as istio redirect target. Because it has labels istio: ingress in pod template, it will be refered by svc defined above.

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: istio-ingress
  namespace: istio-system
spec:
  replicas: 1
  template:
    metadata:
      labels:
        istio: ingress
      annotations:
        sidecar.istio.io/inject: "false"
    spec:
      serviceAccountName: istio-ingress-service-account
      containers:
      - name: istio-ingress
        image: docker.io/istio/proxy:0.7.1
        args:
        - proxy
        - ingress
        - --discoveryAddress
        - istio-pilot:8080 #--controlPlaneAuthPolicy
        - --discoveryRefreshDelay
        - '1s' #discoveryRefreshDelay
        - --drainDuration
        - '45s' #drainDuration
        - --parentShutdownDuration
        - '1m0s' #parentShutdownDuration
        - --connectTimeout
        - '10s' #connectTimeout
        - --serviceCluster
        - istio-ingress
        - --zipkinAddress
        - zipkin:9411
        - --statsdUdpAddress
        - istio-mixer:9125
        - --proxyAdminPort
        - "15000"
        - --controlPlaneAuthPolicy
        - NONE #--controlPlaneAuthPolicy
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        - containerPort: 443
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace
        volumeMounts:
                - name: istio-certs
          mountPath: /etc/certs
          readOnly: true
        - name: ingress-certs
          mountPath: /etc/istio/ingress-certs
          readOnly: true
      volumes:
      - name: istio-certs
        secret:
          secretName: istio.istio-ingress-service-account
          optional: true
      - name: ingress-certs
        secret:
          secretName: istio-ingress-certs
          optional: true

Define how ingress redirect traffic

Following example pushs all traffic to v1 pods. Notice VirtualService doens’t define path, which is instead defined by ingress.

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: productpage
spec:
  hosts:
  - productpage
  gateways:
  - bookinfo
  - mesh #TODO remove this if not needed
  http:
  - route:
    - destination:
        name: productpage
        subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
  - reviews
  http:
  - route:
    - destination:
        name: reviews
        subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - route:
    - destination:
        name: ratings
        subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: details
spec:
  hosts:
  - details
  http:
  - route:
    - destination:
        name: details
        subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: productpage
spec:
  name: productpage
  subsets:
  - name: v1
    labels:
      version: v1
---
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews
spec:
  name: reviews
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
  - name: v3
    labels:
      version: v3
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: ratings
spec:
  name: ratings
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
  - name: v2-mysql
    labels:
      version: v2-mysql
  - name: v2-mysql-vm
    labels:
      version: v2-mysql-vm
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: details
spec:
  name: details
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2

Use istio ingress svc as ingress for web deployments

kubernetes.io/ingress.class: "istio" annotaion force it to use predefined istio ingress. Other annotaion will be ingnored when use this.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: gateway
  annotations:
    kubernetes.io/ingress.class: "istio"
spec:
  rules:
  - http:
      paths:
      - path: /productpage
        backend:
          serviceName: productpage
          servicePort: 9080
      - path: /login
        backend:
          serviceName: productpage
          servicePort: 9080
      - path: /logout
        backend:
          serviceName: productpage
          servicePort: 9080
      - path: /api/v1/products.*
        backend:
          serviceName: productpage
          servicePort: 9080