add:docker部署java

This commit is contained in:
fanxb 2019-02-13 10:28:55 +08:00
parent 3e57990f56
commit 1b97de6e45
3 changed files with 144 additions and 7 deletions

View File

@ -109,3 +109,24 @@ docker cp 容器id:containerPath hostPath
docker cp ecc:/home/ubuntu /home
#将ecc开头的容器内的ubuntu目录拷贝到了本机的/home目录
```
#### 6.连接到容器
  有三种办法
1. 通过 attach 直接进入到容器,用法如下:
```bash
docker attach containerName/containerId
```
不推荐此种用法,同时只能有一个终端操作容器,即时有多个终端连入,界面会同步变化
2. 通过exec连接容器用法如下
```bash
docker exec -it containerName/containerId bash
```
以bash连入容器推荐此种用法,支持多终端连入操作。
3.通过给容器安装ssh服务支持多终端连入不推荐太麻烦了。

View File

@ -1,12 +1,14 @@
---
id="2019-02-01-14-05"
title="3.从零开始在docker中部署java应用"
headWord="在没有docker之前发布项目测试项目都是一件非常头疼的你可能经常会听到这样的话,'测试过几天要测试了过来搭个测试环境。一顿操作后。测试提bug开发"
headWord="&emsp;&emsp;在没有 docker 前,项目转测试是比较麻烦的一件事。首先会化较长的时间搭建测试环境,然后在测试过程中又经常出现测试说是 bug开发说无法复现的情况导致撕逼。<br/>&emsp;&emsp;本篇记录了如何将一个 java 应用部署到 docker 中。"
tags=["docker","springboot","jar","war","elastricsearch","activemq"]
category="linux"
serie="docker教程"
---
**本篇原创发布于 Flex 的个人博客**:[点击跳转](http://tapme.top/blog/detail/2019-02-01-14-05)
# 前言
&emsp;&emsp;在没有 docker 前,项目转测试是比较麻烦的一件事。首先会化较长的时间搭建测试环境,然后在测试过程中又经常出现测试说是 bug开发说无法复现的情况导致撕逼。
@ -54,8 +56,6 @@ serie="docker教程"
### 部署 mysql
&emsp;&emsp;曾经最初的时候在 linux 上手动装一个 mysql 能花上半天的时间,而且还不会进行数据迁移,感觉 mysql 能如此如此快速的查询大量数据很强大。。现在我已然能够熟练的掌握 mysql 安装、卸载。
&emsp;&emsp;使用容器部署 mysql 过程如下:
1. 首先从 docker.hub 中根据各自的需求 pull 对应的 mysql 镜像
@ -70,16 +70,17 @@ docker pull mysql:5.7.24
```bash
# 将宿主机的路径,映射到容器内部。这个路径既可以是文件夹,也可以是文件
-v hostPath/containerPath
-v hostPath:containerPath
```
显然我们通过这个桉树将外部的数据文件夹,配置文件映射到容器中。最后启动这个容器的命令如下:
```bash
docker run --name=mysql -itd -p 3308:3306 -v /etc/localtime:/etc/localtime -v /etc/timezone:/etc/timezone -v /opt/mysql/data:/var/lib/myql -v /opt/mysql/my.cnf -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7.25
# 假设在宿主机中数据存放路径为/opt/mysql/data,配置文件路径为:/opt/mysql/my.cnf
docker run --name=mysql -itd -p 3308:3306 -v /etc/localtime:/etc/localtime -v /etc/timezone:/etc/timezone -v /opt/mysql/data:/var/lib/mysql -v /opt/mysql/my.cnf:/etc/mysql/my.cnf -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7.25
```
**注意:如果 mysql 版本为 8.x还需要映射/var/lib/mysql-files 目录,否则启动报错**
**注意:如果 mysql 版本为 8.x还需要映射容器中的/var/lib/mysql-files 目录,否则启动报错**
下面介绍具体参数含义:
@ -90,4 +91,119 @@ docker run --name=mysql -itd -p 3308:3306 -v /etc/localtime:/etc/localtime -v /e
&emsp;&emsp;可能你们会问为什么要映射`/etc/timezone``/etc/timezone`,这是为了让容器的时间和时区与宿主机保持一致。默认情况下容器为 UTC 标准时间。`/etc/timezone`让容器时间,时区和宿主机一致。但是如果不映射`/etc/timezone`java 应用中的时区还是错的,虽然使用`date -R`命令查看时间和时区都正常。
### 部署elastricsearch容器
### 部署 elastricsearch,activeMQ 容器
&emsp;&emsp;es 和 activeMQ 都依赖 java 的运行环境,所以有两种部署方式:
- 直接拉取 esactiveMQ 对应镜像,通过路径映射部署容器启动
- 在一个 java 镜像中运行 es 和 activeMQ
&emsp;&emsp;这里以第二种方式为例进行说明。
#### 创建 java 镜像
&emsp;&emsp;这里不从 docker hub 中拉取镜像,通过 dockerfile 来制作一个自定义的镜像。由于只需要一个 java 运行环境,所以只要将一个 jre 运行环境加入到一个基础 linux 镜像中即可(这里选择 ubuntu。制作过程如下
&emsp;&emsp;首先创建一个文件夹`dockerFileTest`存放依赖和 dockerfile 文件。
&emsp;&emsp;然后将下载加压后的 jre 运行环境放到`dockerFileTest/jre`目录下。
&emsp;&emsp;接着在 dockerFileTest 目录中创建 Dockerfile 文件,内容如下:
```bash
#说明基础镜像,默认:latest
FROM ubuntu
#将当前路径下的jre文件夹复制到新镜像下的/opt/jre路径
COPY jre /opt/jre
#设置环境变量
ENV JAVA_HOME=/opt/jre CLASSPATH=/opt/jre/lib PATH=$PATH:/opt/jre/bin
```
&emsp;&emsp;最后通过``命令生成新镜像 jre:v1
#### 创建 elastricsearch 容器
&emsp;&emsp;下载好 es假设存放在/root/es1 中,通过以下命令创建一个 es 容器:
```bash
docker run --name=es1 -itd -p 9200:9200 -p 9300:9300 -v /etc/localtime:/etc/localtime -v /etc/timezone:/etc/timezone -v /root/es1:/opt/es -w /opt/es jre:v1 ./bin/elasticsearch -Des.insecure.allow.root=true
```
参数含义如下:
- -w containerPath 设置容器工作目录为 containerPath
&emsp;&emsp;上面的命令以 es1 为容器名,映射 92009300 到宿主机端口,以`./bin/'elasticearch -Des.insecure.allow.root=true`创建 es 容器。最后加的参数为了让 es 能够以 root 在容器中启动。
#### 创建 es 集群
&emsp;&emsp;将之前的 es1 复制一份命名为 es2 作为节点 2。要让两个 es 节点构成 es 集群,需要让节点间能够进行通信,这里使用`--link`参数来让 es2 能够连上 es1 构成集群。`--link`用法如下:
```bash
--link containerName[:alias]
```
es2 启动命令如下:
```bash
docker run --name=es2 -itd -p 9201:9200 -p 9301:9300 --link es1 -v /etc/localtime:/etc/localtime -v /etc/timezone:/etc/timezone -v /root/es2:/opt/es -w /opt/es jre:v1 ./bin/elasticsearch -Des.insecure.allow.root=true
```
然后就能在 es2 中通过 es1 的容器名访问到 es1实际是在 es2 的 host 中增加了一条记录,将 es1 指向 es1 的 IP该 IP 是 docker 的虚拟网卡分配的 IP
&emsp;&emsp;但是使用--link 有一些局限,通过该参数联通的容器必须存在。因此该参数只能用在 B 依赖 A 的情况,如果同时 A 也依赖 B(也就是 AB 要能够相互访问到),这种情况下就不能通过 link 来实现了,原因大家应该能够想到。。。
#### 部署 activeMQ
&emsp;&emsp;在容器中启动 activeMQ 与启动 es 稍有不同。activeMQ 默认是后台启动的,启动完成后启动程序就会退出,因此如果直接以`./bin/activemq start`(假设当前目录在 activemq 中),启动容器会发现在 activemq 启动成功后容器就停止运行了。会出现这种情况是因为`容器中启动的第一个进程结束后容器就会被docker关闭掉`。所以呢我们只需让第一个进程不结束就行了,因此需要我们编写一个启动脚本来启动 activemq 并监测运行情况,一旦 activemq 进程挂掉,就结束启动脚本,否则一直运行。启动脚本代码如下:
```bash
#!/bin/bash
#使用sh脚本启动activemq,然后定时判断服务是否被关闭,关闭后退出脚本,否则一致循环。
#为避免docker容器在active自带的启动脚本运行结束后就关闭容器了
#获取启动pid
out=`./bin/activemq start`
echo "$out"
pid=`echo $out | grep -Eo "pid '[0-9]+'" | grep -Eo "[0-9]+"`
echo "当前mq进程pid为${pid}"
if [ ${#pid} = 0 ]; then
echo "启动失败"
exit 0
fi
while true; do
num=`ps -e | grep -cwE "$pid"`
if [ $num = 0 ]; then
echo "进程异常关闭"
exit 0
fi
sleep 1
done
```
&emsp;&emsp;然后以该脚本作为启动脚本来启动容器即可。启动命令如下:(假设 activemq 目录为/opt/activemq,启动脚本路径为/opt/activemq/start.sh)
```bash
docker run --name=activemq -itd -p 8161:8161 -p 61616:61616 -v /etc/localtime:/etc/localtime -v /etc/timezone:/etc/timezone -v /root/activemq:/opt/activemq -w /opt/activemq jre:v1 /bin/bash ./start.sh
```
## 部署 java 环境包
&emsp;&emsp;还是使用之前制作的 jar 镜像来启动 java 应用,这里以部署 jar 包为例,如果部署 war 包则需要在 tomcat 镜像上部署。特别注意下容器的时间和时区设置,否则 java 程序中无法获取到正确的时间和时区。这里通过映射宿主机的 localtime 和 timezone 文件来让容器时间和时区与宿主机相同。启动命令如下:
```bash
# 启动oms
docker run -itd --name=oms -p 8082:9090 -v /etc/localtime:/etc/localtime -v /etc/timezone:/etc/timezone -v /root/oms.jar:/opt/oms.jar -w /opt --link es1 --link activemq --link oms-mysql --link eureka-server jre:v1 java -jar oms.jar
# 启动das
docker run -itd --name=das -p 8083:9099 -v /etc/localtime:/etc/localtime -v /etc/timezone:/etc/timezone -v /root/das.jar:/opt/oms -w /opt --link es1 --link activemq --link oms-mysql --link eureka-server jre:v1 java -jar das.jar
```
&emsp;&emsp;本篇只是记录了如何使用`一容器一进程`的方式来部署 java 应用,后续可能会继续学习容器编排和容器管理技术。
**本篇原创发布于 Flex 的个人博客**:[点击跳转](http://tapme.top/blog/detail/2019-02-01-14-05)