简单的docker学习 第8章 docker常用服务安装

第8章 常用服务安装

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

8.1 MySQL 官网安装

在 docker hub 官网的 MySQL 官方镜像中有关于 MySQL 安装的命令。这里要以安装 MySQL5.7 为例来演示安装过程

image-20240711160901461

8.1.1 拉取镜像

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

docker pull mysql:5.7

image-20240711161327175

8.1.2 启动 MySQL 容器

以分离模式启动 MySQL 容器

docker run --name mysql -dp 3306:3306 -e MYSQL_ROOT_PASSWORD=101022 mysql:5.7
8.1.3 进入容器

以交互方式进入 mysql 容器。

docker exec -it mysql /bin/bash

image-20240711161641172

8.1.4 客户端连接 mysql
mysql -u root -p

image-20240711161717319

8.1.5 创建数据库与表

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

image-20240711161847763

新建表数据,插入信息

create database test;
use test;
create table emp(id int, name varchar(20), depart varchar(20));
insert into emp values(1, 'zs', 'admin');

image-20240711162732211

8.1.6 客户端 连接 mysql

image-20240711163823242

image-20240711163807149

8.1.7 字符编码问题

当前 mysql 容器好像可以正常运行了。但实际还存在两个较严重的问题。其中一个就是字符编码问题。在表中手工插入一条包含中文的记录,提交时会报错。原因就出现字符编码上

image-20240711163930699

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

show variables like 'character%'

image-20240711164113774

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

8.1.8 数据安全问题

除了编码问题,还存在一个严重问题,就是数据安全问题。前面新建了 test 数据库与 emp 表存放在哪里?在容器系统中的/var/lib/mysql 目录中。

image-20240711164340896

mysql 的运行错误日志对于工作中异常的判断非常重要,其存放在哪里?存放在容器系统的/var/log/mysql 目录中。如果容器被不小心删除了,那么无论是数据文件、日志文件,还是设置字符编码的 my.cnf文件,都将消失。在生产中,这是绝对不允许的,所以要保证数据的安全性。

image-20240711164506226

8.2MySQL 生产安装

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

8.2.1 启动 MySQL 容器

使用命令行启动,具体命令如下

docker run --name mysql \
-e MYSQL_ROOT_PASSWORD=101022 \
-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

image-20240711165324127

这里指定了三个数据卷:

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

  • -v /root/mysql/data:/var/lib/mysql

  • -v /root/mysql/conf:/etc/mysql/conf.d

8.2.2 新建 my.cnf

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

[client]
default_character_set=utf8
[mysql]
default_character_set=utf8
[mysqld]
character_set_server=utf8
8.2.3 重启 mysql 容器

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

docker restart mysql

image-20240711165027401

8.2.4 进入容器连接 mysql

image-20240711165712161

8.2.5 查看字符编码

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

show variables like 'character%';

image-20240711170506865

8.2.6 创建数据库与表
create database test;
use test;
create table emp(id int, name varchar(20), depart varchar(20));
insert into emp values(1, 'zs', 'admin');
8.2.7 客户端插入中文记录

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

image-20240711170827243

image-20240711170804110

8.2.8 查看宿主机数据卷

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

image-20240711170949757

8.3 MySQL 集群安装

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

8.3.1 Master 的安装与配置
  • 启动 master 容器

    docker run --name mysql_master \
    -e MYSQL_ROOT_PASSWORD=101022 \
    -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
    
  • 新建 my.cnf

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

    [client]
    # 客户端连接到MySQL时使用的默认字符集。这确保了客户端和服务器之间的字符编码一致性
    default_character_set=utf8
    [mysql]
    # 这是MySQL命令行工具连接到服务器时使用的字符集
    default_character_set=utf8
    [mysqld]
    # 服务器处理数据时使用的字符集。这影响存储在数据库中的所有字符串数据
    character_set_server=utf8
    # 为从服务器分配一个唯一的ID,这个ID必须在所有参与复制的服务器中是唯一的。它用于标识二进制日志事件的来源
    server_id=01
    # 指定不记录哪些数据库的更改到二进制日志。在这个例子中,mysql系统数据库的更改不会被记录。通常,系统数据库不需要复制
    binlog-ignore-db=mysql
    # 指定二进制日志的文件名前缀。尽管在从服务器上通常不需要记录二进制日志,但有时可能需要,例如在循环复制或故障恢复场景中
    log-bin=master-log-bin
    # 每个线程用于缓存二进制日志事件的内存大小。如果从服务器也用作主服务器的一部分,则此设置很重要
    binlog_cache_size=1M
    # 二进制日志的格式。mixed格式结合了statement和row格式的优点,根据事件类型选择最合适的格式
    binlog_format=mixed
    # 设置二进制日志文件自动过期并被删除的天数。这对于磁盘空间管理很有用。
    expire_logs_days=7
    # 当从服务器遇到指定的错误号时,它会跳过当前事件并继续复制。1062是“Duplicate entry”错误,这可能是因为并发插入导致的
    slave_skip_errors=1062
    
  • 重启 master 容器

    # 由于修改了 mysql 配置,所以需要重启 master 容器,以使新配置生效
    docker restart mysql_master
    
  • 进入容器连接 mysql

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

    docker exec -it mysql_master /bin/bash
    show variables like 'character%' 
    

    image-20240712083328115

  • 创建用户并授权

    # 为当前 MySQL 创建一个用户。
    create user 'slave'@'%' identified by '101022';
    # 为用户授权
    grant replication slave, replication client on *.* to 'slave'@'%';
    

    image-20240712083740923

8.3.2 Slave 的安装与配置
  • 启动 Slave 容器

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

    docker run --name mysql_slave \
    -e MYSQL_ROOT_PASSWORD=101022 \
    -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
    

    image-20240712083942016

  • 新建 my.cnf

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

    [client]
    # 客户端连接到MySQL时使用的默认字符集。这确保了客户端和服务器之间的字符编码一致性
    default_character_set=utf8
    [mysql]
    # 这是MySQL命令行工具连接到服务器时使用的字符集
    default_character_set=utf8
    [mysqld]
    # 服务器处理数据时使用的字符集。这影响存储在数据库中的所有字符串数据
    character_set_server=utf8
    # 为从服务器分配一个唯一的ID,这个ID必须在所有参与复制的服务器中是唯一的。它用于标识二进制日志事件的来源
    server_id=02
    # 指定不记录哪些数据库的更改到二进制日志。在这个例子中,mysql系统数据库的更改不会被记录。通常,系统数据库不需要复制
    binlog-ignore-db=mysql
    # 指定二进制日志的文件名前缀。尽管在从服务器上通常不需要记录二进制日志,但有时可能需要,例如在循环复制或故障恢复场景中
    log-bin=slave-log-bin
    # 每个线程用于缓存二进制日志事件的内存大小。如果从服务器也用作主服务器的一部分,则此设置很重要
    binlog_cache_size=1M
    # 二进制日志的格式。mixed格式结合了statement和row格式的优点,根据事件类型选择最合适的格式
    binlog_format=mixed
    # 设置二进制日志文件自动过期并被删除的天数。这对于磁盘空间管理很有用
    expire_logs_days=7
    # 当从服务器遇到指定的错误号时,它会跳过当前事件并继续复制。1062是“Duplicate entry”错误,这可能是因为并发插入导致的
    slave_skip_errors=1062
    # 指定中继日志文件的名称前缀。中继日志用于存储从主服务器接收到的二进制日志事件
    relay_log=relay-log-bin
    # 如果从服务器本身也是其他从服务器的主服务器,此选项将使从服务器将其更新记录在其自己的二进制日志中
    log_slave_updates=1
    # 设置从服务器上的所有数据库只读,防止直接写入数据。这是推荐的做法,以避免在从服务器上进行意外的数据修改
    # 请注意,server_id应该是唯一的,并且read_only设置可能需要根据具体的应用需求进行调整。此外,binlog_ignore_db和log_bin设置通常在从服务器上不是必需的,除非有特定的需求
    read_only=1
    
  • 重启 slave 容器

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

    docker restart mysql_slave
    
  • 进入容器连接 mysql

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

    docker exec -it mysql_slave /bin/bash
    show variables like 'character%';
    

    image-20240712084958955

8.3.3 配置主从复制
  • 查看 master 状态

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

    show master status;
    

    image-20240712085105540

  • slave 指定 master

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

    # ip为宿主机ip
    change master to 
    master_host='192.168.138.129',master_user='slave',master_password='101022',master_port=3316,master_log_file='master-log-bin.000001',master_log_pos=617,master_connect_retry=30,master_retry_count=3;
    

    image-20240712085942264

  • 查看 slave 状态

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

    show slave status \G;
    

    image-20240712090131570

  • slave 开启同步

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

    start slave;
    

    image-20240712090242237

8.3.4 测试

到这里,一主一从的读写分离集群就搭建完毕了。

下面在 master 中创建一个数据库与表,在 slave 中如果可以查看到,则说明搭建成功。

create database test;
use test;
create table emp(id int, name varchar(20), depart varchar(20));
insert into emp values(1, 'ww', 'admin');
insert into emp values(2, 'zl', 'market');

在slave控制台进行读取数据

image-20240712090617341

8.3.5 发现问题

发现从节节点可以插入数据

image-20240712091756786

这是因为使用的root用户,root用户拥有全部权限,可以进行插入操作,可以修改超级权限用户在从服务也只能进行读操作

set global super_read_only=1;

image-20240712092223736

8.4 Redis 单机版安装

首先从 docker hub 拉取 Redis 镜像

docker pull redis
8.4.2 创建数据卷目录

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

mkdir redis
8.4.3 复制 redis.conf 文件

上传一份 redis 核心配置文件 redis.conf 到宿主机目录/root/redis 中(redis.conf的标准文件在redis官网也可以找到)

# bind 192.168.1.100 10.0.0.1
# bind 127.0.0.1 ::1
bind 192.168.138.129 -::1
protected-mode no
port 6379
tcp-backlog 511
requirepass 101022
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile ""
databases 30
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /data
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-disable-tcp-nodelay no
replica-priority 100
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
appendonly yes
appendfilename "appendonly.aof"
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
slowlog-max-len 128
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
8.4.4 修改 redis.conf
  • 解除 IP 绑定

    将 bind 行注释掉,以解除 Redis 对访问者 IP 的绑定,配置自己机器ip地址

    image-20240712170741323

  • 关闭保护模式

    关闭保护模式,否则只能本机访问自己

    image-20240712112320632

  • 关闭守护模式

    关闭守护模式对于 Redis 容器安装来说非常重要。由于 docker 本身就是以分离模式运行的,如果 Redis 再以该模式运行,则 Redis 无法启动。

    image-20240712112418064

  • 指定持久化目录

    这里要指定 RDB 或 AOF 的持久化目录为/data,这样无论是哪种持久化文件,均会保存到该目录。后面会指定容器中的/data 目录为数据卷挂载点目录

    image-20240712112501539

8.4.5 启动 Redis 容器
docker run --name myredis \
--network host \
-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。

8.4.6 进入容器连接 Redis

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

docker exec -it myredis /bin/bash

image-20240712122508193

8.5 Redis 一主两从集群搭建

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

8.5.1 复制三份 redis.conf

现仍在前面的/root/redis 目录中完成配置。复制 redis.conf 并重命名为 redis1.conf,并在文件最后添加如下配置,以对外宣布当前 redis 的 IP 与端口。注意,该 IP 为 docker 宿主机的 IP,端口号为当前 redis 对外暴露的端口号

slave-announce-ip 192.168.138.129
# 其余redis2.conf 以及 redis3.conf 分别配置 6382 6383
slave-announce-port 6381

image-20240712134753930

8.5.2 启动 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: \
redis-server /etc/redis/redis.conf

image-20240712135029150

8.5.3 启动 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.138.129 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.138.129 6381

image-20240712135355469

8.5.4 关系查看

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

docker exec -it myredis-2 redis-cli --pass 101022 info replication

8.6Redis 高可用集群搭建

生产环境使用集群模式,不使用哨兵模式,暂时不进行研究

8.7 Redis 分布式系统搭建

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

序号角色容器名称网络模式地址
1mastermyredis-1host192.168.138.129:6381
2mastermyredis-2host192.168.138.129:6382
3mastermyredis-3host192.168.138.129:6383
4slavemyredis-4host192.168.138.129:6384
5slavemyredis-5host192.168.138.129:6385
6slavemyredis-6host192.168.138.129:6386
8.7.1 准备目录与配置文件

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

8.7.2 复制六份 redis.conf

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

cluster-enabled true
cluster-config-file nodes-6379.conf

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

8.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
8.7.4 创建系统

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

docker exec -it myredis-1 redis-cli --cluster create --cluster-replicas 1 192.168.138.129:6381 192.168.138.129:6382 192.168.138.129:6383 192.168.138.129:6384 192.168.138.129:6385 192.168.138.129:6386

image-20240712165506312

8.7.5 查看节点信息

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

docker exec -it myredis-1 redis-cli -h 192.168.138.129 -p 6384 cluster nodes

image-20240712170459639

8.7.6 使用客户端验证

image-20240712170919023

image-20240712170843594

8.7.7 系统操作

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

  • 18
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值