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_databasecharacter_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信息需要存放到 中show variables like '%master_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
3)修改完配置需要重启slave容器实例 
docker restart mysql-slave

1.3.3.在主数据库中查看主从同步状态

1)进入主数据库

docker exec -it mysql-master /bin/bash

2)进入Mysql 

mysql -uroot -p
3)查看主从同步状态
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;
4)查看主从同步状态:
# \G 可以将横向的结果集表格转换成纵向展示。
# slave status的字段比较多,纵向展示比友好
show slave status \G;
除了展示刚刚配置的主数据库信息外,主要关注 Slave_IO_RunningSlave_SQL_Running。目前两个值应该都为 No,表示还没有开始。

5)开启主从同步

start slave;
再次查看主从同步状态,Slave_IO_RunningSlave_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

posted @ 2023-11-29 11:07  酒剑仙*  阅读(128)  评论(0)    收藏  举报