一、组件集群部署
1、mysql主从复制
1、拉取mysql镜像
docker pull mysql:5.7.26
2、后台运行主节点镜像、映射端口、挂载容器卷、设置mysql登录密码
docker run -p 3307:3306 --name mysql_master \
-v /mydata/mysql_matser/log:/var/log/mysql \
-v /mydata/mysql_matser/data:/var/lib/mysql \
-v /mydata/mysql_matser/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
-d mysql:5.7.26
3、在master节点添加复制用户
#进入容器
docker exec -it 570c655e637f /bin/bash
#登录mysql
mysql -uroot -p123456
CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
FLUSH PRIVILEGES;
4、修改配置
#进入宿主机的/mydata/mysql_matser/conf/
cd /mydata/mysql_matser/conf/
vim my.cnf
#在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
5、重启mysql
docker restart mysql_master
#检查mysql是否重复成功
docker ps |grep mysql_master
570c655e637f mysql:5.7.26 "docker-entrypoint.s…" 12 minutes ago Up 4 minutes 33060/tcp, 0.0.0.0:3307->3306/tcp, :::3307->3306/tcp mysql_master
6、后台运行主节点镜像、映射端口、挂载容器卷、设置mysql登录密码
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=123456 \
-d mysql:5.7.26
7、修改配置
#进入宿主机的/mydata/mysql_slave/conf/
cd /mydata/mysql_slave/conf/
vim 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
8、重启mysql_slave
docker restart mysql_slave
9、登录mysql_slave,执行主从同步命令
docker exec -it mysql_slave /bin/bash
mysql -uroot -p123456
change master to master_host='master_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;
start slave;
10、查看主从同步状态
show slave status \G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.31.186.94
Master_User: slave
Master_Port: 3307
Connect_Retry: 30
Master_Log_File: mall-mysql-bin.000001
Read_Master_Log_Pos: 769
Relay_Log_File: mall-mysql-relay-bin.000002
Relay_Log_Pos: 477
Relay_Master_Log_File: mall-mysql-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
11、测试主从同步
#主库插入数据
create database test;
create table t1 (id int,name varchar(255));
insert into t1 value (1,'zzzzz');
mysql> select * from t1;
+------+-------+
| id | name |
+------+-------+
| 1 | zzzzz |
+------+-------+
#从库查询数据
use test
mysql> select * from t1 ;
+------+-------+
| id | name |
+------+-------+
| 1 | zzzzz |
+------+-------+
1 row in set (0.00 sec)
2、redis集群
1.运行6个redis节点
docker run -d --name redis-node-1 --net host --privileged=true -v /iflytek/data/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 /iflytek/data/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 /iflytek/data/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 /iflytek/data/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 /iflytek/data/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 /iflytek/data/redis/share/redis-node-6:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6386
#部分命令注释
--net host:使用宿主机的ip和端口,默认
--cluster-enabled yes:开启redis集群
--appendonly yes:开启redis持久化
#docker ps 查看容器是否正常启动
[root@stc-tst02 iflytek]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
be20ccaa6dbf redis:6.0.8 "docker-entrypoint.s…" 3 seconds ago Up 2 seconds redis-node-6
4944a729d351 redis:6.0.8 "docker-entrypoint.s…" 4 seconds ago Up 3 seconds redis-node-5
786da1e4cb85 redis:6.0.8 "docker-entrypoint.s…" 5 seconds ago Up 4 seconds redis-node-4
e99f63e6346f redis:6.0.8 "docker-entrypoint.s…" 5 seconds ago Up 4 seconds redis-node-3
ee8d82ca1043 redis:6.0.8 "docker-entrypoint.s…" 5 seconds ago Up 4 seconds redis-node-2
e0b218bc5f62 redis:6.0.8 "docker-entrypoint.s…" 4 minutes ago Up 4 minutes redis-node-1
2.进入容器构建redis节点主从关系
docker exec -it redis-node-1 /bin/bash
redis-cli --cluster create 172.31.186.xx:6381 172.31.186.xx:6382 172.31.186.xx:6383 172.31.186.xx:6384 172.31.186.xx:6385 172.31.186.xx:6386 --cluster-replicas 1
#出现以下命令,代表构建成功,--cluster-replicas 1 表示为每个master创建一个slave节点
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
3.进入redis-node1查看集群状态
redis-cli -p 6381
127.0.0.1:6381> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:205
cluster_stats_messages_pong_sent:187
cluster_stats_messages_sent:392
cluster_stats_messages_ping_received:182
cluster_stats_messages_pong_received:205
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:392
127.0.0.1:6381> cluster nodes
2.1 redis集群扩容
1.新增两个redis节点
docker run -d --name redis-node-7 --net host --privileged=true -v /iflytek/data/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 /iflytek/data/redis/share/redis-node-8:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6388
2.进入6378容器
docker exec -it redis-node7 /bin/bash
3.将6387redis节点加入集群
#6381 就是原来集群节点里面的领路人,相当于6387拜拜6381的码头从而找到组织加入集群
redis-cli --cluster add-node 172.31.186.94:6387 172.31.186.94:6381
#出现以下信息则代表节点加入成功
[OK] New node added correctly.
4.查看集群状态
redis-cli --cluster check 172.31.186.94:6381
172.31.186.94:6381 (aa6af311...) -> 0 keys | 5461 slots | 1 slaves.
172.31.186.94:6383 (cdf0dacf...) -> 0 keys | 5461 slots | 1 slaves.
172.31.186.94:6382 (3401ab3c...) -> 0 keys | 5462 slots | 1 slaves.
#可以看到6387并没有分配到槽位
172.31.186.94:6387 (1bafd356...) -> 0 keys | 0 slots | 0 slaves.
5.重新分配槽位给新加入的节点
redis-cli --cluster reshard 172.31.186.94:6381
16384除以集群个数 得出的值 就是重新分配的槽位数量
输入新加入集群节点ID
6.查看集群状态
redis-cli --cluster check 172.31.186.xx:6382
172.31.186.94:6381 (aa6af311...) -> 0 keys | 4096 slots | 1 slaves.
172.31.186.94:6383 (cdf0dacf...) -> 0 keys | 4096 slots | 1 slaves.
172.31.186.94:6382 (3401ab3c...) -> 0 keys | 4096 slots | 1 slaves.
172.31.186.94:6387 (1bafd356...) -> 0 keys | 4096 slots | 0 slaves.
7.给新节点配置主从
redis-cli --cluster add-node ip:新slave端口 ip:新master端口 --cluster-slave --cluster-master-id 新主机节点ID
8.查看集群状态
redis-cli --cluster check 172.31.186.xx:6382
172.31.186.94:6382 (3401ab3c...) -> 0 keys | 4096 slots | 1 slaves.
172.31.186.94:6381 (aa6af311...) -> 0 keys | 4096 slots | 1 slaves.
172.31.186.94:6383 (cdf0dacf...) -> 0 keys | 4096 slots | 1 slaves.
172.31.186.94:6387 (1bafd356...) -> 0 keys | 4096 slots | 1 slaves.
2.2 redis集群缩容
先删除丛节点
再退回槽位
最后删除主节点
1.查看6388从节点id
redis-cli --cluster check 172.31.186.xx:6382
2.删除6388从节点
redis-cli --cluster del-node 172.31.186.xx:6388 5f2992c2421ee7e33b7a4adb756fd17f7b1f518f
>>> Removing node 5f2992c2421ee7e33b7a4adb756fd17f7b1f518f from cluster 172.31.186.xx:6388
>>> Sending CLUSTER FORGET messages to the cluster...
>>> Sending CLUSTER RESET SOFT to the deleted node.
3.6387主节点槽位返还(返还给6381节点)
redis-cli --cluster reshard 172.31.186.94:6381
输入槽位数:4096
输入:6381节点ID,让6381节点来接受返回的槽位
输入:6387节点ID
输入:done
输入:yes
4.查看集群状态,查看6387槽位是否返还
redis-cli --cluster check 172.31.186.xx:6381
M: 1bafd3566bb502e6d9a0b42fbda7b3f1896d101f 172.31.186.94:6387
slots: (0 slots) master
5.删除6387主节点
redis-cli --cluster del-node 172.31.186.94:6387 1bafd3566bb502e6d9a0b42fbda7b3f1896d101f
>>> Removing node 1bafd3566bb502e6d9a0b42fbda7b3f1896d101f from cluster 172.31.186.xx:6387
>>> Sending CLUSTER FORGET messages to the cluster...
>>> Sending CLUSTER RESET SOFT to the deleted node.
6.查看集群状态
redis-cli --cluster check 172.31.186.xx:6381
172.31.186.94:6381 (aa6af311...) -> 0 keys | 8192 slots | 1 slaves.
172.31.186.94:6383 (cdf0dacf...) -> 0 keys | 4096 slots | 1 slaves.
172.31.186.94:6382 (3401ab3c...) -> 0 keys | 4096 slots | 1 slaves.
二、dockerfile
dockerfile是构建镜像的文本文件,是由一条条构建镜像的指令和参数构成的脚本
dockerfile执行流程:
指令按照从上到下,顺序执行
docker从基础镜像运行一个容器
执行一条指令对容器作出修改
执行类似docker commit的操作提交一个新的镜像
docker基于刚提交的镜像运行一个新容器
执行dockerfile中的下一条指令,直到所有指令都执行完成
dockerfile编写规范:
1.每条保留字指令必须为大写字母且后面要跟随至少一个参数
2.#表示注释
总结:dockrefile、docker镜像、docker容器关系
dockerfile就像是个药方,里面列出一些药物清单
doker镜像,就是通过药方,去抓取的药物
docker容器就是把抓取的药物熬成药汤
dockerfile常用的指令:
FORM:基础镜像,当前的镜像是基于哪个镜像的,指定一个已经存在的镜像作为模板,第一条必须是FORM
MAINTAINER:镜像维护者的姓名和邮箱地址
RUN:容器构建时需要运行的命令(RUN是在构建容器(docker build)时运行)
两种格式:shell格式和exec格式
shell格式:RUN yum -y install vim
exec格式:RUN ["可执行的文件","参数1","参数2"]
WORKDIR:指定在创建容器后,终端默认登陆的进来工作目录,一个落脚点
USER:指定该镜像以什么样的用户去执行,如果都不指定,默认是root
ENV:设置dockerfile中的环境变量
语法:ENV MY_PATH /usr/local
定义了一个MY_PATH的变量,这个变量的值为 /usr/local
MY_PATH这个变量,可以在后续的任何RUN指令中使用,也可以在其他指令中使用,比如: WORKDIR $MY_PATH
ADD:将宿主机目录下的文件拷贝进镜像且会自动处理URL和解压tar压缩包
COPY:类似ADD,拷贝宿主机的文件和目录到镜像中。
语法:COPY src dest
dest路径如果不存在,会自动创建
EXPOSE:镜像暴露出的端口
VOLUME:容器数据卷,用于数据保存和持久化工作
语法:
CMD:启动容器后要执行的命令,起语法格式和RUN指令一样
注意:dockerfile中可以有多条CMD指令,但是只有最后一条才会生效。CMD的指令,会被docker run 之后的参数替换。
CMD和RUN的区别:RUN是构建镜像时执行,CMD是运行镜像时执行
ENTRYPOINT:类似于 CMD 指令,但是ENTRYPOINT不会被docker run后面的命令覆盖, 而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序
案例:
FORM nignx
ENTRYPOINT ["nginx",”-c“]
CMD ["/etc/nginx/nginx.conf"]
以上dockerfile表示,启动该nginx镜像时,会默认读取/etc/nginx/nginx.conf,如果想读取其他的配置文件,则加入-c参数来传参。docker run nginx:test -c /etc/nginx/new.conf。类型shell编程中$1的用法
在执行docker run的时候可以指定 ENTRYPOINT 运行所需的参数
如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效
dockerfile编写案例:
#基于centos7镜像
FROM centos:7
#编写者信息
MAINTAINER taoliu<taoliu@126.com>
#定义一个MYPATH的变量
ENV MYPATH /usr/local
#进入容器后的落脚路径
WORKDIR $MYPATH
#安装vim编辑器
RUN yum -y install vim
#安装ifconfig命令查看网络IP
RUN yum -y install net-tools
#安装java8及lib库
RUN yum -y install glibc.i686
RUN mkdir /usr/local/java
#ADD 是相对路径jar,把jdk-8u111-linux-x64.tar.gz添加到容器中,安装包必须要和Dockerfile文件在同一位置
ADD jdk-8u111-linux-x64.tar.gz /usr/local/java/
#配置java环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_111
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
ENV PATH $JAVA_HOME/bin:$PATH
#容器暴露为80端口
EXPOSE 80
#输出变量
CMD echo $MYPATH
CMD echo "success--------------ok"
CMD /bin/bash
查看容器:
[root@stc-tst02 myfile]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos_tao 7 1cd71d965142 2 minutes ago 1.18GB
启动容器:
docker run -it centos_tao:7 /bin/bash
查看JDK
java -version
java version "1.8.0_111"
Java(TM) SE Runtime Environment (build 1.8.0_111-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.111-b14, mixed mode)