docker 部署JavaWeb、Mysql、Redis详细教程
docker 部署JavaWeb、Mysql、Redis教程本文将详细介绍如何在Linux下部署Javaweb、MySQL、redis三个容器并实现容器间通信。我将使用Dockerfile制作镜像,使用脚本分别启动这三个镜像的方式进行部署。本文分为以下几个模块:docker基础入门dockerfile编写以及镜像制作容器启动流程本地镜像发布到镜像仓库及镜像导出导入docker-compose容器启
docker 部署JavaWeb、Mysql、Redis教程
本文将详细介绍如何在Linux下部署Javaweb、MySQL、redis三个容器并实现容器间通信。我将使用Dockerfile制作镜像,使用脚本分别启动这三个镜像的方式进行部署。本文分为以下几个模块:
- docker基础入门
- dockerfile编写以及镜像制作
- 容器启动流程
- 本地镜像发布到镜像仓库及镜像导出导入
- docker-compose容器启动管理(了解)
docker基础入门
docker镜像与容器
docker里有镜像和容器两个重要的概念。此博客对镜像和容器之间的区别有介绍http://blog.csdn.net/chszs 。下面是我个人的理解:
镜像类似操作系统的ISO光盘,而容器类似我们的操作系统。我们通过一张光盘可以安装多个操作系统,操作系统可以被用户使用并且修改关闭重启。而光盘一旦被制作完成之后,就无法修改了。
也可以用Java的类和对象来做比喻。镜像相当于Java的class,而容器则是对象,所有的对象创建时都要依赖于class,一个class可以创建无数个对象,每个创建的对象在堆(heap)都有自己独立的内存空间。而容器也是如此,每个容器启动后都在宿主机上占用单独的空间,容器之间文件系统彼此隔绝,可以通过网络进行相互通信。
docker容器间相互通信
可以参照这几篇篇博客,讲的非常全面
https://blog.csdn.net/smooth00/article/details/82842234
https://blog.csdn.net/u013355826/article/details/84987233
我们生产环境最终采用的是–net=host 模式,即与主机共用网络,这样使用的好处是容器直接相当于宿主机里的一个进程,容器间网络通信与普通的进程间通信方式相同,直接使用 localhost:port即可通信。而且我公司计划在一台服务器部署多个容器,使用多个域名共同映射到该服务器,然后在服务器使用nginx对不同域名的请求代理到不同的容器,达到一台云服务器部署多家客户应用的目的。这种情况下如果使用bridge的网络模式,则nginx的配置较为麻烦,故镜像共用宿主机的网络(–net=host)会较为方便。
当然,使用 --link 做容器链接的代码示例也会提供,并且该代码实测可用
dockerfile编写以及镜像制作
Dockerfile编写
1.示例
先以一段正式的Dockerfile文件为例,文件名: Dockerfile
第1行 from tomcat:9.0
即本镜像要引用tomcat9.0这个镜像,如果这个镜像在本地镜像存在则直接使用本地镜像,如果不存在则从远程镜像仓库获取,并安装到本地镜像。
第3行 MAINTAINER hejing "hejing@szlabsun.com"
这行对docker镜像编译无实际影响,只是记录该镜像制作人和联系方式
第5行 WORKDIR /usr/local/tomcat/webapps/
workdir代表容器当前进入到此目录下 即相当于容器执行了 cd /usr/local/tomcat/webapps/
命令
第7行 RUN rm -rf /usr/local/tomcat/webapps/*
run 命令 即相当于在容器执行shell命令 run 后面的即是shell命令
第9行 ADD springboot.war /usr/local/tomcat/webapps/ROOT.war
ADD 和COPY命令都是将本地的文件拷贝到容器内 ADD 宿主机文件或文件夹 容器内文件或文件夹
该命令也可以用 ADD ./ /usr/local/tomcat/webapps/
这条命令代表将当前目录下的所有文件拷贝到容器webapps/下,文件名称不会改变
第11行 RUN echo "Asia/Shanghai" > /etc/timezone
让容器内的时间和宿主机时间一致
以上是制作tomcat带有我们自己的war包的镜像,以下再贴一份运行jar包的dockerfile
FROM anapsix/alpine-java:8_server-jre_unlimited
MAINTAINER hejing@szlabsun.com
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN mkdir -p /opt/projects/weims
WORKDIR /opt/projects/weims
COPY ./weims.jar /opt/projects/weims
EXPOSE 7700
CMD java -jar -Xms512m -Xmx512m -Xss256k -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC /opt/projects/weims/weims.jar
2.mysql数据库Dockerfile
FROM mysql:5.7
MAINTAINER hejing@szlabsun.com
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
COPY ./weims_sd.sql /docker-entrypoint-initdb.d
COPY ./weims_sd.sql /docker-entrypoint-initdb.d
该命令是将 ./下的sql文件放到docker容器数据库启动的初始脚本文件夹中,这样mysql在启动时会执行该脚本,建库建表。
3.redis 镜像dockerfile
redis无需做特别配置 直接运行 docker pull redis
即安装好redis镜像
4.javaweb项目(war包)
FROM tomcat:9.0
MAINTAINER hejing "hejing@szlabsun.com"
WORKDIR /usr/local/tomcat/webapps/
RUN rm -rf /usr/local/tomcat/webapps/*
ADD springboot.war /usr/local/tomcat/webapps/ROOT.war
RUN echo "Asia/Shanghai" > /etc/timezone
镜像制作
1.示例
镜像制作要依赖于编写好的Dockerfile,宿主机进入dockerfile所在的目录,执行 docker build -t weims-hj212 /opt/dockerBuild/hj212/
docker build -t [images名称] [dockerfile所在目录]
以下是镜像build成功之后的显示效果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-COdpibj1-1600758716019)(C:\Users\liucu\AppData\Roaming\Typora\typora-user-images\image-20200922112832296.png)]
镜像制作成功之后 执行 docker images
即可看到编译好的镜像
2.mysql镜像制作
首先 将dockerfile文件放到某一目录下,本示例为 opt/docker/mysql/
然后将初始化脚本也放到该目录下
执行 docker build -t weims-mysql /opt/docker/mysql
即可
3.redis镜像制作
即执行完 docker pull redis 即完成了redis镜像制作
docker容器启动流程
1.示例
以上步骤我们已经制作好了一个镜像,接下来我们要用此镜像来实例化一个容器,执行 docker run -d --name weims-hj212 --net=host weims-hj212
docker run 为运行docker容器的指令
-d 代表在后台运行
–name [containerName] 指定容器的名称
–net=host 指定网络模式为使用宿主机的网络
weims-hj212 此代表镜像的名称 该字段可以写镜像的名称也可以写镜像id
该指令各部分的位置不固定,可以自由组合 如 docker run weims-hj212 --name weims-hj212 --net=host -d
这样一个容器就启动完成了 ,可以执行 docker ps 查看本机的容器运行状态
要进入我们刚刚启动的容器,则可以执行 docker exec -it weims-hj212 /bin/bash
这样 我们就进入了容器内部,可以查看容器的日志以及文件信息等
2.mysql容器启动
在任意目录下执行 docker run -d -p 3307:3306 -v /home/hejing/mysqld.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf -v /opt/docker/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name weims-mysql weims-mysql --lower_case_table_names=1
可以成功启动mysql -p 3307:3306 将本机的3307端口与容器的3306端口做映射,即相当于nginx的反向代理功能,访问宿主机的3307端口即自动代理到容器的3306端口
3.redis容器启动
将reids的配置文件放到某一目录下,本示例的redis配置文件为 /root/redis/redis.conf 执行以下命令,redis即可成功运行
docker run -p 6379:6379 --name weims-redis -v /root/redis/redis.conf:/etc/redis/redis.conf -v /root/redis/data:/data -d weims-redis redis-server /etc/redis/redis.conf --appendonly yes
启动命令解释如下:
-p 6379:6379:把容器内的6379端口映射到宿主机6379端口
-v /root/redis/redis.conf:/etc/redis/redis.conf:把宿主机配置好的redis.conf挂载到容器内的这个位置中
-v /root/redis/data:/data:把redis持久化的数据在宿主机内显示,做数据备份
redis-server /etc/redis/redis.conf:这个是关键配置,让redis不是无配置启动,而是按照这个redis.conf的配置启动
–appendonly yes:redis启动后数据持久化
启动后如果出现一些警告,可参考https://www.cnblogs.com/xsjzhao/p/10882870.html进行解决
4,javaweb容器启动
1.共用宿主机网络方式
配置文件中jdbc 配置中mysql地址 写 localhost:3307或者127.0.0.1:3307 即把mysql容器当成本机的一个进程即可,然后执行
docker run -d --name weims-admin --net=host weims-admin
至此,javaweb启动成功, 访问8080端口即可进入web项目
注:因为我在编写Javaweb的dockerfile时 没有修改tomcat的配置 端口是8080 ,要修改的话可以将自己的配置文件server.xml ADD进容器的tomcat/conf/下
2.通过link建立连接
在javaweb项目的配置文件中以容器名的方式配置mysql和redis的连接host
配置文件如下
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-od1dULlo-1600758716023)(C:\Users\liucu\AppData\Roaming\Typora\typora-user-images\image-20200922144054033.png)]
然后执行命令启动javaweb
docker run -d --name weims-admin -p 8080:8080 --link weims-mysql:weims-mysql --link weims-redis:weims-redis weims-admin
–link命令解析
–link [alias] [contianerName] --link 别名 容器名 代表使用别名映射到容器名,做法原理是将 别名写进本容器的host文件里 对应的ip则是被链接的容器的ip
这样javaweb项目在访问 weims-mysql时 会将其视为一个域名 去本机host找到该域名对应的ip
docker本地镜像发布到镜像仓库及镜像导出导入
1.本地镜像发布到镜像仓库
…
2.镜像导出导入
涉及的命令有export、import、save、load
save
-
命令
docker save [options] images [images...]
示例
docker save -o nginx.tar nginx:latest
或
docker save > nginx.tar nginx:latest
其中-o和>表示输出到文件,nginx.tar
为目标文件,nginx:latest
是源镜像名(name:tag)
load
- 命令
docker load [options]
- 示例
docker load -i nginx.tar
或
docker load < nginx.tar
其中-i和<表示从文件输入。会成功导入镜像及相关元数据,包括tag信息
export
- 命令
docker export [options] container
- 示例
docker export -o nginx-test.tar nginx-test
其中-o表示输出到文件,nginx-test.tar
为目标文件,nginx-test
是源容器名(name)
import
- 命令
docker import [options] file|URL|- [REPOSITORY[:TAG]]
- 示例
docker import nginx-test.tar nginx:imp
或
cat nginx-test.tar | docker import - nginx:imp
区别
- export命令导出的tar文件略小于save命令导出的
- export命令是从容器(container)中导出tar文件,而save命令则是从镜像(images)中导出
- 基于第二点,export导出的文件再import回去时,无法保留镜像所有历史(即每一层layer信息,不熟悉的可以去看Dockerfile),不能进行回滚操作;而save是依据镜像来的,所以导入时可以完整保留下每一层layer信息。如下图所示,
nginx:latest
是save导出load导入的,nginx:imp
是export导出import导入的。
建议
可以依据具体使用场景来选择命令
- 若是只想备份images,使用save、load即可
- 若是在启动容器后,容器内容有变化,需要备份,则使用export、import
docker-compose容器启动管理
docker-compose 是作为多个容器之间管理调度的工具,本例的docker-compose配置文件如下
version: '2'
services:
weims-mysql:
build:
context: ./
dockerfile: ./db/Dockerfile
environment:
MYSQL_ROOT_PASSWORD: DbWeims@2020
restart: always
container_name: weims-mysql
image: weims-mysql
ports:
- 3306:3306
volumes:
- ./weims-mysql:/var/lib/mysql
command: --lower_case_table_names=1
weims-redis:
image: redis:5.0.4
restart: always
container_name: weims-redis
ports:
- 6379:6379
weims-admin:
build:
context: ./
dockerfile: ./weims/Dockerfile
restart: always
container_name: weims-admin
image: weims-admin
ports:
- 8085:8085
depends_on:
- weims-redis
- weims-mysql
links:
- "weims-redis"
- "weims-mysql"
该文件可以成功编译并且启动,但是存在以下问题
- mysql的root密码没有成设置
- weims-admin的web项目使用了–link ,mysql容器启动后的ip是172.0.0.2 , 但是项目启动后访问数据库域名映射为172.0.0.4
在咨询干devops的前同事后,了解到docker-compose在落地使用并不多,所以暂未纠结此处,打算暂时先用脚本的方式分别启动各容器,空闲时间学习k8s,以后用k8s管理容器
更多推荐
所有评论(0)