supported sent publickey permission instancia ec2 conectarse aws available java amazon-ec2 jmx jconsole

java - sent - permission denied(publickey) aws



Cómo conectarse a instancias de Java que se ejecutan en EC2 usando JMX (4)

Estamos teniendo problemas para conectar nuestras aplicaciones Java que se ejecutan en el clúster EC2 de Amazon.

Resultó que el problema era una combinación de dos configuraciones faltantes. El primero obliga al JRE a preferir ipv4 y no v6. Esto fue necesario (supongo) ya que estamos tratando de conectarnos a él a través de una dirección v4:

-Djava.net.preferIPv4Stack=true

El verdadero bloqueador fue el hecho de que JMX funciona contactando primero al puerto RMI que responde con el nombre de host y el puerto para que se conecte el cliente JMX. Sin configuración adicional, utilizará la dirección IP local del cuadro que es una dirección virtual 10.XXX la que un cliente remoto no puede enrutar. Necesitábamos agregar la siguiente configuración, que es el nombre de host externo o IP del servidor; en este caso, es el nombre de host elástico del servidor.

-Djava.rmi.server.hostname=ec2-107-X-X-X.compute-1.amazonaws.com

El truco, si está tratando de automatizar sus instancias EC2 (y por qué diablos no lo haría), es cómo encontrar esta dirección en tiempo de ejecución. Para hacer eso, debe poner algo como lo siguiente en nuestro script de arranque de la aplicación:

# get our _external_ hostname RMI_HOST=`wget -q -O - http://169.254.169.254/latest/meta-data/public-hostname` ... java -server / -Djava.net.preferIPv4Stack=true -Djava.rmi.server.hostname=$RMI_HOST / -jar foo.jar other parameters here > java.log 2>&1

El misterioso IP 169.254.169.254 en el comando wget anterior proporciona información que la instancia de EC2 puede solicitar sobre sí misma. Me decepciona que esto no incluya etiquetas que solo están disponibles en una llamada autenticada.

Inicialmente estaba usando la dirección ipv4 externa, pero parece que el JDK intenta establecer una conexión con el puerto del servidor cuando se inicia. Si usa la IP externa, entonces esto estaba ralentizando el tiempo de arranque de nuestra aplicación hasta que se agotó el tiempo de espera. El nombre de host público se resuelve localmente a la dirección 10-net y al public-ipv4 externamente. Entonces la aplicación ahora está comenzando rápido y los clientes JMX aún funcionan. Woo hoo!

Espero que esto ayude a alguien más. Me costó 3 horas hoy.

Para forzar a su servidor JMX a iniciar el servidor y el registro RMI en puertos designados para que pueda bloquearlos en los grupos de seguridad EC2, consulte esta respuesta:

¿Cómo cerrar rmiregistry corriendo en un puerto particular?

Editar:

Acabamos de volver a tener este problema. Parece que el código JMX de Java está realizando algunas búsquedas de nombres de host en el nombre de host del cuadro y usándolos para tratar de conectarse y verificar la conexión JMX.

El problema parece ser un requisito para que el nombre de host local del cuadro se resuelva en la ip local del cuadro. Por ejemplo, si su /etc/sysconfig/network tiene HOSTNAME=server1.foobar.com entonces, si realiza una búsqueda DNS en server1.foobar.com , debe obtener la dirección virtual 10-NET. Estábamos generando nuestro propio /etc/hosts y el nombre de host del host local faltaba en el archivo. Esto causó que nuestras aplicaciones pausen al inicio o no se inicien.

Finalmente

Una forma de simplificar su creación JMX es usar mi paquete SimpleJMX .

Estamos teniendo problemas para conectar nuestras aplicaciones Java que se ejecutan en el clúster EC2 de Amazon. Definitivamente hemos permitido tanto el "puerto JMX" (que generalmente es el puerto de registro RMI) como el puerto del servidor (que hace la mayor parte del trabajo) al grupo de seguridad para las instancias en cuestión. Jconsole se conecta pero parece colgarse y nunca muestra ninguna información.

Estamos ejecutando nuestro Java con algo como lo siguiente:

java -server -jar foo.jar other parameters here > java.log 2>&1

Hemos tratado:

  • Los Telnet a los puertos se conectan pero no se muestra información.
  • Podemos ejecutar jconsole en la instancia misma usando remote-X11 sobre ssh y se conecta y muestra información. Entonces el JRE lo está exportando localmente.
  • Apertura de todos los puertos en el grupo de seguridad. Weeee.
  • Usando tcpdump para asegurarse de que el tráfico no vaya a otros puertos.
  • Simulándolo localmente Siempre podemos conectarnos a nuestros JRE locales o a los que se ejecutan en otra parte de nuestra red utilizando los mismos parámetros de aplicación.

salidas de la java -version :

OpenJDK Runtime Environment (IcedTea6 1.11.5) (amazon-53.1.11.5.47.amzn1-x86_64) OpenJDK 64-Bit Server VM (build 20.0-b12, mixed mode)

Como un lado, estamos utilizando mi paquete Simple JMX que nos permite establecer el registro RMI y los puertos del servidor que normalmente son elegidos semialeatoriamente por el registro RMI. También puede forzar esto con algo como el siguiente URI de JMX:

service:jmx:rmi://localhost:" + serverPort + "/jndi/rmi://:" + registryPort + "/jmxrmi"

En estos días, usamos el mismo puerto para el servidor y el registro. En el pasado, usamos X como el puerto de registro y X+1 para el puerto del servidor para facilitar las reglas del grupo de seguridad. Se conecta al puerto de registro en jconsole o al cliente JMX que esté utilizando.


La respuesta dada por Gray funcionó para mí, sin embargo, creo que tengo que abrir los puertos TCP de 0 a 65535 o no entrar. Creo que puede conectarse en el puerto JMX principal y luego asignar otro. Lo obtuve de esta publicación de blog que siempre me ha funcionado bien.


Por la segunda respuesta ¿Por qué falla la conexión JMX a Amazon EC2? , la dificultad aquí es que, de forma predeterminada, el puerto RMI se selecciona al azar y los clientes necesitan acceso a los puertos JMX y RMI. Si está ejecutando jdk7u4 o posterior, el puerto RMI se puede especificar a través de una propiedad de la aplicación. El inicio de mi servidor con la siguiente configuración JMX funcionó para mí:

Sin autenticación:

-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.rmi.port=9998 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=<public EC2 hostname>

Con autenticación:

-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.rmi.port=9998 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=true -Dcom.sun.management.jmxremote.password.file=/path/to/jmxremote.password -Djava.rmi.server.hostname=<public EC2 hostname>

También abrí los puertos 9998-9999 en el grupo de seguridad EC2 para mi instancia.


Un enfoque un poco diferente mediante el uso de túneles ssh

  1. (En la máquina remota) Pase las siguientes banderas a la JVM

-Dcom.sun.management.jmxremote.port=1099 -Djava.net.preferIPv4Stack=true -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=127.0.0.1

  1. (En el equipo remoto) Compruebe qué puertos Java comenzó a usar

netstat -tulpn | grep java

tcp 0 0 0.0.0.0:37484 0.0.0.0:* LISTEN 2904/java tcp 0 0 0.0.0.0:1099 0.0.0.0:* LISTEN 2904/java tcp 0 0 0.0.0.0:45828 0.0.0.0:* LISTEN 2904/java

  1. (En la máquina local) Haga túneles ssh para todos los puertos

ssh -N -L 1099:127.0.0.1:1099 ubuntu@<ec2_ip> ssh -N -L 37484:127.0.0.1:37484 ubuntu@<ec2_ip> ssh -N -L 45828:127.0.0.1:45828 ubuntu@<ec2_ip>

  1. (En la máquina local) Conéctese mediante el Control de Misión de Java a "localhost: 1099"