docker常用容器
一、MySQL容器
1.1.简单版 Mysql 5.7 安装
简单的启动Mysql容器:
# 需要使用 -e 配置环境变量 MYSQL_ROOT_PASSWORD(mysql root用户的密码) docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
简单版的Mysql会存在以下问题:
- 中文乱码
- 没有容器卷映射
启动docker容器后,可以正常的连接、创建数据库,创建表,插入数据。但是插入中文则会报错。
-- 创建db01数据库 create database db01; -- 切换到db01; use db01; -- 创建表 create table t1(id int, name varchar(20)); -- 插入英文可以正常插入 insert into t1 values(1, 'abc'); -- 插入中文报错 insert into t1 values(2, '张三');
报错如下:

这是因为docker默认的字符集的问题,可以在mysql中使用以下命令查看数据库字符集:
,
返回的字符集中,character_set_database、character_set_server等都为latin1字符集,所以会报错。
而且因为启动容器时没有配置容器卷映射,当容器意外被删时,数据无法找回。

1.2.实际单机应用版 Mysql 5.7安装
启动 Mysql 容器,并配置容器卷映射:
docker run -d -p 3306:3306 \ --privileged=true \ -v /app/mysql/log:/var/log/mysql \ -v /app/mysql/data:/var/lib/mysql \ -v /app/mysql/conf:/etc/mysql/conf.d \ -e MYSQL_ROOT_PASSWORD=123456 \ --name mysql \ mysql:5.7
在/app/mysql/conf下新建 my.cnf,通过容器卷同步给mysql实例,解决中文乱码问题:
[client] default_character_set=utf8 [mysqld] collation_server = utf8_general_ci character_set_server = utf8
character_set_database=utf8
重启mysql容器,使得容器重新加载配置文件:
docker restart mysql
此时便解决了中文乱码(中文插入报错)问题,也可以在创建表的时候设置编码方式。
而且因为启动时将容器做了容器卷映射,将mysql的配置(映射到/app/mysql/conf)、数据(映射到/app/mysql/data)、日志(映射到/app/mysql/log)都映射到了宿主机实际目录,所以即使删除了容器,也不会产生太大影响。只需要再执行一下启动Mysql容器命令,容器卷还按相同位置进行映射,所有的数据便都可以正常恢复。
1.3.Mysql 主从复制安装
MySQL主从复制的前提:
- 主服务器一定要打开二进制日志
- 必须两台服务器(或者是多个实例)
- 从服务器需要一次数据初始化
- 如果主从服务器都是新搭建的话,可以不做初始化
- 如果主服务器已经运行了很长时间了,可以通过备份将主库数据恢复到从库。
- 主库必须要有对从库复制请求的用户。
- 从库需要有relay-log设置,存放从主库传送过来的二进制日志show variables like '%relay%';
- 在第一次的时候,从库需要change master to去连接主库。
- change master信息需要存放到http://master.info 中show variables like '%master_info%';
- 从库怎么知道,主库发生了新的变化?通过http://relay-log.info记录的已经应用过的relay-log信息。
- 在复制过程中涉及到的线程
- 从库会开启一个I0 thread(线程),负责连接主库,请求binlog, 接收binlog并写入relay-log。
- 从库会开启一个SQL thread(线程),负责执行relay-log中的事件。
- 主库会开启一个dump thrad(线程),负责响应从I0 thread的请求

为了方便容器管理,创建网络模式,主从复制的两个MySQL容器和后续的tomcat集群和nginx添加到该网络

1.3.1.创建主机master
安装主服务器容器实例(端口号3307):
1)启动容器实例
docker run -p 3307:3306 \ --name mysql-master \ --privileged=true \ -v /app/mysql-master/log:/var/log/mysql \ -v /app/mysql-master/data:/var/lib/mysql \ -v /app/mysql-master/conf:/etc/mysql \ -e MYSQL_ROOT_PASSWORD=123456 \ --network mynetwork \ -d mysql:5.7
数据库文件存放路径
- /var/log/mysql中存放的是日志文件
- 其中 /var/lib/mysql/ 就是mysql数据库文件存放路径,
- /etc/mysql中存放的配置相关的文件
2)进入/app/mysql-master/conf,新建my.cnf配置文件
[mysqld] ## 设置server_id, 同一个局域网中需要唯一 server_id=101 ## 指定不需要同步的数据库名称 binlog-ignore-db=mysql ## 开启二进制日志功能 log-bin=mall-mysql-bin ## 设置二进制日志使用内存大小(事务) binlog_cache_size=1M ## 设置使用的二进制日志格式(mixed,statement,row) binlog_format=mixed ## 二进制日志过期清理时间。默认值为0,表示不自动清理 expire_logs_days=7 ## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断 ## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致 slave_skip_errors=1062
3)重启容器实例
docker restart mysql-master
4)进入容器实例内
docker exec -it mysql-master /bin/bash
5)登录mysql,创建数据同步用户
-- 首先使用 mysql -uroot -p 登录mysql -- 创建数据同步用户 create user 'slave'@'%' identified by '123456'; -- 授权 grant replication slave, replication client on *.* to 'slave'@'%'; flush privileges;
1.3.2.创建从数据库slave
安装从服务器容器实例(端口号3308):
1)启动容器服务
docker run -p 3308:3306 \ --name mysql-slave \ --privileged=true \ -v /app/mysql-slave/log:/var/log/mysql \ -v /app/mysql-slave/data:/var/lib/mysql \ -v /app/mysql-slave/conf:/etc/mysql \ -e MYSQL_ROOT_PASSWORD=123456 \ --network mynetwork \ -d mysql:5.7
2)进入/app/mysql-slave/conf目录,创建my.cnf配置文件:
[mysqld] # 设置server_id, 同一个局域网内需要唯一 server_id=102 # 指定不需要同步的数据库名称 binlog-ignore-db=mysql # 开启二进制日志功能,以备slave作为其它数据库实例的Master时使用 log-bin=mall-mysql-slave1-bin # 设置二进制日志使用内存大小(事务) binlog_cache_size=1M # 设置使用的二进制日志格式(mixed,statement,row) binlog_format=mixed # 二进制日志过期清理时间。默认值为0,表示不自动清理 expire_logs_days=7 # 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断 # 如:1062错误是指一些主键重复,1032是因为主从数据库数据不一致 slave_skip_errors=1062 # relay_log配置中继日志 relay_log=mall-mysql-relay-bin # log_slave_updates表示slave将复制事件写进自己的二进制日志 log_slave_updates=1 # slave设置只读(具有super权限的用户除外) read_only=1
docker restart mysql-slave
1.3.3.在主数据库中查看主从同步状态
1)进入主数据库
docker exec -it mysql-master /bin/bash
2)进入Mysql
mysql -uroot -p
show master status;
主要查看返回结果的文件名File、当前位置Position

1.3.4.进入从数据库容器,配置主从复制、
1)进入从数据库
docker exec -it mysql-slave /bin/bash
2)进入数据库
mysql -uroot -p
3)配置从数据库所属的主数据库
-- 格式: -- change master to master_host='宿主机ip',master_user='主数据库配置的主从复制用户名',master_password='主数据库配置的主从复制用户密码',master_port=宿主机主数据库端口,master_log_file='主数据库主从同步状态的文件名File',master_log_pos=主数据库主从同步状态的Position,master_connect_retry=连接失败重试时间间隔(秒); change master to master_host='192.168.42.135',master_user='slave',master_password='123456',master_port=3307,master_log_file='mall-mysql-bin.000001',master_log_pos=815,master_connect_retry=30;
# \G 可以将横向的结果集表格转换成纵向展示。
# slave status的字段比较多,纵向展示比友好
show slave status \G;
Slave_IO_Running、Slave_SQL_Running。目前两个值应该都为 No,表示还没有开始。
5)开启主从同步
start slave;
Slave_IO_Running、Slave_SQL_Running都变为Yes,如下:
1.3.5.主从复制测试:
1)在主数据库上新建库、使用库、新建表、插入数据
create database db01; use db01; create table t1 (id int, name varchar(20)); insert into t1 values (1, 'abc');
2)在从数据库上使用库、查看记录
show databases; use db01; select * from t1;
二、Tomcat部署
2.1.单机版Tomcat部署
生成Tomcat容器
docker run --name=tomcat8080 -p 8080:8080 -v /mydata/tomcat/webapps/:/usr/local/tomcat/webapps/ -d tomcat:8
进入容器内部发现webapps里是空的,并没有我们熟知的ROOT等文件夹,可以发现ROOT等文件在webapps.dist文件夹中,将webapps.dist文件夹中的内容复制一份到webapps文件夹中
#将容器webapps文件夹复制到宿主机
docker cp tomcat8080:/usr/local/tomcat/webapps.dist/. /mydata/tomcat/webapps/

浏览器访问Tomcat,如下:

2.2.搭建Tomcat集群
以Nginx实现tomcat集群,结合上面的MySQL主从复制,实现项目部署

2.2.1.构建Tomcat镜像
1)拉取基础镜像
docker pull dordoka/tomcat
这个镜像中已经包含java8和Tomcat8
2)编写dockerfile
在宿主机根目录下创建myfile,将EasyBuy.war上传到myfile目录,然后编写Dockerfile文件内容如下:
FROM tomcat:9.0.41-jdk8-openjdk MAINTAINER Augus<Auguses@126.com> # 建立数据容器卷 VOLUME ["/usr/local/tomcat/webapps"] # 拷贝war包到容器 COPY EasyBuy.war /usr/local/tomcat/webapps/ EXPOSE 8080
3)构建镜像
docker build -t uag/uag_tomcat .
构建镜像

2.2.2.生成Tomcat容器
搭建Tomcat集群:8080/8081/8082,利用之前创建的镜像,创建容器(8080需要删除重新创建),如下:
docker run --name=tomcat8080 --network mynetwork -p 8080:8080 -d uag/uag_tomcat docker run --name=tomcat8081 --network mynetwork -p 8081:8080 -d uag/uag_tomcat docker run --name=tomcat8082 --network mynetwork -p 8082:8080 -d uag/uag_tomcat
查看生成容器后的映射地址如下:
docker inspect tomcat8080

注意:8081和8082也是会报404的,也是要进行文件夹的转移的
#将容器webapps文件夹复制到宿主机 docker cp tomcat8080:/usr/local/tomcat/webapps.dist/. /var/lib/docker/volumes/2ff53e18f6d66e675ab8eeb0eec4620a3d24fb517cfccc2d682d45b02bd6da8f/_data docker cp tomcat8082:/usr/local/tomcat/webapps.dist/. /var/lib/docker/volumes/64340292c4ebba9028e84e2e6c6fcd0faaad1f84c50a35f8ba48053e3a8f8d85/_data docker cp tomcat8082:/usr/local/tomcat/webapps.dist/. /var/lib/docker/volumes/76f55739b21f5c55ec8d87544015bb15d89cdc07d017bfec3122894ad1323dba/_data
由于war包中需要添加数据库所以需要修改连接的数据库的信息。如下:
vi /var/lib/docker/volumes/b07fdc46923bc94b43d5fcfb11ed94a69b14fd559d8f251bbdea361839cc230a/_data/EasyBuy/WEB-INF/classes/database.properties
由于tomcat和MySQL在同一个自定义网络模式下,所以配置文件通过mysql容器的名称连接即可,如下:

这时候已经有了三个Tomcat容器,完成设置后重启即可访问
2.2.3.启动之前主从复制搭建的数据库导入数据
在里面master主机上创建数据库easybuy,创建表,导入数据如下:

2.2.3.创建nginx容器实现负载均衡
在myfile中创建nginx配置文件nginx_tomcat.conf,如下:
user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; client_max_body_size 10m; client_body_buffer_size 128k; proxy_connect_timeout 5s; proxy_send_timeout 5s; proxy_read_timeout 5s; proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; #tomcat管理界面 upstream tomcatManage { server 192.168.42.135:8080; server 192.168.42.135:8081; server 192.168.42.135:8082; } server { listen 8099; server_name 192.168.42.135; location / { proxy_pass http://tomcatManage; } } }
生成nginx容器如下:
docker run -d -p 8099:8099 --name nginx_tomcat -v /myfile/nginx_tomcat.conf:/etc/nginx/nginx.conf --privileged nginx
同时为了体现出各个Tomcat的区别,顺便修改一下各个tomcat的index.jsp文件用于区分tomcat,这里可以进入容器修改,也可以在映射路径进行修改
vi /usr/local/tomcat/webapps/ROOT/index.jsp
修改如下:依次给添加1、2、3

2.2.4.测试访问
通过Nginx访问tomcat,多次刷新每次都会替换一个tomcat,默认nginx就是轮询策略

通过上面配置的nginx中的地址和ip进行访问,如下:http://192.168.42.135:8099/EasyBuy/Home?action=index


浙公网安备 33010602011771号