项目驱动-两日速成Docker日记

时间:2022-07-26
本文章向大家介绍项目驱动-两日速成Docker日记,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

经验总结写在前面:

  有状态的功能模块,比如Mysql,要将数据文件挂载到宿主机

  如果功能模块之间要通过 localhost 这种屏蔽具体 IP 的设置来通信的话,最好使用 --network=host 来让多个容器都共用一个NetworkSpace ,可以通过localhost互通

项目介绍:内部系统

需求环境:Tomcat + Mysql + Python

工作:前端选取 Excel 表格,传给后台 后台解析 Excel 表格,存入数据库,存入数据库后调用大数据组写好的 接口,通知Python服务器处理 Mysql 中的数据

业务都已经写好了,剩下 前端-后台-大数据 三方业务的联通

还没有联通测试,时间紧迫,懒得在本地搭环境测试,直接用Docker容器测试,反正到时候去内网部署也需要用 Docker 打包过去

一. 制作三者镜像

  1.Tomcat

  直接拉取tomcat:7-jre8, 我用的是 jdk8 写项目,tomcat用7比较稳,本地也是用7,怕出岔子。

  接下去把自己的 war 包 放到 webapps 文件夹里就好了,前端本来想用 Nginx部署,但是只是一个演示程序,就把他一并交给Tomcat吧

  放入 webapps :

  sudo docker ps

  查看到运行的 tomcat 容器的 ID 是 ABC(假设)

  将文件夹放入 webapps, 可能不知道 这个文件夹的路径,这个路径是根据镜像来的,可以先进入容器看一下在哪

  sudo docker exec -it ABC /bin/bash

  上面这个指令就可以进入容器,因为要求容器运行 /bin/bash 并且 -it 要求分配一个 终端

  一般情况下在 tomcat:XXX 中会进入到 /usr/local/tomcat , 这个是设置好的用户登录点

  打一下 ls 指令

  于是知道了webapps 的路径: /usr/local/tomcat/webapps

  使用 cp 指令把 war 包和 前端文件夹复制过去

  sudo docker cp /code/abc.war fb9f:/usr/local/tomcat/webapps

  sudo docker cp /code/dist fb9f:/usr/local/tomcat/webapps

  格式:sudo docker cp 带完整路径的本地文件 容器id:容器中的路径

  这样就可以把两份东西都放到 webapps里,最好重启一下容器,让放入的文件生效。

  sudo docker restart 容器id

  到此,可以正常访问刚刚放进去的 war 包程序 和 前端静态文件

  接着要提交这个容器,把他变成静态的镜像。

  sudo docker commit 容器id 仓库名:标签

  示例: sudo docker commit fb9f wlq/gdj:tomcat

  这样就打包好一个镜像了,具体还可以 把 镜像 push 到远程仓库,和 git 一样,只不过git管理的是代码,docker 管理的是软件一层层的Layer,一个镜像是由许多层Layer组成的,在构建镜像的时候,没执行一次RUN 就会生成新的一层Layer。

  2.Python 服务器

  大数据组给我的是写好的Python程序,需要用命令行的形式运行 .py 文件,还是用Dockerfile 构建比较好。

  Dockerfile 只要构建出 镜像,镜像就和这个Dockerfile 没有关系了,Dockerfile 只是描述要怎么构建镜像

需要python环境,而且版本要求3.6,于是从python:3.6上构建,先是创建一个文件夹,用来存放python服务器的文件,-p 表示递归创建

WORKDIR 改变当前工作目录,使得下方的 COPY 指令能在当前目录下找到 Project 这个文件夹,并且放到后面的 /usr/local/stgdj/py 文件夹里,注意,这些文件夹指的都是镜像中的文件夹,Dockerfile可以塑造

镜像,一层层镜像上运行容器,容器运行时可修改,镜像不行。

  pip3 是安装库,最后用 python 指令运行 de.py

FROM python:3.6
 
RUN mkdir -p /usr/local/stgdj/py 
WORKDIR /usr/local/stgdj/py
COPY Project /usr/local/stgdj/py
WORKDIR /usr/local/stgdj/py
RUN ls 
&& pip3 install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple
 
CMD ["python", "de.py"]

  3.Mysql

  相对于 前两者,Mysql 是有状态的模块,所谓有状态,就是用户的数据需要固定保存,如果机器重启,数据依然还在。

  这就需要把 Mysql 容器的数据文件 挂载在宿主机

  先把镜像构建好:Dockerfile:

FROM mysql:5.7


ENV MYSQL_ROOT_PASSWORD 123
COPY /code/abc.sql /mysql/abc.sql    #将要导入的数据sql文件 COPY到镜像
COPY my.cnf /etc/mysql/my.cnf       #自己写好的配置,放到my.cnf COPY到镜像

RUN chmod 000 /etc/mysql/my.cnf       #把配置文件改下权限,如果是其他人可读写,Mysql会拒绝承认这个安全性低的配置文件

CMD ["mysqld", "--user=root"]       #启动mysql,要把 --user=root 加上,不然的话,无法启动

  其中的MYSQL_ROOT_PASSWORD是指定ROOT用户的密码,很贴心吧,Docker专门设置了这个环境变量

启动容器的时候,要加上挂载选项

sudo docker run -v 宿主机目录:容器目录 镜像id

sudo docker run -v /code/mysql:/var/lib/mysql abc

mysql的数据一般存在 /var/lib/mysql , 所以把这个文件夹挂载到宿主机的 /code/mysql 文件夹中,下一次启动容器,数据还在

接着要进去 容器,把刚才复制进去的 sql 文件导入到数据库

  网络问题:一开始懵懵懂懂, 开了三个容器,三个容器里的配置的相互访问都是 访问localhost, tomcat 的 war 访问数据库是 localhost:3306, 访问py程序是 localhost:5000, py 服务器访问数据库也是 localhost:3306, 当时发现根本无法联通,后来学习到 docker 默认使用桥接模式,三个容器都会有自己独立的 Network Namespace,有自己的IP,端口等一系列网络组件。又不是同一套网络组件,当然无法

从localhost访问。

  一开始用的是 --link 去连接 tomcat 和 mysql,py服务器和 mysql,但是后来发现 tomcat 还要连 py服务器,就束手无策了,因为 --link 只能连接两个容器

  于是把 war 里指定访问IP的配置文件挂载出来放到 宿主机上,把访问 ip 设置成 docker0的 ip 或 宿主机局域网的 ip,但是这样还是不优雅

  其实最终的解决方案是把容器的 网络模式变成 host 这样的话都共用 宿主机的一套网络组件

  可以通过 localhost 相互通信

  sudo docker run --net=host 镜像id