四、docker 仓库之分布式Harbor

实验环境:

业务

ip

系统

harbor1

192.168.11.11

kylin-sp1-0518-x86

harbor2

192.168.11.12

kylin-sp1-0518-x86

nginx、keepalived

192.168.11.21

kylin-sp2-0524-x86

nginx、keepalived

192.168.11.22

kylin-sp2-0524-x86

Harbor 是一个用于存储和分发 Docker 镜像的企业级 Registry服务器,由 vmware 开源,其通过添加一些企业必需的功能特性,例如安全、标识和管理等,扩展了开源 Docker Distribution。作为一个企业级私有 Registry 服务器,Harbor 提供了更好的性能和安全。提升用户使用 Registry 构建和运行环境传输镜像的效率。Harbor 支持安装在多个 Registry 节点的镜像资源复制,镜像全部保存在私有 Registry 中, 确保数据和知识产权在公司内部网络中管控,另外,Harbor 也提供了高级的安全特性,诸如用户管理,访问控制和活动审计等。

vmware 官方开源服务列表地址:https://github.com/vmware/ (现在已经捐献给了CNCF)

云原生基金会:https://www.cncf.io/

harbor 官方 github 地址:https://github.com/goharbor/harbor

harbor 官方网址:https://goharbor.io/

基于角色的访问控制:用户与 Docker 镜像仓库通过“项目”进行组织管理, 一个用户可以对多个镜像仓库在同一命名空间(project)里有不同的权限。

镜像复制:镜像可以在多个 Registry 实例中复制(同步)。尤其适合于负载均衡,高可用,混合云和多云的场景。

图形化用户界面:用户可以通过浏览器来浏览,检索当前Docker 镜像仓库,管理项目和命名空间。

AD/LDAP 支持:Harbor 可以集成企业内部已有的AD/LDAP,用于鉴权认证管理。

审计管理:所有针对镜像仓库的操作都可以被记录追溯,用于审计管理。

国际化:已拥有英文、中文、德文、日文和俄文的本地化版本。更多的语言将会添加进来。

RESTful API :提供给管理员对于 Harbor 更多的操控, 使得与其它管理软件集成变得更容易。

部署简单:提供在线和离线两种安装工具, 也可以安装到vSphere 平台(OVA 方式)虚拟设备。

nginx:harbor 的一个反向代理组件,代理 registry、ui、token 等服务。这个代理会转发 harbor web 和docker client 的各种请求到后端服务上。

harbor-adminserver:harbor 系统管理接口,可以修改系统配置以及获取系统信息。

harbor-db:存储项目的元数据、用户、规则、复制策略等信息。

harbor-jobservice:harbor 里面主要是为了镜像仓库之间同步使用的。

harbor-log:收集其他 harbor 的日志信息。

harbor-ui:一个用户界面模块,用来管理 registry。

registry:存储 docker images 的服务,并且提供pull/push 服务。

redis:存储缓存信息webhook:当 registry 中的image 状态发生变化的时候去记录更新日志、复制等操作。

token service:在 docker client 进行 pull/push的时候负责 token 的发放。

4.1 安装 Harbor

下载地址:https://github.com/goharbor/harbor/releases

安装文档:https://goharbor.io/docs/2.3.0/

4.1.1 安装 docker

本次使用当前 harbor 稳定版本 2.3.5 离线安装包 ,具体名称为 harbor-offline-installer-v2.3.5.tgz

在两台主机上设置主机名,域名解析

[root@localhost ~]# hostnamectl set-hostname harbor1.kylin.com

[root@harbor1 ~]# cat <<EOF>> /etc/hosts
192.168.11.11 harbor1.kylin.com harbor1
192.168.11.12 harbor2.kylin.com harbor2
192.168.11.100 img.kylin.com
EOF
[root@harbor1 ~]# vim /etc/docker/daemon.json
{
  "registry-mirrors": ["https://yydlt76u.mirror.aliyuncs.com"],
  "insecure-registries": [
          "http://img.kylin.com",
          "http://harbor1.kylin.com",
          "http://harbor2.kylin.com"
  ]
}
[root@harbor1 ~]# systemctl daemon-reload 
[root@harbor1 ~]# systemctl restart docker.service 

[root@harbor1 ~]# docker info
...
...
Insecure Registries:
 harbor1.kylin.com
 harbor2.kylin.com
 img.kylin.com
 127.0.0.0/8
Registry Mirrors:
 https://yydlt76u.mirror.aliyuncs.com/
Live Restore Enabled: true

4.1.2 下载 Harbor 安装包

链接:https://pan.baidu.com/s/1VjLbTRVadJBZeXGBo0cVDw

提取码:1111

[root@harbor1 ~]# ls harbor-offline-installer-v2.3.5.tgz 
harbor-offline-installer-v2.3.5.tgz

4.2 配置 Harbor

4.2.1 解压并编辑 harbor.yml 配置文件

之前的版本配置文件名称为 harbor.cfg

[root@harbor1 ~]# tar xf harbor-offline-installer-v2.3.5.tgz -C /usr/local/
[root@harbor1 ~]# cd /usr/local/harbor/
[root@harbor1 harbor]# ls
common.sh  harbor.v2.3.5.tar.gz  harbor.yml.tmpl  install.sh  LICENSE  prepare
[root@harbor1 harbor]# cp harbor.yml.tmpl harbor.yml
[root@harbor1 harbor]# vim harbor.yml

修改以下5行

hostname: harbor1.kylin.com
#开启https需要生成证书 ,但是自己生成的证书不可信,还是需要加入不安全的惊醒仓库,所以此处建议关闭
#https:
  # port: 443
  #certificate: /your/certificate/path     公钥证书
  #private_key: /your/private/key/path     私钥证书

[root@harbor1 harbor]# grep -vEn "#|^$" harbor.yml
5:hostname: harbor1.kylin.com
8:http:
10:  port: 80
34:harbor_admin_password: Harbor12345
37:database:
39:  password: root123
41:  max_idle_conns: 100
44:  max_open_conns: 900
47:data_volume: /data
71:trivy:
73:  ignore_unfixed: false
79:  skip_update: false
82:  insecure: false
95:jobservice:
97:  max_job_workers: 10
99:notification:
101:  webhook_job_max_retry: 10
103:chart:
105:  absolute_url: disabled
108:log:
110:  level: info
112:  local:
114:    rotate_count: 50
118:    rotate_size: 200M
120:    location: /var/log/harbor
132:_version: 2.3.0
189:proxy:
190:  http_proxy:
191:  https_proxy:
192:  no_proxy:
193:  components:
194:    - core
195:    - jobservice
196:    - trivy

4.3 启动 Harbor

4.3.1 安装 docker-compose

启动之前先确保,本机已经安装 docker-compose 命令,如未安装会报错,请先安装。

[root@harbor1 harbor]# ls
common.sh  harbor.v2.3.5.tar.gz  harbor.yml  harbor.yml.tmpl  install.sh  LICENSE  prepare
[root@harbor1 harbor]# ./install.sh 
[Step 0]: checking if docker is installed ...
Note: docker version: 20.10.22
[Step 1]: checking docker-compose is installed ...
✖ Need to install docker-compose(1.18.0+) by yourself first and run this script again.

docker-compose下载链接

链接:https://pan.baidu.com/s/1yh_CSiO6wXouqbpp4N5pkg

提取码:1111

[root@harbor1 ~]# mv docker-compose-Linux-x86_64 /usr/local/bin/docker-compose
[root@harbor1 ~]# 
[root@harbor1 ~]# docker-compose 
[root@harbor1 ~]# docker-compose version
docker-compose version 1.29.2, build 5becea4c
docker-py version: 5.0.0
CPython version: 3.7.10
OpenSSL version: OpenSSL 1.1.0l  10 Sep 2019


如果联网状态下直接进行安装
[root@localhost ~]# yum -y install  docker-compose.noarch
[root@localhost ~]# docker-compose version 
docker-compose version 1.22.0, build f46880f
docker-py version: 4.0.2
CPython version: 3.7.9
OpenSSL version: OpenSSL 1.1.1f  31 Mar 2020

4.3.2 安装

[root@localhost harbor]# pwd
/usr/local/harbor
[root@localhost harbor]# ls
common.sh  harbor.v2.3.5.tar.gz  harbor.yml  harbor.yml.tmpl  install.sh  LICENSE  prepare

[root@localhost harbor]# ./install.sh 

[root@localhost harbor]# docker images
REPOSITORY                      TAG                 IMAGE ID            CREATED             SIZE
goharbor/harbor-exporter        v2.3.5              1730c6f650e2        12 months ago       81.9MB
goharbor/chartmuseum-photon     v2.3.5              47004f032938        12 months ago       179MB
goharbor/redis-photon           v2.3.5              3d0cedc89a0d        12 months ago       156MB
goharbor/trivy-adapter-photon   v2.3.5              5c0212e98070        12 months ago       133MB
goharbor/notary-server-photon   v2.3.5              f20a76c65359        12 months ago       111MB
goharbor/notary-signer-photon   v2.3.5              b9fa38eef4d7        12 months ago       108MB
goharbor/harbor-registryctl     v2.3.5              7a52567a76ca        12 months ago       133MB
goharbor/registry-photon        v2.3.5              cf22d3e386b8        12 months ago       82.6MB
goharbor/nginx-photon           v2.3.5              5e3b6d9ce11a        12 months ago       45.7MB
goharbor/harbor-log             v2.3.5              a03e4bc963d6        12 months ago       160MB
goharbor/harbor-jobservice      v2.3.5              2ac32df5a2e0        12 months ago       211MB
goharbor/harbor-core            v2.3.5              23baee01156f        12 months ago       193MB
goharbor/harbor-portal          v2.3.5              bb545cdedf5a        12 months ago       58.9MB
goharbor/harbor-db              v2.3.5              9826c57a5749        12 months ago       221MB
goharbor/prepare                v2.3.5              a1ceaabe47b2        12 months ago       255MB


[root@harbor1 harbor]# docker ps 
CONTAINER ID   IMAGE                                COMMAND                  CREATED              STATUS                        PORTS                       NAMES
77f43df29d33   goharbor/harbor-jobservice:v2.3.5    "/harbor/entrypoint.…"   About a minute ago   Up About a minute (healthy)                               harbor-jobservice
351b0196198a   goharbor/nginx-photon:v2.3.5         "nginx -g 'daemon of…"   About a minute ago   Up About a minute (healthy)   0.0.0.0:80->8080/tcp        nginx
1cf642be8bda   goharbor/harbor-core:v2.3.5          "/harbor/entrypoint.…"   About a minute ago   Up About a minute (healthy)                               harbor-core
7fcca6701a7d   goharbor/redis-photon:v2.3.5         "redis-server /etc/r…"   About a minute ago   Up About a minute (healthy)                               redis
8527925dd844   goharbor/harbor-portal:v2.3.5        "nginx -g 'daemon of…"   About a minute ago   Up About a minute (healthy)                               harbor-portal
b3d56391077e   goharbor/registry-photon:v2.3.5      "/home/harbor/entryp…"   About a minute ago   Up About a minute (healthy)                               registry
35c744075364   goharbor/harbor-registryctl:v2.3.5   "/home/harbor/start.…"   About a minute ago   Up About a minute (healthy)                               registryctl
b114a64763e2   goharbor/harbor-db:v2.3.5            "/docker-entrypoint.…"   About a minute ago   Up About a minute (healthy)                               harbor-db
a280a5d3962a   goharbor/harbor-log:v2.3.5           "/bin/sh -c /usr/loc…"   About a minute ago   Up About a minute (healthy)   127.0.0.1:1514->10514/tcp   harbor-log

[root@harbor1 harbor]# ss -tnl
State                        Recv-Q                       Send-Q                                             Local Address:Port                                             Peer Address:Port                       Process                       
LISTEN                       0                            512                                                    127.0.0.1:1514                                                  0.0.0.0:*                                                        
LISTEN                       0                            128                                                      0.0.0.0:111                                                   0.0.0.0:*                                                        
LISTEN                       0                            128                                                      0.0.0.0:22                                                    0.0.0.0:*                                                        
LISTEN                       0                            128                                                            *:9090                                                        *:*                                                        
LISTEN                       0                            128                                                         [::]:111                                                      [::]:*                                                        
LISTEN                       0                            512                                                            *:80                                                          *:*                                                        
LISTEN                       0                            128                                                         [::]:22                                                       [::]:*    

[root@harbor1 harbor]# docker-compose ps
      Name                     Command                  State                 Ports          
---------------------------------------------------------------------------------------------
harbor-core         /harbor/entrypoint.sh            Up (healthy)                            
harbor-db           /docker-entrypoint.sh 96 13      Up (healthy)                            
harbor-jobservice   /harbor/entrypoint.sh            Up (healthy)                            
harbor-log          /bin/sh -c /usr/local/bin/ ...   Up (healthy)   127.0.0.1:1514->10514/tcp
harbor-portal       nginx -g daemon off;             Up (healthy)                            
nginx               nginx -g daemon off;             Up (healthy)   0.0.0.0:80->8080/tcp     
redis               redis-server /etc/redis.conf     Up (healthy)                            
registry            /home/harbor/entrypoint.sh       Up (healthy)                            
registryctl         /home/harbor/start.sh            Up (healthy)                            
[root@harbor1 harbor]# 
                                                    

[root@harbor1 harbor]# ls -lh /data/
总用量 0
drwxr-xr-x 2   10000 10000  6  1月  5 14:20 ca_download
drwx------ 3 unbound input 18  1月  5 14:20 database
drwxr-xr-x 2   10000 10000  6  1月  5 14:20 job_logs
drwxr-xr-x 2 unbound input  6  1月  5 14:20 redis
drwxr-xr-x 2   10000 10000  6  1月  5 14:20 registry
drwxr-xr-x 5 root    root  46  1月  5 14:20 secret

data目录包含的文件夹和相应的作用

模块

说明

ca_download

存放用户访问Harbor时所需的CA。

database

存放数据库的目录,Harbor、Clair和Notary 数据库的数据都在此目录

job_logs

存放JobService的日志信息

redis

缓存数据

registry

存放 OCI Artifacts数据(对于大部分用户来说是镜像数据)

secret

存放Harbor内部组件通信所需的加密信息

#chart_storage

存放Helm v2版本的Chart数据。

4.3.3 登录web页面

win电脑需要在hosts文件添加域名才可以使用域名访问,也可以直接使用IP地址访问

http://192.168.11.11/

账号:admin

密码:Harbor2345

4.4 停止与启动和重启Harbor

cd /usr/local/harbor

#停止harbor
docker-compose stop
docker ps -a

#启动harbor
docker-compose start

#重启harbor
docker-compose restart

#如果重启不成功,则直接使用 install.sh 脚本
# docker-compose down
# ./install.sh

4.5 harbor https 配置

[root@harbor1 harbor]# docker-compose down
[root@harbor1 harbor]# docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

[root@harbor1 ~]# mkdir /etc/certs
[root@harbor1 ~]# cd /etc/certs/

#生成自签证书
[root@harbor1 certs]# openssl genrsa -out harbor-ca.key 2048
[root@harbor1 certs]# openssl req -x509 -new -nodes -key harbor-ca.key -subj "/CN=harbor1.kylin.com" -days 7120 -out harbor-ca.crt
[root@harbor1 certs]# ls
harbor-ca.crt  harbor-ca.key



[root@harbor1 certs]# cd /usr/local/harbor/
#修改harbor配置文件
[root@harbor1 harbor]# vim harbor.yml
 13 https:
 14   # https port for harbor, default is 443
 15    port: 443
 16   # The path of cert and key files for nginx
 17   certificate: /etc/certs/harbor-ca.crt     #注意修改保存公钥的路径
 18   private_key: /etc/certs/harbor-ca.key     #注意修改保存私钥的路径

#重新执行安装脚本
./install.sh
#注意自签名证书是不被信任的所以,还是需要配置 --insecure-registry harbor1.kylin.com 才可以使用,或者直接使用授权证书

4.6 配置 docker 使用 harbor 仓库上传下载镜像

4.6.1 编辑 docker 配置文件

可以编写daemon或者一下文件,本文开篇已经写过daemon这里可以不用在写

vim /lib/systemd/system/docker.service
"insecure-registries": [
 "https://harbor1.kylin.com",
 "https://harbor2.kylin.com",
 "https://img.kylin.com"
]

#配置dns解析
cat >> /etc/hosts <<EOF
192.168.11.11 harbor1.kcc.com
192.168.11.12 harbor2.kcc.com
192.168.11.100 harbor.kcc.com
EOF

#重启服务
systemctl daemon-reload 
systemctl restart docker

4.6.2 验证能否登录 harbor

可以现在界面创建一个项目,添加一个成员并设置为项目的管理员

[root@harbor1 harbor]# docker login harbor1.kylin.com
Username: user1
Password: 
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded   #出现这个表示登录成功

4.6.3 测试上传和下载镜像

将之前构建的镜像打标签上传到 harbor 服务器用于测试

4.6.3.1 导入镜像

#先给镜像打tag
[root@harbor1 ~]# docker tag busybox:latest harbor1.kylin.com/kylin1/bbox:v1
[root@harbor1 ~]# docker images | grep bbox
harbor1.kylin.com/kylin1/bbox   v1        beae173ccac6   12 months ago   1.24MB

#上传如果提示project imagesbase not found表示没有这个项目需要先去web端创建项目
[root@harbor1 harbor]# docker push harbor1.kylin.com/kylin1/bbox:v1
Using default tag: latest
The push refers to repository [harbor1.kylin.com/kylin1/bbox]
tag does not exist: harbor1.kylin.com/kylin1/bbox:latest

#创建后再次上传
[root@harbor1 ~]# docker push harbor1.kylin.com/kylin1/bbox:v1 
The push refers to repository [harbor1.kylin.com/kylin1/bbox]
01fd6df81c8e: Pushed 
v1: digest: sha256:62ffc2ed7554e4c6d360bce40bbcf196573dd27c4ce080641a2c59867e732dee size: 527

新建项目时,勾选公开表示可以匿名下载本项目中镜像,但是上传必须登录,如果不勾选表示上传和下载都得登录

4.6.3.2 下载镜像

下载镜像的 docker 主机需要配置 insecure-registries,如果使用可信的证书,则不需要

在harbor2上进行下载测试

#下载时可以写IP地址,如写域名需要配置dns
[root@harbor2 ~]# docker login harbor1.kylin.com

#拉去命令可以登录网页版进行复制
[root@harbor2 ~]# docker pull harbor1.kylin.com/kylin1/bbox@sha256:62ffc2ed7554e4c6d360bce40bbcf196573dd27c4ce080641a2c59867e732dee

[root@harbor2 ~]# docker images 
REPOSITORY                      TAG       IMAGE ID       CREATED         SIZE
harbor1.kylin.com/kylin1/bbox   <none>    beae173ccac6   12 months ago   1.24MB

4.7 实现 harbor 高可用

高可用实现方式

Harbor 支持基于策略的 Docker 镜像复制功能,这类似于MySQL 的主从同步,其可以实现不同的数据中心、不同的运行环境之间同步镜像,并提供友好的管理界面,大大简化了实际运维中的镜像管理工作,已经有用很多互联网公司使用harbor 搭建内网 docker 仓库的案例,并且还有实现了双向复制的案列

4.7.1 实现双向同步复制的高可用

架构图

4.7.1.1 部署harbor的同步集群

#安装俩台harbor主机 harbor1 harbor2

#配置文件harbor.yml

vim harbor.yml

hostname: 192.168.11.11/12

#这里只能写的IP地址,写域名会导致创建目标仓库测试失败

#配置 Harbor 复制必须使用 https

#启动

./install.sh

在 harbor1 的 web 页面配置

这里目标名称可以随便写,访问ID访问密码按自己的情况填写,验证证书不要勾选,之后点测试连接,然后点确定

配置复制规则

名称:随便写

复制模式:选择推送模式,还是拉取模式

触发模式:事件驱动 (如果要将同步之前的旧镜像推送到远程,设置为手动)

其他:默认

###同样的操作在harbor2上进行配置

测试

能从 harbor1 上传下载镜像

能从 harbor2 下载从 harbor1 同步过来的镜像

反之亦然,如果全部成功说明同步没有问题

[root@harbor2 harbor]# docker tag goharbor/nginx-photon:v2.3.5 harbor2.kylin.com/kylin1/harbortest:v1
[root@harbor2 harbor]# docker login harbor2.kylin.com
[root@harbor2 harbor]# docker push harbor2.kylin.com/kylin1/harbortest:v1

本来原有的镜像使用手动复制进行同步

4.7.1.2 安装 nginx

在开启两台虚拟机11.21和11.22

两台都执行
[root@localhost ~]# yum -y install nginx

#如果 nginx 需要监听 VIP,需要配置下面内核参数
#vim /etc/sysctl.conf
#net.ipv4.ip_nonlocal_bind = 1
#此参数表示是否允许服务绑定一个本机不存在的IP地址
#sysctl -p

[root@localhost ~]# cp /etc/nginx/nginx.conf{,.bak}


[root@localhost ~]# vim /etc/nginx/nginx.conf

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
events {
    worker_connections 1024;
}
stream {
    upstream harbor_server {
      hash $remote_addr consistent;
      server 192.168.11.11:443 max_fails=3 fail_timeout=30s;
      server 192.168.11.12:443 max_fails=3 fail_timeout=30s;
    }
    server {
       listen 80;
       listen 443;
       proxy_connect_timeout 3s;
       proxy_timeout 30s;
       proxy_pass harbor_server;
    }
}

[root@localhost ~]# nginx -t

[root@localhost ~]# systemctl enable --now nginx
[root@localhost ~]# ss -tnl
State                        Recv-Q                       Send-Q                                             Local Address:Port                                             Peer Address:Port                       Process                       

LISTEN                       0                            511                                                      0.0.0.0:80                                                    0.0.0.0:*                                                        

LISTEN                       0                            511                                                      0.0.0.0:443                                                   0.0.0.0:*                                                        

4.7.1.3 安装keepalive

#俩台都执行

[root@localhost ~]# vim /etc/keepalived/keepalived.conf 
! Configuration File for keepalived
  
global_defs {
   router_id LVS_DEVEL
}
vrrp_script check-nginx {
  script "/etc/keepalived/chnginx.sh"
  weight -30
  timeout 2
  fall 2
  rise 3
  interval 2
}
vrrp_instance VI_1 {
  state MASTER
  interface ens160
  virtual_router_id 80
  priority 100
  advert_int 1
  authentication {
      auth_type PASS
      auth_pass 1111
  }
  virtual_ipaddress {
        192.168.11.100/24
  }
  track_script {
  check-nginx
  }
}
~        


[root@localhost ~]# vim /etc/keepalived/chnginx.sh
#!/bin/bash
/usr/bin/killall -0 nginx

[root@localhost ~]# chmod +x /etc/keepalived/chnginx.sh

#ke2配置修改相关内容和脚本
vrrp_instance VI_1 {
  state BACKUP
  interface ens160
  virtual_router_id 80
  priority 80


#启动全部
[root@localhost keepalived]# systemctl start keepalived.service 
[root@localhost keepalived]# systemctl enable keepalived.service 

[root@localhost ~]# ip a

2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0c:29:63:07:0f brd ff:ff:ff:ff:ff:ff
    inet 192.168.11.21/24 brd 192.168.11.255 scope global noprefixroute ens160
       valid_lft forever preferred_lft forever
    inet 192.168.11.100/24 scope global secondary ens160
       valid_lft forever preferred_lft forever
    inet6 fe80::4bfd:424c:d8e:a76/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

4.7.1.4 docker测试

在harbor1上传镜像,之后在harbor2上使用vip进行登录下载或者上传测试

[root@harbor2 docker]# docker login img.kylin.com

Login Succeeded

[root@harbor2 ~]# docker images | grep bbox

[root@harbor2 ~]#

[root@harbor2 harbor]# docker pull img.kylin.com/kylin1/bbox:v1

[root@harbor2 harbor]# docker images | grep bbox

harbor1.kylin.com/kylin1/bbox v1 beae173ccac6 12 months ago 1.24MB

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值