Search code examples
kubernetesistio

503 UH error on Kubernetes with Istio, but service is working


I have a problem with the proper configuration of communication between my services on Kubernetes(minikube) with Istio installed.

I'm trying to send POST request from my service to elasticsearch, but all the time I'm receive:

POST /_bulk?timeout=1m HTTP/1.1" 503 UH "-" "-" 0 19 0 - "-" "Apache-HttpAsyncClient/4.1.4 (Java/11.0.9.1)" "1a290357-7b18-9692-9392-d0298ed3276c" "elasticsearch:9200" "-" - - 10.102.10.19:9200 172.18.0.12:39194 - default

Istioctl analyze doesn't shows any problems. I also disabled mtls.

Do you have any idea what could be wrong? I don't understand why there is UH (unhealthy), because elasticsearch works and the Kiali dashboard also displays it as healthy.

My deployments + services:

Elasticsearch

apiVersion: v1
kind: Service
metadata:
  name: elasticsearch
  labels:
    app: elasticsearch
    tier: database
spec:
  selector:
    app: elasticsearch
  ports:
  - name: "http-9200"
    port: 9200
    targetPort: 9200
  - name: "tcp-9300"
    port: 9300
    targetPort: 9300
  selector:
    app: elasticsearch
    tier: database

---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: elasticsearch
  labels:
    service: elasticsearch
spec:
  serviceName: elasticsearch
  replicas: 1
  selector:
    matchLabels:
      service: elasticsearch
  template:
    metadata:
      labels:
        service: elasticsearch
    spec:
      terminationGracePeriodSeconds: 300
      initContainers:
      - name: fix-the-volume-permission
        image: busybox
        command:
        - sh
        - -c
        - chown -R 1000:1000 /usr/share/elasticsearch/data
        securityContext:
          privileged: true
        volumeMounts:
        - name: data
          mountPath: /usr/share/elasticsearch/data
      - name: increase-the-vm-max-map-count
        image: busybox
        command:
        - sysctl
        - -w
        - vm.max_map_count=262144
        securityContext:
          privileged: true
      - name: increase-the-ulimit
        image: busybox
        command:
        - sh
        - -c
        - ulimit -n 65536
        securityContext:
          privileged: true
      containers:
      - name: elasticsearch
        image: docker.elastic.co/elasticsearch/elasticsearch-oss:6.2.4
        ports:
        - containerPort: 9200
          name: "http-9200"
        - containerPort: 9300
          name: "tcp-9300"
        env:
          - name: cluster.name
            value: elasticsearch-cluster
          - name: node.name
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: ES_JAVA_OPTS
            value: -Xms4g -Xmx4g
        volumeMounts:
        - name: data
          mountPath: /usr/share/elasticsearch/data
  volumeClaimTemplates:
  - metadata:
      name: data
      annotations:
        volume.beta.kubernetes.io/storage-class: "standard"
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi



My-Service

apiVersion: v1
kind: Service
metadata:
  name: scrappers-service
  labels:
    name: scrappers-service
spec:
  ports:
  - nodePort: 30164
    name: "http-8080"
    port: 8080
    targetPort: 8080
  selector:
    app: scrappers-service
  type: NodePort
---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: scrappers-service
  labels:
    name: scrappers-service
spec:
  selector:
    matchLabels:
      app: scrappers-service
  replicas: 1
  template:
    metadata:
      labels:
        app: scrappers-service
    spec:
      containers:
      - image: example/scrappers:master
        imagePullPolicy: Never
        name: scrappers-service
        ports: 
        - containerPort: 8080

Solution

  • As mentioned here

    I decided to use the solution described by elasticsearch. I mean elasticseach-operator. I applied all steps and it just works without any bigger problems.

    So the solution would be to follow elasticsearch documentation, which use below annotations to make it work.

    annotations:
      traffic.sidecar.istio.io/excludeOutboundPorts: "" 
      traffic.sidecar.istio.io/excludeInboundPorts: ""
    

    To make the validating webhook work under Istio, you need to exclude the inbound port 9443 from being proxied. This can be done by editing the template definition of the elastic-operator StatefulSet to add the following annotations to the operator Pod:

    [...]
    spec:
      template:
        metadata:
          annotations:
            traffic.sidecar.istio.io/excludeInboundPorts: "9443"
            traffic.sidecar.istio.io/includeInboundPorts: '*'
    [...]
    

    If you have configured Istio in permissive mode, examples defined elsewhere in the ECK documentation will continue to work without requiring any modifications. However, if you have enabled strict mutual TLS authentication between services either via global (MeshPolicy) or namespace-level (Policy) configuration, the following modifications to the resource manifests are necessary for correct operation.

    apiVersion: elasticsearch.k8s.elastic.co/v1
    kind: Elasticsearch
    metadata:
      name: elastic-istio
    spec:
      version: 7.10.0
      http:
        tls: 
          selfSignedCertificate:
            disabled: true
      nodeSets:
      - name: default
        count: 3
        podTemplate:
          metadata:
            annotations:
              traffic.sidecar.istio.io/includeInboundPorts: "*"
              traffic.sidecar.istio.io/excludeOutboundPorts: "9300" 
              traffic.sidecar.istio.io/excludeInboundPorts: "9300"
          spec:
            automountServiceAccountToken: true 
    

    If you do not have automatic mutual TLS enabled, you may need to create a Destination Rule to allow the operator to communicate with the Elasticsearch cluster. A communication issue between the operator and the managed Elasticsearch cluster can be detected by looking at the operator logs to see if there are any errors reported with the text 503 Service Unavailable.

    apiVersion: networking.istio.io/v1alpha3
    kind: DestinationRule
    metadata:
      name: elastic-istio
    spec:
      host: "elastic-istio-es-http.default.svc.cluster.local"
      trafficPolicy:
        tls:
          mode: ISTIO_MUTUAL
    

    There are related github issues: