相关系列文章:
1、Docker+Harbor私有仓库快速搭建
2、Docker+Jenkins+Harbor
Ip | 部署内容 | 说明 |
---|---|---|
192.168.88.7 | Docker、Mysql、redis、nacos | node1 |
192.168.88.8 | Docker、Mysql、redis、nacos | node2 |
192.168.88.9 | Docker、redis、nacos、nginx | node3 |
各个服务器都需要执行,配置完重启docker:service docker restart
2377:用于集群管理通信的TCP端口
4789:用于容器覆盖网络
7946:用于容器网络发现
firewall-cmd --zone=public --add-port=2377/tcp --permanent
firewall-cmd --zone=public --add-port=4789/tcp --permanent
firewall-cmd --zone=public --add-port=4789/udp --permanent
firewall-cmd --zone=public --add-port=7946/tcp --permanent
firewall-cmd --zone=public --add-port=7946/udp --permanent
firewall-cmd --reload
# 查看防火墙状态
systemctl status firewalld
# 启动
systemctl start firewalld
# 停止
systemctl stop firewalld
# 开机自启
systemctl enable firewalld
# node1主节点执行命令,将运行的结果用于node2服务器执行
docker swarm init
其他:
# 查询swarm集群节点,主节点才可运行
docker node ls
# 解散swarm集群
docker swarm leave -f
如果要删除一个节点,执行命令为 :docker node rm -f [节点的ID]
如果要解散 swarm 集群 先再 【manager节点】上删除 所有 【worker 节点】 再强制删除自己,执行:docker swarm leave -f
最后,还需要在各个【worker 节点】主机上执行:docker swarm leave
# swarm_mysql为自定义名称
docker network create -d overlay --attachable swarm_mysql
其他:
# 查看虚拟网络:
docker network inspect swarm_mysql
# 所有虚拟网络:
docker network ls
# 删除虚拟网络:
docker network rm swarm_mysql
配置证书
官网
pxc8.0默认开启同步加密方式,需要每台服务器都配置一样证书才能通过认证。每台服务器都需要执行
# 创建目录
mkdir -p ~/pxc-docker/config
cd ~/pxc-docker/config
vim custom.cnf
custom.cnf文件:
[mysqld]
ssl-ca = /cert/ca.pem
ssl-cert = /cert/server-cert.pem
ssl-key = /cert/server-key.pem
[client]
ssl-ca = /cert/ca.pem
ssl-cert = /cert/client-cert.pem
ssl-key = /cert/client-key.pem
[sst]
encrypt = 4
ssl-ca = /cert/ca.pem
ssl-cert = /cert/server-cert.pem
ssl-key = /cert/server-key.pem
# 此目录用于生成自签名SSL证书
mkdir -m 777 -p ~/pxc-docker/cert
# 使用官方镜像生成证书到~/pxc-docker/cert目录
docker run --name pxc-cert --rm -v ~/pxc-docker/cert:/cert percona/percona-xtradb-cluster:8.0 mysql_ssl_rsa_setup -d /cert
# 镜像不存在则下载镜像,每台服务器都要执行
docker pull percona/percona-xtradb-cluster:8.0
# 重命名
docker tag percona/percona-xtradb-cluster:8.0 pxc
# 删除镜像
docker rmi percona/percona-xtradb-cluster:8.0
#node1执行
docker volume create pxc_node1
#node2执行
docker volume create pxc_node2
创建容器
node1服务器执行:
docker run -d \
--net=swarm_mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
-e CLUSTER_NAME=pxc-cluster \
--name=pxc_node1 \
-v pxc_node1:/var/lib/mysql \
-v ~/pxc-docker/cert:/cert \
-v ~/pxc-docker/config:/etc/percona-xtradb-cluster.conf.d \
-p 3306:3306 \
--privileged \
pxc
CLUSTER_NAME: pxc集群名称,每个节点的名称要一样
name: 容器名称
net:加入到虚拟网络
MYSQL_ROOT_PASSWORD: mysql的root密码
docker run -d \
--net=swarm_mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
-e CLUSTER_NAME=pxc-cluster \
-e CLUSTER_JOIN=pxc_node1 \
--name=pxc_node2 \
-v pxc_node2:/var/lib/mysql \
-v ~/pxc-docker/cert:/cert \
-v ~/pxc-docker/config:/etc/percona-xtradb-cluster.conf.d \
-p 3306:3306\
--privileged \
pxc
-e CLUSTER_NAME=pxc-cluster 表示加入上面的集群
-e CLUSTER_JOIN=pxc_node1 表示加入node1节点
ps:
1、如果pxc_node2节点启动失败,可以尝试把node1服务器上面命令生成的证书重新拷贝到node2服务器上,然后重启docker,重启容器:docker restart pxc_node2
2、可以使用命令查询日志:docker logs pxc_node2
3、如果模拟节点宕机后重启失败,可以检查一下防火墙相关端口是否开放,节点是否加入swarm集群
4、因为我这里集群只有两台机子,当node1节点模拟宕机后再重新启动后,两个服务器的mysql数据库数据是不同步,只有我重新删除node1、node2的pxc_node1、pxc_node2容器后,重新运行启动容器才同步数据,网上其他文章说node1以节点方式加入node2集群即可正常同步数据,这一点未验证,需要的自行验证,需要明确更多集群的数据同步情况的自行测试。一般建议集群数量>=3,操作步骤类似。
5、实践测试可以参考:https://www.yuque.com/liweiming/linux/fcw6w8#9a96ee84
6、非正常关闭,node1不是最后一个离开节点可以修改挂载卷下面的grastate.dat文件中的safe_to_bootstrap修改为1后保存,然后重启
参考:
https://blog.csdn.net/gy_cjz/article/details/125790214
https://blog.csdn.net/weixin_45821811/article/details/119421774
Ip | 端口 | 说明 |
---|---|---|
192.168.88.7 | 6381、6382 | node1 |
192.168.88.8 | 6383、6384 | node2 |
192.168.88.9 | 6385、6386 | node3 |
node1服务器redis-cluster.tmpl
#端口号
port ${PORT}
#设置客户端连接后进行任何其他指定前需要使用的密码
requirepass 123456
# 当master服务设置了密码保护时(用requirepass制定的密码)
# slave服务连接master的密码
masterauth 123456
#daemonize no 将daemonize yes注释起来或者 daemonize no设置,因为该配置和docker run中-d参数冲突,会导致容器一直启动失败
daemonize no
# 任何主机都可以连接到redis
bind 0.0.0.0
#是否开启保护模式,默认开启。要是配置里没有指定bind和密码。开启该参数后,redis只会本地进行访问,拒绝外部访问。
protected-mode no
# 默认情况下,redis会在后台异步的把数据库镜像备份到磁盘,但是该备份是非常耗时的,而且备份也不能很频繁,如果发生诸如拉闸限电、拔插头等状况,那么将造成比较大范围的数据丢失。
# 所以redis提供了另外一种更加高效的数据库备份及灾难恢复方式。
# 开启append only模式之后,redis会把所接收到的每一次写操作请求都追加到appendonly.aof文件中,当redis重新启动时,会从该文件恢复出之前的状态。
# 但是这样会造成appendonly.aof文件过大,所以redis还支持了BGREWRITEAOF指令,对appendonly.aof 进行重新整理。
# 你可以同时开启asynchronous dumps 和 AOF
appendonly yes
#集群开关,默认是不开启集群模式。
cluster-enabled yes
#集群配置文件的名称,每个节点都有一个集群相关的配置文件,持久化保存集群的信息。这个文件并不需要手动配置,这个配置文件有Redis生成并更新,每个Redis集群节点需要一个单独的配置文件,请确保与实例运行的系统中配置文件名称不冲突
cluster-config-file nodes.conf
#节点互连超时的阀值。集群节点超时毫秒数
cluster-node-timeout 15000
#在某些部署中,Redis群集节点地址发现失败,因为地址是NAT ted的,或者因为端口是转发的(典型情况是Docker和其他容器
#为了使Redis集群在这样的环境中工作,静态每个节点都知道需要其公共地址的配置。这个
cluster-announce-ip 192.168.88.7
#客户端端口
cluster-announce-port ${PORT}
#总线端口 为 port+10000
cluster-announce-bus-port 1${PORT}
node2服务器redis-cluster.tmpl
#端口号
port ${PORT}
#设置客户端连接后进行任何其他指定前需要使用的密码
requirepass 123456
# 当master服务设置了密码保护时(用requirepass制定的密码)
# slav服务连接master的密码
masterauth 123456
#daemonize no 将daemonize yes注释起来或者 daemonize no设置,因为该配置和docker run中-d参数冲突,会导致容器一直启动失败
daemonize no
# 任何主机都可以连接到redis
bind 0.0.0.0
#是否开启保护模式,默认开启。要是配置里没有指定bind和密码。开启该参数后,redis只会本地进行访问,拒绝外部访问。
protected-mode no
# 默认情况下,redis会在后台异步的把数据库镜像备份到磁盘,但是该备份是非常耗时的,而且备份也不能很频繁,如果发生诸如拉闸限电、拔插头等状况,那么将造成比较大范围的数据丢失。
# 所以redis提供了另外一种更加高效的数据库备份及灾难恢复方式。
# 开启append only模式之后,redis会把所接收到的每一次写操作请求都追加到appendonly.aof文件中,当redis重新启动时,会从该文件恢复出之前的状态。
# 但是这样会造成appendonly.aof文件过大,所以redis还支持了BGREWRITEAOF指令,对appendonly.aof 进行重新整理。
# 你可以同时开启asynchronous dumps 和 AOF
appendonly yes
#集群开关,默认是不开启集群模式。
cluster-enabled yes
#集群配置文件的名称,每个节点都有一个集群相关的配置文件,持久化保存集群的信息。这个文件并不需要手动配置,这个配置文件有Redis生成并更新,每个Redis集群节点需要一个单独的配置文件,请确保与实例运行的系统中配置文件名称不冲突
cluster-config-file nodes.conf
#节点互连超时的阀值。集群节点超时毫秒数
cluster-node-timeout 15000
#在某些部署中,Redis群集节点地址发现失败,因为地址是NAT ted的,或者因为端口是转发的(典型情况是Docker和其他容器
#为了使Redis集群在这样的环境中工作,静态每个节点都知道需要其公共地址的配置。这个
cluster-announce-ip 192.168.88.8
#客户端端口
cluster-announce-port ${PORT}
#总线端口 为 port+10000
cluster-announce-bus-port 1${PORT}
node3服务器redis-cluster.tmpl
#端口号
port ${PORT}
#设置客户端连接后进行任何其他指定前需要使用的密码
requirepass 123456
# 当master服务设置了密码保护时(用requirepass制定的密码)
# slav服务连接master的密码
#
masterauth 123456
#daemonize no 将daemonize yes注释起来或者 daemonize no设置,因为该配置和docker run中-d参数冲突,会导致容器一直启动失败
daemonize no
# 任何主机都可以连接到redis
bind 0.0.0.0
#是否开启保护模式,默认开启。要是配置里没有指定bind和密码。开启该参数后,redis只会本地进行访问,拒绝外部访问。
protected-mode no
# 默认情况下,redis会在后台异步的把数据库镜像备份到磁盘,但是该备份是非常耗时的,而且备份也不能很频繁,如果发生诸如拉闸限电、拔插头等状况,那么将造成比较大范围的数据丢失。
# 所以redis提供了另外一种更加高效的数据库备份及灾难恢复方式。
# 开启append only模式之后,redis会把所接收到的每一次写操作请求都追加到appendonly.aof文件中,当redis重新启动时,会从该文件恢复出之前的状态。
# 但是这样会造成appendonly.aof文件过大,所以redis还支持了BGREWRITEAOF指令,对appendonly.aof 进行重新整理。
# 你可以同时开启asynchronous dumps 和 AOF
appendonly yes
#集群开关,默认是不开启集群模式。
cluster-enabled yes
#集群配置文件的名称,每个节点都有一个集群相关的配置文件,持久化保存集群的信息。这个文件并不需要手动配置,这个配置文件有Redis生成并更新,每个Redis集群节点需要一个单独的配置文件,请确保与实例运行的系统中配置文件名称不冲突
cluster-config-file nodes.conf
#节点互连超时的阀值。集群节点超时毫秒数
cluster-node-timeout 15000
#在某些部署中,Redis群集节点地址发现失败,因为地址是NAT ted的,或者因为端口是转发的(典型情况是Docker和其他容器
#为了使Redis集群在这样的环境中工作,静态每个节点都知道需要其公共地址的配置。这个
cluster-announce-ip 192.168.88.9
#客户端端口
cluster-announce-port ${PORT}
#总线端口 为 port+10000
cluster-announce-bus-port 1${PORT}
node1服务器mkdir.sh
for port in `seq 6381 6382`; do \
mkdir -p ${port}/conf \
PORT=${port} envsubst < redis-cluster.tmpl > ${port}/conf/redis.conf \
mkdir -p ${port}/data;\
done
node2服务器mkdir.sh
for port in `seq 6383 6384`; do \
mkdir -p ${port}/conf \
PORT=${port} envsubst < redis-cluster.tmpl > ${port}/conf/redis.conf \
mkdir -p ${port}/data;\
done
node3服务器mkdir.sh
for port in `seq 6385 6386`; do \
mkdir -p ${port}/conf \
PORT=${port} envsubst < redis-cluster.tmpl > ${port}/conf/redis.conf \
mkdir -p ${port}/data;\
done
node1服务器
docker run -d --name redis-6381 --net host --privileged=true \
-v /opt/redis-cluster/6381/conf/redis.conf:/etc/redis/redis.conf \
-v /opt/redis-cluster/6381/data:/data \
redis:6.0.8 redis-server /etc/redis/redis.conf
docker run -d --name redis-6382 --net host --privileged=true \
-v /opt/redis-cluster/6382/conf/redis.conf:/etc/redis/redis.conf \
-v /opt/redis-cluster/6382/data:/data \
redis:6.0.8 redis-server /etc/redis/redis.conf
node2服务器
docker run -d --name redis-6383 --net host --privileged=true \
-v /opt/redis-cluster/6383/conf/redis.conf:/etc/redis/redis.conf \
-v /opt/redis-cluster/6383/data:/data \
redis:6.0.8 redis-server /etc/redis/redis.conf
docker run -d --name redis-6384 --net host --privileged=true \
-v /opt/redis-cluster/6384/conf/redis.conf:/etc/redis/redis.conf \
-v /opt/redis-cluster/6384/data:/data \
redis:6.0.8 redis-server /etc/redis/redis.conf
node3服务器
docker run -d --name redis-6385 --net host --privileged=true \
-v /opt/redis-cluster/6385/conf/redis.conf:/etc/redis/redis.conf \
-v /opt/redis-cluster/6385/data:/data \
redis:6.0.8 redis-server /etc/redis/redis.conf
docker run -d --name redis-6386 --net host --privileged=true \
-v /opt/redis-cluster/6386/conf/redis.conf:/etc/redis/redis.conf \
-v /opt/redis-cluster/6386/data:/data \
redis:6.0.8 redis-server /etc/redis/redis.conf
随便进入一个容器并为6台机器构建集群关系,–cluster-replicas 1 表示为每个master创建一个slave节点
docker exec -it redis-6381 bash
redis-cli -a 123456 --cluster create 192.168.88.7:6381 192.168.88.7:6382 192.168.88.8:6383 192.168.88.8:6384 192.168.88.9:6385 192.168.88.9:6386 --cluster-replicas 1
如果连接不上其他服务器的redis或者长时间处于连接状态,可以检查一下以下端口是否开放
# node1
firewall-cmd --zone=public --add-port=6381/tcp --permanent
firewall-cmd --zone=public --add-port=6382/tcp --permanent
firewall-cmd --zone=public --add-port=16381/tcp --permanent
firewall-cmd --zone=public --add-port=16382/tcp --permanent
firewall-cmd --reload
# node2
firewall-cmd --zone=public --add-port=6383/tcp --permanent
firewall-cmd --zone=public --add-port=6384/tcp --permanent
firewall-cmd --zone=public --add-port=16383/tcp --permanent
firewall-cmd --zone=public --add-port=16384/tcp --permanent
firewall-cmd --reload
# node3
firewall-cmd --zone=public --add-port=6385/tcp --permanent
firewall-cmd --zone=public --add-port=6386/tcp --permanent
firewall-cmd --zone=public --add-port=16385/tcp --permanent
firewall-cmd --zone=public --add-port=16386/tcp --permanent
firewall-cmd --reload
# 查看防火墙开放端口信息
firewall-cmd --list-all
# 查看防火墙端口是否开放
firewall-cmd --query-port=8080/tcp
其他错误:[ERR] Node 192.168.88.7:6381 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.
解决:删除每个服务器每个节点下面data文件下的nodes.conf、appendonly.aof文件,重启节点
# 连接redis查看集群信息 -c表示使用集群模式
redis-cli -c -h 192.168.88.7 -p 6381
auth 123456
cluster info
# 查询集群节点信息
cluster nodes
1. 编辑docker.service
vim /usr/lib/systemd/system/docker.service
找到 ExecStart字段修改如下
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock
2. 重启docker重新读取配置文件,重新启动docker服务
systemctl daemon-reload
systemctl restart docker
3.开放2375端口
firewall-cmd --zone=public --add-port=2375/tcp --permanent
firewall-cmd --reload
mkdir -p /home/nginx/www /home/nginx/logs /home/nginx/conf
vim /home/nginx/conf/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
server{
listen 80;
server_name localhost;
charset utf-8;
location / {
root /usr/share/nginx/html/;
try_files $uri $uri/ =404;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
#部署的服务器需要安装docker compose
安装可参考:Docker+Harbor私有仓库快速搭建
vim /home/nginx/docker-compose.yml
version: '3.3'
services:
nginx:
image: nginx
restart: always
hostname: nginx
container_name: nginx
privileged: true
ports:
- 80:80
volumes:
- ./conf/nginx.conf:/etc/nginx/nginx.conf
- ./www/:/usr/share/nginx/html/
- ./logs/:/var/log/nginx/
docker compose up -d
vim /home/nginx/www/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>nginx</title>
</head>
<body>
<h1>首页</h1>
</body>
</html>
官网:https://nacos.io/zh-cn/docs/v2/guide/admin/cluster-mode-quick-start.html
# node1、node2、node3
firewall-cmd --zone=public --add-port=8848/tcp --permanent
firewall-cmd --reload
node1服务器执行
# --配置主机ip和端口
# --配置数据库主机、用户名、密码、数据库名
# --net=host 主机模式
docker run -d \
-e PREFER_HOST_MODE=hostname \
-e MODE=cluster \
-e NACOS_APPLICATION_PORT=8848 \
-e NACOS_SERVERS="192.168.88.7:8848 192.168.88.8:8848 192.168.88.9:8848" \
-e SPRING_DATASOURCE_PLATFORM=mysql \
-e MYSQL_SERVICE_HOST=192.168.88.7 \
-e MYSQL_SERVICE_PORT=3306 \
-e MYSQL_SERVICE_USER=root \
-e MYSQL_SERVICE_PASSWORD=123456 \
-e MYSQL_SERVICE_DB_NAME=nacos_config \
-e NACOS_SERVER_IP=192.168.88.7 \
-p 8848:8848 \
--restart=always \
--net=host \
--name nacos1 \
nacos/nacos-server:v2.1.1
node2服务器执行
docker run -d \
-e PREFER_HOST_MODE=hostname \
-e MODE=cluster \
-e NACOS_APPLICATION_PORT=8848 \
-e NACOS_SERVERS="192.168.88.7:8848 192.168.88.8:8848 192.168.88.9:8848" \
-e SPRING_DATASOURCE_PLATFORM=mysql \
-e MYSQL_SERVICE_HOST=192.168.88.7 \
-e MYSQL_SERVICE_PORT=3306 \
-e MYSQL_SERVICE_USER=root \
-e MYSQL_SERVICE_PASSWORD=123456 \
-e MYSQL_SERVICE_DB_NAME=nacos_config \
-e NACOS_SERVER_IP=192.168.88.8 \
-p 8848:8848 \
--restart=always \
--net=host \
--name nacos2 \
nacos/nacos-server:v2.1.1
node3服务器执行
docker run -d \
-e PREFER_HOST_MODE=hostname \
-e MODE=cluster \
-e NACOS_APPLICATION_PORT=8848 \
-e NACOS_SERVERS="192.168.88.7:8848 192.168.88.8:8848 192.168.88.9:8848" \
-e SPRING_DATASOURCE_PLATFORM=mysql \
-e MYSQL_SERVICE_HOST=192.168.88.7 \
-e MYSQL_SERVICE_PORT=3306 \
-e MYSQL_SERVICE_USER=root \
-e MYSQL_SERVICE_PASSWORD=123456 \
-e MYSQL_SERVICE_DB_NAME=nacos_config \
-e NACOS_SERVER_IP=192.168.88.9 \
-p 8848:8848 \
--restart=always \
--net=host \
--name nacos3 \
nacos/nacos-server:v2.1.1