title: 基于Docker的中间件部署安装手册
date: 2023-01-03 11:34:29
tags:
本文通篇以流水账的形式叙述,主要是用来记录基于docker
环境离线安装中间件的部署过程(命令行极速版,没有操作详解)。
Ubuntu
搭建,其他操作系统可能不适用
docker
按照操作系统要求,选取合适的docker
版本,下载地址:docker下载地址
将下载好的软件包上传至服务器,并解压至/usr/local
目录
tar -zxvf docker-20.10.22.tgz -C /usr/local && mv /usr/local/docker/* /usr/bin
rm -rf /usr/local/docker
进入/etc/systemd/system
目录,并创建docker.service
文件
touch /etc/systemd/system/docker.service
编辑docker.service
服务文件(关注ExecStart
启动命令)
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target
[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
# docker默认数据目录为/var/lib/docker,使用df -hl /var/lib/docker查看磁盘空间是否足够,否则使用--graph重新指定docker的
# 数据目录,若内网搭建镜像仓库,可使用--insecure-registry=127.0.0.1(镜像仓库ip)指向自己的镜像仓库
ExecStart=/usr/bin/dockerd --selinux-enabled=false --graph=/home/docker
ExecReload=/bin/kill -s HUP $MAINPID
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
# Uncomment TasksMax if your systemd version supports it.
# Only systemd 226 and above support this version.
#TasksMax=infinity
TimeoutStartSec=0
# set delegate yes so that systemd does not reset the cgroups of docker containers
Delegate=yes
# kill only the docker process, not all processes in the cgroup
KillMode=process
# restart the docker process if it exits prematurely
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s
[Install]
WantedBy=multi-user.target
给docker.service
文件添加执行权限
chmod 755 /etc/systemd/system/docker.service
重新加载配置文件
systemctl daemon-reload
启动docker
systemctl start docker
设置开机启动
systemctl enable docker.service
查看docker状态
systemctl status docker.service
mysql
集群(一主二从)下载mysql
镜像上传至服务器,并解压镜像包
docker load -i mysql.tar
创建挂载目录
# 创建配置目录和数据目录
mkdir -p /home/mysql/conf /home/mysql/data
# 创建配置文件
touch /home/mysql/conf/my.cnf
编辑my.cnf
[mysqld]
# 设置server_id,集群中每个服务的server_id不能存在相同
server-id = 1
# 设置时区
default-time-zone = '+08:00'
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
# 容器数据目录
datadir = /var/lib/mysql
secure-file-priv= NULL
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# Custom config should go here
!includedir /etc/mysql/conf.d/
max_connections=1000
wait_timeout=28800
interactive_timeout=28800
## 开启binlog
log-bin=mysql-bin
## binlog缓存
binlog_cache_size=1M
## binlog格式(mixed、statement、row,默认格式是statement)
binlog_format=mixed
##设置字符编码为utf8mb4
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect='SET NAMES utf8mb4'
# 忽略大小写
lower_case_table_names=1
[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
# 设置server_id,注意要唯一
server-id=2
# 忽略大小写
lower_case_table_names=1
max_connections=1000
wait_timeout=28800
interactive_timeout=28800
default-time_zone = '+8:00'
# 开启binlog
log-bin=mysql-slave-bin
# relay_log配置中继日志
relay_log=edu-mysql-relay-bin
# 如果需要同步函数或者存储过程
log_bin_trust_function_creators=true
# binlog缓存
binlog_cache_size=1M
# binlog格式(mixed、statement、row,默认格式是statement)
binlog_format=mixed
#设置字符编码为utf8mb4
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect='SET NAMES utf8mb4'
slave_skip_errors=1062
[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
运行实例
主节点
docker run -itd -p 3306:3306 \
--name mysql-icp-master \
--restart=always \
-v /home/mysql/conf/my.cnf:/etc/mysql/my.cnf \
-v /home/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=sillybilly@2022 \
70325c69f1fe
从节点1
docker run -itd -p 3306:3306 \
--name mysql-icp-slave1 \
--restart=always \
-v /home/mysql/conf/my.cnf:/etc/mysql/my.cnf \
-v /home/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=sillybilly@2022 \
70325c69f1fe
从节点2
docker run -itd -p 3306:3306 \
--name mysql-icp-slave2 \
--restart=always \
-v /home/mysql/conf/my.cnf:/etc/mysql/my.cnf \
-v /home/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=sillybilly@2022 \
70325c69f1fe
主从同步配置
进入master节点容器,并执行mysql命令
# 进入mysql命令列界面
mysql -uroot -psillybilly@2022
# 查看主节点信息
SHOW MASTER STATUS;
执行结果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O0dTkdAW-1676527943448)(null)]
进入mysql
从节点,编辑同步配置
# 配置连接的参数
change master to master_host='10.10.33.102',master_user='root',master_password='sillybilly@2022',master_log_file='mysql-bin.000003',master_log_pos=62973466;
master_host
:主节点ip
master_user
:主节点登录用户名
master_password
:主节点mysql登录密码
master_log_file
:主节点日志文件,修改为master
节点执行SHOW MASTER STATUS
结果后的File
字段
master_log_pos
:二进制文件开始位置,修改为master
节点执行SHOW MASTER STATUS
结果后的Position
字段
# 停止连接,如果一次成功无需使用该命令
stop slave;
# 重置连接
reset slave;
# 启动同步
start slave;
# 查看从节点状态是否成功
show slave status;
# 观察两项都为Yes时代表成功。
# Slave_IO_Running: Yes
# Slave_SQL_Running: Yes
如果失败的话,需要执行stop slave
并检查主节点的账号、密码,地址,pos
等参数
minio
集群下载minio docker
镜像包,并解压镜像,这里不过多赘述
启动docker
实例
docker run -d \
-p 9000:9000 \
-p 19001:19001 \
--name minio-icp \
--restart=always \
-v /data/minio/data:/data \
-e "MINIO_ROOT_USER=sillybilly" \
-e "MINIO_ROOT_PASSWORD=sillybilly@2022" \
minio/minio server /data \
--console-address ":19001" \
--address ":9000"
MINIO_ROOT_USER
:用户名
MINIO_ROOT_PASSWORD
:密码
console-address
:web控制台端口,可不指定
address
:api访问端口
主机映射
# 57、58、59三台服务器添加主机映射
vim /etc/hosts
# 在文件末尾添加以下信息 (实际需改成自己的ip地址,填内网ip,不能填公网ip)
10.10.33.57 minio1
10.10.33.58 minio2
10.10.33.59 minio3
每个节点指定两个数据目录,例如/opt/data1
,/opt/data2
,最好是两块单独的磁盘
启动minio
实例
docker run -d --name minio-icp \
--restart=always \
--net=host \
-e "MINIO_ROOT_USER=sillybilly" \
-e "MINIO_ROOT_PASSWORD=sillybilly@2022" \
-v /opt/data1:/data1 \
-v /opt/data2:/data2 \
minio/minio server \
--address ":9000" \
--console-address ":19001" \
http://minio{1...3}/data{1...2}
访问10.10.33.57:19001
验证
elasticsearch
集群ip | hostname | default-role |
---|---|---|
10.10.33.57 | node1 | master |
10.10.33.58 | node2 | slave1 |
10.10.33.59 | node3 | slave2 |
elasticsearch8.x
需要jdk17
,因为我们大多数项目路使用jdk8
,所以本次搭建使用elasticsearch:7.17.8
添加主机映射
vim /etc/hosts
# 添加主机映射关系至文件末尾
10.10.33.57 node1
10.10.33.58 node2
10.10.33.59 node3
调整系统打开文件句柄数以及用户创建进程数
vi /etc/security/limits.conf
# 末尾添加
* soft nofile 65536
* hard nofile 131072
* soft nproc 2048
* hard nproc 4096
#增大文件句柄数
echo 'vm.max_map_count=262144' >>/etc/sysctl.conf
# 立即生效
sysctl -p
启动elasticsearch
容器,拷贝es
挂载目录
# 先简单起容器,方便从容器中把配置拷贝出来
docker run -d --name elasticsearch \
-p 9200:9200 \
-p 9300:9300 \
-e "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms256m -Xmx256m" \
elasticsearch:7.17.8
# 拷贝挂载目录
docker cp elasticsearch:/usr/share/elasticsearch/config /data1/elasticsearch
docker cp elasticsearch:/usr/share/elasticsearch/logs /data1/elasticsearch
docker cp elasticsearch:/usr/share/elasticsearch/data /data1/elasticsearch
docker cp elasticsearch:/usr/share/elasticsearch/plugins /data1/elasticsearch
elasticsearch.yml
配置
master
# 设置集群名称,集群内所有节点的名称必须一致。
cluster.name: icp-es-cluster
# 设置节点名称,集群内节点名称必须唯一。
node.name: node1
# 表示该节点会不会作为主节点,true表示会;false表示不会
node.master: true
# 当前节点是否用于存储数据,是:true、否:false
node.data: true
# 索引数据存放的位置
#path.data: /usr/share/elasticsearch/data
# 日志文件存放的位置
#path.logs: /usr/share/elasticsearch/logs
# 需求锁住物理内存,是:true、否:false
#bootstrap.memory_lock: true
# 监听地址,用于访问该es
network.host: 0.0.0.0
# es对外提供的http端口,默认 9200
http.port: 19200
# TCP的默认监听端口,默认 9300
transport.tcp.port: 19300
# 设置这个参数来保证集群中的节点可以知道其它N个有master资格的节点。默认为1,对于大的集群来说,可以设置大一点的值(2-4)
discovery.zen.minimum_master_nodes: 1
# es7.x 之后新增的配置,写入候选主节点的设备地址,在开启服务后可以被选为主节点
discovery.seed_hosts: ["10.10.33.57:19300", "10.10.33.58:19300","10.10.33.59:19300"]
discovery.zen.fd.ping_timeout: 1m
discovery.zen.fd.ping_retries: 5
# es7.x 之后新增的配置,初始化一个新的集群时需要此配置来选举master
cluster.initial_master_nodes: ["node1"]
# 是否支持跨域,是:true,在使用head插件时需要此配置
http.cors.enabled: true
# “*” 表示支持所有域名
http.cors.allow-origin: "*"
ingest.geoip.downloader.enabled: false
slave1
# 设置集群名称,集群内所有节点的名称必须一致。
cluster.name: icp-es-cluster
# 设置节点名称,集群内节点名称必须唯一。
node.name: node2
# 表示该节点会不会作为主节点,true表示会;false表示不会
node.master: true
# 当前节点是否用于存储数据,是:true、否:false
node.data: true
# 索引数据存放的位置
#path.data: /usr/share/elasticsearch/data
# 日志文件存放的位置
#path.logs: /usr/share/elasticsearch/logs
# 需求锁住物理内存,是:true、否:false
#bootstrap.memory_lock: true
# 监听地址,用于访问该es
network.host: 0.0.0.0
# es对外提供的http端口,默认 9200
http.port: 19200
# TCP的默认监听端口,默认 9300
transport.tcp.port: 19300
# 设置这个参数来保证集群中的节点可以知道其它N个有master资格的节点。默认为1,对于大的集群来说,可以设置大一点的值(2-4)
discovery.zen.minimum_master_nodes: 1
# es7.x 之后新增的配置,写入候选主节点的设备地址,在开启服务后可以被选为主节点
discovery.seed_hosts: ["10.10.33.57:19300", "10.10.33.58:19300","10.10.33.59:19300"]
discovery.zen.fd.ping_timeout: 1m
discovery.zen.fd.ping_retries: 5
# es7.x 之后新增的配置,初始化一个新的集群时需要此配置来选举master
cluster.initial_master_nodes: ["node1"]
# 是否支持跨域,是:true,在使用head插件时需要此配置
http.cors.enabled: true
# “*” 表示支持所有域名
http.cors.allow-origin: "*"
ingest.geoip.downloader.enabled: false
slave2
# 设置集群名称,集群内所有节点的名称必须一致。
cluster.name: icp-es-cluster
# 设置节点名称,集群内节点名称必须唯一。
node.name: node3
# 表示该节点会不会作为主节点,true表示会;false表示不会
node.master: true
# 当前节点是否用于存储数据,是:true、否:false
node.data: true
# 索引数据存放的位置
#path.data: /usr/share/elasticsearch/data
# 日志文件存放的位置
#path.logs: /usr/share/elasticsearch/logs
# 需求锁住物理内存,是:true、否:false
#bootstrap.memory_lock: true
# 监听地址,用于访问该es
network.host: 0.0.0.0
# es对外提供的http端口,默认 9200
http.port: 19200
# TCP的默认监听端口,默认 9300
transport.tcp.port: 19300
# 设置这个参数来保证集群中的节点可以知道其它N个有master资格的节点。默认为1,对于大的集群来说,可以设置大一点的值(2-4)
discovery.zen.minimum_master_nodes: 1
# es7.x 之后新增的配置,写入候选主节点的设备地址,在开启服务后可以被选为主节点
discovery.seed_hosts: ["10.10.33.57:19300", "10.10.33.58:19300","10.10.33.59:19300"]
discovery.zen.fd.ping_timeout: 1m
discovery.zen.fd.ping_retries: 5
# es7.x 之后新增的配置,初始化一个新的集群时需要此配置来选举master
cluster.initial_master_nodes: ["node1"]
# 是否支持跨域,是:true,在使用head插件时需要此配置
http.cors.enabled: true
# “*” 表示支持所有域名
http.cors.allow-origin: "*"
ingest.geoip.downloader.enabled: false
初始化容器
docker run -d \
--name=elasticsearch-icp \
--restart=always \
--network=host \
-v /data1/elasticsearch/config:/usr/share/elasticsearch/config \
-v /data1/elasticsearch/logs:/usr/share/elasticsearch/logs \
-v /data1/elasticsearch/data:/usr/share/elasticsearch/data \
-v /data1/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
elasticsearch:7.17.8
验证
# 浏览器输入地址 查看3个节点是否都加入集群
http://10.10.33.102:19200/_cat/nodes
QA
如果出现新启动的节点无法加入集群,报错例如: "Caused by: org.elasticsearch.cluster.coordination.CoordinationStateRejectedException: This node previously joined a cluster with UUID [NR0YxxfATD2Y1q4PnhXfoA] and is now trying to join a different cluster with UUID [3d1d4hnwR2e5kU9yYH2K5w]. This is forbidden and usually indicates an incorrect discovery or cluster bootstrapping configuration. Note that the cluster UUID persists across restarts and can only be changed by deleting the contents of the node's data paths [] which will also remove any data held by this node."
可以删除/data1/elasticsearch/data
中的数据,再次重启容器
kibana
(单机)kibana.yml
配置
#Kibana的映射端口
server.port: 15601
#网关地址
server.host: "0.0.0.0"
#Kibana实例对外展示的名称
server.name: "kibana"
#Elasticsearch的集群地址,也就是说所有的集群IP
elasticsearch.hosts: ["http://10.10.33.57:19200","http://10.10.33.58:19200","http://10.10.33.59:19200"]
#设置页面语言,中文使用zh-CN,英文使用en
i18n.locale: "zh-CN"
xpack.monitoring.ui.container.elasticsearch.enabled: true
# es用户名、密码
elasticsearch.username: ""
elasticsearch.password: ""
容器启动
docker run -itd \
--network=host \
-v /data1/kibana/kibana.yml:/usr/share/kibana/config/kibana.yml \
--name kibana-icp \
kibana:7.17.8
only-office
(单机)下载only-office
镜像包,这里以onlyoffice/documentserver:7.1
为例
创建挂载目录
# 文档日志
mkdir -p /home/onlyoffice/documentserver/logs
# 证书
mkdir -p /home/onlyoffice/documentserver/data
# 文件缓存
mkdir -p /home/onlyoffice/documentserver/lib
# 数据库
mkdir -p /home/onlyoffice/documentserver/db
启动实例
docker run -i -t -d \
--name office-icp \
-p 7001:80 \
--restart=always \
-v /home/onlyoffice/documentserver/logs:/var/log/onlyoffice \
-v /home/onlyoffice/documentserver/data:/var/www/onlyoffice/Data \
-v /home/onlyoffice/documentserver/lib:/var/lib/onlyoffice \
-v /home/onlyoffice/documentserver/db:/var/lib/postgresql \
onlyoffice/documentserver:7.1
redis
主从ip | port | role |
---|---|---|
10.10.33.58 | 16379 | master |
10.10.33.58 | 26379 | sentinel |
10.10.33.59 | 16379 | slave |
10.10.33.59 | 26379 | sentinel |
10.10.33.60 | 16379 | slave |
10.10.33.60 | 26379 | sentinel |
下载redis
镜像包,安装版本:7.0.4
新增主、从节点redis.conf
配置
# bind 127.0.0.1
# 开启集群 这里是主从 不需要开启
#cluster-enabled yes
# 默认yes,开启保护模式,限制为本地访问
protected-mode no
# 默认no,改为yes意为以守护进程方式启动,可后台运行,除非kill进程,改为yes会使配置文件方式启动redis失败
daemonize no
dir ./
appendonly yes
logfile "access.log"
# redis密码配置
requirepass sillybilly@2022
# 修改端口号
port 16379
############################以下配置为从服务器配置,主服务器无需配置#################
#下面的IP和端口号为表示为redis主服务器
# replicaof 10.10.33.58 16379
# 如果主服务器配置了密码,则需要添加如下命令(zsrj@2022表示redis主服务器的密码)
# masterauth sillybilly@2022
新增哨兵sentinel.conf
配置
# 哨兵使用的端口号,默认是26379,可以更改
port 26379
# 文件存储位置
dir "/"
# 日志保存的文件路径(该文件路径必须存在)
logfile "/sentinel.log"
# 哨兵监控IP为10.10.33.58端口号为16379的redis主服务器,主服务器名称为redis-master,最后的数字表示数量,例如3台哨兵,其中有2台哨兵认为redis主服务器已经宕机,则主机已经宕机,否则不认为redis的主服务器宕机
sentinel monitor redis-master 10.10.33.58 16379 2
# 在指定的毫秒数内,若主节点没有应答哨兵的 PING 命令,此时哨兵认为服务器主观下线,默认时间为 30 秒。
sentinel down-after-milliseconds redis-master 5000
# 如果主服务器配置了密码,则哨兵也必须配置密码,否则哨兵无法对主从服务器进行监控,该密码与主服务器密码一致
sentinel auth-pass redis-master sillybilly@2022
# redis哨兵密码
requirepass sillybilly@2022
创建并启动主、从容器
# 主节点 10.10.33.58
docker run --net host --name redis-icp-master \
-v /home/redis/redis.conf:/redis.conf \
-v /home/redis/data:/data \
--privileged=true -d redis:7.0.4 redis-server /redis.conf
# 从节点 10.10.33.59
docker run --net host --name redis-icp-slave1 \
-v /home/redis/redis.conf:/redis.conf \
-v /home/redis/data:/data \
--privileged=true -d redis:7.0.4 redis-server /redis.conf
# 从节点 10.10.33.60
docker run --net host --name redis-icp-slave2 \
-v /home/redis/redis.conf:/redis.conf \
-v /home/redis/data:/data \
--privileged=true -d redis:7.0.4 redis-server /redis.conf
创建并启动哨兵
# 启动从节点1哨兵 10.10.33.58
docker run --net host --name redis-icp-sentinel1 \
-v /home/redis/sentinel.conf:/sentinel.conf \
-d redis:7.0.4 redis-sentinel /sentinel.conf
# 启动从节点2哨兵 10.10.33.59
docker run --net host --name redis-icp-sentinel2 \
-v /home/redis/sentinel.conf:/sentinel.conf \
-d redis:7.0.4 redis-sentinel /sentinel.conf
# 启动从节点3哨兵 10.10.33.60
docker run --net host --name redis-icp-sentinel3 \
-v /home/redis/sentinel.conf:/sentinel.conf \
-d redis:7.0.4 redis-sentinel /sentinel.conf
环境验证
# 进入主节点容器内部 containerId 为58环境master节点容器id
docker exec -it [containerId] bash
# 进入redis命令列界面
redis-cli -a sillybilly@2022 -p 16379
# 查看主从信息
info replication
# 进入哨兵容器内部 containerId 为任意环境哨兵容器id
docker exec -it [containerId] bash
# 进入redis命令列界面
redis-cli -a sillybilly@2022 -p 16379
# 查看哨兵监控信息
info sentinel
…
# 获取Docker中运行的组件的内网IP
docker inspect --format='{{.NetworkSettings.IPAddress}}' 【容器实例名称】
# 列出可用磁盘
fdisk -l
# 创建一个新的磁盘分区 使用命令:"fdisk 磁盘名称" (仅限2T磁盘的分区)
# 按提示依次操作
fdisk /dev/sdb
mkfs.ext4 /dev/sdb1
UUID
sudo blkid
UUID
写入配置sudo vim /etc/fstab
# 文件末尾添加磁盘信息
# UUID为上一步查询的结果 /data为挂载目录
# ext4:文件系统类型 defaults:挂载参数
# 第五个字段为dump 参数 用检查一个文件系统是否应该进行 dump 备份。不需要就设置为 0,如果需要每天备份,设置为 1,不定期备份,设置为 2
# 第六个字段为开机检查分区的次序。对于根分区,这个值为 1,表示优先。其它文件系统可以设置为 2,表示次优,如果为 0 或没有设置,开机跳过此文件系统的检查
UUID=d6644d06-0532-49d7-b7d4-5875b555a29c /data ext4 defaults 0 1
# 退出编辑 重启
reboot