前言
前一章介绍了docker的基础知识,适合零基础小白阅读和学习,当然非小白也可用于查阅,查漏补缺,本章开始将记录一些docker的高级部分,难度上也会提升很多,内容较多,比较枯燥,不过看下来一定会非常受用。
一、复杂安装
1、安装MySQL主从复制
1)新建主服务器容器实例3307
docker run -p 3307:3306 --name mysql-master \
-v /myapp/mysql-master/log:/var/log/mysql \
-v /myapp/mysql-master/data:/var/lib/mysql \
-v /myapp/mysql-master/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7
2)进入/myapp/mysql-master/conf目录下新建my.cnf.(配置文件的参数很重要,有一点不对都无法启动!!!)
[mysqld]
## 设置serverid,同一局域网中需要唯一
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错误是指一些主键重复
slave_skip_errors=1062
3)修改完配置后重启master实例docker restart mysql-master
4)进入mysql-master容器
docker exec -it mysql-master /bin/bash
mysql -uroot -proot
5)master容器实例内创建数据同步用户
# 创建用户和密码
CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
# 给用户授权
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
6)新建从服务器容器实例3308
docker run -p 3308:3306 --name mysql-slave \
-v /myapp/mysql-slave/log:/var/log/mysql \
-v /myapp/mysql-slave/data:/var/lib/mysql \
-v /myapp/mysql-slave/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7
7)进入/mydata/mysql-slave/conf目录下新建my.cnf
[mysqld]
## 设置serverid,同一局域网中需要唯一
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错误是指一些主键重复
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)修改完配置后重启slave实例
9)在主数据库中查看主从同步状态show master status;
10)进入mysql-slave容器
11)在从数据库中配置主从复制
change master to master_host='192.168.61.111', master_user='slave', master_password='123456', master_port=3307, master_log_file='mall-mysql-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:连接失败重试的时间间隔,单位为秒。
master_log_file和master_log_pos是第九步查出来的,注意修改哦
12)在从数据库中查看主从同步状态show slave status \G;
,此时还未启动主从复制。
13)在从数据库中开启主从同步start slave
,再次查看主从同步状态会发现上图红框的属性已经是Yes。
14)测试主从同步
2、安装Redis集群
2.1 3主3从redis集群配置
1)关闭防火墙+启动docker后台服务
配置过程会涉及很多端口,如果打开防火墙则需要将这个端口全部放行。
systemctl stop firewalld
systemctl start docker
2)新建6个Redis容器实例
–net host:使用宿主机的IP和端口,默认,此时就不用写-p进行端口映射了。
–cluster-enabled yes:开启redis集群
docker run -d --name redis-node-1 --net host --privileged=true -v /myapps/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 /myapps/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 /myapps/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 /myapps/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 /myapps/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 /myapps/redis/share/redis-node-6:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6386
3)进入容器redis-node-1并为6台机器构建集群关系
这个地方进入谁都一样,知识要进入一个容器就好。这里以redis-node-1为例。
docker exec -it redis-node-1 /bin/bash
注意,进入docker容器后才能执行以下命令,且注意自己的真实IP地址
–cluster-replicas 1 表示为每个master创建一个slave节点
redis-cli --cluster create 192.168.61.111:6381 192.168.61.111:6382 192.168.61.111:6383 192.168.61.111:6384 192.168.61.111:6385 192.168.61.111:6386 --cluster-replicas 1
4)链接进入6381作为切入点,查看集群状态
redis-cli -p 6381
cluster info
cluster nodes
可见,三主三从搭建成功,6381-6384,6382-6385,6383-6386。
2.2 主从容错切换迁移
1)数据读写存储
当我们使用redis-cli -p 6381
进入redis,添加数据可能会出现如下情况。是因为我们已经搭建了集群模式,每个主redis的槽已经敲定了,k1所属的槽不在6381,因此我们需要使用 -c 优化路由。
2)容错切换迁移
当主6382宕机时,对应的真实从机上位,本次对应从机6385。
也可以通过redis-cli --cluster check 192.168.61.111:6381
查看集群状态。
2.3 主从扩容
1)新建6387、6388两个节点+新建后启动+查看是否8节点
docker run -d --name redis-node-7 --net host --privileged=true -v /myapps/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 /myapps/redis/share/redis-node-8:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6388
docker ps
2)进入6387容器实例内部docker exec -it redis-node-7 /bin/bash
3)将新增的6387节点(空槽号)作为master节点加入原集群
redis-cli --cluster add-node 192.168.61.111:6387 192.168.61.111:6381
4)检查集群情况redis-cli --cluster check 192.168.61.111:6381
5)重新分配槽号redis-cli --cluster reshard 192.168.61.111:6381
6)再次检查集群情况redis-cli --cluster check 192.168.61.111:6381
,此时slots已经分配成功了。
7)为主节点6387分配从节点6388
命令:redis-cli --cluster add-node ip:新slave端口 ip:新master端口 --cluster-slave --cluster-master-id 新主机节点ID,e4781f644d4a4e4d4b4d107157b9ba8144631451是6387的编号,按照自己实际情况
redis-cli --cluster add-node 192.168.61.111:6388 192.168.61.111:6387 --cluster-slave --cluster-master-id 9275816cef74e3e8bb8f942d8f70540a7a895045
8)第3次检查集群情况redis-cli --cluster check 192.168.61.111:6381
为什么6387是3个新的区间,以前的还是连续?
重新分配成本太高,所以前3节点各自匀出来一部分,从6381/6382/6383三个旧节点分别匀出1364个坑位给新节点6387
2.4 主从缩容
本次将新加入的节点6387和6388移除,先移除从节点6388。
1)检查集群情况redis-cli --cluster check 192.168.61.111:6381
,查看63
命令:redis-cli --cluster del-node ip:从机端口 从机6388节点ID
redis-cli --cluster del-node 192.168.61.111:6388 023780843d0b32d7c0a1baf67d69e16579103a79
2)将6387的槽号清空,重新分配,本例将清出来的槽号都给6381(本次是测试,实际情况根据实际情况分配)
redis-cli --cluster reshard 192.168.61.111:6381
3)第二次检查集群情况,此时发现6387的槽位已经为0了
4)删除6387节点
redis-cli --cluster del-node 192.168.61.111:6387 9275816cef74e3e8bb8f942d8f70540a7a895045
5)第三次检查集群情况,此时发现6387节点已经被删除了
二、DockerFile
DockerFile是构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本。
- 每条保留字都必须为大写字母且后面要跟随至少一个参数
- 指令按照从上到下,顺序执行
- #表示注释
- 每条指令都会创建一个新的镜像层并对镜像进行提交
1、常用保留字指令
FROM:基础镜像,当前新镜像是基于哪个镜像的,指定一个已经存在的镜像作为模板,第一条必须是FROM。
MAINTAINER:镜像维护者的姓名和邮箱地址。
RUN:容器运行时需要的命令,是在docker build时运行,两种格式:shell格式和exec格式。
EXPOSE:当前容器对外暴露出的端口
WORKDIR:指定在创建容器后,终端登录进来默认的工作目录。
USER:指定该镜像以什么用户执行,不指定默认root。
ENV:用来在构建镜像过程中设置环境变量。
ADD:将宿主机目录下的文件拷贝进镜像且会自动处理URL和tar压缩包。
COPY:拷贝文件和目录到镜像中
VOLUMN:容器数据卷,用于数据保存和持久化。
CMD:指定容器运行时要做的事。会被docker run后面的命令覆盖。
ENTRYPOINT:也是指定容器运行时要做的事。类似CMD,但是不会被docker run后面的命令覆盖。而且这些命令会被当作参数送给ENTRYPOINT指令指定的程序。
2、使用Dockerfile构建镜像
1)创建一个目录作为存放Dockerfile文件和jdk压缩文件。mkdir /myfiles
2)进入该目录并创建Dockerfile,注意,文件名必须为Dockerfile。
Dockerfile文件内容:
FROM centos:centos7.9.2009:我的centos镜像版本为centos7.9.2009
FROM centos:centos7.9.2009
MAINTAINER zhangdl<zhangdl945@163.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH
#安装vim编辑器
RUN yum -y install vim
#安装ifconfig命令查看网络IP
RUN yum -y install net-tools
#安装jdk8以及lib库
RUN yum -y install glibc.i686
RUN mkdir /usr/local/java
ADD jdk-8u331-linux-x64.tar.gz /usr/local/java
#配置java环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_331
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
EXPOSE 80
CMD echo $MYPATH
CMD /bin/bash
3)构建镜像 docker build -t 新镜像名字:TAG .(注意最后有一个点.)
4)运行测试 docker run -it 新镜像名字:TAG
3、通过Dockerfile构建微服务镜像并运行测试
1)创建一个微服务,并打包成jar包
2)创建Dockerfile文件并在同级目录下上传微服务jar包
# 基础镜像使用java
FROM openjdk
# 作者
MAINTAINER zhangdl
# VOLUME 指定临时文件目录为/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmp
VOLUME /tmp
# 将jar包添加到容器中并更名为zzyydocker.jar
ADD dockerboot-0.0.1-SNAPSHOT.jar mymsfile.jar
# 运行jar包
RUN bash -c 'touch /mymsfile.jar'
ENTRYPOINT ["java","-jar","/mymsfile.jar"]
# 暴露端口
EXPOSE 6001
3)构建镜像
4)运行镜像
5)测试应用
注意:需要端口映射,不然无法访问哦。
构建时如果出现就会出现仓库名和版本都为的虚悬镜像。
需删除它,重新构建
三、Docker网络
在不启动docker时,通过ifconfig
可以查看到有三个情况:ens33、lo、virbr0。
在启动后会多产生一个docker0的虚拟网桥。docker0就是作为docker的网关。每产生一个docker实例,就会多一对veth-eth0。docker0是bridge模式。docker容器内部的ip是有可能会发生改变的。
Docker网络能干嘛,注意涉及两方面的功能:
① 容器间的互联和通信以及端口映射容器
② IP变动时候可以通过服务名直接网络通信而不受到影响
1、常用命令
查看网络:docker network ls
查看网络源数据:docker network inspect XXX网络名字
删除网络:docker network rm XXX网络名字
2、网络模式
网络模式大致分为如下五种:
bridge模式:使用–network bridge指定,默认使用docker0
host模式:使用–network host指定
none模式:使用–network none指定
container模式:使用–network container:NAME或者容器ID指定
自定义模式:使用–network 自定义网络指定。自定义网络本身就维护好了主机名和ip的对应关系(ip和域名都能通),可以通过服务名进行通信。
四、Docker-compose容器编排
Docker-Compose是Docker官方的开源项目,负责实现对Docker容器集群的快速编排。Compose允许用户通过一个单独的docker-compose.yml模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。
官网地址:https://docs.docker.com/compose/compose-file/compose-file-v3/
1、下载
下载地址:https://docs.docker.com/compose/install/
2、安装
因为是从github下载,会有些慢,懂得其他方法的自行解决哦。
curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
添加权限:chmod +x /usr/local/bin/docker-compose
版本:docker-compose --version
3、步骤
1)编写Dockerfile定义各个微服务应用并构建出对应的镜像文件。
2)使用 docker-compose.yml 定义一个完整业务单元,安排好整体应用中的各个容器服务。
3)执行docker-compose up命令 来启动并运行整个应用程序,完成一键部署上线。
4、命令
docker-compose -h # 查看帮助
docker-compose up # 启动所有docker-compose服务
docker-compose up -d # 启动所有docker-compose服务并后台运行
docker-compose down # 停止并删除容器、网络、卷、镜像。
docker-compose exec yml里面的服务id # 进入容器实例内部 docker-compose exec docker-compose.yml文件中写的服务id /bin/bash
docker-compose ps # 展示当前docker-compose编排过的运行的所有容器
docker-compose top # 展示当前docker-compose编排过的容器进程
docker-compose stop # 停止当前docker-compose编排过的容器进程
五、Docker轻量级可视化工具Portainer
Portainer 是一款轻量级的应用,它提供了图形化界面,用于方便地管理Docker环境,包括单机环境和集群环境。
其实在使用集群环境是,都会考虑使用K8S。
1、下载
官网地址:https://www.portainer.io/
2、安装
docker run -d -p 8000:8000 -p 9000:9000 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer
3、登录使用
第一次登录需创建admin,访问地址:xxx.xxx.xxx.xxx:9000。
页面上的东西也比较简单,在之前的学习中都有学过相关命名。因此,看一看就能懂,此处不再举例说明了。
六、Docker容器监控之CAdvisor+InfluxDB+Granfana(CIG)
Portainer是轻量级可视化工具,而CIG就是重量级的,它是由三部分构成,每部分负责不同的功能。
CAdvisor监控收集、InfluxDB存储数据、Granfana展示图表
通过docker下载安装三个组件,然后通过docker-compose启动即可。
注意:最好是设置成always,保证docker重启后自动启动服务,进行监控。
访问地址:
浏览cAdvisor收集服务,http://ip:8080/(第一次启动会比较的慢)cadvisor也有基础的图形展现功能,这里主要用它来作数据采集
浏览influxdb存储服务,http://ip:8083/
浏览grafana展现服务,http://ip:3000
结束语
后面几部分的内容。相对记录的比较简单了,因为在我自己做的时候也没有前面详细,大家根据自己的情况浏览就好哦。
其实很多东西都不是很难,就是需要多练,熟悉了就很简单了,咱们江湖再会!
参考
B站尚硅谷:https://www.bilibili.com/video/BV1gr4y1U7CY