### Description

The new [readiness port](https://www.elastic.co/guide/en/elasticsearch/reference/8.4/advanced-configuration.html#readiness-tcp-port) makes readiness checks on Kubernetes much easier. However the current implementation only allows connections through localhost. TCP probes on Kubernetes are run by the kubelet which is a process running on the Kubernetes node (and not from within the container or the Pod). The [Kubernetes documentation](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#tcp-probes) mentions it, but it is kind of subtle: 

> For a TCP probe, the kubelet makes the probe connection at the node, not in the pod, which means that you can not use a service name in the host parameter since the kubelet is unable to resolve it.


That means a standard Kubernetes readiness probe cannot be used for Elasticsearch:
```
          readinessProbe:
            tcpSocket:
              port: 8080
```

Instead, only an `exec` probe that runs a shell command inside the container can be used that relies in this case on the presence of the `nc` command in the container image:

```
    readinessProbe:
      exec:
        command: ["nc", "-z", "-v", "-w5", "127.0.0.1", "8080"] 
```



x-pack/plugin/shutdown/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/shutdown/NodeShutdownIT.java
/**
     * Ensures that attempting to delete the status of a node that is not registered for shutdown gives a 404 response code.
     */
    public void testDeleteNodeNotRegisteredForShutdown() throws Exception {
        Request deleteReq = new Request("DELETE", "_nodes/this-node-doesnt-exist/shutdown");
        ResponseException ex = expectThrows(ResponseException.class, () -> client().performRequest(deleteReq));
        assertThat(ex.getResponse().getStatusLine().getStatusCode(), is(404));
    }
    @SuppressWarnings("unchecked")
    private void assertNoShuttingDownNodes(String nodeIdToShutdown) throws IOException {
        Request getShutdownStatus = new Request("GET", "_nodes/" + nodeIdToShutdown + "/shutdown");
        Map<String, Object> statusResponse = responseAsMap(client().performRequest(getShutdownStatus));
        List<Map<String, Object>> nodesArray = (List<Map<String, Object>>) statusResponse.get("nodes");
        assertThat(nodesArray, empty());
    }
    @SuppressWarnings("unchecked")
    private void assertUnassignedShard(String nodeIdToShutdown, String indexName) throws Exception {
        Request checkShardsRequest = new Request("GET", "_cat/shards/" + indexName);
        checkShardsRequest.addParameter("format", "json");
        checkShardsRequest.addParameter("h", "index,shard,prirep,id,state");
        assertBusy(() -> {
            List<Object> shardsResponse = entityAsList(client().performRequest(checkShardsRequest));
            int startedShards = 0;
            int unassignedShards = 0;
            for (Object shard : shardsResponse) {
                Map<String, Object> shardMap = (Map<String, Object>) shard;
                assertThat(
                    "no shards should be assigned to a node shutting down for removal",
                    shardMap.get("id"),
                    not(equalTo(nodeIdToShutdown))