• Docker 学习笔记(十):Centos7 中 Docker 部署 Redis 集群,打包 SpringBoot 微服务


    一、前言

    记录时间 [2024-4-17]

    系列文章简摘:
    Docker 学习笔记(六):挑战容器数据卷技术一文通,实战多个 MySQL 数据同步,能懂会用,初学必备
    Docker 学习笔记(七):介绍 Dockerfile 相关知识,使用 Dockerfile 构建自己的 centos 镜像
    Docker 学习笔记(九):Docker 网络原理,理解 docker0,虚拟网卡,容器互联,以及跨网络连通

    更多 Docker 相关文章请参考上面专栏哦,入门篇 1~5,精髓篇 6~10,从零基础开始,一步一步构建 Docker 知识。

    本文讲述了如何在 Centos7 中使用 Docker 部署 Redis 集群,以及如何把 SpringBoot 微服务打包成 Docker 镜像发布。通过动手实践,加深对 Docker 网络的理解。


    二、部署 Redis 集群

    1. Redis 集群概述

    在 Docker 中部署 Redis 集群,此集群具备 分片 + 高可用 + 负载均衡 的特性。

    如图所示,在 Docker 中启动了 6 个 Redis 服务,其中 3 个为主机,另外 3 个为从机,每一个主机都有自己的从机。平常的时候,从机对主机的数据进行备份;当主机出现故障,从机顶替主机提供服务,完成故障转移。

    在这里插入图片描述


    2. Redis 集群部署

    创建网卡

    为 Redis 创建自定义网卡,把 172.38.0.0/16 分配给它。

    # 创建网卡
    docker network create redis --subnet 172.38.0.0/16
    
    # 查看所有网卡
    docker network ls
    
    # 查看 redis 网卡
    docker network inspect redis
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    创建 redis 配置文件

    部署这个 Redis 集群需要启动 6 个 Docker 容器,并且每个容器都要进行 Redis 服务配置。

    同样的东西写 6 份,首先想到循环。

    编写一个 Shell 脚本,通过脚本来创建这 6 份 redis 配置文件。

    # for 循环 6 次
    for port in $(seq 1 6); \
    do \
    
    # 创建 redis 配置文件
    mkdir -p /mydata/redis/node-${port}/conf
    touch /mydata/redis/node-${port}/conf/redis.conf
    
    # 编写 redis.conf 配置
    cat << EOF >/mydata/redis/node-${port}/conf/redis.conf
    port 6379									# 容器端口 6379
    bind 0.0.0.0
    cluster-enabled yes							# 开启集群
    cluster-config-file nodes.conf
    cluster-node-timeout 5000
    cluster-announce-ip 172.38.0.1${port}		# 连接集群 ip
    cluster-announce-port 6379
    cluster-announce-bus-port 16379
    appendonly yes
    EOF
    
    done
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    脚本执行成功后,这 6 份 redis 配置文件便全部创建完毕了。

    文件保存在 /mydata/redis 目录下,查看发现,6 个 node 下面都有 redis.conf 配置文件。检查一下吧:

    [root@localhost ~]# cd /mydata/redis
    
    # 6 个 node
    [root@localhost redis]# ls
    node-1  node-2  node-3  node-4  node-5  node-6
    
    [root@localhost redis]# cd node-1
    [root@localhost node-1]# ls
    conf
    [root@localhost node-1]# cd conf
    [root@localhost conf]# ls
    redis.conf
    
    # 这段便是使用脚本写入的配置
    [root@localhost conf]# cat redis.conf
    port 6379
    bind 0.0.0.0
    cluster-enabled yes
    cluster-config-file nodes.conf
    cluster-node-timeout 5000
    cluster-announce-ip 172.38.0.11
    cluster-announce-port 6379
    cluster-announce-bus-port 16379
    appendonly yes
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    启动 6 个 redis 服务

    以 redis-1 为例,服务启动时完成了如下配置:

    • -p 宿主机端口:容器端口:端口映射
    • --name:服务容器的命名
    • -v 宿主机路径:容器内路径:数据卷挂载
    • --net:设置服务使用的网络
    • -d:后台运行
    • --ip:设置服务 IP 地址
    • redis-server:通过配置文件启动 redis 服务
    # 一共启动 6 个 redis 服务
    # 第一个 redis-1,把刚刚创建的 node-1 配置文件挂载到容器里
    docker run -p 6371:6379 -p 16371:16379 --name redis-1 \
    -v /mydata/redis/node-1/data:/data \
    -v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \
    -d --net redis --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
    
    # 第二个 redis-2,把刚刚创建的 node-2 配置文件挂载到容器里
    docker run -p 6372:6379 -p 16372:16379 --name redis-2 \
    -v /mydata/redis/node-2/data:/data \
    -v /mydata/redis/node-2/conf/redis.conf:/etc/redis/redis.conf \
    -d --net redis --ip 172.38.0.12 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
    
    # 以此类推
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    当然我们可以直接使用脚本,6 个容器会依次启动。

    查看刚刚启动的容器:启动成功。

    # 脚本启动 6 个容器,依次启动
    for port in $(seq 1 6); \
    do \
    docker run -p 637${port}:6379 -p 1637${port}:16379 --name redis-${port} \
    -v /mydata/redis/node-${port}/data:/data \
    -v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
    -d --net redis --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
    done
    
    # 查看是否启动成功
    docker ps
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    创建集群

    进入服务容器 redis-1,在服务中创建集群,并设置集群分片。

    # 进入 redis-1
    docker exec -it redis-1 /bin/sh
    
    # 创建集群 通过集群方式连接 cluster-replicas 集群分片
    # 把 6 个服务容器的 ip 和 端口 都放进去
    redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1
    
    # 确定 yes
    # Can I set the above configuration? (type 'yes' to accept): yes
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    3. Redis 集群测试

    连接集群

    集群创建完毕后,我们来连接集群。

    # -c 以集群方式,否则是单机模式
    redis-cli -c
    
    • 1
    • 2

    进入集群查看:

    # cluster_size:3 当前集群数量为 3
    127.0.0.1:6379> 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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    查看 node 节点:

    127.0.0.1:6379> cluster nodes
    
    • 1

    如图,在 node 中能够清晰的观察到主机 master 和从机 slave 之间的关系。

    在这里插入图片描述


    测试集群

    使用 set a b,在集群中存放变量 a,a 的值为 “b”:

    可以发现,172.38.0.13:6379,也就是 redis-3 完成了这个 set 操作,变量 a 被存放在 redis-3 中。redis-4 是 redis-3 的从机,redis-4 中也保存了变量 a

    127.0.0.1:6379> set a b
    -> Redirected to slot [15495] located at 172.38.0.13:6379
    OK
    
    • 1
    • 2
    • 3

    然后,我们模拟 redis-3 出故障,把容器 redis-3 给停掉。

    看看能不能从集群中获取变量 a 的值:可以获取,并且是从 redis-4 中获取的。

    /data # redis-cli -c
    127.0.0.1:6379> get a
    -> Redirected to slot [15495] located at 172.38.0.14:6379
    "b"
    
    • 1
    • 2
    • 3
    • 4

    再次查看 node 节点:

    我们发现,redis-3 已经停掉了,此时 redis-4 代替它成为了 master 主机。完成了故障转移。

    在这里插入图片描述


    至此,我们使用 Docker 搭建 Redis 集群完成。


    三、部署 SpringBoot 微服务

    接下来我们尝试将 SpringBoot 微服务打包成 Docker 镜像

    1. 构建 SpringBoot 项目

    IDEA 创建项目

    使用 IDEA 创建一个 SpringBoot 项目。

    具体步骤:打开 IDEA ==> New Project ==> 选择 Spring Initializr ==> 勾选 Spring Web 依赖

    在这里插入图片描述


    设置 JDK 和 Language

    注意:3.0 以上版本 SpringBoot 需要 JDK 版本 17 以上,项目中每个部分的 Language 都要同 JDK 版本保持一致。

    File ==> Project Structure ==> Project / Modules

    在这里插入图片描述


    在这里插入图片描述


    配置 Maven

    Maven 如果不想配置的话,就用 IDEA 内置的 Bundle 好了。

    具体的配置步骤是:

    • 下载 Maven,下载地址
    • 本地 + 远程仓库配置
    • IDEA 配置 Maven 路径

    找到 conf 下的 settings.xml 文件,设置本地仓库:

    <localRepository>这里写本地 maven 仓库路径localRepository>
    
    • 1

    设置远程仓库,用阿里云镜像:

    <mirror>
        <id>aliyunmavenid>
        <mirrorOf>*mirrorOf>
        <name>Aliyun Maven Mirrorname>
        <url>https://maven.aliyun.com/repository/publicurl>
    mirror>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    IDEA 配置 Maven 路径:File ==> Settings ==> Build

    在这里插入图片描述


    2. 打包应用

    写一个微服务

    可以通过 Web 接口访问我们的微服务。

    在 demo 下创建 package controller,在 controller 下写一个 java 文件 HelloController

    @RestController
    public class HelloController {
    
        @RequestMapping("/hello")
        public String hello() {
            return "hello,yuanyuan";
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    IDEA 测试运行

    启动项目,默认的端口是 8080,浏览器尝试访问一下:会返回 hello 字符串。

    http://localhost:8080/hello
    
    • 1

    通过 Maven 打包应用

    打开右侧的 Maven 窗口,双击 package 打包。

    看到 BUILD SUCCESS 才算打包成功。jar 包位于 target 目录下。

    在这里插入图片描述

    CMD 测试运行

    在本机命令行中测试一下 jar 包是否可用:

    java -jar demo-0.0.1-SNAPSHOT.jar
    
    • 1

    3. 编写 Dockerfile 镜像

    在 demo 中创建 Dockerfile 文件:

    FROM java:8
    
    COPY *.jar /app.jar
    
    CMD ["--server.port=8080"]
    
    EXPOSE 8080
    
    ENTRYPOINT ["java", "-jar", "/app.jar"]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    把 Dockerfile 和 jar 包上传到 Liunx 中:通过 FinalShell 上传。

    进入 Dockerfile 所在目录,构建 spring-boot 镜像

    docker build -t spring-boot .
    
    • 1

    4. 发布运行

    通过刚刚构建的 spring-boot 镜像,我们将微服务发布运行。

    运行一个 spring-boot-web 容器,随机指定宿主机端口映射:

    docker run -d -P --name spring-boot-web spring-boot
    
    # 查看容器端口信息  port 32778->8080/tcp
    docker ps
    
    • 1
    • 2
    • 3
    • 4

    宿主机自测:访问成功,项目发布成功。

    外网测试请打开防火墙。

    [root@localhost ~]# curl localhost:32778
    {"timestamp":"2024-04-17T04:27:03.151+00:00","status":404,"error":"Not Found","path":"/"} 
    [root@localhost ~]# curl localhost:32778/hello
    hello,yuanyuan
    
    • 1
    • 2
    • 3
    • 4

    当我们使用 Docker 之后,通过镜像就可以交付开发项目了。


    四、总结

    本文讲述了如何在 Centos7 中使用 Docker 部署 Redis 集群,以及如何把 SpringBoot 微服务打包成 Docker 镜像发布。通过动手实践,加深对 Docker 网络的理解。


    一些参考资料

    狂神说系列 Docker 教程:https://www.bilibili.com/video/BV1og4y1q7M4/
    Docker 官方文档:https://docs.docker.com/engine/install/centos/
    Docker 远程仓库:https://hub.docker.com/
    FinalShell 下载:http://www.hostbuf.com/t/988.html
    Maven 仓库地址:https://mvnrepository.com/

  • 相关阅读:
    正则表达式学习笔记
    SP297 AGGRCOW - Aggressive cows
    企业面临的网络安全风险及应对策略
    Karmada 多云容器编排引擎支持多调度组,助力成本优化
    基于词袋和SVM的图片分类(计算机视觉课程设计)
    java计算机毕业设计springboot+vue废弃资源回收系统
    第一届电子纸产业创新应用论坛
    Go 语言搭建个人博客(qiucode.cn 重构篇 一)
    【图像检测】基于计算机视觉实现椭圆检测附matlab代码
    FastDFS模拟场景
  • 原文地址:https://blog.csdn.net/Sareur_1879/article/details/137879429