如何configuration在AWS / ElasticBeanstalk / Docker上运行的GlassFish实例?

我正在使用GlassFish来提供Java EE Web应用程序。 事情在我的本地开发机器上正常工作。 我有

  • 将postgres JDBC库复制到正确的位置
  • 在Glassfishpipe理控制台中configuration连接池和JDBC资源
  • 部署了一个使用所述连接的web应用程序
  • 在我的浏览器中看到了结果

我正在尝试将相同的应用程序部署到AWS Elastic Beanstalk托pipe的Glassfish实例。 AWS-EB使用Docker来部署Glassfish实例。 我只能做上面的第三步(部署一个networking应用程序),完全不知道如何做前两个。

我喜欢做的是通过networking访问Glassfishpipe理控制台,但是这似乎并没有在任何级别的工作。 另一种方法是在我的本地机器上使用玻璃鱼“asadmin”来configuration远程玻璃鱼,但我也无法做到这一点。

如何configurationAWS EB上托pipe的Glassfish实例? 这甚至有可能吗?

我已经做了一些观察,但是我会很欣赏确认或其他方式:

  • 看起来AWS在他们的CLI中有一个叫做“asadmin”的命令,这个命令是关于自动调节的,并且和glassfish一起使用的“asadmin”同名。 除了努力让谷歌search,两者似乎没有任何关系
  • 如果我连接到包含Docker和Glassfish实例的AWS EC2实例,则会发生以下情况
    • sudo docker ps返回有端口4848 / tcp,8080 / tcp,8181 / tcp,没有映射
    • wget localhost:8080 – 连接被拒绝
    • 相同的8181和4848
    • wget localhost:80返回Glassfish主页的网页
  • 在同一个运行docker的实例中检查我得到一个内部IP地址(称为1.2.3.4),然后在该EC实例上
    • wget 1.2.3.4:8080 (和4848,8181 )都返回html文件
    • wget 1.2.3.4:80 – 连接被拒绝
  • 如果我在Docker容器中运行bash shell,下面的事情看起来是正确的
    • wget localhost:8080 (和4848,8181)都返回格式正确的页面
    • wget localhost:80 – 连接被拒绝

所以,也许我需要告诉EC2实例从localhost转发到1.2.3.4,但是如何在EB负载均衡器扩展时实现这一点。

任何build议将不胜感激。

接下来是对我有用的东西 – 但我有一种感觉,我错过了一些东西。 任何编辑/评论将是最受欢迎的。

EB / Docker部署中有各种钩子,允许在EB实例内的Docker容器内的glassfish实例中执行部署后挂接。 我使用post-deploy钩子来build立一个连接池。 以下是最终安装的样子,仅供参考:

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

总体预期结果是,在部署应用程序之后,在Docker实例内部运行asadmin命令来创buildJDBC连接池,并将该连接池变成jdbc资源。 在我的本地机器上,命令将会是

 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 

其中'jdbc / dev'是java代码需要知道的以通常的方式获得连接的名称

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

我们希望命令在docker实例中运行,因为docker实例可以访问您在AWSpipe理控制台中声明的环境variables,所以我可以传递configuration信息,而不必在构build脚本中传递。

为了达到这个结果,我们要求在安装过程中在EC2实例中创build一个文件,在我的情况下称为/opt/elasticbeanstalk/hooks/appdeploy/post/99_configure_jdbc.sh 。 该文件将在EC2实例中以root用户身份执行后部署。 我将其称为ec2-post-deploy-hook

我们将使用.ebextensions / .config文件创build该文件,如此处所述

我的.config文件有以下内容:

 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 

内容后的所有内容:| 结束于ec2-post-deploy-hook

我从http://junkheap.net/blog/2013/05/20/elastic-beanstalk-post-deployment-scripts学到了这个想法。

只需要最后一行和最后一行,但其他行对debugging很有用。 输出结束于EC2实例的/ tmp / post。

那个文件中的一个技巧就是我们总是可以得到docker容器的ID

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

因为部署之后只会有一个Docker容器在运行,并且它的名字中会有“最新”的。

ec2-post-deploy-hook的最后一行使用docker在docker实例中运行我最初想要运行的那些命令 – 也就是asadmin命令。 我在我的.war文件中部署了一个名为setup_pool.sh的文件,因此在部署过程中它会在已知位置结束。 我的setup_pool.sh看起来像这样(我把它称为docker-post-deploy-hook ):

 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 

这个文件在Docker实例中运行。 这两个asadmin命令是肉,但同样,在docker实例中有一些debugging到/ tmp / setup_connections

密码等是从AWS环境获得的。

我现在唯一不能做的就是在首次部署时提供AWS环境variables。 我不知道为什么,但我似乎只能在实例启动并运行后设置它们。 这意味着我必须部署两次虚拟部署,然后进行环境编辑,然后进行真正的部署。

所以,总结一下,

  • 在部署
    • .config文件生成一个ec2-post-deploy-hook文件,
    • AWS系统部署docker-post-deploy-hook作为部署到glassfish的.war的一部分
  • 在部署后,
    • 弹性beanstalk系统运行ec2-post-deploy-hook
    • ec2-post-deploy-hook运行docker-post-deploy-hook
    • docker-post-deploy-hook运行asadmin来设置适当的连接池
  • 在运行时,Web应用程序中的Java代码使用连接池

这一切工作。 这是一种丑陋的看法,但是,你知道,我也是。

在经过了一段时间之后,我终于find了一个可以接受的解决方法(至less对我来说)如下:

创buildDockerFile并将其直接打包到WAR中(最高级别,而不是任何文件夹)。 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/ 

现在当部署这个WAR(我正在使用'eb deploy')。 这个DockerFile被执行。

在上面的简单例子中 – 首先mysql jdbc驱动程序被下载并安装到glassfish的lib目录中。 接下来,我已经打包了WAR文件中的domain.xml文件(所有的资源等),当glassfish启动的时候,它被移动到了glassfish的domain config文件夹中。