<p>I've got my own microservice and till now I've been exposing the service with <code>type: NodePort</code> along with <code>nginx-ingress</code> helm chart to my own Public IP with https; I've noticed when running linter on my microservice helm chart that it's not safe (to use NodePort) and I should be using ClusterIP - could someone explain why?</p>

<p>If your cluster is set up so that the worker nodes are directly accessible from outside the cluster, then anything you have set as a NodePort-type service will be accessible too.  In particular, this means that <code>http://any-node.k8s.example.com:32345/</code> could reach your back-end service, bypassing any controls that you've set up in the ingress layer.  You generally don't want that.</p>

<p>A reasonable approach here (and probably what your linter is encouraging) is to use NodePort or LoadBalancer-type services <em>only</em> for your ingress service.  Anything else should register itself with that ingress service (using a native Kubernetes Ingress object, or an Istio VirtualService, or ...) but have ClusterIP-type services for intra-cluster access.</p>

<pre class="lang-none prettyprint-override"><code>     +------------+  NP  +---------+ CIP  +-------------+
---&gt; | (any node) | ---&gt; | ingress | ---&gt; | application |
     +------------+      +---------+      +-------------+
                 |__________________________^
      a NodePort application service would allow this path
                   (bypassing the ingress)
</code></pre>
