GlusterFs集群部署和Heketi配置

本文详细介绍了GlusterFS的多种存储模式,包括分布卷、复制模式、条带模式等,并逐步讲解了GlusterFS集群的安装配置、Heketi的部署与使用,以及如何通过Heketi创建和管理GlusterFS卷。同时,文章涵盖了集群的卸载和Gluster volume的调优基础知识。

1. 了解GlusterFS几种存储模式

分布卷(DHT)

默认模式。将文件以hash算法随机分布到一个文件服务器节点中进行存储。Volume创建命令如下:

gluster volume create test-volume server1:/exp1 server2:/exp2

复制模式(AFR)

将文件复制到replica x个文件节点中。Volume创建命令如下:

gluster volume create test-volume replica 2 transport tcp server1:/exp1 server2:/exp2

条带模式(Striped)

类似raid0,将文件切割成多个数据块,分别存储到stripe x个文件节点中。可以通过如下命令创建Volume:

gluster volume create test-volume stripe 2 transport tcp server1:/exp1 server2:/exp2

分布式条带模式(组合型)

分布式卷(DHT)和条带模式(Striped)的组合,至少需要4台服务器才能创建。存储时将文件切割成多个数据库,然后每个数据块以hash算法随机分布到一个文件服务器上进行存储。Volume创建命令如下:

gluster volume create test-volume stripe 2 transport tcp server1:/exp1 server2:/exp2 server3:/exp3 server4:/exp4

分布式复制模式(组合型)

分布式卷(DHT)和复制模式(AFR)的组合,至少需要4台服务器才能创建。将文件以hash算法随机分布到一个文件服务器节点,然后在通过复制算法复制replica x个节点进行保存。创建命令:

gluster volume create test-volume replica 2 transport tcp server1:/exp1 server2:/exp2 server3:/exp3 server4:/exp4

条带复制卷模式(组合型)

条带模式(Striped)和复制模式(AFT)的组合型,需要至少4台服务器才可以创建,将文件拆成多个数据块,分别复制存储到replica x个节点上。创建命令如下:

gluster volume create test-volume stripe 2 replica 2 transport tcp server1:/exp1 server2:/exp2 server3:/exp3 server4:/exp4

分布式条带复制模式(组合型)

三种模式的组合,至少需要8太服务器才能创建,至少2个服务器组,每个组包含2个条带模式节点和2个复制节点。创建命令:

gluster volume create test-volume stripe 2 replica 2 transport tcp server1:/exp1 server2:/exp2 server3:/exp3 server4:/exp4 server5:/exp5 server6:/exp6 server7:/exp7 server8:/exp8

2. 准备工作

搭建集群时采用裸盘进行搭建,因此在搭建前需要保持每个节点至少有2TB的裸跑供集群使用。

  1. 查看磁盘

    通过lsblk命令可以查看到当前服务器可用的磁盘空间和挂载情况,如:

    [root@HP-Map-Dev-1 ~]# lsblk
    NAME                                        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
    sda                                           8:0    0  100G  0 disk 
    ├─sda1                                        8:1    0    1G  0 part /boot
    └─sda2                                        8:2    0   99G  0 part 
      ├─centos-root                             253:0    0   50G  0 lvm  /
      └─centos-home                             253:1    0 41.1G  0 lvm  /home
    sdb                                           8:16   0    4T  0 disk 
    ├─sdb1                                        8:17   0  1.8T  0 part 
    │ └─ceph--b5f52a01--2cd7--444a--b0b4--69ab5e16f162-osd--data--1a378cfc--b6ca--4683--9548--f8df231a971f
                                                253:3    0  1.8T  0 lvm  
    └─sdb2                                        8:18   0  1.8T  0 part 
      └─ceph--b0c5a99a--e838--41bd--8870--ffe829764c36-osd--data--dd2d578c--8def--4ce6--ab6a--ac7bfbf648a3
                                                253:2    0  1.8T  0 lvm  
    sr0                                          11:0    1 1024M  0 rom  
    rbd0                                        252:0    0    5G  0 disk /var/lib/kubelet/plugins/kubernetes.io/csi/pv/pvc-edf0192e-174d-43b9-b320-d624e451b77d/globalmount/0001-0009-rook-ceph-0000000000000001-5877653a-28ad-11eb-b1e6-6e4e1efdd373
    rbd1                                        252:16   0    5G  0 disk /var/lib/kubelet/plugins/kubernetes.io/csi/pv/pvc-57dc57d7-0544-4cab-af83-dcc992a89196/globalmount/0001-0009-rook-ceph-0000000000000001-f935ee04-28ac-11eb-b1e6-6e4e1efdd373
    rbd2                                        252:32   0    5G  0 disk /var/lib/kubelet/plugins/kubernetes.io/csi/pv/pvc-8f61ac1f-4c86-4a5e-bda2-9194bbbcc9b8/globalmount/0001-0009-rook-ceph-0000000000000001-585cdeea-28ad-11eb-b1e6-6e4e1efdd37
    

    可见rbd0、rbd1、rbd2三个盘挂载到了/var/lib/kubelet/plugins/kubernetes.io/csi/pv目录之下。

  2. 清除已有的lvm
    查看当前节点上存在的lvm,在确保lvm中数据可以正常删除的前提下删除原有的lvm分区释放磁盘空间。LVM的删除过程大致如下:

    • 先卸载系统上面的 LVM 文件系统 (包括快照与所有 LV)
    • 使用 lvremove 移除 LV
    • 使用 vgchange -a n VGname 让 VGname 这个 VG 不具有 Active 的标志
    • 使用 vgremove 移除 VG
    • 使用 pvremove 移除 PV

    相关示例操作如下:

    # 卸载文件系统上的挂载,全部卸载完成后需要再次确认/etc/fstable或其他自动挂载配置是否关闭,否则可能导致重启后挂载失败导致主机无法正常启动
    umount /var/lib/kubelet/plugins/kubernetes.io/csi/pv/pvc-8f61ac1f-4c86-4a5e-bda2-9194bbbcc9b8/globalmount/0001-0009-rook-ceph-0000000000000001-585cdeea-28ad-11eb-b1e6-6e4e1efdd373/
    
    # 查看lv
    lvdisplay
    # 移除LV
    lvremove /dev/rbd1
    
    # 查看vg
    vgdisplay
    # 从vg中删除pv
    vgreduce centos /dev/sdb
    # 删除vg
    vgremove xxxx
    
    # 查看pv
    pvs
    # 删除pv,注意!!!删除前需要确认pv中是否有数据,如果有数据需要使pvmove将数据移动走,否则会导致数据丢失
    pvremove xxxx
    
    # 查看lvm常规信息
    dmsetup ls
    # 删除
    dmsetup remove xxx
    

    特别注意:在pv删除前需要确认pv上是否有数据,有数据一定要先使用pvmove移动到其他pv上,否则可能导致数据丢失

  3. 磁盘分区

    非必须操作。如果需要将大磁盘中部分分区留作其他用途时可以进行磁盘分区。

    # 修改已有磁盘分区
    fdisk /dev/xxx
    
    # 格式化磁盘
    fdisk /dev/xxx
    
    # 重新制作分区
    fdisk /dev/xxx
    # 如果磁盘总空间超过2TB,用fdisk可能无法正常分区,此时可以使用parted工具进行分区
    # parted /dev/xxx
    

    分区完成之后用于GlusterFs分布式存储的分区不需要再进行分区格式化。

  4. 修改主机host

    编辑/etc/hosts文件,增加主机hosts定义。

    10.8.202.135 gluster-node1
    10.8.202.136 gluster-node2
    10.8.202.137 gluster-node3
    10.8.202.133 gluster-node4
    10.8.202.134 gluster-node5
    
  5. 关闭防火墙和SELinux

    # 关闭防火墙
    systemctl stop firewalld;systemctl disable firewalld
    
    # 关闭SELinux
    setenforce 0
    

    编辑/etc/selinux/config文件,将其中的SELINUX修改为disabled

3.安装GlusterFs

3.1 在线安装

# 安装epel依赖源
yum -y install epel-release
# 查看有哪些版本
yum search centos-release-gluster
# 安装glaster-7的代码仓库,离线包地址:https://buildlogs.centos.org/centos/7/storage/x86_64/gluster-7/
yum install -y centos-release-gluster7.noarch
# 安装 glusterfs-server,当前安装的版本为7.8
yum install -y glusterfs-server glusterfs-fuse
# 查看gluster版本
gluster --version
# 启动服务
systemctl start glusterd.service
systemctl enable glusterd.service
systemctl status glusterd

3.2 编译安装

  1. 下载依赖

    yum -y --disablerepo=rhs* --enablerepo=*optional-rpms install git autoconf \
        automake bison dos2unix flex fuse-devel glib2-devel libaio-devel \
        libattr-devel libibverbs-devel librdmacm-devel libtool libxml2-devel lvm2-devel make \
        openssl-devel pkgconfig pyliblzma python-devel python-eventlet python-netifaces \
        python-paste-deploy python-simplejson python-sphinx python-webob pyxattr readline-devel \
        rpm-build systemtap-sdt-devel tar libcmocka-devel libacl-devel
    

    如果下载失败可以找一台能正常下载的主机,然后使用如下命令下载安装包

    # 创建缓存目录
    mkdir -p package
    
    # 下载安装包
    yum --disablerepo=rhs* --enablerepo=*optional-rpms install git autoconf \
        automake bison dos2unix flex fuse-devel glib2-devel libaio-devel \
        libattr-devel libibverbs-devel librdmacm-devel libtool libxml2-devel lvm2-devel make \
        openssl-devel pkgconfig pyliblzma python-devel python-eventlet python-netifaces \
        python-paste-deploy python-simplejson python-sphinx python-webob pyxattr readline-devel \
        rpm-build systemtap-sdt-devel tar libcmocka-devel libacl-devel --downloadonly --downloaddir=./package
    
  2. 下载安装包

    • 从https://download.gluster.org/pub/gluster/glusterfs/下载所需要的glusterFs源码包(本文下载7.8版本)。
    • 从https://github.com/urcu/userspace-rcu下载最新userspace-rcu源码包。
  3. 编译安装userspace-rcu

    unzip userspace-rcu-master.zip
    cd userspace-rcu-master
    ./bootstrap
    ./configure
    make -j8 && make install
    ldconfig
    
  4. 编译安装glusterfs

    # 解压代码
    tar xf glusterfs-7.8.tar.gz
    
    # 进入代码目录
    cd glusterfs-7.8
    
    # 生成配置
    ./autogen.sh
    ./configure
    
    # 编译。注意!如果是7.8在编译前线执行FAQ中错误1的修复,否则会编译出错
    make -j8 && make install
    

    FAQ:

    • error: redefinition of 'cds_list_add_tail_rcu’

      解决办法:https://blog.youkuaiyun.com/weixin_30781433/article/details/101663057

      修改/usr/local/include/urcu/rculist.h./contrib/userspace-rcu/rculist-extra.h两个文件,给该文件加上编译控制条件:

      #ifndef CDS_LIST_ADD_TAIL_CRU
      #define CDS_LIST_ADD_TAIL_CRU
      static inline
      void cds_list_add_tail_rcu(struct cds_list_head *newp,
                      struct cds_list_head *head)
      {
              newp->next = head;
              newp->prev = head->prev;
              rcu_assign_pointer(head->prev->next, newp);
              head->prev = newp;
      }
      #endif
      

      之后执行make clea然后再重新make -j8 & make install

  5. 配置配置

    # 配置glusterFs开机启动
    systemctl enable glusterd
    
    # 启动glusterFs
    systemctl start glusterd
    
    # 查看glusterFs启动状态
    systemctl status glusterd
    
  6. 测试
    可以使用gluster peer status查看当前集群状态。如下为常见的测试命令:

    # 查看集群状态
    gluster peer status
    
    # 查看volume信息
    gluster volue info
    
    # 查看所有的volume
    gluster volime list
    

3.3 GlusterFs集群配置

3.3.1 节点发现

在任意一个节点上发现其他节点,组成GlusterFs集群,假设另外节点的hostname为gluster-server02则命令为:

gluster peer probe gluster-server02
  • 常见问题:
    1. Probe returned with unknown errno 107
      可能原因如下:
      • 查看目标服务器上的防火墙是否关闭;

      • 查看glusterd在两台机器上都启动并运行;

      • 检查两台服务器能否ping的通;

3.3.2 节点移除

要移除节点可以使用如下命令:

gluster peer detach gluster-server02

4. Heketi部署

Heketi提供了一个RESTful管理界面,可以用来管理GlusterFS卷的生命周期。 通过Heketi,就可以像使用OpenStack Manila,Kubernetes和OpenShift一样申请可以动态配置GlusterFS卷。Heketi会动态在集群内选择bricks构建所需的volumes,这样以确保数据的副本会分散到集群不同的故障域内。同时Heketi还支持任意数量的ClusterFS集群,以保证接入的云服务器不局限于单个GlusterFS集群。

注意:heketi只能部署单节点!

4.1 在线安装heketi

在一个节点上安装heketi服务:

# 当前安装的是9.0版本
yum install heketi heketi-client  -y

# 查看版本
heketi --version
heketi-cli --version

4.2 离线安装heketi

从https://github.com/heketi/heketi下载离线安装包如heketi-v6.0.0.linux.amd64.tar.gz

  1. 安装

    解压离线安装包并安装:

    tar -xvf heketi-v6.0.0.linux.amd64.tar.gz
    
    # 安装
    cd heketi
    \cp heketi /usr/bin/
    \cp heketi-cli /usr/bin/
    

4.3 heketi配置和启动

  1. 创建数据目录

    创建heketi所需要的目录:

    # 添加用户
    useradd heketi
    
    # 创建数据目录
    mkdir -p /var/lib/heketi/
    mkdir -p /etc/heketi/
    
    # 修改用户组
    chown -R heketi:heketi /etc/heketi
    chown -R heketi:heketi /var/lib/heketi
    
  2. 创建ssh免密登录密钥

    在heketi运行的主机上生成密钥,并将密钥拷贝到其他主机上:

    ssh-keygen -t rsa -q -f /etc/heketi/id_rsa -N ''
    
    for host in gluster-node1 gluster-node2 gluster-node3; do ssh-copy-id -i /etc/heketi/id_rsa root@${host}; done
    
    #ssh-copy-id -i /etc/heketi/id_rsa root@glusterfs-c1-node01
    #ssh-copy-id -i /etc/heketi/id_rsa root@glusterfs-c1-node02
    #ssh-copy-id -i /etc/heketi/id_rsa root@glusterfs-c1-node03
    

    将公钥拷贝heketi_key.pub到其他服务器节点的根目录下。
    建议以非root方式配置heketi,配置方法可以查阅《以非root用户部署Heketi.md》中的说明。

  3. 修改配置

    将解压后的配置文件拷贝到/etc/heketi目录下。然后做如下修改:

    • 修改use_auth: true启用认证,并修改admin和user用户的key。开启后在调用是需要添加--user=admin --secret=123456(123456为设置的admin的key值);
    • 修改executorssh
    • 修改sshexeckeyfile为**/etc/heketi/id_rsa**,userroot,必须以root用户执行。
  4. 修改heketi启动服务

    修改/usr/lib/systemd/system/heketi.service文件,否则启动服务时会报错:

    [Unit]
    Description=Heketi Server
    
    [Service]
    Type=simple
    WorkingDirectory=/var/lib/heketi
    EnvironmentFile=-/etc/heketi/heketi.json
    User=heketi
    ExecStart=/usr/bin/heketi --config=/etc/heketi/heketi.json
    Restart=on-failure
    StandardOutput=syslog
    StandardError=syslog
    
    [Install]
    WantedBy=multi-user.target
    

    注意:在线安装的heketi,启动用户为heketi,此时/etc/heketi和/var/lib/heketi的用户组必须是heketi用户。

  5. 配置

    配置heketi开机自启动。

    # 配置glusterFs开机启动
    systemctl enable heketi.service
    
    # 启动glusterFs
    systemctl start heketi.service
    
    # 查看glusterFs启动状态
    systemctl status heketi.service
    
  6. 测试

    在确认heketi启动完成后,可以使用如下命令访问heketi服务器查看是否正常启动:

    curl http://127.0.0.1:8080/hello
    # Hello from Heketi
    

4.4 设置heketi系统拓扑

拓扑信息用于让Heketi确认可以使用的节点、磁盘和集群,管理员必须自行确定节点的故障域。故障域是赋予一组节点的整数值,这组节点共享相同的交换机、电源或其他任何会导致它们同时失效的组件。管理员必须确认哪些节点构成一个集群,Heketi使用这些信息来确保跨故障域中创建副本,从而提供数据冗余能力,Heketi支持多个Gluster存储集群。

  1. 创建heketi集群topology
    glutserfs集群数据主要包含节点node,brick存储点device,创建一个heketi集群的topology,文件路径为/etc/heketi/heketi-topology.json,内容如下:

    {
      "clusters": [
        {
          "nodes": [
            {
              "node": {
                "hostnames": {
                  "manage": [
                    "192.168.124.81"
                  ],
                  "storage": [
                    "192.168.124.81"
                  ]
                },
                "zone": 1
              },
              "devices": [
                "/dev/sdb"
              ]
            },
            {
              "node": {
                "hostnames": {
                  "manage": [
                    "192.168.124.82"
                  ],
                  "storage": [
                    "192.168.124.82"
                  ]
                },
                "zone": 1
              },
              "devices": [
                "/dev/sdb"
              ]
            },
            {
              "node": {
                "hostnames": {
                  "manage": [
                    "192.168.124.83"
                  ],
                  "storage": [
                    "192.168.124.83"
                  ]
                },
                "zone": 1
              },
              "devices": [
                "/dev/sdb"
              ]
            }		
          ]
        }
      ]
    }
    

    上面的系统拓扑中定义三个节点在同一个集群中,并指明各个节点用于提供存储的设备。注意:IP不能改为hostname,否则在k8s中创建时可能出错。

  2. 加载系统拓扑

    先将HEKETI服务器的信息设置为环境变量,之后使用heketi-cli工具加载系统拓扑:

    # 设置环境变量,注意glusterfs-c1-node02为heketi服务器的hostname
    echo "export HEKETI_CLI_SERVER=http://glusterfs-c1-node02:8080" > /etc/profile.d/heketi.sh
    
    # 激活配置
    source /etc/profile.d/heketi.sh
    
    # 查看已有集群
    heketi-cli --user admin --secret myAdmin88..  --json  cluster list
    
    # 加载系统拓扑
    heketi-cli --user=admin --secret=myAdmin88.. topology load --json=/etc/heketi/heketi-topology.json 
    

FAQ:

  1. Unable to add device: /bin/bash: pvcreate: command not found

    解决办法:创建是在/usr/bin目录下创建一个软连接,指向pvcreate:

       ln -s /usr/sbin/pvcreate /usr/bin/pvcreate
    
  2. Unable to create node: /bin/bash: gluster: command not found

    解决办法:在/usr/bin目录下创建一个软连接,指向gluster:

    ln -s  /usr/local/sbin/gluster /usr/bin/gluster
    

4.5 通过heketi创建volume

  1. 创建volume
    执行如下命令测试通过heketi创建volume:

    # 创建一个测试卷(大小1GB,默认3副本)
    heketi-cli --user=admin --secret=myAdmin88.. volume create --size=1 
    

    创建成功提示如下类似信息:

    Name: vol_cd2ca1fe4ebf512a3f5b39b37bf92f65
    Size: 1
    Volume Id: cd2ca1fe4ebf512a3f5b39b37bf92f65
    Cluster Id: 00488c61aceb8db43b8b9145eb7deef5
    Mount: glusterfs-c1-node01:vol_cd2ca1fe4ebf512a3f5b39b37bf92f65
    Mount Options: backup-volfile-servers=glusterfs-c1-node02,glusterfs-c1-node03
    Block: false
    Free Size: 0
    Block Volumes: []
    Durability Type: replicate
    Distributed+Replica: 3
    
  2. 查看
    可以通过heketi-cli查看分区,也可以通过glusterfs查看。查看创建的volume的命令如下:

     # 通过heketi查看
     heketi-cli volume list --user=admin --secret=myAdmin88..
    
     # 通过glusterfs查看
     gluster volume list
     # 查看volume详细信息,其中vol_a0eef26f5873eb842dd65db819b2fa65为要查看的volume name。
     gluster volume info vol_a0eef26f5873eb842dd65db819b2fa65 
     # 查看volume状态
     gluster volume status vol_a0eef26f5873eb842dd65db819b2fa65
    
     # 查看挂载状态
     cat /etc/fstab
    
     # 查看pv,vg,lvm
     lvs
     vgs
     pvs
    
  3. 挂载使用
    在一台主机上创建挂载目录,然后挂载创建的volume到目录下使用:

    # 创建挂载点
    mkdir -p /mnt/volume0
    # 挂载volume
    mount -t glusterfs glusterfs-c1-node01:/vol_a0eef26f5873eb842dd65db819b2fa65 /mnt/volume0/
    
    # 以复制集模式挂载,3个副本
    #mount -t glusterfs -o auto_unmount,backup-volfile-servers=10.8.203.227:10.8.203.228:10.8.203.229 10.8.203.227:vol_00d56383ccd22f7e8db8f280d146c4e8 /mnt/volume0 
    # 写入测试数据
    cd /mnt/volume0/
    for i in `seq -w 1 100`; do cp -rp /var/log/messages /mnt/volume0/copy-test-$i; done
    # 查看测试数据
    ls -lA /mnt/volume0/copy* | wc -l
    100
    

    在其他节点上创建挂载点,然后挂载目录进行测试。

    如果需要开机自动挂载,可以在/etc/fstab中增加自动挂载配置,如:

    127.0.0.1:vol_d5155371d164d27e69e7924ce7460e29 /nfs/data glusterfs auto_unmount,backup-volfile-servers=gluster-c2-node1:gluster-c2-node2:gluster-c2-node3 0 0
    
  4. 删除

    使用heketi-cli删除volume:

    # 查看volume id或者通过 gluster volume list查看,其中不包含vol_开头的部分即为id
    heketi-cli volume list --user=admin --secret=myAdmin88..
    
    # 删除,假设id为xxxx
    heketi-cli volume delete xxxx --user=admin --secret=myAdmin88..
    

5. 删除集群

假设heketi和gluster无法正常使用,那么可以使用传统的方式进行数据清理:

5.1 使用heketi删除

如果heketi和gluster还可以正常使用,可以通过如下步骤删除集群:

# 删除volume
## 查看volume列表
heketi-cli --user admin --secret myAdmin88..  volume list
## 删除volume,需要删除所有的volume
heketi-cli --user admin --secret myAdmin88..  volume delete b1e33efc21748998836160e01c9cb2b2

# 删除集群
## 查看集群
heketi-cli --user admin --secret myAdmin88..  --json  cluster list
## 删除集群,集群id_xxxxx
heketi-cli --user admin --secret myAdmin88..  --json  cluster delete id_xxxxx

# 删除vg
## 查看vg
vgs
## 删除
vgremove xxxx

# 删除pv
## 查看pv
pvs
## 删除pv
pvremove /dev/sdb

完成删除操作后停止heketi和gluster的服务即可。停止服务之后执行如下命令清楚heketi数据

rm -rf /etc/heketi
rm -rf /var/lib/heketi

5.2 传统方式删除

  1. 卸载已挂载目录

查看/etc/fstab中已经挂载的目录,然后使用umount命令进行取消挂载。之后从fstab中将该条挂载记录删除

  1. 删除lvm
# 查看lvm,lvdisplay可以接上vg的名称查看指定vg上的lvm
lvdisplay

# 删除lvm,假设lvm的id为xxxx
lvremove xxxx
  1. 删除VG
# 查看vg
vgs

# 删除,假设id为vg_xxxxx
vgremove vg_xxxxx
  1. 删除pv
# 查看所有的pv
pvs

# 删除pv,假设磁盘为/dev/sdb
pvremove /dev/sdb
  1. 卸载服务
systemctl stop heketi.service
systemctl disable heketi.service

systemctl stop gluster
systemctl disable gluster
  1. 清除历史数据
    执行如下命令清除heketi的预留数据:
rm -rf /etc/heketi
rm -rf /var/lib/heketi

6. 卸载

6.1 gluster卸载

6.1.1 卸载源码编译安装的glusterFs

如果是基于源码编译安装的glusterfs可以在编译安装目录下通过如下命令进行卸载:

make uninstall-recursive
make uninstall
make mostlyclean-recursive
make clean-recursive
make distclean-recursive

然后执行如下删除文件:

for i in `find / -name "gluster*"`; do rm -rf $i; done
6.1.2 卸载在线安装的glusterFs

在线安装的方式使用如下命令卸载:

yum remove -y glusterfs glusterfs-server glusterfs-fuse

7. Gluster volume调优

待补充。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值