• 【Docker】Docker进阶(一)


    一、Docker复杂安装

    1.1、安装mysql主从复制

    1.1.1、配置主机

    主机的my.cnf

    [mysqld]
    ## 设置server_id,同一局域网中需要唯一
    server_id=101
    ## 指定不需要同步的数据库名称
    binlog-ignore-db=mysql  
    #启用二进制日志  
    log-bin=mysql-bin 
    ## 设置二进制日志使用内存大小(事务)
    binlog_cache_size=1M  
    ## 设置使用的二进制日志格式(mixed,statement,row)
    binlog_format=mixed  
    ## 二进制日志过期清理时间。默认值为0,表示不自动清理。
    expire_logs_days=7  
    ## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。
    ## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
    slave_skip_errors=1062  
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    启动docker

    docker run -p 3307:3306 --name mysql-master 
    -v /www/wwwroot/dockerData/mysql/master/log:/var/log/mysql 
    -v /www/wwwroot/dockerData/mysql/master/data:/var/lib/mysql 
    -v /www/wwwroot/dockerData/mysql/master/conf:/etc/mysql/conf.d  
    -e MYSQL_ROOT_PASSWORD=root 
    -d mysql:5.7
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    主机容器实例内创建数据同步用户

    CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
    GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
    
    • 1
    • 2

    1.1.2、配置从机

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    启动docker

    docker run -p 3308:3306 
    --name mysql-slave 
    -v /www/wwwroot/dockerData/mysql/slave/log:/var/log/mysql 
    -v /www/wwwroot/dockerData/mysql/slave/data:/var/lib/mysql 
    -v /www/wwwroot/dockerData/mysql/slave/conf:/etc/mysql/conf.d  
    -e MYSQL_ROOT_PASSWORD=root 
    -d mysql:5.7
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    1.1.3、配置主从复制

    在主机 输入show master status;
    在这里插入图片描述
    在从机输入

    -- 格式:
    --change master to master_host='宿主机ip'
    --master_user='主数据库配置的主从复制用户名' 
    --master_password='主数据库配置的主从复制用户密码' 
    --master_port=宿主机主数据库端口
    --master_log_file='主数据库主从同步状态的文件名File'
    --master_log_pos=主数据库主从同步状态的Position
    --master_connect_retry=连接失败重试时间间隔(秒);
    
    change master to master_host='192.168.3.100',master_user='slave',master_password='123456',master_port=3307,master_log_file='mysql-bin.000003',master_log_pos=154,master_connect_retry=30;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在从机查看主从同步状态:

    # \G 可以将横向的结果集表格转换成纵向展示。
    # slave status的字段比较多,纵向展示比友好
    show slave status \G;
    
    • 1
    • 2
    • 3

    除了展示刚刚配置的主数据库信息外,主要关注 Slave_IO_RunningSlave_SQL_Running。目前两个值应该都为No,表示还没有开始。

    在从机:开启主从同步:

    start slave;
    
    • 1

    再次查看主从同步状态, Slave_IO_RunningSlave_SQL_Running都变为Yes
    主从复制测试:
    在主机

    create database db01;
    use db01;
    create table t1 (id int, name varchar(20));
    insert into t1 values (1, 'abc');
    
    • 1
    • 2
    • 3
    • 4

    在从机

    show databases;
    use db01;
    select * from t1;
    
    • 1
    • 2
    • 3

    1.2、安装Redis 3主3从

    1.2.1、安装

    使用docker搭建3主3从的Redis集群,每台主机都对应一台从机。
    启动6台redis容器

    # 启动第1台节点
    # --net host 使用宿主机的IP和端口,默认
    # --cluster-enabled yes 开启redis集群
    # --appendonly yes 开启redis持久化
    # --port 6381 配置redis端口号
    docker run -d --name redis-node-1 --net host --privileged=true -v /www/wwwroot/dockerData/redis/redis-node-1:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6381
    
    # 启动第2台节点
    docker run -d --name redis-node-2 --net host --privileged=true -v /www/wwwroot/dockerData/redis/redis-node-2:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6382
    
    # 启动第3台节点
    docker run -d --name redis-node-3 --net host --privileged=true -v /www/wwwroot/dockerData/redis/redis-node-3:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6383
    
    # 启动第4台节点
    docker run -d --name redis-node-4 --net host --privileged=true -v /www/wwwroot/dockerData/redis/redis-node-4:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6384
    
    # 启动第5台节点
    docker run -d --name redis-node-5 --net host --privileged=true -v /www/wwwroot/dockerData/redis/redis-node-5:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6385
    
    # 启动第6台节点
    docker run -d --name redis-node-6 --net host --privileged=true -v /www/wwwroot/dockerData/redis/redis-node-6:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6386
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    1.2.2、构建主从关系:

    # 宿主机IP:端口
    redis-cli --cluster create 192.168.xxx.xxx:6381 192.168.xxx.xxx:6382 192.168.xxx.xxx:6383 192.168.xxx.xxx:6384 192.168.xxx.xxx:6385 192.168.xxx.xxx:6386 --cluster-replicas 1
    
    • 1
    • 2

    redis尝试自动进行主从节点分配
    因为我们的docker容器IP相同,所以会出现警告[WARNING] Some slaves are in the same host as their master,可以直接忽略该警告

    redis自动分配结果完成后,需要输入 Yes 确认配置信息:
    在这里插入图片描述
    Waiting for the cluster to join长时间没有反应的解决方法

    在这里插入图片描述
    在6381结点上查看集群状态:

    redis-cli -p 6381
    cluster info
    其中:
    cluster_state:ok 
    分配的哈希槽数量 cluster_slots_assigned为16384
    集群节点数量cluster_known_nodes为6 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    1.2.3、集群读写

    当使用 redis-cli连接redis集群时,需要添加 -c参数,否则可能会出现读写出错。

    docker exec -it redis-node-1 /bin/bash
    set k1 v1
    
    • 1
    • 2

    会有提示信息,哈希槽为12706,重定向到6383(即节点3,哈希槽[10923, 16383]):

    1.2.4、集群信息检查

    # 输入任意一台主节点地址都可以进行集群检查
    redis-cli --cluster check 192.168.xxx.xxx:6381
    
    • 1
    • 2

    1.2.5、主从扩容

    假如因为业务量激增,需要向当前3主3从的集群中再加入1主1从两个节点。

    启动2台新的容器节点 :

    # 启动第7台节点
    docker run -d --name redis-node-7 --net host --privileged=true -v /www/wwwroot/dockerData/redis/redis-node-7:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6387
    #启动第8台节点
    docker run -d --name redis-node-8 --net host --privileged=true -v /www/wwwroot/dockerData/redis/redis-node-8:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6388
    
    • 1
    • 2
    • 3
    • 4

    进入6387(节点7)容器内部

    docker exec -it redis-node-7 /bin/bash
    
    • 1

    将6387作为master加入集群

    # redis-cli --cluster add-node 本节点地址 要加入的集群中的其中一个节点地址
    redis-cli --cluster add-node 192.168.xxx.xxx:6387 192.168.xxx.xxx:6381
    
    • 1
    • 2

    检查当前集群状态 可以发现,6387节点已经作为master加入了集群,但是该节点没有被分配槽位。
    重新分配集群的槽位

    redis-cli --cluster reshard 192.168.xxx.xxx:6381
    
    • 1

    redis经过槽位检查后,会提示需要分配的槽位数量:

    例如,我们现在是4台master,我们想要给node7分配4096个槽位,这样每个节点都是4096个槽位。
    输入4096后,会让输入要接收这些哈希槽的节点ID,填入node7的节点ID即可。(就是节点信息中很长的一串十六进制串)。

    然后会提示,询问要从哪些节点中拨出一部分槽位凑足4096个分给Node7。一般选择all,即将之前的3个主节点的槽位都均一些给Node7,这样可以使得每个节点的槽位数相等均衡。

    输入all之后,redis会列出一个计划,内容是自动从前面的3台master中拨出一部分槽位分给Node7的槽位,需要确认一下分配的计划。

    输入yes确认后,redis便会自动重新洗牌,给Node7分配槽位

    重新分配完成后,可以进行集群信息检查,查看分配结果
    在这里插入图片描述
    为主节点6387分配从节点6388:

    redis-cli --cluster add-node 192.168.xxx.xxx:6388 192.168.xxx.xxx:6381 --cluster-slave --cluster-master-id 【node7节点的十六进制编号字符串】
    
    • 1

    检查集群当前状态 成功!

    1.2.5、主从缩容

    假如业务高峰期过去,需要将4主4从重新缩容到3主3从。即从集群中移除node8和node7.
    首先删除从节点6388:

    redis-cli --cluster del-node 192.168.xxx.xxx:6388 6388节点编号
    
    • 1

    对node7重新分配哈希槽:

    redis-cli --cluster reshard 192.168.xxx.xxx:6381
    
    • 1

    如果我们想直接把node7的4096个哈希槽全部分给某个节点,可以直接输入4096。
    输入4096后,会让输入要接收这些哈希槽的节点ID。假如我们想把这4096个槽都分给Node1,直接输入node1节点的编号即可。
    然后会提示,询问要从哪些节点中拨出一部分槽位凑足4096个分给Node1。这里我们输入node7的节点编号,回车后输入done。

    将node7从集群中移除

    redis-cli --cluster del-node 192.168.xxx.xxx:6387 node7节点编号
    
    • 1

    二、Dockerfile

    2.1、Dockerfile

    Dockerfile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本。

    构建步骤:

    1. 编写Dockerfile文件
    2. docker build命令构建镜像
    3. docker run依据镜像运行容器实例

    2.2、构建过程

    Dockerfile编写:

    • 每条保留字指令都必须为大写字母,且后面要跟随至少一个参数
    • 指令按照从上到下顺序执行
    • #表示注释
    • 每条指令都会创建一个新的镜像层并对镜像进行提交

    Docker引擎执行Docker的大致流程:

    1. docker从基础镜像运行一个容器
    2. 执行一条指令并对容器做出修改
    3. 执行类似docker commit的操作提交一个新的镜像层
    4. docker再基于刚提交的镜像运行一个新容器
    5. 执行Dockerfile中的下一条指令,直到所有指令都执行完成

    2.3、 Dockerfile保留字

    以tomcat为例

    2.3.1、FROM

    基础镜像,当前新镜像是基于哪个镜像的,指定一个已经存在的镜像作为模板。Dockerfile第一条必须是FROM

    # FROM 镜像名
    FROM hub.c.163.com/library/tomcat
    
    • 1
    • 2

    2.3.2、MAINTAINER

    镜像维护者的姓名和邮箱地址

    # 非必须
    MAINTAINER NaCl @163.com
    
    • 1
    • 2

    2.3.3、RUN

    容器构建时需要运行的命令。 RUN是在docker build时运行
    有两种格式:
    shell格式

    # 等同于在终端操作的shell命令
    # 格式:RUN <命令行命令>
    RUN yum -y install vim
    
    • 1
    • 2
    • 3

    exec格式

    # 格式:RUN ["可执行文件" , "参数1", "参数2"]
    RUN ["./test.php", "dev", "offline"]  # 等价于 RUN ./test.php dev offline
    
    • 1
    • 2

    2.3.4、EXPOSE

    当前容器对外暴露出的端口。

    # EXPOSE 要暴露的端口
    # EXPOSE [/
    EXPOSE 3306 33060
    
    • 1
    • 2
    • 3

    2.3.5、WORKDIR

    指定在创建容器后, 终端默认登录进来的工作目录。

    ENV CATALINA_HOME /usr/local/tomcat
    WORKDIR $CATALINA_HOME
    
    • 1
    • 2

    2.3.6、USER

    指定该镜像以什么样的用户去执行,如果不指定,默认是root。(一般不修改该配置)

    # USER [:]
    USER patrick
    
    • 1
    • 2

    2.3.7、ENV

    用来在构建镜像过程中设置环境变量。

    这个环境变量可以在后续的任何RUN指令或其他指令中使用

    # 格式 ENV 环境变量名 环境变量值
    # 或者 ENV 环境变量名=值
    ENV MY_PATH /usr/mytest
    
    # 使用环境变量
    WORKDIR $MY_PATH
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2.3.8、VOLUME

    容器数据卷,用于数据保存和持久化工作。类似于 docker run 的-v参数。

    # VOLUME 挂载点
    # 挂载点可以是一个路径,也可以是数组(数组中的每一项必须用双引号)
    VOLUME /var/lib/mysql
    
    • 1
    • 2
    • 3

    2.3.9、ADD

    将宿主机目录下(或远程文件)的文件拷贝进镜像,且会自动处理URL和解压tar压缩包。

    2.3.10、COPY

    类似ADD,拷贝文件和目录到镜像中。

    将从构建上下文目录中<源路径>的文件目录复制到新的一层镜像内的<目标路径>位置。

    COPY src dest
    COPY ["src", "dest"]
    # :源文件或者源目录
    # :容器内的指定路径,该路径不用事先建好。如果不存在会自动创建
    
    • 1
    • 2
    • 3
    • 4

    2.3.11、CMD

    指定容器启动后要干的事情。
    有两种格式:
    shell格式:

    # CMD <命令>
    CMD echo "hello world"
    
    • 1
    • 2

    exec格式

    # CMD ["可执行文件", "参数1", "参数2" ...]
    CMD ["catalina.sh", "run"]
    # CMD ["参数1", "参数2" ....],与ENTRYPOINT指令配合使用
    
    • 1
    • 2
    • 3

    Dockerfile中如果出现多个CMD指令,只有最后一个生效。CMD会被docker run之后的参数替换。
    CMD是在docker run时运行,而 RUN是在docker build时运行。

    2.3.12、ENTRYPOINT

    用来指定一个容器启动时要运行的命令。

    类似于CMD命令,但是ENTRYPOINT不会被docker run后面的命令覆盖,这些命令参数会被当做参数送给ENTRYPOINT指令指定的程序。

    ENTRYPOINT可以和CMD一起用,一般是可变参数才会使用CMD,这里的CMD等于是在给ENTRYPOINT传参。

    当指定了ENTRYPOINT后,CMD的含义就发生了变化,不再是直接运行期命令,而是将CMD的内容作为参数传递给ENTRYPOINT指令,它们两个组合会变成 “”。

    FROM nginx
    
    ENTRYPOINT ["nginx", "-c"]  # 定参
    CMD ["/etc/nginx/nginx.conf"] # 变参
    
    • 1
    • 2
    • 3
    • 4

    对于此Dockerfile,构建成镜像 nginx:test后,如果执行;

    • docker run nginx test,则容器启动后,会执行 nginx -c /etc/nginx/nginx.conf
    • docker run nginx:test /app/nginx/new.conf,则容器启动后,会执行 nginx -c /app/nginx/new.conf

    2.4、构建镜像

    2.4.1、eg:CentOS+JDK8

    编写DockerFile文件

    FROM centos:7 #安装CentOS7
    MAINTAINER NaCl<> #作者+邮箱
     
    ENV MYPATH /usr/local #启动docker后命令行在/usr/local
    WORKDIR $MYPATH
     
    RUN yum -y install vim          #安装vim编辑器
    
    RUN yum -y install net-tools    #安装ifconfig命令查看网络IP
    
    RUN yum -y install glibc.i686   #安装lib库
    
    RUN mkdir /usr/local/java       #在docker里创建安装java的文件路径
    
    #ADD 是相对路径jar,把jdk-8u341-linux-x64.tar.gz添加到容器中,安装包必须要和Dockerfile文件在同一位置
    ADD jdk-8u341-linux-x64.tar.gz /usr/local/java/
    
    #配置java环境变量
    ENV JAVA_HOME /usr/local/java/jdk1.8.0_341
    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 echo "success--------------ok"
    CMD /bin/bash
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    进入到DockerFile文件路径下进行构建镜像(带一个.)
    docker build -t mycentos:1.0.0 .

    2.5、虚悬镜像

    虚悬镜像:仓库名、标签名都是 的镜像,称为 dangling images(虚悬镜像)。

    在构建或者删除镜像时可能由于一些错误导致出现虚悬镜像

    列出docker中的虚悬镜像:

    docker image ls -f dangling=true
    
    • 1

    虚悬镜像一般是因为一些错误而出现的,没有存在价值,可以删除:\

    # 删除所有的虚悬镜像
    docker image prune
    
    • 1
    • 2
  • 相关阅读:
    C语言指针变量的引用距离
    【工具配置篇】VSCode 常用使用总结
    2022 icpc 沈阳站 L. Tavern Chess -dfs大模拟
    13.8 - 软件测试工作量及成本估算 3.9 - 软件测试成本估算示例
    2020 年 Java 面试题集锦(金九银十)
    卫星位姿的相关概念
    18. knife4j 接口文档
    bm19bm7
    记录--UNI-APP安卓本地打包详细教程(保姆级)
    vue中响应式的步骤
  • 原文地址:https://blog.csdn.net/lushixuan12345/article/details/127738399