参考文章:
DRBD 相关知识
DRBD 简介
DRBD的全称为:Distributed Replicated Block Device(DRBD)分布式块设备复制,DRBD是由内核模块和相关脚本构成,用以构建高可用的集群。其实现方式是通过网络来镜像整个设备。可以把它看作是一种网络RAID。它允许用户在远程机器上建立一个本地块设备的实时镜像。
DRBD 是如何工作的
(DRBD Primary)负责接收数据,把数据写到本地磁盘并发送给另一台主机(DRBD Secondary)。另一个主机再将数据存到自己的磁盘中。目前,DRBD 每次只允许对一个节点进行读写访问,但这对于通常的故障切换高可用集群来说已经足够用了,有可能以后的版本支持两个节点进行读写存取。
DRBD 协议说明:
1)数据一旦写入磁盘并发送到网络中就认为完成了写入操作。
2)收到接收确认就认为完成了写入操作。
3)收到写入确认就认为完成了写入操作。
DRBD 与 HA 的关系
一个 DRBD 系统由两个节点构成,与 HA 集群类似,也有主节点和备用节点之分,在带有主要设备的节点上,应用程序和操作系统可以运行和访问 DRBD 设备(/dev/drbd*)。在主节点写入的数据通过 DRBD 设备存储到主节点的设备写入到备用节点的磁盘中。现在大部分的高可用性集群都会使用共享存储,而 DRBD 也可以作为一个共享存储设备,使用 DRBD 不需要太多的硬件的设备。因为它在 TCP/IP 网络中运行,所以,利用 DRBD 作为共享存储设备,节约很多成本,因为价格要比专用的存储网络便宜很多;其性能与稳定性方面也不错。
DRBD 工作原理
DRBD是linux的内核的存储层中的一个分布式存储系统,可用使用DRBD在两台Linux服务器之间共享块设备,共享文件系统和数据。类似网络RAID-1,其工作的原理架构图如下:
DRBD 的特性
分布式复制块设备(DRBD技术)是一种基于软件的,无共享,复制的存储解决方案,在服务器之间的对块设备(硬盘、分区、逻辑卷等)进行镜像。
DRBD镜像数据的特性:
1)实时性:当某个应用程序完成对数据的修改时,复制功能立即发生
2)透明性:应用程序的数据存储在镜像块设备上是独立透明的,他们的数据在两个节点上都保存一份,因此,无论哪一台服务器宕机,都不会影响应用程序读取数据的操作,所以说是透明的。
3)同步镜像和异步镜像:同步镜像表示当应用程序提交本地的写操作后,数据会同步写到两个节点上去;异步镜像表示当应用程序提交写操作后,只有当本地的节点上完成写操作后,另一个节点才可以完成写操作。
DRBD 的模式
DRBD 共有2种模式,一种是 DRBD 的主从模式,另一种是 DRBD 的双主模式
1)DRBD的主从模式:
这种模式下,其中一个节点作为主节点,另一个节点作为从节点。其中主节点可以执行读、写操作;从节点不可以挂载文件系统,因此也不可以执行读写操作。在这种模式下,资源在任何时间只能存储在主节点上。这种模式可用在任何的文件系统(ext3、ext4、xfs)等。默认这种模式下,一旦主节点发生故障,从节点需要手工将资源进行转移,且主节点变成从节点和从节点变成主节点需要手动进行切换。不能自动进行转移,因此比较麻烦。
为了解决手动将资源和节点进行转移,可以将 DRBD 做成高可用集群的资源代理(RA),这样一旦其中的一个节点宕机,资源就会自动转移到另一个节点,从而保证服务的连续性。
2)DRBD 的双主模式:
这是 DRBD8.0 之后的新特性,在双主模式下,任何资源在任何特定的时间都存在两个主节点。这种模式需要一个共享的集群文件系统,利用分布式的锁机制进行管理,如 GFS 和 OCFS2。部署双主模式时,DRBD 可以是负载均衡的集群,这就需要从两个并发的主节点中选取一个首选的访问数据。这种模式默认是禁用的,如果要是用的话必须在配置文件中进行申明。
DRBD 的复制模式
DRBD 的复制功能就是将应用程序提交的数据一份保存在本地节点,一份复制传输保存在另一份节点上。但是 DRBD 需要对传输的数据进行确认以便保证另一个节点的写操作完成,就需要用到 DRBD 的复制模式,DRBD 有三种复制模式:
1)协议A:异步复制协议
一旦本地磁盘写入已经完成,数据包已在发送队列中,则写被认为是完成的。在一个节点上发生故障时,可能发生数据丢失,因为被写入到远程节点上的数据可能仍在发送队列。尽管,在故障转移节点上的数据是一致的,但没有及时更新。这通常是用于地理上分开的节点。
2)协议B:内存同步(半同步)复制协议
一旦本地磁盘写入已完成且复制数据包达到了对等节点则认为写在主节点上被认为是完成的。数据丢失可能发生在参加的两个节点同时故障的情况下,因为在传输中的数据可能不会被提交到磁盘。
3)协议C:同步复制协议
只有在本地和远程节点的磁盘已经确认了写操作完成,写才被认为完成。没有任何数据丢失,所以这是一个集群节点的流行模式,但I/O吞吐量依赖于网络带宽。一般使用协议C,但选择C协议将影响流量,从而影响网络延迟。为了数据可靠性,我们在生产环境使用时须慎重选择使用哪一种协议。
DRBD 配置文件说明
DRBD 的主配置文件为 /etc/drbd.conf
;为了管理的便捷性,目前通常会将配置文件分成多个部分,且都保存至 /etc/drbd.d
目录中,主配置文件中仅使用 "include"
指令将这些配置文件片断整合起来。通常,/etc/drbd.d
目录中的配置文件为 global_common.conf
和所有以 .res
结尾的文件。其中 global_common.conf
中主要定义 global
段和 common
段,而每一个 .res
的文件用于定义一个资源。
global
段在配置文件中仅能出现一次,且如果所有的配置信息都保存至同一个配置文件中而不分开为多个文件的话,global
段必须位于配置文件的最开始处。目前 global
段中可以定义的参数仅有 minor-count
, dialog-refresh
, disable-ip-verification
和 usage-count
。
common
段则用于定义被每一个资源默认继承的参数,可以在资源定义中使用的参数都可以在 common
段中定义。实际应用中,common
段并非必须,但建议将多个资源共享的参数定义为 common
段中的参数以降低配置文件的复杂度。
resource
段则用于定义 DRBD 资源,每个资源通常定义在一个单独的位于 /etc/drbd.d
目录中的以 .res
结尾的文件中。资源在定义时必须为其命名,名字可以由非空白的ASCII字符组成。每一个资源段的定义中至少要包含两个 host
子段,以定义此资源关联至的节点,其它参数均可以从 common
段或 DRBD 的默认中进行继承而无须定义。
DRBD配置文件如下:
1 | [root@drbd1 ~]# cat /etc/drbd.d/global_common.conf |
DRBD 安装配置(主从模式)
环境架构
这里使用所用环境为 ubuntu server 24.04 操作系统,在下面的操作步骤中 # command 的命令表示主从节点服务器都需要执行。
主机名 | IP 地址 | 系统版本 | 备注 |
---|---|---|---|
gitlab-server01 | 192.168.0.31 | Ubuntu Server 24.04 LTS | GitLab 主节点 |
gitlab-server02 | 192.168.0.32 | Ubuntu Server 24.04 LTS | GitLab 从节点 |
初始配置
两台机器上添加 DRBD 磁盘,并进行分区,不做格式化,并在本地系统创建 /data 目录,不做挂载操作。这里系统使用的是 LVM 管理,所以新建一个逻辑卷(data)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20# 将新加的磁盘分区
fdisk /dev/sdb
# 按照提示创建一个 Linux LVM 类型的分区
"n" --> "p" --> "1" --> "回车" --> "回车" --> "t" --> "8e" --> "w"
# 刷新磁盘信息
partprobe
# 创建 pv
pvcreate /dev/sdb1
# 扩容 vg
vgextend ubuntu-vg /dev/sdb1
# 创建 lv
lvcreate -l 100%Free -n data ubuntu-vg
# 创建指定大小空间的 lv
# lvcreate -L 40G -n data ubuntu-vg两台服务器之间的防火墙要允许互相访问,这里测试关闭selinux和防火墙(两台服务器同样操作)
1
2systemctl stop ufw
setenforce 0 //临时性关闭;永久关闭需修改/etc/sysconfig/selinux的SELINUX为disablehosts 绑定(两台服务器同样操作)
1
2
3
4cat >> /etc/hosts << EOF
192.168.0.31 gitlab-server01
192.168.0.32 gitlab-server02
EOF两台服务器进行时间同步(两台服务器同样操作,此处由于服务器配置了时间同步,所以略过)
1
2# yum -y install ntpdate
# ntpdate -u asia.pool.ntp.org
安装 DRBD
在两台服务器同样执行以下命令安装 DRBD
1
2apt update
apt install -y drbd-utils在(非常)旧的 Ubuntu 版本上,您可能还需要显式安装 drbd8-module;在较新的版本中,默认内核已包含上游 DRBD 版本。
安装过程可能需要手动配置 Postfix 邮件重启系统,确保内核已加载模块 drbd
1
2
3
4# lsmod |grep drbd
drbd 458752 0
lru_cache 16384 1 drbd
libcrc32c 12288 3 btrfs,drbd,raid456
配置 DRBD
在两台服务器上同样执行以下命令
查看 DRBD 配置文件
1
2
3
4
5# cat /etc/drbd.conf //主配置文件
# You can find an example in /usr/share/doc/drbd.../drbd.conf.example
include "drbd.d/global_common.conf";
include "drbd.d/*.res";备份配置文件
1
# cp /etc/drbd.d/global_common.conf{,.bak}
创建全局配置文件
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
29# vim /etc/drbd.d/global_common.conf //编辑全局配置文件
global {
usage-count no; # 是否参加 DRBD 使用统计,默认为 yes。官方统计drbd的装机量
udev-always-use-vnr;
}
common {
protocol C; # 指定复制协议,复制协议共有三种,为协议 A,B,C,默认协议为协议 C
handlers { # 该配置段用来定义一系列处理器,用来回应特定事件。
}
## DRBD 同步时使用的验证方式和密码。该配置段用来更加精细地调节 DRBD 属性,它作用于配置节点在启动或重启时。常用选项有:
startup {
wfc-timeout 15; # 该选项设定一个时间值,单位是秒。在启用DRBD块时,初始化脚本DRBD会阻塞启动进程的运行,直到对等节点的出现该选项就是用来限制这个等待时间的,默认为0,即不限制,永远等待。
degr-wfc-timeout 15; # 该选项也设定一个时间值,单位为秒。也是用于限制等待时间,只是作用的情形不同:它作用于一个降级集群(即那些只剩下一个节点的集群)在重启时的等待时间。
outdated-wfc-timeout 15; #同上,也是用来设定等待时间,单位为秒。它用于设定等待过期节点的时间
}
options {
}
disk {
on-io-error detach; # 发生I/O错误的节点将放弃底层设备,以diskless mode继续工作。在diskless mode下,只要还有网络连接,DRBD将从secondary node读写数据,而不需要failover(故障转移)。该策略会导致一定的损失,但好处也很明显,DRBD服务不会中断。官方推荐和默认策略。
}
net {
}
syncer {
rate 30M; # 设置主备节点同步时的网络速率
}
}创建资源文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17# vim /etc/drbd.d/gitlab.res #编辑资源配置文件
resource gitlab {
on gitlab-server01 {
device /dev/drbd1; # device 指定的參数最后必须有一个数字,用于 global 的 minor-count,否则会报错。device指定drbd应用层设备。
disk /dev/mapper/ubuntu--vg-data; # 新建的 LV 分区磁盘
address 192.168.0.31:7789; # DRBD 监听的地址和端口,端口可以自定义。
meta-disk internal;
}
on gitlab-server02 {
device /dev/drbd1;
disk /dev/mapper/ubuntu--vg-data; # 新建的 LV 分区磁盘
address 192.168.0.32:7789;
meta-disk internal;
}
}在两个节点上初始化 DRBD 元数据
1
2
3
4
5
6
7drbdadm create-md gitlab
# 正常的话会输出以下信息
initializing activity log
initializing bitmap (1280 KB) to all zero
Writing meta data...
New drbd meta data block successfully created.启动 DRBD 服务
1
systemctl enable --now drbd
查看 DRBD 状态以及资源组状态
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17# 查看 DRBD 状态
systemctl status drbd
# 查看 资源组
root@gitlab-server01:~# cat /proc/drbd
version: 8.4.11 (api:1/proto:86-101)
srcversion: 211FB288A383ED945B83420
1: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent C r-----
ns:0 nr:0 dw:0 dr:0 al:8 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:41937628
root@gitlab-server02:~# cat /proc/drbd
version: 8.4.11 (api:1/proto:86-101)
srcversion: 211FB288A383ED945B83420
1: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent C r-----
ns:0 nr:0 dw:0 dr:0 al:8 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:41937628由上面两台主机的DRBD状态查看结果里的ro:Secondary/Secondary表示两台主机的状态都是备机状态,ds是磁盘状态
将 gitlab-server01 服务器配置为 DRBD 的主节点,进行初始化设备同步
1
2
3
4
5
6
7
8
9root@gitlab-server01:~# drbdsetup /dev/drbd1 primary --force
root@gitlab-server01:~# cat /proc/drbd
version: 8.4.11 (api:1/proto:86-101)
srcversion: 211FB288A383ED945B83420
1: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r-----
ns:634388 nr:0 dw:0 dr:636532 al:8 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:41303240
[>....................] sync'ed: 1.6% (40332/40952)M
finish: 0:22:48 speed: 30,176 (30,208) K/sec同步完成时状态如下
1
2
3
4
5
6root@gitlab-server01:~# cat /proc/drbd
version: 8.4.11 (api:1/proto:86-101)
srcversion: 211FB288A383ED945B83420
1: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r-----
ns:41953124 nr:0 dw:0 dr:41955268 al:8 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0说明:
ro 在主从服务器上分别显示Primary/Secondary
和Secondary/Primary
ds显示UpToDate/UpToDate
表示主从配置成功此时也可以使用以下命令查看资源状态
1
2
3
4
5
6
7
8
9
10
11root@gitlab-server01:~# drbdadm status gitlab
gitlab role:Primary
disk:UpToDate
peer role:Secondary
replication:Established peer-disk:UpToDate
root@gitlab-server02:~# drbdadm status gitlab
gitlab role:Secondary
disk:UpToDate
peer role:Primary
replication:Established peer-disk:UpToDate
验证 DRBD 主备
gitlab-server01 主节点挂载 drbd1,创建测试数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23# 格式化 drbd1
mkfs.ext4 /dev/drbd1
# 创建挂载目录
mkdir /data
# 挂载设备 drbd1
mount /dev/drbd1 /data
# 查看挂载信息
root@gitlab-server01:~# df -Th
Filesystem Type Size Used Avail Use% Mounted on
tmpfs tmpfs 387M 1.5M 386M 1% /run
/dev/mapper/ubuntu--vg-root ext4 53G 2.2G 48G 5% /
tmpfs tmpfs 1.9G 0 1.9G 0% /dev/shm
tmpfs tmpfs 5.0M 0 5.0M 0% /run/lock
/dev/sda2 ext4 2.0G 95M 1.7G 6% /boot
tmpfs tmpfs 387M 8.0K 387M 1% /run/user/1000
/dev/drbd1 ext4 40G 24K 38G 1% /data
# 创建测试文件
touch /data/{test1,test2,test3}
echo "test" > /data/test.txt特别注意:
从节点(Secondary)上不允许对 DRBD 设备进行任何操作,包括只读,所有的读写操作只能在主节点(Primary)上进行。
只有当主节点(Primary)挂掉时,从节点(Secondary)才能提升为主节点(Primary)。主节点切换,将 gitlab-server01 节点关机,然后将 gitlab-server02节点设置为主节点
1
2
3
4
5
6
7
8
9
10root@gitlab-server02:~# drbdadm primary gitlab
root@gitlab-server02:~# mkdir /data
root@gitlab-server02:~# mount /dev/drbd1 /data/
root@gitlab-server02:~# cat /data/
lost+found/ test1 test2 test3 test.txt
root@gitlab-server02:~# cat /data/test.txt
test
# 在 gitlab-server02 节点创建测试数据
echo 'gitlab-server02' > /data/test2启动 gitlab-server01 服务器,然后再切换 gitlab-server01 为主节点,gitlab-server02 为备节点
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15# gitlab-server02 取消挂载 drbd1 设备
root@gitlab-server02:~# umount /data
# 将 gitlab-server02 角色配置为 从
root@gitlab-server02:~# drbdadm secondary gitlab
# 将 gitlab-server01 角色设置为主
root@gitlab-server01:~# drbdadm primary gitlab
# gitlab-server01 挂载 drbd 设备
root@gitlab-server01:~# mount /dev/drbd1 /data/
# gitlab-server01 服务器查看刚才在 gitlab-server02 上修改文件是否正常
root@gitlab-server01:~# cat /data/test2
gitlab-server02
安装 GitLab(两个节点都要安装)
安装并配置必要的依赖项
1
2
3
4
5sudo apt-get update
sudo apt-get install -y curl openssh-server ca-certificates tzdata perl
# 安装 Postfix 来发送通知电子邮件(可选)
sudo apt-get install -y postfix添加 GitLab 包存储库并安装包
1
curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | sudo bash
安装 gitlab-ce 软件包
1
2
3
4
5
6
7
8
9
10
11
12
13sudo apt-get install gitlab-ce
# 列出可用版本
apt-cache madison gitlab-ce
# 安装指定版本
sudo apt-get install gitlab-ce=17.1.2-ce.0
# 固定版本以限制自动更新
sudo apt-mark hold gitlab-ce
# 显示哪些包裹被固定版本
sudo apt-mark showhold修改配置
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
29
30
31
32
33# 外部访问的地址
external_url 'https://gitlab.59izt.com'
# 发送邮件的地址
gitlab_rails['gitlab_email_from'] = '1562658xxxx@163.com'
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.163.com" #在线邮件服务器地址
gitlab_rails['smtp_port'] = 25 #端口号,开启本地发邮件的端口
gitlab_rails['smtp_user_name'] = "1562658xxxx@163.com" #邮箱地址
gitlab_rails['smtp_password'] = "xxxxasdasdsadsad" #邮箱授权码
gitlab_rails['smtp_domain'] = "163.com"
gitlab_rails['smtp_authentication'] = "login" #在登录时,查看是否有授权码
gitlab_rails['smtp_enable_starttls_auto'] = true #加密方式
gitlab_rails['smtp_tls'] = false #加密方式
# 更改 gitlab 数据存放目录
git_data_dirs({
"default" => {
"path" => "/data/git-data"
}
})
# 修改 postgresql 数据存放目录
postgresql['data_dir'] = "/data/postgresql/data"
postgresql['dir'] = "/data/postgresql"
postgresql['home'] = "/data/postgresql"
# 启用 https 配置
nginx['enable'] = true
nginx['client_max_body_size'] = '250m'
nginx['redirect_http_to_https'] = true
nginx['ssl_certificate'] = "/data/gitlab/ssl/59izt.com.pem"
nginx['ssl_certificate_key'] = "/data/gitlab/ssl/59izt.com.key"
主节点操作
将 drbd 挂载到 gitlab 数据目录,gitlab 默认的数据目录在
/var/opt/gitlab
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# 停止gitlab服务
gitlab-ctl stop
# 将 gitlab-server01 设置为主节点
drbdadm primary gitlab
# 挂载drbd1
mount /dev/drbd1 /data
#同步历史数据
rsync -av /var/opt/gitlab/git-data /data/git-data
rsync -av /var/opt/gitlab/postgresql /data/postgresql
#删除原文件
rm -fr /var/opt/gitlab/{git-data,postgresql}
# 创建 SSL 证书目录并上传证书到该目录
mkdir -p /data/gitlab/ssl
# 重新编译 gitlab 配置文件
gitlab-ctl reconfigure
# 检查 gitlab 配置文件
gitlab-ctl check-config
#启动gitlab
gitlab-ctl start配置 DNS 解析域名,然后浏览器访问
http://gitlab.59izt.com
并登录,除非您在安装过程中提供了自定义密码,否则密码将随机生成并在/etc/gitlab/initial_root_password
中存储 24 小时。使用此密码和用户名 root 登录。如果密码不对,也可以使用以下命令重置密码
1
gitlab-rake "gitlab:password:reset"
根据提示输入用户名和新的密码即可
登录 gitlab 创建 spring 项目,测试下载项目以及 push 修改
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43# 测试拉取代码
$ git clone https://gitlab.59izt.com/pet/gateway.git
Cloning into 'gateway'...
Username for 'https://gitlab.59izt.com': root
Password for 'https://root@gitlab.59izt.com':
remote: Enumerating objects: 30, done.
remote: Total 30 (delta 0), reused 0 (delta 0), pack-reused 30 (from 1)
Receiving objects: 100% (30/30), 49.97 KiB | 24.98 MiB/s, done.
# 在仓库中新增文件
wanwu@192 ~ % cd gateway
echo "1111111" > test.txt
wanwu@192 gateway % git add .
wanwu@192 gateway % git commit -m "测试上传"
[master c3b0134] 测试上传
Committer: 万物 <wanwu@192.168.0.101>
Your name and email address were configured automatically based
on your username and hostname. Please check that they are accurate.
You can suppress this message by setting them explicitly. Run the
following command and follow the instructions in your editor to edit
your configuration file:
git config --global --edit
After doing this, you may fix the identity used for this commit with:
git commit --amend --reset-author
1 file changed, 1 insertion(+)
create mode 100644 test.txt
# 测试 push 操作
wanwu@192 gateway % git push
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 8 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 288 bytes | 288.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
To https://gitlab.59izt.com/pet/gateway.git
0934f0e..c3b0134 master -> master登录 gitlab 查看提交是否正常
模拟主节点宕机
关闭主节点服务器,在备节点将 drbd 角色设置为主节点
1
drbdadm primary gitlab
挂载 drbd1 设备
1
mount /dev/drbd1 /data/
启动 gitlab
1
gitlab-ctl start
修改 DNS 解析地址到 gitlab-server02 服务器上,打开浏览器访问
https://gitlab.59izt.com
,查看是否能正常登录服务器,以及刚在 gitlab-server01 节点提交的文件是否正常。