文章目录
- 1. 卸载docker服务 步骤(实用!!)
- 2. docker 私有库
- 3. 容器数据卷的使用
- 4. 容器卷和主机互通互联
- 5. 容器卷ro 和 rw读写规则
- 6. 卷的继承和共享
- 7. docker 安装 tomcat
- 8. docker 安装mysql
- 8.1 运行mysql容器
- 8.2 docker mysql容器卷配置(非常重要)
- 8.3 docker mysql的中文问题
- 9. docker 安装redis
- 10. docker 之 mysql主从复制
- 11. 分布式存储 之 哈希取余算法 (基于redis集群缓存场景)
- 12. 分布式存储 之 一致性哈希算法 (基于redis集群缓存场景)
- 13. 分布式存储 之 哈希槽分区 (基于redis集群缓存场景)
1. 卸载docker服务 步骤(实用!!)
docker卸载准备工作:
# 1.杀死dockers有关容器
docker kill $(docker ps -a -q)
# 2.删除所有docker容器:
docker rm $(docker ps -a -q)
# 3.删除所有docker镜像:
docker rmi $(docker images -q)
# 4.停止 docker 服务:
systemctl stop docker
# 5.删除docker相关存储目录:(分别进行执行以下四个命令)
rm -rf /etc/docker
rm -rf /run/docker
rm -rf /var/lib/dockershim
rm -rf /var/lib/docker
# (注意)6.如果删除不掉,则先umount,然后再重新执行上面那步“删除docker相关存储目录”。
umount /var/lib/docker/devicemapper
docker卸载步骤:
# 1.查看系统已经安装了那些docker包
yum list installed | grep docker
# 2.remove卸载掉这些相关的docker包
yum remove containerd.io.x86_64 docker-ce.x86_64 docker-ce-cli.x86_64 docker-ce-rootless-extras.x86_64 docker-scan-plugin.x86_64 [...依据上面的docker服务]
# 3.再次查看,是否有遗漏
yum list installed | grep docker
# 4.再看看docker命令,是否还存在。
docker version
-bash: /usr/bin/docker: No such file or directory
# 5.至此成功卸载docker。
2. docker 私有库
阿里云的Docker Registry是阿里云提供的公共镜像仓库,如果涉及机密的公司不可能提供镜像给公网,所以就要创建一个本地的私人仓库。
提示:阿里云的docker registry与docker hub差不多的,只不过docker hub访问很慢而已!
Docker Registry是官方提供的工具,可以用于构建私有镜像仓库。
构建私有镜像仓库也很简单,直接通过pull命令拉去一个就可以:
# 拉去registry镜像,用于构建私有仓库。
docker pull registry
# 相当于本地有个私有Docker hub。
运行私有库命令:
# 运行私有库,-v是卷的意思,-p代表指定端口
docker run -d -v /data/registry:/var/lib/registry -p 5000:5000 --name myRegistry registry
# 搭建ubuntu系统(步骤):
docker run -it ubuntu
# 先更新包管理工具
apt-get update
# 之后进行各种安装命令
# 例如:安装ifconfig命令
apt-get install net-tools
将镜像上传到私有库的步骤如下:
第一步:发起get请求查看私服库上面有什么镜像:
- 格式:curl -XGET http://私有库所在ip:私有库所在端口/v2/_catalog
第二步:使用docker tag命令创建出标准格式的镜像文件。
- docker tag命令作用:在docker中,tag是用于标记本地镜像,并且将其归入某一仓库的命令;该命令可以用于给镜像打标签。
- 格式如下:docker tag 镜像:Tag Host:Port/Repository:Tag
第三步:docker默认不允许http方式推送镜像,因此要修改配置文件使之支持http。修改后不生效,要重启docker服务。
- 新增/etc/docker/daemon.json的内容如下:(insecure-registries是告诉docker这个地址是安全的!)
第四步:启动docker的私有仓库。
- 类似命令:docker run -d -v /data/registry:/var/lib/registry -p 5000:5000 --name myRegistry registry
- 如果冲突了,可以通过docker ps -a命令查看,通过docker start 镜像ID启动起来就可以了。
第五步:使用push命令,推送对应的镜像。
第六步:再次通过curl来查看,私有库是否有镜像了。
- 格式:curl -XGET http://localhost:5000/v2/_catalog
第七步:拉去私有库的镜像。
- 格式:docker pull localhost:5000/myubuntu:1.2
3. 容器数据卷的使用
注意:
- –privileged=true的使用。
使用-v 参数来绑定容器卷的时候,最好添加上--privileged=true参数,不然没有权限。
容器数据卷效果如下:
容器卷的作用:
- 就是持久化的一个效果。
- 将docker容器内的数据保存进宿主机的磁盘中。
如何运行一个带有容器卷的容器实例:
- 命令格式:docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录 镜像名 。
- 实际上就是相当于把宿主机和docker容器中的两个目录关联其来了。
4. 容器卷和主机互通互联
容器卷和主机的互通互联案例如下:
# 使用-v 来创建宿主机目录和docker容器目录。
[root@VM-4-14-centos/]$ docker run -it --privileged=true -v /tmp/host_data:/tmp/docker_data --name=u1 ubuntu
# 这样对改目录的内容进行修改,对应的宿主机的内容也会同步!
root@6823da652301:/tmp/docker_data$ touch dockerin.txt
root@6823da652301:/tmp/docker_data$ pwd
/tmp/docker_data
# 对一个容器的目录如下:
[root@VM-4-14-centos host_data]$ pwd
/tmp/host_data
[root@VM-4-14-centos host_data]$ ll
total 0
-rw-r--r-- 1 root root 0 Sep 1 13:08 dockerin.txt
这个过程是双向的,在容器对应目录里面改变,宿主机会改变。在宿主机对应目录下改变,容器里面也会改变!
-v 命令是可以挂载多个容器卷的,例如:一个挂载日志,一个挂在业务逻辑等等。
5. 容器卷ro 和 rw读写规则rw读写规则是可以配置的:
- docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内剥:rw 。这里的rw就是可读可写。
- 默认是可读可写的。
容器内部限制,只能读不能写ro(read only) :
6. 卷的继承和共享举个例子:
- 容器1完成和宿主机的映射,容器2继承容器1的卷规则。
卷继承格式如下:
- docker run -it --privileged=true --volumes-from 父类 --name u2 ubuntu
如果u2停止了,并不会影响u3,u3只是继承了u2的容器卷而已。
直接去hub.docker.com官方仓库搜索tomcat:
也可以通过docker search tomcat查看一下。
# 查看tomcat版本呢
docker search tomcat
# 拉取tomcat,注意这里是拉取得最新版
docker pull tomcat
# 拉取成功后,检查一下
docker images
# 创建容器(运行镜像) 或者 后台启动 -d
docker run -it -p 8080:8080 --name t1 tomcat
启动后,可以访问一下tomcat 的主页,验证一下。
注意:新版的tomcat默认webapps下面是没有内容的,有一个webapps.dist是原本的,可以将webapps.dist解压为webapps就可以访问到tomcat的主页了。
一般项目上用不到最新版本的tomcat,因此一般下载tomcat8-jdk8版本的,去hub.docker.com上面可以搜索看到:
8. docker 安装mysql8.1 运行mysql容器
同样docker search查询一下 或者 hub上面搜索 :
学会去官方文档找教程:
运行mysql容器:
- 格式:docker run --name Mymysql -e MYSQL_ROOT_PASSWORD=密码 -d mysql:tag
- 注意:服务器本身携带了mysql,3306可能被占用的情况。
# 启动mysql容器实例:
docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
# 开启交互mysql , 输入对应命令:
[root@VM-4-14-centos ~] docker exec -it 733e8e6172c4 /bin/bash
root@733e8e6172c4:/ mysql -uroot -p123456
# 执行一系列的命令就可以了。
远程连接可以直接连接服务器ip和对应端口就可以了。
8.2 docker mysql容器卷配置(非常重要)
容器卷就是持久化,如果没有配置mysql容器卷,那么mysql容器一旦被删除,那么mysql容器里面的数据就没有了,这跟删库一样了。
因此,一定要配置容器卷!
docker run -d -p 3306:3306 --privileged=true \
-v /itholmes/mysql/log:/var/log/mysql \
-v /itholmes/mysql/data:/var/lib/mysql \
-v /itholmes/mysql/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=123456 --name Mymysql mysql:5.7
8.3 docker mysql的中文问题
docker安装的mysql的中文数据问题:
原因是docker默认字符集编码是latin1:
使用show variables like 'character%'命令在第三方工具的误区:
解决中文问题的前提是启动的时候一定要配好容器卷:
my.cnf配置如下:
[client]
default_character_set=utf8
[mysqld]
collation_server = utf8_general_ci
character_set_server = utf8
这样就即解决了持久化问题,又解决中文问题了。
9. docker 安装redis第一步:拉取redis镜像。
# 拉取redis镜像
docker images redis:6.0.8
第二步:配置redis.conf文件,可以去copy一个。通过容器数据卷的配置来操作redis容器相关配置。
同样redis也是要用容器数据卷的形式来存储相关配置,数据等等。
在容器卷对应目录下面,复制一份原始的redis.conf配置文件,并修改其内容:
- 第一步:开启redis密码验证。(根据情况添加)
- 第二步:允许redis外地连接!注释掉 bind 127.0.0.1 不然外机无法访问redis的!
- 第三步:daemonize no 。关闭守护进程,因为会和docker run -d参数冲突所以要将其设置为no。
- 第四步:开启redis数据持久化 appendonly yes (根据情况配置)。
第三步:启动redis容器。命令如下:
docker run -p 6379:6379 --name myredis --privileged=true \
-v /app/redis/redis.conf:/etc/redis/redis.conf \
-v /app/redis/data:/data \
-d redis:6.0.8 redis-server /etc/redis/redis.conf
# redis-server /etc/redis/redis.conf是要指定宿主主机的redis.conf文件。
# 只有这样宿主机的redis.conf才会生效!
再次提醒要指定宿主机器的redis.conf文件,不然就会用redis容器里面默认的配置文件!
第一步:容器卷形式启动名为mysql-master的容器。
docker run -p 3307:3306 --name mysql-master \
-v /mydata/mysql-master/log:/var/log/mysql \
-v /mydata/mysql-master/data:/var/lib/mysql \
-v /mydata/mysql-master/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7
第二步:去宿主机容器数据卷对应的目录下面进行配置操作。
- 创建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
第三步:修改完配置后,重启master实例。
docker restart mysql-master
第四步:进入mysql-master容器,创建用户赋予用户权限(从机必须要有对应用户和权限才对!)。
# 进入交互式mysql-master容器
docker exec -it mysql-master /bin/bash
# 进入mysql客户端
mysql -uroot -proot
# 创建用户
create user 'slave'@'%' identified by '123456';
# 给用户赋予权限
grant replication slave, replication client on *.* to 'slave'@'%';
第五步:创建启动一个从数据库,。
docker run -p 3308:3306 --name mysql-slave \
-v /mydata/mysql-slave/log:/var/log/mysql \
-v /mydata/mysql-slave/data:/var/lib/mysql \
-v /mydata/mysql-slave/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7
第六步:同样在对应的容器数据卷目录下,配置从数据库相关信息。
- 创建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
第七步:重启master-slave容器实例。
docker restart mysql-slave
第八步:在主数据库中查看主从同步状态。为了后面从数据库配置参数做准备。
第九步:在从数据库中配置主从复制。
- 从数据库中配置主从复制,命令格式:
change master to master_host='宿主机IP',master_user='slave',master_password='123456',master_port=3307,master_log_file='mall-mysql-bin.000001',master_log_pos=617,master_connect_retry=30;
- 主从复制的参数命令说明:
- 案例命令过程如下:
# 打开交互,从数据库容器
docker exec -it mysql-slave /bin/bash
# 进入mysql客户端
mysql -uroot -proot
# 配置主从复制参数
change master to master_host='127.0.0.1',master_user='slave',master_password='123456',master_port=3307,master_log_file='mall-mysql-bin.000001',master_log_pos=617,master_connect_retry=30;
第十步:在从数据库中查看主从同步状态。
# 查看从数据库的状态 \G是一个key-value键值对的形式。
show slave status \G;
第十一步:在从数据库中,开启主从复制。
# 在mysql客户端中执行命令
start slave
# 也可以关闭
stop slave
这里由于是云服务器,所以动了一下防火墙和白名单。一旦碰了防火墙一定要重启docker服务,不然从数据库就没办法去连接主数据库了。
第十二步:测试,往主数据库里面添加数据,看看从数据库能不能同步了。
踩坑注意事项:
- docker运行的时候最好不要去操作防火墙!!!!!不然会导致docker容器网络有问题。
举个例子,如果有2亿的数据需要做缓存,怎么办?
像下面哈希取余分区,根据某种哈希算法取余映射到哪个redis节点上面。
优点:
缺点:
总结:
- 哈希取余分区算法算是比较常用的,只不过该算法适合小数据量环境。
- 问题:扩容、缩容或者某个机器宕机了,分母数量改变了,取余数这种就不行了。
一致性哈希算法设计目的是为了解决分布式缓存数据变动和映射问题,某个机器宕机了,分母数量改变了的情况。
一致性哈希算法 - 算法构建一致性哈希环:
一致性哈希算法将整个哈希值空间组织成一个虚拟的圆环。
整个空间按顺时针方向组织。
一致性哈希算法 - 服务器IP节点映射:
一致性哈希算法 - key落到服务器的落键规则:
一致性哈希算法 优缺点:
- 优点:提高了容错性(中间有节点服务宕机了也没事。)和扩展性(中间添加节点也是没事的)。
- 缺点:有数据倾斜的问题。节点太少,分布不均匀。
哈希槽分区是最好的!!大厂标配。
原理:在数据和节点之间又加了一层,这层称为哈希槽(slot),用于管理数据和节点之间的关系。
hash槽:redis集群最大槽数是16384个。
为什么redis集群槽数为2^14 - 1(16384个)呢?
也是对16384取余,余数是几key就落入对应的槽里面。以槽为单位,槽的数目也是固定的。
redis集群搭建见下一章。