3、docker软件的安装

docker软件的安装

一、容器数据卷

1.1 作用

将docker容器内的数据保存进宿主机的磁盘中,类似于redis中的rdb和aof文件

1.2 docker中的数据卷

原因:docker容器在使用过程中会产生数据,但是当容器实例删除后,容器内的数据自然也就没有了,为了保存这些数据,在docker中使用卷,具有以下特点:

  • 数据卷在容器之间共享或重用数据。
  • 卷中的数据如果更改会直接实时生效。
  • 数据卷中的更改不会包含在镜像的更新中。
  • 数据卷的声明周期一直持续到没有容器使用它为止。

案例

1.2.1:在宿主机和容器之间添加容器卷
# 添加命令
# docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录      镜像名
docker run -it --privileged=true -v /zpyl/myjuan:/tem/test myubuntu:1.1
# 查看数据卷是否挂载成功
# docker inspect 容器ID
docker inspect 17e5f69e2156 
# 查看容器和宿主机之间的数据共享
# 1、docker修改,主机同步
# 2、主机修改,docker同步
# 3、docker容器stop,主机修改,docker容器重启数据同步
1.2.2:读写规则映射添加说明
# 默认情况下是rw,允许读和写
docker run -it --privileged=true -v /zpyl/myjuan:/tem/test:rw myubuntu:1.1
#容器实例内部被限制ro,只能读不能写
docker run -it --privileged=true -v /zpyl/myjuan:/tem/test:ro myubuntu:1.1
1.2.3:卷的继承和共享
# 容器1完成和宿主机的映射                 宿主机       容器      别名   镜像名
docker run -it  --privileged=true -v /mydocker/u:/tmp --name u1 ubuntu
# 容器2继承容器1的卷规则                            父类容器id
docker run -it  --privileged=true --volumes-from 父类  --name u2 ubuntu
docker run -it --privileged=true --volumes-from 9d3e48e9130d  --name u2 ubuntu

二、常规安装软件

总体安装步骤:

1、搜索镜像 2、拉起镜像 3、查看镜像 4、启动镜像 - 服务器端口映射 5、停止容器 6、移除容器

2.1 安装Tomcat

# 搜索镜像:
# 在https://hub.docker.com/中搜到镜像
# 拉起镜像:
docker pull tomcat
# 查看镜像:
docker images
# 启动镜像
docker run -d -p 8080:8080 --name t1 tomcat
# 访问
127.0.0.1:8080

注意:访问的时候可能会出现404错误,这是由于新版的tomcat将原先的页面删除,需要做一下简单的配置

# 进入tomcat容器
docker exec -it cf213de62594 /bin/bash
# 进入tomcat文件夹
cd /usr/local/tomcat
# 删除webapps
rm -rf webapps
# 重命名webapps.dist
mv webapps.dist webapps
# 访问
127.0.0.1:8080

建议安装免修改版

docker pull billygoo/tomcat8-jdk8

2.2 安装mysql

2.2.1 安装单机版
# 下载
docker pull mysql:5.7
# 开启镜像
docker run -d -p 3306:3306 --privileged=true -v /zpyl/mysql/log:/var/log/mysql -v /zpyl/mysql/data:/var/lib/mysql -v /zpyl/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 --name mysql mysql:5.7
# 在宿主机的conf.d中新建my.cnf文件,添加以下内容,通过容器数据卷同步给mysql容器
[client]
default_character_set=utf8
[mysqld]
collation_server = utf8_general_ci
character_set_server = utf8
# 重启mysql容器
docker restart mysql

解析:

docker run -d -p 3306:3306 --privileged=true -v /zpyl/mysql/log:/var/log/mysql -v /zpyl/mysql/data:/var/lib/mysql -v /zpyl/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 --name mysql mysql:5.7

做好数据库的备份,将mysql的日志、数据和配置在宿主机和容器之间添加数据卷

2.2.1 安装主从复制版
# 安装主机
docker run -d -p 3307:3306 --privileged=true -v /zpyl/mysql-master/log:/var/log/mysql -v /zpyl/mysql-master/data:/var/lib/mysql -v /zpyl/mysql-master/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 --name mysql-master mysql:5.7
# 在zpyl/mysql-master/conf 下新建my.cnf文件,添加以下信息
    [mysqld]
    ## 设置server_id,同一局域网中需要唯一
    server_id=101
    ## 指定不需要同步的数据库名称
    binlog-ignore-db=mysql
    ## 开启二进制日志功能
    log-bin=dblog-bin
    ## 设置二进制日志使用内存大小(事务)
    binlog_cache_size=1M
    ## 设置使用的二进制日志格式(mixed,statement,row)
    binlog_format=mixed
    ## 二进制日志过期清理时间。默认值为0,表示不自动清理。
    expire_logs_days=7
    ## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。
    ## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
    slave_skip_errors=1062
    ## 字符集
    collation_server = utf8_general_ci
	character_set_server = utf8
	[client]
	default_character_set=utf8
# 重启容器
docker restart mysql-master
# 查看服务是否正常启动
docker ps
# 如果出现服务未启动,查看日志
docker logs -f --tail 10 mysql-master
# 进入主机中创建数据同步的用户
CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
# 为用户授予权限
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
# 安装从机
docker run -d -p 3308:3306 --privileged=true -v /zpyl/mysql-slave/log:/var/log/mysql -v /zpyl/mysql-slave/data:/var/lib/mysql -v /zpyl/mysql-slave/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 --name mysql-slave mysql:5.7
# 在zpyl/mysql-slave/conf 下新建my.cnf文件,添加以下信息
    [mysqld]
    ## 设置server_id,同一局域网中需要唯一
    server_id=102
    ## 指定不需要同步的数据库名称
    binlog-ignore-db=mysql
    ## 开启二进制日志功能,以备Slave作为其它数据库实例的Master时使用
    log-bin=dblog-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
     ## 字符集
    collation_server = utf8_general_ci
	character_set_server = utf8
	[client]
	default_character_set=utf8
# 重启服务
docker start mysql-slave
# 在主数据库中查看主从同步状态,记录下file和position
show master status;
# 在从数据库中配置主从复制
change master to master_host='192.168.1.18', master_user='slave', master_password='123456', master_port=3307, master_log_file='dblog-bin.000001', master_log_pos=154, master_connect_retry=30;
	##参数说明
	# master_host:主数据库的IP地址; #master_port:主数据库的运行端口;
	# master_user:在主数据库创建的用于同步数据的用户账号;
	# master_password:在主数据库创建的用于同步数据的用户密码;
    # master_log_file:指定从数据库要复制数据的日志文件,通过查看主数据的状态,获取File参数;
    # master_log_pos:指定从数据库从哪个位置开始复制数据,通过查看主数据的状态,获取Position参数;
	# master_connect_retry:连接失败重试的时间间隔,单位为秒。
# 在从数据库中查看主从同步状态    Slave_IO_Running和Slave_SQL_Running 此时都为No,表示没有开启
show slave status \G;
# 从从数据库中开启主从同步
start slave;
# 再次查看主从同步状态 可以看到Slave_IO_Running和Slave_SQL_Running 此时都为Yes,则表示同步成功
# 在主库中测试增删改查,在从库中看结果

2.3 安装redis

2.3.1 redis单机版
# 下载
docker pull redis:6.0.8
# 在宿主机上新建redis文件夹,作为容器数据卷,将官网下载的redis.conf文件放入其中 https://github.com/redis/redis/blob/6.0.8/redis.conf
mkdir /zpyl/redis
# 修改redis.conf文件的以下配置
# 1、开启redis验证  
requirepass 123
# 2、允许redis外地连接 注释掉 # bind 127.0.0.1
# 3、daemonize no 将daemonize yes注释起来或者 daemonize no设置,因为该配置和docker run中-d参数冲突,会导致容器一直启动失败
# 4、开启redis数据持久化  appendonly yes
# 运行redis容器
docker run -p 6379:6379 --name redis --privileged=true -v /zpyl/redis/redis.conf:/etc/redis/redis.conf -v /zpyl/redis/data:/data -d redis:6.0.8 redis-server /etc/redis/redis.conf
# 测试redis
docker exec -it redis redis-cli
2.3.2 redis集群版

题:1~2亿条数据需要缓存,请问如何设计这个存储案例?

答案:使用redis进行分布式存储,一般有三种解决方案

  • 哈希取余分区
  • 一致性哈希算法分区
  • 哈希槽分区
2.3.2.1 哈希取余分区


借助公式hash(key) % N机器总数,计算出哈希值,用来决定数据映射到哪一个节点上。

优点:简单粗暴,直接有效

缺点:进行扩容或缩容比较麻烦,每次redis的总数发生变化时,整个数据的映射关系就需要重新计算,如果某一台机器出现问题,或导致hash取余全部重新洗牌。

2.3.2.2 一致性哈希算法分区

缘由:为了解决分布式缓存数据变动和映射的问题,不在依据机器总数进行取余,根据自然数进行取余,当服务器个数发生变化时,尽量减少客户端到服务器的映射关系。

概念:一致性hash算法是 2 32 2^{32} 232对进行取模,将产生的0~ 2 31 2^{31} 231-1的值,这些值构成一个hash空间,将它们按照顺序首尾相连,构成以环形空间,简称hash环。

在这里插入图片描述

然后将服务器映射到hash环上,通过对服务器的唯一标识进行hash取值,这样每台机器在环上就有一个位置了。

在这里插入图片描述

最后将要保存的数据进行哈希取值,找到环上的位置,从此位置顺时针走,找到最近的一台服务器,那么这就是目标服务器。

在这里插入图片描述

优点:具有容错性,假如服务器宕机时,只影响它本身存储的内容,不需要重新构建映射关系

​ 具有扩展性,在A,B节点之间添加X服务器时,只影响后面的A到X之间的数据,只需要将A到X之间的数据复制到X上即可,不需要重新hash。

缺点:当服务器上的节点太少的时候,容易造成节点分布不均匀而造成的数据倾斜问题。

2.3.2.3 哈希槽分区

缘由:解决一致性哈希算法的数据倾斜问题

思路:在数据和节点之间又加了一层,这层称为哈希槽,用于管理数据和节点之间的关系,相当于节点上放的是槽,而槽里放的是数据。

hash槽:一个redis集群中只能有16384个槽,编号为0~ 2 14 − 1 2^{14}-1 2141,redis会根据节点的数量大致均等的将hash槽映射到不同的节点,当需要放置一个key-value时, redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,也就是映射到某个节点上。

在这里插入图片描述

2.3.2.4 搭建redis集群
# 启动6个redis容器
docker run -d --name redis-node-1 --net host --privileged=true -v /zpyl/redis/share/redis-node-1:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6381
docker run -d --name redis-node-2 --net host --privileged=true -v /zpyl/redis/share/redis-node-2:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6382
docker run -d --name redis-node-3 --net host --privileged=true -v /zpyl/redis/share/redis-node-3:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6383
docker run -d --name redis-node-4 --net host --privileged=true -v /zpyl/redis/share/redis-node-4:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6384
docker run -d --name redis-node-5 --net host --privileged=true -v /zpyl/redis/share/redis-node-5:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6385
docker run -d --name redis-node-6 --net host --privileged=true -v /zpyl/redis/share/redis-node-6:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6386
	## 解析
	# --net host:使用宿主机的ip和端口
	# --privileged=true 获取宿主机的root用户权限
	# --cluster-enabled yes 开启redis集群
	# --appendonly yes 开启持久化
	# --port 6386 redis端口号 
# 进入其中一台机器构建集群关系
docker exec -it redis-node-1 /bin/bash
# 构建主从关系
redis-cli --cluster create 192.168.1.18:6381 192.168.1.18:6382 192.168.1.18:6383 192.168.1.18:6384 192.168.1.18:6385 192.168.1.18:6386 --cluster-replicas 1
	## 解析
	# --cluster-replicas 1 表示为每一个master创建一个slave节点
# 如果输出:All nodes agree about slots configuration和All 16384 slots covered则表示3主3从构建完成
# 连接其中一台redis
redis-cli -p 6381
# 查看集群状态
cluster info
# 查看节点信息
cluster nodes
2.3.2.4.1 数据读写存储

当使用redis-cli -p 6381 直接对redis新增key-value时,可能会出现报错

在这里插入图片描述

使用-c来优化路由 redis-cli -p 6381 -c

然后在执行操作

在这里插入图片描述

查看集群信息:redis-cli --cluster check 192.168.1.18:6386

2.3.2.4.2 容错切换迁移

仔细查看节点的主从状态使用cluster nodes查看

在这里插入图片描述

主机6381,从机6386

将主机6381停止,在次查看

在这里插入图片描述

发现此前的6386变成主机继续工作了

在此启动6381,在此查看

在这里插入图片描述

此时6381则变成了从机

检查集群的状态

redis-cli --cluster check 192.168.1.18:6381

2.3.2.4.3 主从扩容
# 新建俩个节点6387和6388
docker run -d --name redis-node-7 --net host --privileged=true -v /zpyl/redis/share/redis-node-7:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6387
docker run -d --name redis-node-8 --net host --privileged=true -v /zpyl/redis/share/redis-node-8:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6388
# 进入6387节点作为master节点加入集群 
# 							新加入的主节点6387    原集群节点6381
redis-cli -cluster add-node 192.168.1.18:6387 192.168.1.18:6381
# 查看集群节点状态
redis-cli --cluster check 192.168.1.18:6381
# 发现哈希槽号为空,这是因为没有分配槽号
# 重新分配槽号                  集群中的节点
redis-cli --cluster reshard 192.168.1.18:6381
# 重新分配时会询问你移动多少个节点到新的节点上,这里根据实际情况进行填写
How many slots do you want to move (from 1 to 16384)? 4096
# 询问你将这些节点分配到哪个节点,输入你新添加等的节点的id即可
What is the receiving node ID? de08089905620c891a9c790a2fe7e2ed9df6c747
# 会询问你从哪些节点进行转移,输入all表示从所有节点中随机抽取
Please enter all the source node IDs. all
# 重新查看集群节点状态
redis-cli --cluster check 192.168.1.18:6381
# 发现新添加的节点的哈希槽号并不是连续的,而之前分配的节点是连续的,这是因为重新分配的成本太高,所以是从前面节点中各自匀一点出来的
# 为6387分配从节点6388
# redis-cli --cluster add-node ip:新slave端口 ip:新master端口 --cluster-slave --cluster-master-id 新主机节点ID
redis-cli --cluster add-node 192.168.1.18:6388 192.168.1.18:6387 --cluster-slave --cluster-master-id de08089905620c891a9c790a2fe7e2ed9df6c747
# 重新查看集群节点状态
redis-cli --cluster check 192.168.1.18:6381
2.3.2.4.5 主机缩容
# 将6388删除(从机)
# redis-cli --cluster del-node ip:端口 节点ID
redis-cli --cluster del-node 192.168.1.18:6388 8c0eaf342c8befa8c51f2ecb3137281e17ff2ad9
# 将6387删除(主机)
# 将主机的的哈希槽清空,将清出来的槽位都给6386
redis-cli --cluster reshard 192.168.111.147:6386
# 重新分配时会询问你移动多少个节点到新的节点上,这里根据实际情况进行填写
How many slots do you want to move (from 1 to 16384)? 4096
# 询问你将这些节点分配到哪个节点,输入待分配的节点的id即可这里使用6386的
What is the receiving node ID? 0d1f2fbfa05044fcaaf415001220e9e752d70bea
# 输入提供的节点的id,这里选择6387的
Source node #1: de08089905620c891a9c790a2fe7e2ed9df6c747
# 然后输入done
Source node #2:done
# 将6387删除
redis-cli --cluster del-node 192.168.1.18:6387 de08089905620c891a9c790a2fe7e2ed9df6c747
# 重新查看集群节点状态
redis-cli --cluster check 192.168.1.18:6381
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

启航zpyl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值