2014-12-08 7 views
8

Sto usando GlassFish per servire un'applicazione web Java EE. Le cose stanno funzionando bene sulla mia macchina di sviluppo locale. HoCome configurare un'istanza GlassFish in esecuzione su AWS/ElasticBeanstalk/Docker?

  • copiati librerie Postgres JDBC nel posto giusto
  • configurato un pool di connessioni e di risorse JDBC nel Glassfish console di amministrazione
  • implementato una web-app che utilizza detto collegamento
  • visto i risultati in il mio browser

Sto provando a distribuire la stessa app per l'istanza di Glassfish ospitata su AWS Elastic Beanstalk. AWS-EB utilizza Docker per distribuire l'istanza di Glassfish. Posso fare solo il terzo passo sopra (distribuire un'applicazione web), e sono completamente in perdita come fare i primi due.

Quello che mi piacerebbe fare è avere accesso web alla console di amministrazione di Glassfish tramite, ma non sembra funzionare a nessun livello. Un'alternativa sarebbe quella di usare il pesce di vetro "asadmin" sulla mia macchina locale per configurare il pesce di vetro remoto, ma non posso nemmeno farlo.

Come si configura un'istanza di Glassfish ospitata su EB AWS? È possibile?

Ho fatto alcune osservazioni, ma mi farebbe piacere la conferma o meno:

  • sembra che AWS avere un comando nella loro CLI chiamato 'asadmin' che è di circa autoscaling, e ha lo stesso nome come 'asadmin' che viene fornito con glassfish. Oltre a fare ricerche su Google difficile, i due sembrano avere nulla a che fare con l'altro
  • se collego all'istanza AWS EC2 contenente l'istanza Docker e Glassfish, le seguenti cose accadono
    • sudo finestra mobile ps rendimenti che ci sono porte 4848/tcp, 8080/tcp, 8181/tcp, e che nessuno sono mappati
    • wget localhost: 8080 - collegamento rifiutato
    • stesso per 8181 e 4848
    • wget localhost: 80 restituisce la pagina web della home page Glassfish
  • in quella stessa istanza in esecuzione finestra mobile ispezionare ottengo un indirizzo IP interno (lo chiamano 1.2.3.4), poi su tale istanza CE
    • wget 1.2.3.4:8080 (e 4848, 8181) tutti restituiscono file html
    • wget 1.2.3.4:80 - connessione rifiutata
  • se corro una shell bash nel contenitore finestra mobile, le seguenti cose sembrano essere vero
    • wget localhost: 8080 (e 4848, 8181) restituiscono tutte bene pagine formate
    • wget localhost: 80 - connessione rifiutata

Così forse ho bisogno di dire all'istanza EC2 di inoltrare da localhost alla 1.2.3.4, ma come posso farlo quando il bilanciamento del carico EB lo scala.

Qualsiasi consiglio sarebbe molto apprezzato.

+0

Si prega di inviare la vostra risposta docker ps (è possibile offuscare gli IP) anche se possibile il file manifest di aws docker json. –

+0

Ciao Usman. Temo di non sapere cosa sia un file manifest di aws docker figlio. (Che ora sospetto sia il mio problema ...) –

+0

Intendevo il file Dockerrun.aws.json. http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create_deploy_docker_image.html –

risposta

6

Quello che segue è qualcosa che funziona per me - ma ho la sensazione che mi manchi qualcosa. Eventuali modifiche/commenti sarebbero i benvenuti.

Nella distribuzione EB/Docker sono presenti vari hook che consentono l'esecuzione di hook post-deployment da eseguire in un'istanza glassfish, all'interno di un contenitore docker, all'interno di un'istanza EB. Ho usato ganci post-distribuzione per configurare un pool di connessioni. Ecco cosa la finale di installazione sembra, appena per riferimento:

| | | \_WAR_/ | | | 
| | \_Glassfish_/ | | 
| \____Docker____/ | 
\____EC2 Instance____/ 

Il risultato complessivo desiderato è che, dopo l'applicazione viene distribuito, all'interno l'istanza Docker, i asadmin comandi vengono eseguiti per creare un pool di connessioni JDBC e per rendere quel pool di connessioni in una risorsa jdbc. Sulla mia macchina locale, i comandi sarebbero

asadmin create-jdbc-connection-pool 
    --datasourceclassname org.postgresql.ds.PGConnectionPoolDataSource 
    --restype javax.sql.ConnectionPoolDataSource 
    --property user=USERNAME:password=PASSWORD:serverName=DBHOST:portNumber=5432:databaseName=DBNAME 
    poolName 

asadmin create-jdbc-resource --connectionpoolid poolName jdbc/dev 

Dove 'jdbc/dev' è il nome che il codice Java ha bisogno di sapere per ottenere una connessione nel modo consueto cioè

InitialContext ctx = new InitialContext(); 
ds = (DataSource)ctx.lookup("jdbc/dev"); 

Vogliamo i comandi da eseguire all'interno dell'istanza di finestra mobile, poiché l'istanza di finestra mobile ha accesso alle variabili di ambiente dichiarate nella console di amministrazione di AWS, pertanto è possibile passare le informazioni di configurazione senza averle negli script di build.

Per ottenere questo risultato, è necessario che un file viene creato nella istanza EC2 durante l'installazione, nel mio caso chiamato /opt/elasticbeanstalk/hooks/appdeploy/post/99_configure_jdbc.sh. Questo file verrà eseguito dopo la distribuzione, come root, nell'istanza EC2. Mi riferirò ad esso come ec2-post-deploy-hook.

che andremo a creare il file utilizzando un file .ebextensions/.config, come documentato qui

mio.file di configurazione ha il seguente contenuto:

files: 
    "/opt/elasticbeanstalk/hooks/appdeploy/post/99_configure_jdbc.sh": 
    mode: "000755" 
    owner: root 
    group: root 
    content: | 
     #!/bin/bash 
     date > /tmp/post 2>&1 
     dockerid=`docker ps | grep latest | cut -d" " -f1` 
     echo $dockerid >> /tmp/post 2>&1 
     docker ps >> /tmp/post 2>&1 
     docker exec $dockerid /var/app/WEB-INF/classes/setup_pool.sh >> tmp/post 2>&1 

Tutto dopo il contenuto : | finisce nell'ec2-post-deploy-hook.

Ho imparato questa idea da http://junkheap.net/blog/2013/05/20/elastic-beanstalk-post-deployment-scripts.

Solo l'ultima riga e la quarta riga sono necessarie, ma le altre righe sono utili per il debug. L'output finisce in/tmp/post sull'istanza EC2.

Quello trucco in quel file è che possiamo sempre ottenere l'ID del contenitore finestra mobile da

sudo docker ps | grep latest | cut -d" " -f1 

perché dopo la distribuzione non ci sarà un solo Docker contenitore in esecuzione, e avrà "ultima" in il suo nome.

L'ultima riga di ec2-post-deploy-hook utilizza la finestra mobile per eseguire, all'interno dell'istanza di finestra mobile, i comandi che inizialmente desideravo eseguire, ovvero i comandi di asadmin. Distribuisco un file chiamato setup_pool.sh nel mio file .war, quindi finisce in una posizione nota durante la distribuzione. Il mio setup_pool.sh assomiglia a questo (ed io lo chiamo un finestra mobile post-deploy-gancio):

dbuser=$PARAM1 
dbpass=$PARAM2 
dbhost=$PARAM3 
dbname=$PARAM4 

date > /tmp/setup_connections 
echo '*********' >> /tmp/setup_connections 
asadmin create-jdbc-connection-pool --datasourceclassname org.postgresql.ds.PGConnectionPoolDataSource --restype javax.sql.ConnectionPoolDataSource --property user=${dbuser}:password=${dbpass}:serverName=${dbhost}:portNumber=5432:databaseName=${dbname} ei-connection-pool >> /tmp/setup_connections 2>&1 
echo '*********' >> /tmp/setup_connections 
asadmin create-jdbc-resource --connectionpoolid ei-connection-pool jdbc/dev >> /tmp/setup_connections 2>&1 
echo '*********' >> /tmp/setup_connections 

Questo file viene eseguito all'interno di nell'istanza finestra mobile. I due asadmin comandi sono la carne, ma ancora una volta, c'è un po 'di debug in/tmp/setup_connections all'interno dell'istanza finestra mobile

password, ecc, sono ottenuti dall'ambiente AWS.

L'unica cosa che non posso fare a questo punto è avere le variabili di ambiente AWS disponibili alla prima distribuzione. Non ho idea del perché, ma mi sembra di essere in grado di impostarli solo dopo che l'istanza è attiva e funzionante. Ciò significa che devo eseguire il deployment due volte, una distribuzione fittizia, seguita da una modifica dell'ambiente, seguita da una distribuzione reale.

Quindi, riassumendo,

  • al dispiegamento
    • un file .config genera un post-distribuire EC2-gancio di file,
    • il sistema AWS distribuisce la finestra mobile-post-Installare- gancio come parte del .war distribuita su Glassfish
  • alla distribuzione postale,
    • sistema beanstalk elastico esegue l'EC2 post-implementazione-hook
    • EC2 post-implementazione-hook corre finestra mobile post-implementazione-hook
    • finestra mobile post-implementazione-hook corre asadmin impostare i pool di connessioni appropriate
  • in fase di esecuzione, il codice Java nel web app si avvale del pool di connessioni

E tutto funziona. È brutto da vedere, ma, lo sai, lo sono anch'io.

3

Dopo aver lottato con questo me stesso per qualche tempo, credo di aver finalmente trovato una soluzione accettabile (almeno per me) come segue: -

Creare DockerFile e il pacchetto direttamente all'interno del WAR (al massimo livello, non in qualsiasi cartella). DockerFile -

# Use the AWS Elastic Beanstalk Glassfish image 
FROM  amazon/aws-eb-glassfish:4.1-jdk8-onbuild-3.5.1 

# Exposes port 8080 
EXPOSE  8080 4848 8181 

# Install Datasource dependencies 
RUN   curl -L -o /tmp/connectorj.zip https://server/path/connectorj.zip && \ 
      unzip /tmp/connectorj.zip -d /tmp && \ 
      cp /tmp/connectorj/mysql-connector-java-5.1.36-bin.jar /usr/local/glassfish4/glassfish/domains/domain1/lib/ && \ 
      mv /var/app/WEB-INF/classes/domain.xml /usr/local/glassfish4/glassfish/domains/domain1/config/ 

Ora, quando questa guerra è distribuito (sto usando 'eb deploy'). Questo DockerFile viene eseguito.

Nel semplice esempio precedente, il primo driver jdbc mysql viene scaricato e installato nella directory lib di glassfish. Successivamente ho impacchettato domain.xml (tutte le risorse, ecc. Già configurate) all'interno della stessa WAR, viene spostato nella cartella di configurazione del dominio glassfish per essere caricato all'avvio di glassfish.

+0

Questa è una soluzione molto più pulita. Un possibile miglioramento potrebbe essere l'esecuzione di comandi con l'eseguibile asadmin per configurare il dominio invece di sostituire l'intero dominio.xml. Le dipendenze potrebbero essere scaricate da Maven per evitare l'uso di un repository privato. – Vova

Problemi correlati