<p>I have a problem with the proper configuration of communication between my services on Kubernetes(minikube) with Istio installed.</p>
<p>I'm trying to send <code>POST</code> request from my service to elasticsearch, but all the time I'm  receive:</p>
<pre><code>POST /_bulk?timeout=1m HTTP/1.1&quot; 503 UH &quot;-&quot; &quot;-&quot; 0 19 0 - &quot;-&quot; &quot;Apache-HttpAsyncClient/4.1.4 (Java/11.0.9.1)&quot; &quot;1a290357-7b18-9692-9392-d0298ed3276c&quot; &quot;elasticsearch:9200&quot; &quot;-&quot; - - 10.102.10.19:9200 172.18.0.12:39194 - default
</code></pre>
<p><code>Istioctl analyze</code> doesn't shows any problems. I also disabled mtls.</p>
<p>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.</p>
<p>My deployments + services:</p>
<p><strong>Elasticsearch</strong></p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: v1
kind: Service
metadata:
  name: elasticsearch
  labels:
    app: elasticsearch
    tier: database
spec:
  selector:
    app: elasticsearch
  ports:
  - name: &quot;http-9200&quot;
    port: 9200
    targetPort: 9200
  - name: &quot;tcp-9300&quot;
    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: &quot;http-9200&quot;
        - containerPort: 9300
          name: &quot;tcp-9300&quot;
        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: &quot;standard&quot;
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi



</code></pre>
<p><strong>My-Service</strong></p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: v1
kind: Service
metadata:
  name: scrappers-service
  labels:
    name: scrappers-service
spec:
  ports:
  - nodePort: 30164
    name: &quot;http-8080&quot;
    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
</code></pre>

<p>As mentioned <a href="https://stackoverflow.com/a/64965037/11977760">here</a></p>
<blockquote>
<p>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.</p>
</blockquote>
<p>So the solution would be to follow elasticsearch <a href="https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-service-mesh-istio.html" rel="nofollow noreferrer">documentation</a>, which use below annotations to make it work.</p>
<pre><code>annotations:
  traffic.sidecar.istio.io/excludeOutboundPorts: &quot;&quot; 
  traffic.sidecar.istio.io/excludeInboundPorts: &quot;&quot;
</code></pre>
<hr />
<blockquote>
<p>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:</p>
</blockquote>
<pre><code>[...]
spec:
  template:
    metadata:
      annotations:
        traffic.sidecar.istio.io/excludeInboundPorts: &quot;9443&quot;
        traffic.sidecar.istio.io/includeInboundPorts: '*'
[...]
</code></pre>
<blockquote>
<p>If you have configured Istio in <strong>permissive mode</strong>, examples defined elsewhere in the ECK documentation will continue to work without requiring any modifications. However, if you have enabled <strong>strict mutual TLS</strong> authentication between services either via global (MeshPolicy) or namespace-level (Policy) configuration, the following modifications to the resource manifests are necessary for correct operation.</p>
</blockquote>
<pre><code>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: &quot;*&quot;
          traffic.sidecar.istio.io/excludeOutboundPorts: &quot;9300&quot; 
          traffic.sidecar.istio.io/excludeInboundPorts: &quot;9300&quot;
      spec:
        automountServiceAccountToken: true 
</code></pre>
<blockquote>
<p>If you <strong>do not have automatic mutual TLS</strong> 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.</p>
</blockquote>
<pre><code>apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: elastic-istio
spec:
  host: &quot;elastic-istio-es-http.default.svc.cluster.local&quot;
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL
</code></pre>
<hr />
<p>There are related github issues:</p>
<ul>
<li><a href="https://github.com/istio/istio/issues/14662" rel="nofollow noreferrer">https://github.com/istio/istio/issues/14662</a></li>
<li><a href="https://github.com/elastic/cloud-on-k8s/issues/2770" rel="nofollow noreferrer">https://github.com/elastic/cloud-on-k8s/issues/2770</a></li>
</ul>
