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

时间:2014-12-08 05:18:16

标签: amazon-web-services glassfish docker

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

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

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

我喜欢做的是通过网络访问Glassfish管理控制台,但这似乎不适用于任何级别。另一种方法是在我的本地机器上使用玻璃鱼“asadmin”配置远程玻璃鱼,但我也不能做到这一点。

如何配置AWS EB上托管的Glassfish实例?它甚至可能吗?

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

  • 看来AWS在他们的CLI中有一个名为'asadmin'的命令,它与autoscaling有关,并且与glassfish附带的'asadmin'同名。除了努力进行谷歌搜索之外,这两者似乎没有任何关系
  • 如果我连接到包含Docker和Glassfish实例的AWS EC2实例,则会发生以下情况
    • sudo docker ps 返回端口4848 / tcp,8080 / tcp,8181 / tcp,并且没有映射
    • wget localhost:8080 - 拒绝连接
    • 同样适用于8181和4848
    • wget localhost:80 返回Glassfish主页的网页
  • 在运行 docker inspect 的同一个实例中,我得到一个内部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负载均衡器将其扩展时,我该如何实现呢?

非常感谢任何建议。

2 个答案:

答案 0 :(得分:6)

以下内容对我有用 - 但我有一种感觉,我错过了一些东西。任何编辑/评论都是最受欢迎的。

EB / Docker部署中有各种钩子,允许执行post-deployement钩子在EB实例中的dockfish容器中的glassfish实例中运行。我使用部署后挂钩来设置连接池。这是最终安装的样子,仅供参考:

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

总体预期结果是,在部署应用程序后,在Docker实例中,运行 asadmin 命令以创建JDBC连接池,并将该连接池转换为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实例可以访问您在AWS管理控制台中声明的环境变量,因此我可以在构建脚本中传递配置信息。

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

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

我的.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学到了这个想法。

只需要最后一行和第四行,但其他行对调试很有用。输出在EC2实例的/ tmp / post中结束。

该文件中的一个技巧是我们总能通过

获取docker容器的ID
sudo docker ps | grep latest | cut -d" " -f1

因为在部署之后只会运行一个Docker容器,并且它将具有" latest"以它的名字。

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实例中的/ tmp / setup_connections中进行了一些调试

密码等来自AWS环境。

此时我唯一不能做的就是首次部署时可以使用AWS环境变量。我不明白为什么,但我似乎只能在实例启动并运行后设置它们。这意味着我必须部署两次,一次虚拟部署,然后编辑环境,然后进行实际部署。

所以,总结一下,

  • 部署时
    • .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代码使用连接池

一切正常。它看起来有点难看,但是,你知道,我也是。

答案 1 :(得分:4)

在我自己挣扎了一段时间之后,我想我终于找到了一个可接受的解决方法(至少对我而言)如下: -

创建DockerFile并将其直接打包在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的域配置文件夹中加载。