According to the documentation, Elasticsearch reserves port 9300-9400 for cluster communication and port 9200-9300 for accessing the elasticsearch APIs. You get the impression that these ranges are inclusive: so port 9300 is part of the first and the second port range.
Now, my IT ops department won't like that, so hopefully I got it wrong. Anyone knows?
Elasticsearch will bind to a single port for both HTTP and the node/transport APIs.
It'll try the lowest available port first, and if it is already taken, try the next. If you run a single node on your machine, it'll only bind to 9200 and 9300.
See also: Elasticsearch Internals: Networking Introduction
Related
I'm trying to create a cluster of three servers with dotCMS 5.2.6 installed.
They have to interface with a second cluster of 3 elasticsearch nodes.
Despite my attempts to combine them, the best case I've obtained is with both dotCMS and elastic up and running but from dot admin backend (Control panel > Configuration > Network) I always see my three servers with red status due to Index red status.
I have tested the following combinations:
In plugins/com.dotcms.config/conf/dotcms-config-cluster-ext.properties
AUTOWIRE_CLUSTER_TRANSPORT=false
es.path.home=WEB-INF/elasticsearch
Using AUTOWIRE_CLUSTER_TRANSPORT=true seems not to change the result
In plugins/com.dotcms.config/ROOT/dotserver/tomcat-8.5.32/webapps/ROOT/WEB-INF/elasticsearch/config/elasticsearch-override.yml
transport.tcp.port: 9301
discovery.zen.ping.unicast.hosts: first_es_server:9300, second_es_server:9300, third_es_server:9300
Using transport.tcp.port: 9300 cause dotCMS startup failure with error:
ERROR cluster.ClusterFactory - Unable to rewire cluster:Failed to bind to [9300]
Caused by: com.dotmarketing.exception.DotRuntimeException: Failed to bind to [9300]
Of course, port 9300 is listening on the three elasticsearch nodes they are configured with transport.tcp.port: 9300 and have no problem to start and create their cluster.
Using transport.tcp.port: 9301 dotCMS can start and join the elastic cluster but the index status is always red even if the indexation seems to work and nothing is apparently affected.
Using transport.tcp.port: 9309 (as suggested in the dotCMS online reference) or any other port number lead to the same result as 9301 case but from dot admin backend (Control panel > Configuration > Network) the Index information for each machine still repot 9301 as ES port.
Main Question
I would like to know where the ES port can be edited considering my Elasticsearch cluster is performing well (all indices are green) and the elasticsearch-override.yml within dotCMS plugin doesn't affect the default 9301 reported by the backend.
Is the HTTP interface enabled on ES? If not, I would enable it and see what the cluster health is and what the index health is. It might be that you need to adjust your expected replicas.
https://www.elastic.co/guide/en/elasticsearch/reference/current/cat-health.html
and
https://www.elastic.co/guide/en/elasticsearch/reference/current/cat-indices.html
FWIW, the upcoming version of dotCMS (5.3.0) does not support embedded elasticsearch and requires a vanilla external ES node/custer to connect to.
I'm trying to run an elasticsearch cluster with each es-node running in its own container. These containers are deployed using ECS across several machines that may be running other unrelated containers. To avoid port conflicts each port a container exposes is assigned a random value. These random ports are consistent across all running containers of the same type. In other words, all running es-node containers map port 9300 to the same random number.
Here's the config I'm using:
network:
host: 0.0.0.0
plugin:
mandatory: cloud-aws
cluster:
name: ${ES_CLUSTER_NAME}
discovery:
type: ec2
ec2:
groups: ${ES_SECURITY_GROUP}
any_group: false
zen.ping.multicast.enabled: false
transport:
tcp.port: 9300
publish_port: ${_INSTANCE_PORT_TRANSPORT}
cloud.aws:
access_key: ${AWS_ACCESS_KEY}
secret_key: ${AWS_SECRET_KEY}
region: ${AWS_REGION}
In this case _INSTANCE_PORT_TRANSPORT is the port that 9300 is bound to on the host machine. I've confirmed that all the environment variables used above are set correctly. I'm also setting network.publish_host to the host machine's local IP via a command line arg.
When I forced _INSTANCE_PORT_TRANSPORT (and in turn transport.publish_port) to be 9300, everything worked great, but as soon as it's given a random value, nodes can no longer connect to each other. I see errors like this using logger.discovery=TRACE:
ConnectTransportException[[][10.0.xxx.xxx:9300] connect_timeout[30s]]; nested: ConnectException[Connection refused: /10.0.xxx.xxx:9300];
at org.elasticsearch.transport.netty.NettyTransport.connectToChannelsLight(NettyTransport.java:952)
at org.elasticsearch.transport.netty.NettyTransport.connectToNode(NettyTransport.java:916)
at org.elasticsearch.transport.netty.NettyTransport.connectToNodeLight(NettyTransport.java:888)
at org.elasticsearch.transport.TransportService.connectToNodeLight(TransportService.java:267)
at org.elasticsearch.discovery.zen.ping.unicast.UnicastZenPing$3.run(UnicastZenPing.java:395)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
It seems like the port a node binds to is the same as the port it pings while trying to connect to other nodes. Is there any way to make them different? If not, what's the point of transport.publish_port?
The way the discovery-ec2 plugin works is that it's collecting a list of IP addresses using AWS EC2 API and use this list as unicast list of nodes.
But it does not collect any information from the running cluster. Obviously the node is not yet connected!
So it does not know anything about the publish_port of other nodes.
It just adds an IP address. And that's all. Elasticsearch then is using the default port which is 9300.
So there is nothing you can do IMO to fix that in the short time.
But we can imagine adding a new feature which is close to what has been implemented for Google Compute Engine. We are using a specific metadata to get this port from the GCE APIs.
We could do the same for Azure and EC2. Do you want to open an issue so we can track the effort?
I have setup an elastic-search cluster with two data nodes , one master node and one client node with KIBANA.
I was running it with iptables disabled on each node (CC 6). Now i need to enable iptables and i want to know which of the ports (9200 , 9300) , i need to open on each node and in which direction (incoming or outgoing). The discovery is using uni-cast.
I would also like to know on which node i should place authentication , i.e just the client node ?
Cluster: mycluster
data-node1
data-node2
master-node1
client-node1
Thanks.
9200 is used for the HTTP API, 9300 is used for communication between nodes and cluster.
For the above configuration I would:
Bind port 9200 on all hosts to 127.0.0.1
Bind port 9300 on all hosts to the local lan, i.e. 192.168.x.x
Run nginx and apply basic authentication (htpasswd for example), reverse proxy to 127.0.0.1:5601 (kibana), assuming you're running your client node on the same machine as you are running Kibana on.
In your Kibana configuration, have it connect to localhost:9200 and bind the interface to 127.0.0.1
Starting from version 2.0 Elasticsearch binds only on the loopback interface by default (_local_ in terms of configuration).
The documentation says that there is a way to switch to another network, for example, _non_loopback_ binds to the first non-loopback interface. It works fine.
But I cannot figure out how do I combine these settings so that Elasticsearch binds on both loopback and non-loopback interfaces simultaneously?
PS. My reason is that I use Logstash on each Elasticsearch instance that connects to it via localhost, but I also want other Elasticsearch instances to see each other to form the cluster...
For 2.0 you would need to use
network.bind_host: 0
As of ElasticSearch 7.x, this configuration has changed yet again. for a simple single node cluster bound to loopback, local and external IPs, you essentially do this:
network.host: [_local_, _site_, _global_]
cluster.initial_master_nodes: node-1
The cluster node setting is explained here while the network host setting is in the documentation here, although it doesn't say how you would assign multiple values to network.host.
Go to
'<path_to_elasticsearch>/elasticsearch-2.3.4/config'
Open elasticsearch.yml
Add
network.host: 0.0.0.0
Now check which port elasticsearch is using (9200 is default), go to firewall inbound rules and add those ports.
I have port 9200 proxied via 80 on my server running elasticsearch. I have a camel route that needs to index documents to this server.
Is it supported in the camel-elasticsearch plugin? ie access elastic search via a non 9300 port?
I understand that port 9300 uses a native elasticsearch transport protocol.
What are my options here? Can I proxy 9300 via apache? I'm not sure if that works.
Or does the camel-elasticsearch plugin support http transport? Please help. Thanks.
The port you are referring to, it is the HTTP port:
http.port A bind port range. Defaults to 9200-9300.
http.publish_port The port that HTTP clients should use when communicating with this node. Useful when a cluster node is behind a
proxy or firewall and the http.port is not directly addressable from
the outside. Defaults to the actual port assigned via http.port.
http.bind_host The host address to bind the HTTP service to. Defaults to http.host (if set) or network.bind_host.
http.publish_host The host address to publish for HTTP clients to connect to. Defaults to http.host (if set) or
network.publish_host.
http.host Used to set the http.bind_host and the http.publish_host Defaults to http.host or network.host.
So you really don't need a proxy, you can have elasticsearch listen directly on port 80.
If you already have a process running on port 80; then you can proxy the connections to 9200 (and leave elastic search as default).
Java Transport Client ---> Apache HTTP Proxy(80) ----> ES (9300) [ Can
I do this? As I understand that Java Transport Client uses a non-http
protocol? ]
The protocol has nothing to do with the port.
Simply pass 80 to InetSocketTransportAddress. See the documentation for a complete example.