一、前言
记录时间 [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
创建 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
脚本执行成功后,这 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
启动 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
# 以此类推
当然我们可以直接使用脚本,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
创建集群
进入服务容器 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
3. Redis 集群测试
连接集群
集群创建完毕后,我们来连接集群。
# -c 以集群方式,否则是单机模式
redis-cli -c
进入集群查看:
# 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
查看 node 节点:
127.0.0.1:6379> cluster nodes
如图,在 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
然后,我们模拟 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"
再次查看 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>
设置远程仓库,用阿里云镜像:
<mirror>
<id>aliyunmaven</id>
<mirrorOf>*</mirrorOf>
<name>Aliyun Maven Mirror</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
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";
}
}
IDEA 测试运行
启动项目,默认的端口是 8080,浏览器尝试访问一下:会返回 hello 字符串。
http://localhost:8080/hello
通过 Maven 打包应用
打开右侧的 Maven 窗口,双击 package 打包。
看到 BUILD SUCCESS 才算打包成功。jar 包位于 target 目录下。
CMD 测试运行
在本机命令行中测试一下 jar 包是否可用:
java -jar demo-0.0.1-SNAPSHOT.jar
3. 编写 Dockerfile 镜像
在 demo 中创建 Dockerfile 文件:
FROM java:8
COPY *.jar /app.jar
CMD ["--server.port=8080"]
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app.jar"]
把 Dockerfile 和 jar 包上传到 Liunx 中:通过 FinalShell 上传。
进入 Dockerfile 所在目录,构建 spring-boot 镜像
docker build -t spring-boot .
4. 发布运行
通过刚刚构建的 spring-boot 镜像,我们将微服务发布运行。
运行一个 spring-boot-web 容器,随机指定宿主机端口映射:
docker run -d -P --name spring-boot-web spring-boot
# 查看容器端口信息 port 32778->8080/tcp
docker ps
宿主机自测:访问成功,项目发布成功。
外网测试请打开防火墙。
[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
当我们使用 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/