使用docker 部署应用

虽然知道如何部署war包到服务器上了,但是docker这么火,不学习学习装装逼怎么行呢,今天就来尝尝鲜。


使用docker 部署应用_第1张图片
201806291530261215908089.jpg

注:阿里云上选的系统是centos,下面是具体的安装步骤都是在centos系统下完成的。

docker环境搭建

sudo yum update  // 如果需要,对yum进行更新
yum -y install docker-io // 使用yum 安装docker
service docker start // 安装成功后启动docker
docker run hello-world // 从官网下个hello-world的镜像,启动容器打印hello-world,说明启动成功

docker部署mysql镜像

如果我们直接创建一个空的数据库,那直接下载mysql镜像就行了。

docker pull hub.c.163.com/library/mysql:5.7 // 使用网易的仓库下载mysql镜像
docker tag hub.c.163.com/library/mysql:5.7 mysql:5.7 // 重命名mysql镜像名

由于要把本地数据库的数据也迁移到阿里云上,为此,需要对mysql镜像进行定制化,我事先将本地的数据库脚本导出到为此创建dockerfile如下:

FROM mysql:5.7

#设置免密登录
ENV MYSQL_ALLOW_EMPTY_PASSWORD yes

#将所需文件放到容器中
COPY setup.sh /mysql/setup.sh
COPY schema.sql /mysql/schema.sql
COPY privileges.sql /mysql/privileges.sql

#设置容器启动时执行的命令
CMD ["sh", "/mysql/setup.sh"]

其中setup.sh为启动执行脚本,内容如下:

#!/bin/bash
set -e

#查看mysql服务的状态,方便调试,这条语句可以删除
echo `service mysql status`

echo '1.启动mysql....'
#启动mysql
service mysql start
sleep 3
echo `service mysql status`

echo '2.开始导入数据....'
#导入数据
mysql < /mysql/schema.sql
echo '3.导入数据完毕....'

sleep 3
echo `service mysql status`

#重新设置mysql密码
echo '4.开始修改密码....'
mysql < /mysql/privileges.sql
echo '5.修改密码完毕....'

#sleep 3
echo `service mysql status`
echo 'mysql容器启动完毕,且数据导入成功'

tail -f /dev/null

具体的sql语句放在schema.sql文件中,这样启动后就会自动创建表结构,插数据。另外要注意的是这里是先导入数据,然后才是设置用户和权限,是因为mysql容器一开始为免密登录,Dockerfile中有如下设置:ENV MYSQL_ALLOW_EMPTY_PASSWORD yes,此时执行导入数据命令不需要登录验证操作,如果是先执行权限操作,那么导入数据则需要登录验证,整个过程就麻烦了许多。
设置数据库权限的脚步privileges.sql文件内容如下:

use mysql;
select host, user from user;
-- 因为mysql版本是5.7,因此新建用户为如下命令:
create user docker identified by '123456';
-- 将docker_mysql数据库的权限授权给创建的docker用户,密码为123456:
grant all on docker_mysql.* to docker@'%' identified by '123456' with grant option;
-- 这一条命令一定要有:
flush privileges;

安装mongodb镜像

docker pull hub.c.163.com/public/mongodb:3.2.0

安装elasticsearch镜像

docker pull hub.c.163.com/library/elasticsearch:2.4.1

使用docker插件build spring boot工程

首先在mac系统上安装并启动docker,这里就不再阐述了。

下面要部署的是我的个人博客网站。应用分为博客应用和文件服务器应用。其中博客应用需要连接mysql进行数据持久化,elasticsearch进行全文索引,而文件服务器需要用到mongodb进行非结构化存储。为此下面要编译出两个个人镜像,以及对下载的mysql,es镜像进行相关配置,下面就详细介绍这些内容:

  • 首先是博客应用的配置
    在pom.xml文件中添加配置,这样idea会自动下载docker的编译插件。
    
        yunsblog
    
    
        compile
        
            
                com.spotify
                docker-maven-plugin
                0.4.11
                
                    ${docker.image.prefix}/${project.artifactId}
                    ${project.basedir}/src/main/docker
                    
                        
                            /
                            ${project.build.directory}
                            ${project.build.finalName}.jar
                        
                    
                
            
    
    

接着在项目的pom.xml同级目录下创建dockerfile文件,作为docker编译生成镜像的依据。dockerfile内容如下:

FROM java:8-jre
ADD demo-0.0.1-SNAPSHOT.jar /app/
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app/demo-0.0.1-SNAPSHOT.jar"]
EXPOSE 8080

第一句表示此镜像依赖jdk镜像,编译时会先下载jdk镜像。
第二句表示会将maven编译后的jar包拷贝到镜像的/app/目录下。
第三句表示启动镜像对应的容器的时候,会执行java -jar /app/demo-0.0.1-SNAPSHOT.jar命令 ,即启动应用。
第四句表示暴露容器的8080端口,因为应用也是默认暴露的8080端口,这样部署后应用才能被访问。

上述几步都完成后,就可以在pom.xml文件目录下执行下面的命令去编译生成应用的jar包和镜像:

mvn package -Dmaven.test.skip=true docker:build

如果mvn配了有时候没生效,需要执行下:

source ~/.bash_profile

编译后,我们使用docker image ls命令就可以看到我们新生成的镜像了:

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
yunsblog/demo       latest              63b7e4d9b807        22 minutes ago      381MB

如果我们在本地直接启动容器,也就直接启动应用了:


屏幕快照 2018-07-21 上午10.48.29.png
  • 接着是文件服务器应用的配置
    文件服务器的docker配置大部分都和博客应用的配置相同,唯一不同的就是dockerfile:
FROM java:8-jre
ADD demo-0.0.1-SNAPSHOT.jar /app/
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app/demo-0.0.1-SNAPSHOT.jar"]
EXPOSE 8081

因为应用服务器在application.properties属性文件中暴露的是8081端口,所以容器也要相应暴露8081端口。
使用mvn package -Dmaven.test.skip=true docker:build命令编译后生成了文件服务器的镜像:

REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
fileserver/demo     latest              554845dd9ca9        About a minute ago   336MB

现在问题来了,由于我们直接在本地mac系统上编译生成了镜像文件,那这个镜像文件在哪呢?百度后发现位置为:

/Users/{YourUserName}/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/Docker.qcow2

问题又来了,镜像的格式是qcow2格式,这怎么导入到阿里云上生成镜像呢?这回百度不出来办法了,于是想到了另外一个办法,那就是拿着生成的jar包和dockerfile一起上传到阿里云上,在阿里云上使用docker来生成镜像。其实这样也有好处,毕竟上传一个镜像速度肯定也是要比上传jar包慢很多的。
下面我们将jar包和对应的dokerfile上传到阿里云上后,在dockerfile目录下执行:

docker build -t yubuyun/blog .

这样就开始生成镜像了。生成的过程有点慢,可能是下载依赖的时候网速有点慢。
生成好镜像后,最后一步就是将这几个容器连接起来。

  • 启动mysql容器:
    首先先编译镜像:
docker build -t yubuyun/mysql .

然后启动容器:

docker run -d -p 3306:3306 --name docker-mysql yubuyun/mysql

注意,这里的镜像是我之前自定义dockerfile的镜像。启动容器的时候,将容器的3306端口映射到阿里云主机的3306端口上。

  • 启动mongodb容器
docker run -d -p 27017:27017 hub.c.163.com/public/mongodb:3.2.0
  • 启动elasticsearch容器
docker run -d -p 9200:9200 -p 9300:9300  hub.c.163.com/library/elasticsearch:2.4.1
  • 启动文件服务器应用
docker run -d -p 8081:8081 --name fileserver --link docker-mongoldb fcfd7f...
  • 启动博客应用
docker run -d -p 8080:8080 --name blog --link docker-elasticsearch --link docker-mysql fcfd7f...

结果启动后,连接mysql失败了,进入mysql容器登陆成功了,说明账号密码对的,问题就在容器间的连接上,问了下同事,使用docker-compose可以实现容器互通,但是上面这个方法到底哪里有问题,还得再查查,顺便再学习一下docker-compose和docker三剑客了。

写到这本来要告一断落,但是还是不死心,感觉用上面这种方法是可以实现的,一定是配置问题,于是百度了许久,发现有篇博文也遇到了相同的问题,于是照着这篇文章再来了一遍,终于成功了,下面再分享一下过程,参考日志为:https://www.jb51.net/article/126278.htm
修改要修改下应用的数据库连接:

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#spring.datasource.url=jdbc:mysql://127.0.0.1:3306/db_activiti?useUnicode=yes&serverTimezone=GMT
spring.datasource.url=jdbc:mysql://mysql:3306/db_activiti?useUnicode=yes&serverTimezone=GMT
spring.datasource.username=root
spring.datasource.password=abc123

spring.data.elasticsearch.properties.transport.tcp.connect_timeout=120s
spring.data.elasticsearch.cluster-name=elasticsearch
spring.data.elasticsearch.cluster-nodes=127.0.0.1:9300

file.server.url=http://localhost:8081/upload
spring.http.multipart.max-file-size=30Mb
spring.http.multipart.max-request-size=30Mb

可以看出修改了mysql的连接信息,原来localhost肯定是有问题的,其中localhost替换为mysql,这个是后面link数据库的别名。

修改后重新部署blog容器,运行命令为:

docker run -p 8080:8080 --name blog --link docker-mysql:mysql b3cb50328ee8

按照上述办法最终真的可以连接上mysql,但是新的问题了,在照着这种办法连接elasticsearch的时候,发现es容器启动一会就会报错,百度了一下说这是由于es占用内存较大,其默认配置为需要1g内存,而我的ecs只有1g的内存 ,所以导致es启动失败,为此需要修改es的配置文件,在/config/jvm.options文件中,但是由于我使用的es是低版本的2.4.1(为什么使用这个版本呢,这是因为使用的spring data jpa只支持2.4.1以下的版本),这个低版本没有这个配置文件,那可以在哪个地方改下这个呢?
百度一下,有两种方法可以修改这个内存,一个是设置es的环境变量

export ES_HEAP_SIZE=512m

另一个是在启动命令中加上:

./bin/elasticsearch -Xmx512m -Xms512m

第二种方法我试了不行,找不到参数-X,下面就试下第一种方法行不行。
设置如上环境变量后,es启动后坚持2个小时左右还是挂了,而且当应用连接后马上就挂,问了下搞运维的同学,证实了es对内存的要求比较高,阿里云1g的乞丐版怕是玩不了了,用一句话来结束云上的es体验:从入门到放弃。

docker run -p 8080:8080 --name blog --link docker-mysql:mysql --link fileserver:fileserver c8bcf97ebf15
show dis
db.runoob.insert({"name":"菜鸟教程"})
sudo docker logs -f -t --tail 行数 容器名

你可能感兴趣的:(使用docker 部署应用)