Docker—8章(常用服务器安装)


第8章 常用服务器安装

本章主要学习最常用的,也是安装起来稍有些麻烦的 MySQL Redis 两种服务器的Docker 安装。至于其它服务器的 Docker 安装,大家可自行查找资料。只要 MySQL Redis这两类服务器学会了安装,其它服务器的安装基本也不会有太大问题了。

1. MySQL 官网安装

docker hub 官网的 MySQL 官方镜像中有关于 MySQL 安装的命令。

这里要以安装 MySQL5.7 为例来演示安装过程。

1.1 拉取镜像

先拉取 MySQL5.7 的镜像到本地。

1.2 启动MySQL容器

分离模式启动 MySQL 容器。

 docker run --name mysql -dp 3306:3306 -e MYSQL_ROOT_PASSWORD=111 mysql:5.7
  • -e MYSQL_ROOT_PASSWORD=111:设置环境变量 MYSQL_ROOT_PASSWORD 的值为 “111”,这将设置 MySQL 的 **root **用户密码为 “111”。

1.3 进入容器

交互方式进入 mysql 容器。

docker exec -it mysql bash

1.4 客户端连接MySQL

mysql 容器内,使用 mysql 客户端连接 mysql 服务。

mysql -uroot -p

1.5 创建数据库与表

通过该客户端创建一个新的数据库 test,并在其中创建一个表 emp(id, name,depart),用于测试该 MySQL 服务。

1.6 Navicat连接MySQL

window 系统中使用 Navicat 连接上这个 mysql 容器提供的 mysql 服务。然后就可以看到新建的 test 数据库与 emp 表了。

1.7 字符编码问题

当前 mysql 容器好像可以正常运行了。但实际还存在两个较严重的问题。其中一个就是字符编码问题

在表中手工插入一条包含中文的记录,提交时会报错。原因就出现字符编码上。

查看当前 mysql 中的字符编码,发现大多数是 latin1,不是 utf8。问题就出在这里。

如果要解决这个问题,就需要在容器系统的/etc/mysql/conf.d 中新建一个my.cnf文件,在其中指定字符编码。

1.8 数据安全问题

除了编码问题,还存在一个严重问题,就是数据安全问题。

前面新建了 test 数据库与 emp 表存放在哪里?在容器系统中的/var/lib/mysql 目录中。

mysql 的运行错误日志对于工作中异常的判断非常重要,其存放在哪里?存放在容器系统的/var/log/mysql 目录中。

如果容器被不小心删除了,那么无论是数据文件、日志文件,还是设置字符编码的 my.cnf文件,都将消失。在生产中,这是绝对不允许的,所以要保证数据的安全性。

2. MySQL 生产安装

为了保证数据的安全性,在生产环境下安装的 mysql 容器,在启动时都会使用数据卷来持久化数据

2.1 启动MySQL容器

docker run --name mysql \
-e MYSQL_ROOT_PASSWORD=111 \
-v /root/mysql/data:/var/lib/mysql \
-v /root/mysql/log:/var/log/mysql \
-v /root/mysql/conf:/etc/mysql/conf.d \
-dp 3306:3306 \
mysql:5.7

这里指定了三个数据卷:

  • -v /root/mysql/log:/var/log/mys
  • -v /root/mysql/log:/var/log/mys
  • -v /root/mysql/log:/var/log/mys

2.2 新建my.cnf

在宿主机的/root/mysql/conf 目录(数据卷目录)中新建my.cnf文件,并在其中键入如下内容:

[client]
default_character_set=utf8
[mysql]
default_character_set=utf8
[mysqld]
character_set_server=utf8

2.3 重启MySQL容器

docker restart mysql

2.4 进入容器连接mysql

2.5 查看字符编码

此时查看当前 mysql 的字符编码,已经全变为了 utf8

2.6 创建数据库和表

2.7 Navicat插入中文记录

此时再在表中插入中文记录就没有问题了。

2.8 查看宿主机数据卷

此时再查看宿主机中数据卷目录,已经有了文件。

3. MySQL 集群安装

单机版的 MySQL 存在单点问题,且在高并发场景下性能会急剧下降。所以,生产中对于 MySQL 都是使用读写分离的主从集群。既保证了数据的安全性,又提升了性能。

下面要使用 Docker 搭建一个“一主一从”的 MySQL 读写分离集群。

3.1 Master的安装与配置

3.1.1 启动 master 容器

docker run --name mysql_master \
-e MYSQL_ROOT_PASSWORD=111 \
-v /root/mysql_master/data:/var/lib/mysql \
-v /root/mysql_master/log:/var/log/mysql \
-v /root/mysql_master/conf:/etc/mysql/conf.d \
-dp 3316:3306 \
mysql:5.7

3.1.2 新建 my.cnf

在宿主机的/root/mysql_master/conf 目录中新建 my.cnf 文件,并在其中键入如下内容:

[client]
default_character_set=utf8
[mysql]
default_character_set=utf8
[mysqld]
character_set_server=utf8
server_id=01
binlog-ignore-db=mysql
log-bin=master-log-bin
binlog_cache_size=1M
binlog_format=mixed
expire_logs_days=7
slave_skip_errors=1062
  • [client][mysql]:这两个部分分别指定了 MySQL 客户端和服务器的默认字符集为 UTF-8 编码。
  • [mysqld]:该部分包含了 MySQL 服务器的其他参数设置。
  • character_set_server=utf8:设置 MySQL 服务器默认字符集为 UTF-8 编码。
  • server_id=01:设置 MySQL 服务器的唯一标识符为 “01”。
  • binlog-ignore-db=mysql:设置 MySQL 服务器忽略所有对 mysql 数据库的更新操作。
  • log-bin=master-log-bin:启用二进制日志功能,并设置二进制日志的名称为 “master-log-bin”。
  • binlog_cache_size=1M:设置二进制日志缓存大小为 1MB。
  • binlog_format=mixed:设置二进制日志的格式为混合模式,这种模式可以同时记录语句和行级别的变更。
  • expire_logs_days=7:设置二进制日志的过期时间为 7 天,过期的日志将会被自动删除。
  • slave_skip_errors=1062:如果 MySQL 从服务器在执行 SQL 语句时发生了唯一键冲突(Error 1062),则自动跳过该错误并继续执行。

3.1.3 重启 master 容器

由于修改了 mysql 配置,所以需要重启 master 容器,以使新配置生效。

3.1.4 进入容器连接 mysql

进入容器并连接上 mysql 后,查看其字符编码,可以看到其是支持中文的。

3.1.5 创建用户

为当前 MySQL 创建一个用户。

  • CREATE USER:创建用户关键字。
  • 'slave'@'%':用户名称和主机名。'slave' 为用户名称,'%' 表示该用户可以在任何主机上连接到 MySQL 服务器。
  • IDENTIFIED BY '123456':设置用户的密码为 ‘123456’。

3.1.6 授权用户

为新创建的用户授权。

  • GRANT:授权关键字。
  • REPLICATION SLAVEREPLICATION CLIENT:授权的权限类型,分别为复制从服务器复制客户端
  • *.*:授权的数据库和表,* 表示任意数据库和表。
  • TO 'slave'@'%':授权给名为 ‘slave’ 的用户,该用户可以在任何主机上连接到 MySQL 服务器。% 表示任意主机

3.2 Slave的安装与配置

3.2.1 启动 Slave 容器

再打开一个会话窗口,在其中启动 Slave 容器。

docker run --name mysql_slave \
-e MYSQL_ROOT_PASSWORD=111 \
-v /root/mysql_slave/data:/var/lib/mysql \
-v /root/mysql_slave/log:/var/log/mysql \
-v /root/mysql_slave/conf:/etc/mysql/conf.d \
-dp 3326:3306 \
mysql:5.7

3.2.2 新建 my.cnf

在宿主机的/root/mysql_slave/conf 目录中新建 my.cnf 文件,并在其中键入如下内容:

[client]
default_character_set=utf8
[mysql]
default_character_set=utf8
[mysqld]
character_set_server=utf8
server_id=02
binlog-ignore-db=mysql
log-bin=slave-log-bin
binlog_cache_size=1M
binlog_format=mixed
expire_logs_days=7
slave_skip_errors=1062
relay_log=relay-log-bin
log_slave_updates=1
read_only=1
  • [client]:客户端配置节,用于设置客户端的默认字符集为 utf8。
  • [mysql]:MySQL 配置节,用于设置 MySQL 的默认字符集为 utf8。
  • [mysqld]:MySQL 服务器配置节,用于设置 MySQL 服务器的各种选项。

[mysqld] 节中,具体的配置选项如下:

  • character_set_server:设置服务器的默认字符集为 utf8。
  • server_id:设置 MySQL 服务器的唯一 ID,用于在主从复制中区分不同的服务器
  • binlog-ignore-db=mysql:设置不将 mysql 数据库的操作写入二进制日志。
  • log-bin=slave-log-bin:启用二进制日志,并设置二进制日志文件的前缀为 slave-log-bin。
  • binlog_cache_size=1M:设置二进制日志缓存的大小为 1MB。
  • binlog_format=mixed:设置二进制日志格式为 mixed,即按需选择使用语句复制或行复制。
  • expire_logs_days=7:设置二进制日志文件自动清理的时间为 7 天。
  • slave_skip_errors=1062:设置当出现错误码为 1062(即唯一键冲突)时跳过该错误。
  • relay_log=relay-log-bin:启用中继日志,并设置中继日志文件的前缀为 relay-log-bin。
  • log_slave_updates=1:设置从服务器将接收到的修改操作写入自己的二进制日志中。
  • read_only=1:设置从服务器为只读模式,禁止在从服务器上进行写操作

3.2.3 重启 slave 容器

由于修改了 mysql 配置,所以需要重启 slave 容器,以使新配置生效。

3.2.4 进入容器连接 mysql

进入容器并连接上 mysql 后,查看其字符编码,可以看到其是支持中文的。

3.3 配置主从复制

3.3.1 查看 master 状态

master 中运行 show master status 命令,查看二进制日志文件名及要开始的位置。

3.3.2 slave 指定 master

slave 中通过运行change master to命令来指定其要连接的 master 相关信息

这是 MySQL 主从复制中用于设置从服务器连接主服务器的命令。具体的解释如下:

  • change master to:用于启动从服务器连接主服务器的命令。
  • master_host='192.168.254.131':设置主服务器的 IP 地址为 192.168.254.131。
  • master_user='slave':设置连接主服务器的用户名为 slave。
  • master_password='123456':设置连接主服务器的密码为 123456。
  • master_port=3316:设置连接主服务器的端口为 3316。

3.3.3 查看 slave 状态

slave 中查看 slave 状态发现,当前 slave master 的同步复制还没有开始。

show slave status \GMySQL 中用于查看从服务器的状态信息的命令,\G 参数表示使用纵向格式显示结果,更方便查看。具体的解释如下:

  • show slave status:用于显示从服务器的状态信息。
  • \G:使用纵向格式显示结果。

这个命令会返回一个包含多个字段的结果集,其中一些比较重要的字段如下:

  • Slave_IO_RunningSlave_SQL_Running:用于表示从服务器 I/O 线程和 SQL 线程的运行状态,一般应该都为 Yes
  • Master_HostMaster_Port:用于表示从服务器连接的主服务器的 IP 地址和端口号。
  • Master_UserMaster_Log_File:用于表示从服务器连接主服务器时使用的用户名和从服务器读取 binlog 文件时的文件名。
  • Exec_Master_Log_PosRead_Master_Log_Pos:用于表示从服务器 SQL 线程当前读取的 binlog 文件中的位置。
  • Seconds_Behind_Master:用于表示从服务器相对于主服务器的延迟时间,一般应该为 0,表示从服务器已经和主服务器保持同步

3.3.4 slave 开启同步

slave 中使用 start slave 命令开启 slave数据同步

start slave

此时再次查看 slave 的状态,发现同步已经开始。

3.4 测试

到这里,一主一从的读写分离集群就搭建完毕了。下面在 master 中创建一个数据库与表,在 slave 中如果可以查看到,则说明搭建成功。

3.4.1 在 master 中写入

3.4.2 在 slave 中读取

slave 中可以查看到在 master 中写入的数据,说明集群搭建成功。

4. Redis 单机版安装

注意:

从下面一部分开始,Redis这一块其实有点问题,待后续我更新内容

4.1 拉取Redis

首先从 docker hub 拉取 Redis 镜像,这里拉取最新版。

4.2 创建数据卷目录

首先要在宿主机/root 目录中创建一个目录 redis,将来用于存放外挂文件 redis.conf

mkdir redis

4.3 启动redis容器

docker run --name myredis \
-v /root/redis/redis.conf:/etc/redis/redis.conf \
-v /root/redis/data:/data \
-dp 6379:6379 \
redis:latest \
redis-server /etc/redis/redis.conf

这里指定了两个数据卷,其中一个是文件,一个是目录:

  • -v /root/redis/redis.conf:/etc/redis/redis.conf
  • -v /root/redis/data:/data

对于该启动命令需要注意的是,其后面运行的命令为 redis-server,且加载的配置文件为挂载点目录/etc/redis 中的 redis.conf

4.4进入容器连接Redis

通过 docker exec 命令进入 Redis 容器后,就可通过 redis-cli 客户端连接上这个 Redis,然后执行 Redis 命令了。

5. Redis 一主两从集群搭建

现要搭建一个“一主两从”的 Redis 集群。这三个容器的端口号都保持默认,但对外暴露出的端口号分别为 6381、6382、6383。其中,6381 的为 master,另外两个为 slave

5.1 启动master

首先启动 master,即启动 myredis-1 容器。

docker run --name myredis-1 \
-v /root/redis/redis1.conf:/etc/redis/redis.conf \
-v /root/redis/data/6381:/data \
-dp 6381:6379 \
redis:latest \
redis-server /etc/redis/redis.conf

5.2 启动两个slave

在启动 slave 的命令中需要指出其 slaveof 于谁。

docker run --name myredis-2 \
-v /root/redis/redis2.conf:/etc/redis/redis.conf \
-v /root/redis/data/6382:/data \
-dp 6382:6379 \
redis:latest \
redis-server /etc/redis/redis.conf --slaveof 192.168.254.131 6381
docker run --name myredis-3 \
-v /root/redis/redis3.conf:/etc/redis/redis.conf \
-v /root/redis/data/6383:/data \
-dp 6383:6379 \
redis:latest \
redis-server /etc/redis/redis.conf --slaveof 192.168.254.131 6381

5.3 关系查看

查看这三个容器节点的 info replication,可以看到它们间的主从关系已经建立

5.4 数据测试

master 节点 myredis-1(主) 中写入数据

slave 节点 myredis-2 myredis-3 节点中可读出数据。

6. Redis 高可用集群搭建

主从集群存在的问题是,其容灾方式只能采用冷处理方案,无法在生产中使用。所以,这里要搭建一个“一主两从三哨兵”的高可用集群,以达到热处理的容灾方案。

对于“一主两从”集群,仍使用前面的即可。下面直接搭建三个 Sentinel 节点的集群。这三个容器的端口号都保持默认,但对外暴露出的端口号分别为 26381、26382、26383

6.1 启动sentinel

启动三个 sentinel 容器

docker run --name mysentinel-1 \
-v /root/redis/sentinel1.conf:/etc/redis/sentinel.conf \
-dp 26381:26379 \
redis:latest \
redis-sentinel /etc/redis/sentinel.conf
docker run --name mysentinel-2 \
-v /root/redis/sentinel2.conf:/etc/redis/sentinel.conf \
-dp 26382:26379 \
redis:latest \
redis-sentinel /etc/redis/sentinel.conf
docker run --name mysentinel-3 \
-v /root/redis/sentinel3.conf:/etc/redis/sentinel.conf \
-dp 26383:26379 \
redis:latest \
redis-sentinel /etc/redis/sentinel.conf

6.2 关系查看

  • sentinel_masters: 当前监控的Redis主节点数量
  • sentinel_tilt: Sentinel模式下,被认为是瘫痪的节点的数量
  • sentinel_running_scripts: 当前正在运行的脚本数量
  • sentinel_scripts_queue_length: 等待运行的脚本数量
  • sentinel_simulate_failure_flags: 模拟失败的标志数量

以上命令的查看结果说明 sentinel master 的监视成功,说明高可用集群搭建成功。连接任何一个 sentinel 容器节点查看到的信息与上面的都是相同的。

6.3 故障转移测试

为了验证高可用性,现将充当 master 的容器 myredis-1 停掉。

此时,再查看另外两个 redis 容器的状态数据,发现 myredis-2 成为了 myredis-3slave,即 myredis-3 成为了新的 master

此时再次 myredis-1 容器启动

再查看 myredis-1 的状态数据,发现其成为了 myredis-3 slave

7. Redis 分布式系统搭建

Redis 集群的每个节点中的保存的数据都是相同的。而 Redis 分布式系统的节点中存放的数据可以是不同的。当有数据写入请求到达分布式系统后,系统会采用虚拟槽分区算法将数据写入到相应节点。

下面要搭建一个三主三从的 Redis 分布式系统。

序号 角色 容器名称 网络模式 暴露地址
1 master myredis-1 host 192.168.254.131:6381
2 master myredis-2 host 192.168.254.131:6382
3 master myredis-3 host 192.168.254.131:6383
4 slave myredis-4 host 192.168.254.131:6384
5 slave myredis-5 host 192.168.254.131:6385
6 slave myredis-6 host 192.168.254.131:6386

7.1 准备目录与配置文件

/rootmkdir 一个名称为 cluster 的目录,并将前面的配置文件/root/redis/redis.conf复制到这里。

7.2 复制六份redis.conf

复制 redis.conf redis1.conf,并在其中将下面两个配置前的注释去掉。这两项配置,一个是用于开启 cluster 功能,即分布式系统功能;一个是指定其需要的配置文件名称。

然后再以 redis1.conf 为模板复制出 5 份,分别为 redis2.conf、redis3.conf、redis4.conf、redis5.conf、redis6.conf。这 6 份配置文件内容完全相同。

7.3 启动Redis

启动 6 个 Redis 容器

docker run --name myredis-1 \
--network host \
-v /root/cluster/redis1.conf:/etc/redis/redis.conf \
-v /root/cluster/data/6381:/data \
-d redis:latest \
redis-server /etc/redis/redis.conf --port 6381
docker run --name myredis-2 \
--network host \
-v /root/cluster/redis2.conf:/etc/redis/redis.conf \
-v /root/cluster/data/6382:/data \
-d redis:latest \
redis-server /etc/redis/redis.conf --port 6382
docker run --name myredis-3 \
--network host \
-v /root/cluster/redis3.conf:/etc/redis/redis.conf \
-v /root/cluster/data/6383:/data \
-d redis:latest \
redis-server /etc/redis/redis.conf --port 6383
docker run --name myredis-4 \
--network host \
-v /root/cluster/redis4.conf:/etc/redis/redis.conf \
-v /root/cluster/data/6384:/data \
-d redis:latest \
redis-server /etc/redis/redis.conf --port 6384
docker run --name myredis-5 \
--network host \
-v /root/cluster/redis5.conf:/etc/redis/redis.conf \
-v /root/cluster/data/6385:/data \
-d redis:latest \
redis-server /etc/redis/redis.conf --port 6385
docker run --name myredis-6 \
--network host \
-v /root/cluster/redis6.conf:/etc/redis/redis.conf \
-v /root/cluster/data/6386:/data \
-d redis:latest \
redis-server /etc/redis/redis.conf --port 6386

7.4 创建系统

6 个节点启动后,它们仍是 6 个独立的 Redis,通过 redis-cli --cluster create 命令可将 6个节点创建为一个分布式系统--cluster replicas 1 指定每个 master 会带有一个 slave 副本。

回车后即可看到如下的计划日志:

键入 yes 后再回车,即可按照上面的计划完成系统创建。

7.5 查看节点信息

通过 cluster nodes 命令可以查看到系统中各节点的关系及连接情况。只要能看到每个节点给出 connected,就说明分布式系统已经成功搭建

7.6 系统操作

对于如何对分布式系统进行操作,例如,slot 相关查询、故障转移、动态扩容、动态缩容等,与使用虚拟机搭建的分布式系统的操作命令相同,唯一不同的就是,需要首先通过docker exec –it 命令进入到容器内部再执行这些命令。


文章作者: 念心卓
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 念心卓 !
  目录